using Raven.Client.Documents; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using zero.Core.Database.Indexes; using zero.Core.Entities; using zero.Core.Extensions; namespace zero.Core.Routing { public class PageRouteProvider : ZeroRouteProvider { public static string PAGE_TYPE_PARAM = "pageType"; public static string PAGE_ID_PARAM = "pageId"; protected IPageUrlBuilder UrlBuilder { get; set; } public PageRouteProvider(IPageUrlBuilder urlBuilder) : base(Constants.Pages.PageRouteProviderAlias) { UrlBuilder = urlBuilder; } /// public override Task IsRouteStale(RoutingContext context, Page previous, Page current) { bool compareUrlPart = !UrlBuilder.GetUrlPart(previous).Equals(UrlBuilder.GetUrlPart(current)); return Task.FromResult(compareUrlPart || !previous.ParentId.Equals(current.ParentId)); } /// public override async Task Create(RoutingContext context, Page model) { if (model is PageFolder) { return null; } IEnumerable parents = await GetParents(context, model); Route route = new(); route.Id = Id(model); route.ReferenceId = model.Id; route.Url = UrlBuilder.GetUrl(model, parents); route.DependsOn(model.Id); route.DependsOn(parents.Select(x => x.Id).ToArray()); route.Param(PAGE_TYPE_PARAM, model.PageTypeAlias); route.Param(PAGE_ID_PARAM, model.Id); return route; } /// public override async Task Model(RoutingContext context, Route route) { Page page = await context.Session.LoadAsync(route.ReferenceId); PageRoute resolved = new(route); resolved.Page = page; resolved.Parents = await GetParents(context, page); resolved.PageType = route.Param(PAGE_TYPE_PARAM); return resolved; } /// public override async IAsyncEnumerable Seed(RoutingContext context) { var stream = await context.Session.Advanced.StreamAsync(context.Session.Query()); while (await stream.MoveNextAsync()) { yield return await Create(context, stream.Current.Document); } } /// /// Get parents for a page /// protected virtual async Task> GetParents(RoutingContext context, Page model) { Pages_ByHierarchy.Result result = await context.Session.Query() .ProjectInto() .Include(x => x.Path.Select(p => p.Id)) .FirstOrDefaultAsync(x => x.Id == model.Id); return (await context.Session.LoadAsync(result.Path.Select(x => x.Id))).Select(x => x.Value).ToList(); } } }