Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/tooling/docs-assembler/Cli/RepositoryCommands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public async Task<int> BuildAll(
var navigation = new GlobalNavigation(assembleSources, navigationFile);

var pathProvider = new GlobalNavigationPathProvider(navigationFile, assembleSources, assembleContext);
var htmlWriter = new GlobalNavigationHtmlWriter(logFactory, navigation);
var htmlWriter = new GlobalNavigationHtmlWriter(logFactory, navigation, collector);
var legacyPageChecker = new LegacyPageChecker();
var historyMapper = new PageLegacyUrlMapper(legacyPageChecker, assembleSources.HistoryMappings);

Expand Down
13 changes: 10 additions & 3 deletions src/tooling/docs-assembler/Navigation/GlobalNavigation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public GlobalNavigation(AssembleSources assembleSources, GlobalNavigationFile na

var navigationIndex = 0;
var allNavigationItems = new HashSet<INavigationItem>();
UpdateParent(allNavigationItems, NavigationItems, null);
UpdateParent(allNavigationItems, NavigationItems, null, null);
UpdateNavigationIndex(NavigationItems, ref navigationIndex);
TopLevelItems = NavigationItems.OfType<TableOfContentsTree>().Where(t => !t.Hidden).ToList();
NavigationLookup = TopLevelItems.ToDictionary(kv => kv.Source, kv => kv);
Expand All @@ -64,23 +64,30 @@ public GlobalNavigation(AssembleSources assembleSources, GlobalNavigationFile na
private void UpdateParent(
HashSet<INavigationItem> allNavigationItems,
IReadOnlyCollection<INavigationItem> navigationItems,
INodeNavigationItem<INavigationModel, INavigationItem>? parent
INodeNavigationItem<INavigationModel, INavigationItem>? parent,
IRootNavigationItem<INavigationModel, INavigationItem>? topLevelNavigation
)
{
if (parent is IRootNavigationItem<INavigationModel, INavigationItem> tree)
topLevelNavigation ??= tree;
foreach (var item in navigationItems)
{
switch (item)
{
case FileNavigationItem fileNavigationItem:
if (parent is not null)
fileNavigationItem.Parent = parent;
if (topLevelNavigation is not null)
fileNavigationItem.Model.NavigationRoot = topLevelNavigation;
_ = allNavigationItems.Add(fileNavigationItem);
break;
case DocumentationGroup documentationGroup:
if (parent is not null)
documentationGroup.Parent = parent;
if (topLevelNavigation is not null)
documentationGroup.Index.NavigationRoot = topLevelNavigation;
_ = allNavigationItems.Add(documentationGroup);
UpdateParent(allNavigationItems, documentationGroup.NavigationItems, documentationGroup);
UpdateParent(allNavigationItems, documentationGroup.NavigationItems, documentationGroup, topLevelNavigation);
break;
default:
_navigationFile.EmitError($"Unhandled navigation item type: {item.GetType()}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,45 @@
// See the LICENSE file in the project root for more information

using System.Collections.Concurrent;
using Elastic.Documentation.Diagnostics;
using Elastic.Documentation.Site.Navigation;
using Elastic.Markdown.IO.Navigation;
using Microsoft.Extensions.Logging;

namespace Documentation.Assembler.Navigation;

public class GlobalNavigationHtmlWriter(ILoggerFactory logFactory, GlobalNavigation globalNavigation) : INavigationHtmlWriter
public class GlobalNavigationHtmlWriter(ILoggerFactory logFactory, GlobalNavigation globalNavigation, DiagnosticsCollector collector) : INavigationHtmlWriter
{
private readonly ILogger<Program> _logger = logFactory.CreateLogger<Program>();

private readonly ConcurrentDictionary<(string, int), string> _renderedNavigationCache = [];

public async Task<NavigationRenderResult> RenderNavigation(IRootNavigationItem<INavigationModel, INavigationItem> currentRootNavigation, int maxLevel, Cancel ctx = default)
{
INodeNavigationItem<INavigationModel, INavigationItem> lastParentBeforeRoot = currentRootNavigation;
INodeNavigationItem<INavigationModel, INavigationItem> parent = currentRootNavigation;
while (parent.Parent is not null)
{
lastParentBeforeRoot = parent;
parent = parent.Parent;
}
if (_renderedNavigationCache.TryGetValue((lastParentBeforeRoot.Id, maxLevel), out var html))
if (currentRootNavigation.Parent is not null && currentRootNavigation.Parent.Depth != 0)
collector.EmitGlobalError($"Passed root is not actually a top level navigation item {currentRootNavigation.NavigationTitle} ({currentRootNavigation.Id}) in {currentRootNavigation.Url}");

if (_renderedNavigationCache.TryGetValue((currentRootNavigation.Id, maxLevel), out var html))
{
return new NavigationRenderResult
{
Html = html,
Id = lastParentBeforeRoot.Id
Id = currentRootNavigation.Id
};
}

_logger.LogInformation("Rendering navigation for {NavigationTitle} ({Id})", lastParentBeforeRoot.NavigationTitle, lastParentBeforeRoot.Id);
_logger.LogInformation("Rendering navigation for {NavigationTitle} ({Id})", currentRootNavigation.NavigationTitle, currentRootNavigation.Id);

if (lastParentBeforeRoot is not DocumentationGroup group)
if (currentRootNavigation is not DocumentationGroup group)
return NavigationRenderResult.Empty;

var model = CreateNavigationModel(group, maxLevel);
html = await ((INavigationHtmlWriter)this).Render(model, ctx);
_renderedNavigationCache[(lastParentBeforeRoot.Id, maxLevel)] = html;
_renderedNavigationCache[(currentRootNavigation.Id, maxLevel)] = html;
return new NavigationRenderResult
{
Html = html,
Id = lastParentBeforeRoot.Id
Id = currentRootNavigation.Id
};
}

Expand Down
Loading