using Raven.Client.Documents; using Raven.Client.Documents.Linq; using Raven.Client.Documents.Session; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using zero.Core.Database.Indexes; using zero.Core.Entities; using zero.Core.Extensions; using zero.Core.Options; namespace zero.Core.Api { public class PageTreeApi : BackofficeApi, IPageTreeApi { public PageTreeApi(IBackofficeStore store) : base(store) { } /// public async Task> GetChildren(string parentId = null, string activeId = null) { IList items = new List(); IReadOnlyCollection pageTypes = Backoffice.Options.Pages.GetAllItems(); string[] openIds = new string[0] { }; using IAsyncDocumentSession session = Store.OpenAsyncSession(); IList pages = await session .Query() .WhereIf(x => x.ParentId == parentId, !parentId.IsNullOrEmpty(), x => x.ParentId == null) .OrderBy(x => x.Sort) .ToListAsync(); // get hierarchy so we know if we should set the page to open if (!activeId.IsNullOrEmpty()) { Pages_ByHierarchy.Result result = await session.Query() .ProjectInto() .Include(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.Select(x => x.Id).ToArray(); IList children = await session.Query() .ProjectInto() .Where(x => x.Id.In(pageIds)) .ToListAsync(); // function to get modifier icon TreeItemModifier GetModifier(IPage 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 (IPage page in pages) { PageType pageType = pageTypes.FirstOrDefault(x => x.Alias == page.PageTypeAlias); if (pageType == null) { continue; // TODO the page type does not exist anymore } int childCount = 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) }); } 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 IPageTreeApi { /// /// Get all children for the current parent page (or root if empty) /// Task> GetChildren(string parentId = null, string activeId = null); } }