start new controllers
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
namespace zero.Models;
|
||||
|
||||
public interface IZeroRouteEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the entity
|
||||
/// </summary>
|
||||
string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique hash for this entity (primarily used for routing)
|
||||
/// </summary>
|
||||
string Hash { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using Newtonsoft.Json;
|
||||
using Raven.Client.Documents.Session;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace zero.Models;
|
||||
|
||||
public class ListQuery<T>
|
||||
{
|
||||
public string Search { get; set; } = null;
|
||||
|
||||
public Expression<Func<T, object>> SearchSelector { get; set; } = null;
|
||||
|
||||
public Expression<Func<T, object>>[] SearchSelectors { get; private set; } = Array.Empty<Expression<Func<T, object>>>();
|
||||
|
||||
public string OrderBy { get; set; } = "createdDate";
|
||||
|
||||
public ListQueryOrderType OrderType { get; set; } = ListQueryOrderType.String;
|
||||
|
||||
public bool OrderIsDescending { get; set; } = true;
|
||||
|
||||
public Func<IQueryable<T>, IQueryable<T>> OrderQuery = null;
|
||||
|
||||
public int Page { get; set; } = 1;
|
||||
|
||||
public int PageSize { get; set; } = 30;
|
||||
|
||||
public bool IncludeInactive { get; set; } = false;
|
||||
|
||||
public QueryStatistics Statistics { get; internal set; }
|
||||
|
||||
public void SearchFor(params Expression<Func<T, object>>[] selectors)
|
||||
{
|
||||
SearchSelectors = selectors;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ListQuery<T, TFilter> : ListQuery<T> where TFilter : IListSpecificQuery
|
||||
{
|
||||
public TFilter Filter { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public static class ListQueryExtensions
|
||||
{
|
||||
public static ListQuery<T, TFilter> AsList<T, TFilter>(this string options) where TFilter : IListSpecificQuery
|
||||
{
|
||||
return JsonConvert.DeserializeObject<ListQuery<T, TFilter>>(options);
|
||||
}
|
||||
|
||||
public static ListQuery<T> AsList<T>(this string options) where T : IListSpecificQuery
|
||||
{
|
||||
return JsonConvert.DeserializeObject<ListQuery<T>>(options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface IListSpecificQuery { }
|
||||
|
||||
public class EmptyListSpecificQuery : IListSpecificQuery { }
|
||||
|
||||
|
||||
public class ListQueryDateRange
|
||||
{
|
||||
public DateTimeOffset? From { get; set; }
|
||||
|
||||
public DateTimeOffset? To { get; set; }
|
||||
}
|
||||
|
||||
public class ListQueryRange
|
||||
{
|
||||
public decimal? From { get; set; }
|
||||
|
||||
public decimal? To { get; set; }
|
||||
}
|
||||
|
||||
public enum ListQueryOrderType
|
||||
{
|
||||
String,
|
||||
Number
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
using FluentValidation.Results;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace zero.Models;
|
||||
|
||||
[DataContract(Name = "result", Namespace = "")]
|
||||
public class EntityResult<T>
|
||||
{
|
||||
[DataMember(Name = "model")]
|
||||
public T Model { get; set; }
|
||||
|
||||
[DataMember(Name = "success")]
|
||||
public bool IsSuccess { get; set; }
|
||||
|
||||
[DataMember(Name = "errors")]
|
||||
public IList<EntityResultError> Errors { get; set; } = new List<EntityResultError>();
|
||||
|
||||
public EntityResult() { }
|
||||
|
||||
public EntityResult(ValidationResult validation)
|
||||
{
|
||||
IsSuccess = validation.IsValid;
|
||||
Errors = validation.Errors.Select(x => new EntityResultError()
|
||||
{
|
||||
Property = x.PropertyName,
|
||||
Message = x.ErrorMessage
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public static EntityResult<T> From<TOrigin>(EntityResult<TOrigin> with, T model = default)
|
||||
{
|
||||
EntityResult<T> result = new EntityResult<T>();
|
||||
|
||||
result.IsSuccess = with.IsSuccess;
|
||||
result.Errors = with.Errors;
|
||||
result.Model = model;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void AddError(string property, string message)
|
||||
{
|
||||
IsSuccess = false;
|
||||
Errors.Add(new EntityResultError()
|
||||
{
|
||||
Property = property,
|
||||
Message = message
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void AddError(string message)
|
||||
{
|
||||
IsSuccess = false;
|
||||
Errors.Add(new EntityResultError()
|
||||
{
|
||||
Property = Constants.ErrorFieldNone,
|
||||
Message = message
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public EntityResult<T> Combine(EntityResult<T> with)
|
||||
{
|
||||
if (IsSuccess && !with.IsSuccess)
|
||||
{
|
||||
IsSuccess = false;
|
||||
}
|
||||
foreach (EntityResultError error in with.Errors)
|
||||
{
|
||||
Errors.Add(error);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static EntityResult<T> Success() => new EntityResult<T>() { IsSuccess = true };
|
||||
|
||||
public static EntityResult<T> Success(T model) => new EntityResult<T>() { IsSuccess = true, Model = model };
|
||||
|
||||
public static EntityResult<T> Fail() => new EntityResult<T>() { };
|
||||
|
||||
public static EntityResult<T> Fail(string property, string message)
|
||||
{
|
||||
EntityResult<T> result = new EntityResult<T>();
|
||||
result.AddError(property, message);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static EntityResult<T> Fail(string message)
|
||||
{
|
||||
EntityResult<T> result = new EntityResult<T>();
|
||||
result.AddError(message);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static EntityResult<T> Fail(ValidationResult validation) => new EntityResult<T>(validation);
|
||||
|
||||
public static EntityResult<T> Fail(EntityResultError error) => Fail(error.Property, error.Message);
|
||||
|
||||
public static EntityResult<T> Fail(IEnumerable<EntityResultError> errors) => new EntityResult<T>() { IsSuccess = !errors.Any(), Errors = errors.ToList() };
|
||||
}
|
||||
|
||||
|
||||
public class EntityResult : EntityResult<object>
|
||||
{
|
||||
public EntityResult() : base() { }
|
||||
|
||||
public EntityResult(ValidationResult validation) : base(validation) { }
|
||||
|
||||
public static EntityResult Maybe(bool isSuccess) => isSuccess ? Success() : Fail();
|
||||
|
||||
public new static EntityResult Success() => new EntityResult() { IsSuccess = true };
|
||||
|
||||
public new static EntityResult Fail() => new EntityResult() { };
|
||||
}
|
||||
|
||||
|
||||
[DataContract(Name = "resultError", Namespace = "")]
|
||||
public class EntityResultError
|
||||
{
|
||||
[DataMember(Name = "property")]
|
||||
public string Property { get; set; }
|
||||
|
||||
[DataMember(Name = "message")]
|
||||
public string Message { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
namespace zero.Models;
|
||||
|
||||
public class Paged<T> : Paged
|
||||
{
|
||||
public IList<T> Items { get; set; } = new List<T>();
|
||||
|
||||
public Paged(IList<T> items, long totalItems, long pageNumber, long pageSize) : this(totalItems, pageNumber, pageSize)
|
||||
{
|
||||
Items = items;
|
||||
}
|
||||
|
||||
public Paged<TTarget> MapTo<TTarget>(Func<T, TTarget> convertItem)
|
||||
{
|
||||
return new Paged<TTarget>(Items.Select(x => convertItem(x)).Where(x => x != null).ToList(), TotalItems, Page, PageSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class Paged
|
||||
{
|
||||
public long Page { get; protected set; }
|
||||
|
||||
public long PageSize { get; protected set; }
|
||||
|
||||
public long TotalPages { get; protected set; }
|
||||
|
||||
public long TotalItems { get; protected set; }
|
||||
|
||||
public bool HasMore { get; protected set; }
|
||||
|
||||
|
||||
public Paged(long totalItems, long page, long pageSize)
|
||||
{
|
||||
TotalItems = totalItems;
|
||||
Page = page;
|
||||
PageSize = pageSize;
|
||||
|
||||
if (pageSize > 0)
|
||||
{
|
||||
TotalPages = (long)Math.Ceiling(totalItems / (decimal)pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
TotalPages = 1;
|
||||
}
|
||||
|
||||
HasMore = TotalPages > Page;
|
||||
}
|
||||
|
||||
public int GetSkipSize()
|
||||
{
|
||||
if (Page > 0 && PageSize > 0)
|
||||
{
|
||||
return Convert.ToInt32((Page - 1) * PageSize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using Newtonsoft.Json;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace zero.Models;
|
||||
|
||||
[DebuggerDisplay("Id = {Id,nq}, Name = {Name}, Alias = {Alias}")]
|
||||
public class ZeroEntity : ZeroIdEntity, IZeroDbConventions, IZeroRouteEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Full name of the entity
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Alias (non-unique) which can be used in the frontend and URLs
|
||||
/// </summary>
|
||||
public string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A key which can be used to query this entity in code
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sort order
|
||||
/// </summary>
|
||||
public uint Sort { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the entity is visible in the frontend
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unique hash for this entity (primarily used for routing)
|
||||
/// </summary>
|
||||
public string Hash { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Backoffice user who last modified this content
|
||||
/// </summary>
|
||||
public string LastModifiedById { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Date of last modification
|
||||
/// </summary>
|
||||
public DateTimeOffset LastModifiedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Backoffice user who created this content
|
||||
/// </summary>
|
||||
public string CreatedById { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Date of creation
|
||||
/// </summary>
|
||||
public DateTimeOffset CreatedDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Configuration of the base entity (which this one inherits from)
|
||||
/// </summary>
|
||||
public BlueprintConfiguration Blueprint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Language of the entity
|
||||
/// </summary>
|
||||
public string LanguageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// [Warning] This field is always empty when bound to the database.
|
||||
/// It is only filled in the app-code for routing.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string Url { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace zero.Models;
|
||||
|
||||
[RavenCollection("Previews")]
|
||||
public class ZeroEntityPreview : ZeroEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the original entity
|
||||
/// </summary>
|
||||
public string OriginalId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contains the entity content
|
||||
/// </summary>
|
||||
public ZeroEntity Content { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace zero.Models;
|
||||
|
||||
public class ZeroIdEntity
|
||||
{
|
||||
/// <summary>
|
||||
/// Id of the entity
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace zero.Models;
|
||||
|
||||
public class ZeroReference
|
||||
{
|
||||
public ZeroReference() { }
|
||||
|
||||
public ZeroReference(ZeroEntity entity)
|
||||
{
|
||||
Id = entity.Id;
|
||||
Name = entity.Name;
|
||||
}
|
||||
|
||||
public static ZeroReference From(ZeroEntity entity)
|
||||
{
|
||||
return entity == null ? null : new ZeroReference(entity);
|
||||
}
|
||||
|
||||
public static ZeroReference From<T>(T entity, Func<T, string> transform) where T : ZeroEntity
|
||||
{
|
||||
return entity == null ? null : new ZeroReference()
|
||||
{
|
||||
Id = entity.Id,
|
||||
Name = transform(entity)
|
||||
};
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
Reference in New Issue
Block a user