diff --git a/src/tooling/docs-assembler/Cli/RepositoryCommands.cs b/src/tooling/docs-assembler/Cli/RepositoryCommands.cs index e68b62689..b2f674660 100644 --- a/src/tooling/docs-assembler/Cli/RepositoryCommands.cs +++ b/src/tooling/docs-assembler/Cli/RepositoryCommands.cs @@ -169,7 +169,7 @@ public async Task 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); diff --git a/src/tooling/docs-assembler/Navigation/GlobalNavigation.cs b/src/tooling/docs-assembler/Navigation/GlobalNavigation.cs index f028616cd..82e98557d 100644 --- a/src/tooling/docs-assembler/Navigation/GlobalNavigation.cs +++ b/src/tooling/docs-assembler/Navigation/GlobalNavigation.cs @@ -47,7 +47,7 @@ public GlobalNavigation(AssembleSources assembleSources, GlobalNavigationFile na var navigationIndex = 0; var allNavigationItems = new HashSet(); - UpdateParent(allNavigationItems, NavigationItems, null); + UpdateParent(allNavigationItems, NavigationItems, null, null); UpdateNavigationIndex(NavigationItems, ref navigationIndex); TopLevelItems = NavigationItems.OfType().Where(t => !t.Hidden).ToList(); NavigationLookup = TopLevelItems.ToDictionary(kv => kv.Source, kv => kv); @@ -64,9 +64,12 @@ public GlobalNavigation(AssembleSources assembleSources, GlobalNavigationFile na private void UpdateParent( HashSet allNavigationItems, IReadOnlyCollection navigationItems, - INodeNavigationItem? parent + INodeNavigationItem? parent, + IRootNavigationItem? topLevelNavigation ) { + if (parent is IRootNavigationItem tree) + topLevelNavigation ??= tree; foreach (var item in navigationItems) { switch (item) @@ -74,13 +77,17 @@ private void UpdateParent( 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()}"); diff --git a/src/tooling/docs-assembler/Navigation/GlobalNavigationHtmlWriter.cs b/src/tooling/docs-assembler/Navigation/GlobalNavigationHtmlWriter.cs index 9a65dd4ad..a69c99c16 100644 --- a/src/tooling/docs-assembler/Navigation/GlobalNavigationHtmlWriter.cs +++ b/src/tooling/docs-assembler/Navigation/GlobalNavigationHtmlWriter.cs @@ -3,13 +3,14 @@ // 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 _logger = logFactory.CreateLogger(); @@ -17,34 +18,30 @@ public class GlobalNavigationHtmlWriter(ILoggerFactory logFactory, GlobalNavigat public async Task RenderNavigation(IRootNavigationItem currentRootNavigation, int maxLevel, Cancel ctx = default) { - INodeNavigationItem lastParentBeforeRoot = currentRootNavigation; - INodeNavigationItem 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 }; }