start new controllers

This commit is contained in:
2021-11-23 15:43:21 +01:00
parent bffddbe9a8
commit a9bf2d28cb
61 changed files with 578 additions and 891 deletions
+14
View File
@@ -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; }
}
+81
View File
@@ -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
}
+127
View File
@@ -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; }
}
+58
View File
@@ -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;
}
}
+75
View File
@@ -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; }
}
+15
View File
@@ -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; }
}
+9
View File
@@ -0,0 +1,9 @@
namespace zero.Models;
public class ZeroIdEntity
{
/// <summary>
/// Id of the entity
/// </summary>
public string Id { get; set; }
}
+30
View File
@@ -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; }
}