diff --git a/zero.Core/Api/PageTreeApi.cs b/zero.Core/Api/PageTreeApi.cs
index 087e2d1b..b14e460b 100644
--- a/zero.Core/Api/PageTreeApi.cs
+++ b/zero.Core/Api/PageTreeApi.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using zero.Core.Database.Indexes;
using zero.Core.Entities;
using zero.Core.Extensions;
using zero.Core.Options;
@@ -27,10 +28,11 @@ namespace zero.Core.Api
///
- public async Task> GetChildren(string parentId = null)
+ public async Task> GetChildren(string parentId = null, string activeId = null)
{
IList items = new List();
IReadOnlyCollection pageTypes = Options.Pages.GetAllItems();
+ string[] openIds = new string[0] { };
using (IAsyncDocumentSession session = Backoffice.Raven.OpenAsyncSession())
{
@@ -40,6 +42,20 @@ namespace zero.Core.Api
.WhereIf(x => x.ParentId == parentId, !parentId.IsNullOrEmpty(), x => x.ParentId == null)
.ToListAsync();
+ if (!activeId.IsNullOrEmpty())
+ {
+ Pages_ByHierarchy.Result result = await session.Query()
+ .ProjectInto()
+ .Include(x => x.Path.Select(p => p.Id))
+ .ForApp(Backoffice.AppId)
+ .FirstOrDefaultAsync(x => x.Id == activeId);
+
+ if (result != null)
+ {
+ openIds = result.Path.Select(x => x.Id).ToArray(); // .Union(new string[1] { activeId })
+ }
+ }
+
foreach (Page page in pages)
{
PageType pageType = pageTypes.FirstOrDefault(x => x.Alias == page.PageTypeAlias);
@@ -58,6 +74,7 @@ namespace zero.Core.Api
ParentId = page.ParentId,
Sort = page.Sort,
Icon = pageType.Icon,
+ IsOpen = openIds.Contains(page.Id),
IsInactive = !page.IsActive
});
}
@@ -78,6 +95,27 @@ namespace zero.Core.Api
return items;
}
+
+
+ ///
+ public async Task> GetHierarchy(string id)
+ {
+ using (IAsyncDocumentSession session = Backoffice.Raven.OpenAsyncSession())
+ {
+ Pages_ByHierarchy.Result result = await session.Query()
+ .ProjectInto()
+ .Include(x => x.Path.Select(p => p.Id))
+ .ForApp(Backoffice.AppId)
+ .FirstOrDefaultAsync(x => x.Id == id);
+
+ if (result == null)
+ {
+ return new List();
+ }
+
+ return (await session.LoadAsync(result.Path.Select(x => x.Id))).Select(x => x.Value).ToList();
+ }
+ }
}
@@ -86,6 +124,11 @@ namespace zero.Core.Api
///
/// Get all children for the current parent page (or root if empty)
///
- Task> GetChildren(string parentId = null);
+ Task> GetChildren(string parentId = null, string activeId = null);
+
+ ///
+ /// Get hierarchy for a page
+ ///
+ Task> GetHierarchy(string id);
}
}
diff --git a/zero.Core/Database/Indexes/Pages_ByHierarchy.cs b/zero.Core/Database/Indexes/Pages_ByHierarchy.cs
new file mode 100644
index 00000000..32c4273e
--- /dev/null
+++ b/zero.Core/Database/Indexes/Pages_ByHierarchy.cs
@@ -0,0 +1,53 @@
+using Raven.Client.Documents.Indexes;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using zero.Core.Entities;
+
+namespace zero.Core.Database.Indexes
+{
+ public class Pages_ByHierarchy : AbstractIndexCreationTask
+ {
+ public class Result : IZeroIdEntity, IAppAwareEntity, IZeroDbConventions
+ {
+ public string Id { get; set; }
+
+ public string AppId { get; set; }
+
+ public string Name { get; set; }
+
+ public List Path { get; set; } = new List();
+ }
+
+
+ public class PathResult
+ {
+ public string Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+
+ public Pages_ByHierarchy()
+ {
+ Map = items => items.Select(item => new Result
+ {
+ Id = item.Id,
+ Name = item.Name,
+ AppId = item.AppId,
+ Path = Recurse(item, x => LoadDocument(x.ParentId))
+ .Where(x => x != null && x.Id != null && x.Id != item.Id)
+ .Reverse()
+ .Select(current => new PathResult()
+ {
+ Id = current.Id,
+ Name = current.Name
+ })
+ .ToList()
+ });
+
+ StoreAllFields(FieldStorage.Yes);
+ //Index(x => x.ChannelId, FieldIndexing.Exact);
+ }
+ }
+}
diff --git a/zero.Debug/Resources/tree-1.debug.json b/zero.Debug/Resources/tree-1.debug.json
deleted file mode 100644
index 1decdf0c..00000000
--- a/zero.Debug/Resources/tree-1.debug.json
+++ /dev/null
@@ -1,46 +0,0 @@
-[
- {
- "id": "10",
- "parentId": "1",
- "sort": 0,
- "name": "Products",
- "icon": "fth-folder",
- "hasChildren": false
- },
- {
- "id": "11",
- "parentId": "1",
- "sort": 1,
- "name": "Checkout",
- "icon": "fth-folder",
- "hasChildren": false
- },
- {
- "id": "12",
- "parentId": "1",
- "sort": 2,
- "name": "About us",
- "icon": "fth-folder",
- "modifier": {
- "name": "Redirect",
- "icon": "fth-arrow-up-right"
- },
- "hasChildren": false
- },
- {
- "id": "13",
- "parentId": "1",
- "sort": 3,
- "name": "Support",
- "icon": "fth-folder",
- "hasChildren": true
- },
- {
- "id": "14",
- "parentId": "1",
- "sort": 4,
- "name": "News",
- "icon": "fth-folder",
- "hasChildren": false
- }
-]
\ No newline at end of file
diff --git a/zero.Debug/Resources/tree.debug.json b/zero.Debug/Resources/tree.debug.json
deleted file mode 100644
index 8cc32f1b..00000000
--- a/zero.Debug/Resources/tree.debug.json
+++ /dev/null
@@ -1,20 +0,0 @@
-[
- {
- "id": "1",
- "parentId": null,
- "sort": 0,
- "name": "Home",
- "description": "Entry point on the website",
- "icon": "fth-home",
- "hasChildren": true
- },
- {
- "id": "recyclebin",
- "parentId": null,
- "sort": 1000,
- "name": "@page.recyclebin.name",
- "description": "@page.recyclebin.description",
- "icon": "fth-trash",
- "hasChildren": false
- }
-]
\ No newline at end of file
diff --git a/zero.Web.UI/App/components/tree.vue b/zero.Web.UI/App/components/tree.vue
index b554153f..622e2893 100644
--- a/zero.Web.UI/App/components/tree.vue
+++ b/zero.Web.UI/App/components/tree.vue
@@ -11,15 +11,22 @@
{{item.name | localize}}
-
+
-
+