From 3cc644de68dde27a52e068bc32a15f8e1f1fcc4f Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Wed, 26 Aug 2020 11:10:52 +0200 Subject: [PATCH] move tor ecycle bin works for pages --- zero.Core/Api/BackofficeApi.cs | 28 +++++++- zero.Core/Api/PagesApi.cs | 64 +++++++++---------- zero.Core/Api/RecycleBinApi.cs | 59 ++++++++--------- zero.Core/Entities/Pages/Page.cs | 8 --- .../Entities/RecycleBin/RecycledEntity.cs | 6 +- zero.Core/Entities/Translation.cs | 5 +- zero.Debug/Controllers/TestController.cs | 2 + zero.Web/Controllers/PagesController.cs | 2 +- zero.Web/Defaults/ZeroBackofficePlugin.cs | 3 +- 9 files changed, 96 insertions(+), 81 deletions(-) diff --git a/zero.Core/Api/BackofficeApi.cs b/zero.Core/Api/BackofficeApi.cs index 2ac23def..f42dfe94 100644 --- a/zero.Core/Api/BackofficeApi.cs +++ b/zero.Core/Api/BackofficeApi.cs @@ -241,16 +241,33 @@ namespace zero.Core.Api } + /// + public async Task DeleteByIds(params string[] ids) where T : IZeroIdEntity + { + int successCount = 0; + + foreach (string id in ids) + { + EntityResult result = await DeleteById(id); + successCount += result.IsSuccess ? 1 : 0; + } + + return successCount; + } + + /// public async Task Purge(string querySuffix = null, Parameters parameters = null) { var collectionName = Raven.Conventions.FindCollectionName(typeof(T)); - Operation operation = await Raven.Operations.SendAsync(new DeleteByQueryOperation(new IndexQuery() + var operationQuery = new DeleteByQueryOperation(new IndexQuery() { - Query = $"from {collectionName} {querySuffix ?? String.Empty}", + Query = $"from {collectionName} c {querySuffix ?? String.Empty}", QueryParameters = parameters - })); + }); + + Operation operation = await Raven.Operations.SendAsync(operationQuery); await operation.WaitForCompletionAsync(TimeSpan.FromSeconds(30)); } @@ -281,6 +298,11 @@ namespace zero.Core.Api /// Task> DeleteById(string id) where T : IZeroIdEntity; + /// + /// Deletes entities by Id + /// + Task DeleteByIds(params string[] ids) where T : IZeroIdEntity; + /// /// Delete a whole collection (with an optional query suffix, i.e. a where statement) /// diff --git a/zero.Core/Api/PagesApi.cs b/zero.Core/Api/PagesApi.cs index 93611ab6..210dd484 100644 --- a/zero.Core/Api/PagesApi.cs +++ b/zero.Core/Api/PagesApi.cs @@ -15,11 +15,17 @@ namespace zero.Core.Api { public class PagesApi : AppAwareBackofficeApi, IPagesApi where T : IPage { + const string RECYCLE_BIN_GROUP = "pages"; + protected IZeroOptions Options { get; private set; } - public PagesApi(IZeroOptions options, IBackofficeStore store) : base(store) + protected IRecycleBinApi RecycleBinApi { get; private set; } + + + public PagesApi(IZeroOptions options, IBackofficeStore store, IRecycleBinApi recycleBinApi) : base(store) { Options = options; + RecycleBinApi = recycleBinApi; } @@ -180,51 +186,39 @@ namespace zero.Core.Api public async Task> Delete(string id, bool moveToRecycleBin = true) { IList pages = await GetByIdWithDescendants(id); + string[] ids = pages.Select(x => x.Id).ToArray(); - using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) + if (moveToRecycleBin) { - session.Advanced.WaitForIndexesAfterSaveChanges(throwOnTimeout: false); - - foreach (T page in pages) - { - if (moveToRecycleBin) - { - page.IsRecycled = true; - await session.StoreAsync(page); - } - else - { - session.Delete(page.Id); - } - } - - await session.SaveChangesAsync(); + await RecycleBinApi.Add(pages, RECYCLE_BIN_GROUP); } - return EntityResult.Success(pages.Select(x => x.Id).ToArray()); + await DeleteByIds(ids); + + return EntityResult.Success(ids); } /// - public async Task> Restore(string id) - { - IList pages = await GetByIdWithDescendants(id); + //public async Task> Restore(string id) + //{ + // IList pages = await GetByIdWithDescendants(id); - using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) - { - session.Advanced.WaitForIndexesAfterSaveChanges(throwOnTimeout: false); + // using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) + // { + // session.Advanced.WaitForIndexesAfterSaveChanges(throwOnTimeout: false); - foreach (T page in pages) - { - page.IsRecycled = false; - await session.StoreAsync(page); - } + // foreach (T page in pages) + // { + // page.IsRecycled = false; + // await session.StoreAsync(page); + // } - await session.SaveChangesAsync(); - } + // await session.SaveChangesAsync(); + // } - return EntityResult.Success(pages.Select(x => x.Id).ToArray()); - } + // return EntityResult.Success(pages.Select(x => x.Id).ToArray()); + //} /// @@ -327,6 +321,6 @@ namespace zero.Core.Api /// /// Restores a page from the recycle bin /// - Task> Restore(string id); + //Task> Restore(string id); } } diff --git a/zero.Core/Api/RecycleBinApi.cs b/zero.Core/Api/RecycleBinApi.cs index 177130b3..ee405f3b 100644 --- a/zero.Core/Api/RecycleBinApi.cs +++ b/zero.Core/Api/RecycleBinApi.cs @@ -1,4 +1,6 @@ -using Raven.Client.Documents.Session; +using Newtonsoft.Json; +using Raven.Client.Documents.Session; +using System; using System.Collections.Generic; using System.Threading.Tasks; using zero.Core.Entities; @@ -7,60 +9,60 @@ using zero.Core.Utils; namespace zero.Core.Api { - public class RecycleBinApi : AppAwareBackofficeApi, IRecycleBinApi where T : IRecycledEntity, new() + public class RecycleBinApi : AppAwareBackofficeApi, IRecycleBinApi { - public RecycleBinApi(IBackofficeStore store) : base(store) + Type Type; + + public RecycleBinApi(IBackofficeStore store, IRecycledEntity entity) : base(store) { - + Type = entity.GetType(); } /// - public async Task> Add(TEntity model, string group = null, string operationId = null) where TEntity : IZeroEntity + public async Task> Add(TEntity model, string group = null, string operationId = null) where TEntity : IZeroEntity { - T entity = new T() - { - Group = group, - Content = null, - OriginalId = model.Id, - OperationId = operationId, - Name = model.Name - }; + IRecycledEntity entity = Activator.CreateInstance(Type) as IRecycledEntity; + entity.Group = group; + entity.Content = model; + entity.OriginalId = model.Id; + entity.OperationId = operationId; + entity.Name = model.Name; return await SaveModel(entity); } /// - public async Task>> Add(IEnumerable models, string group = null) where TEntity : IZeroEntity + public async Task>> Add(IEnumerable models, string group = null) where TEntity : IZeroEntity { - IList results = new List(); + IList results = new List(); string operationId = IdGenerator.Create(); foreach (TEntity model in models) { - EntityResult result = await Add(model, group, operationId); + EntityResult result = await Add(model, group, operationId); if (!result.IsSuccess) { - return EntityResult>.Fail(result.Errors); + return EntityResult>.Fail(result.Errors); } results.Add(result.Model); } - return EntityResult>.Success(results); + return EntityResult>.Success(results); } /// - public async Task> GetByQuery(RecycleBinListQuery query) + public async Task> GetByQuery(RecycleBinListQuery query) { query.SearchSelector = x => x.Name; using (IAsyncDocumentSession session = Raven.OpenAsyncSession()) { - return await session.Query() + return await session.Query() .Scope(Scope) .WhereIf(x => x.Group == query.Group, !query.Group.IsNullOrWhiteSpace()) .WhereIf(x => x.OperationId == query.OperationId, !query.OperationId.IsNullOrWhiteSpace()) @@ -72,7 +74,7 @@ namespace zero.Core.Api /// public async Task Delete(string id) { - await DeleteById(id); + await DeleteById(id); } @@ -80,41 +82,40 @@ namespace zero.Core.Api public async Task DeleteAll() { // TODO make Purge operations app-aware - await Purge(); + await Purge(); } /// public async Task DeleteByOperation(string operationId) { - await Purge("where OperationId = $id", new Raven.Client.Parameters() { { "id", operationId } }); + await Purge("where c.OperationId = $id", new Raven.Client.Parameters() { { "id", operationId } }); } /// public async Task DeleteByGroup(string group) { - await Purge("where Group = $group", new Raven.Client.Parameters() { { "group", group } }); + await Purge("where c.Group = $group", new Raven.Client.Parameters() { { "group", group } }); } } - - public interface IRecycleBinApi where T : IRecycledEntity + public interface IRecycleBinApi { /// /// Adds an entity to the recycle bin. This operation will not remove this entity from it's own collection! /// - Task> Add(TEntity model, string group = null, string operationId = null) where TEntity : IZeroEntity; + Task> Add(TEntity model, string group = null, string operationId = null) where TEntity : IZeroEntity; /// /// Adds the specified entities to the recycle bin. This operation will not remove entities from their own collection! /// - Task>> Add(IEnumerable models, string group = null) where TEntity : IZeroEntity; + Task>> Add(IEnumerable models, string group = null) where TEntity : IZeroEntity; /// /// Get all recycled items /// - Task> GetByQuery(RecycleBinListQuery query); + Task> GetByQuery(RecycleBinListQuery query); // /// Deletes a country by Id diff --git a/zero.Core/Entities/Pages/Page.cs b/zero.Core/Entities/Pages/Page.cs index c4b16c22..79f263db 100644 --- a/zero.Core/Entities/Pages/Page.cs +++ b/zero.Core/Entities/Pages/Page.cs @@ -17,9 +17,6 @@ namespace zero.Core.Entities /// public string AppId { get; set; } - /// - public bool IsRecycled { get; set; } - /// public DateTimeOffset? PublishDate { get; set; } @@ -40,11 +37,6 @@ namespace zero.Core.Entities /// string PageTypeAlias { get; set; } - /// - /// Whether this page is recycled or not - /// - bool IsRecycled { get; set; } - /// /// Date when the page is published /// diff --git a/zero.Core/Entities/RecycleBin/RecycledEntity.cs b/zero.Core/Entities/RecycleBin/RecycledEntity.cs index da27cfff..385f25c1 100644 --- a/zero.Core/Entities/RecycleBin/RecycledEntity.cs +++ b/zero.Core/Entities/RecycleBin/RecycledEntity.cs @@ -17,7 +17,7 @@ namespace zero.Core.Entities public string Group { get; set; } /// - public string Content { get; set; } + public IZeroEntity Content { get; set; } } @@ -35,9 +35,9 @@ namespace zero.Core.Entities string OperationId { get; set; } /// - /// Contains the entity content as JSON + /// Contains the entity content /// - string Content { get; set; } + IZeroEntity Content { get; set; } /// /// Recycled entities can be grouped together (e.g. pages, media, ...) diff --git a/zero.Core/Entities/Translation.cs b/zero.Core/Entities/Translation.cs index f70546c2..717888d6 100644 --- a/zero.Core/Entities/Translation.cs +++ b/zero.Core/Entities/Translation.cs @@ -1,4 +1,6 @@ -namespace zero.Core.Entities +using zero.Core.Attributes; + +namespace zero.Core.Entities { public class Translation : ZeroEntity, ITranslation { @@ -26,6 +28,7 @@ } + [Collection("Translations")] public interface ITranslation : IZeroEntity, ILanguageAwareEntity, IAppAwareShareableEntity, IZeroDbConventions { /// diff --git a/zero.Debug/Controllers/TestController.cs b/zero.Debug/Controllers/TestController.cs index 3d35e60e..eb71c8b7 100644 --- a/zero.Debug/Controllers/TestController.cs +++ b/zero.Debug/Controllers/TestController.cs @@ -7,6 +7,7 @@ using System.Linq; using System.Threading.Tasks; using zero.Core.Api; using zero.Core.Entities; +using zero.Core.Utils; namespace zero.Debug.Controllers { @@ -56,6 +57,7 @@ namespace zero.Debug.Controllers } + [HttpGet] public IActionResult Things([FromServices] IValidator appValidator) { diff --git a/zero.Web/Controllers/PagesController.cs b/zero.Web/Controllers/PagesController.cs index 3337cde9..4a31529b 100644 --- a/zero.Web/Controllers/PagesController.cs +++ b/zero.Web/Controllers/PagesController.cs @@ -55,7 +55,7 @@ namespace zero.Web.Controllers public async Task Copy([FromBody] CopyModel model) => Json(await Api.Copy(model.Id, model.DestinationId, model.IncludeDescendants)); - public async Task Delete([FromQuery] string id, [FromQuery] bool moveToRecycleBin = false) => Json(await Api.Delete(id, moveToRecycleBin)); + public async Task Delete([FromQuery] string id) => Json(await Api.Delete(id, true)); public class CopyModel diff --git a/zero.Web/Defaults/ZeroBackofficePlugin.cs b/zero.Web/Defaults/ZeroBackofficePlugin.cs index e238c852..7a5ed78d 100644 --- a/zero.Web/Defaults/ZeroBackofficePlugin.cs +++ b/zero.Web/Defaults/ZeroBackofficePlugin.cs @@ -35,7 +35,8 @@ namespace zero.Web.Defaults services.AddTransient(typeof(IPagesApi<>), typeof(PagesApi<>)); services.AddTransient(typeof(IPageTreeApi<>), typeof(PageTreeApi<>)); services.AddTransient(typeof(IUserApi<>), typeof(UserApi<>)); - services.AddTransient(typeof(IRecycleBinApi<>), typeof(RecycleBinApi<>)); + services.AddTransient(typeof(IRecycleBinApi), typeof(RecycleBinApi)); + // services.AddTransient(typeof(IRecycleBinApi), typeof(RecycleBinApi)); services.AddTransient(); services.AddTransient();