diff --git a/src/Elastic.ApiExplorer/Landing/LandingNavigationItem.cs b/src/Elastic.ApiExplorer/Landing/LandingNavigationItem.cs index 28ef25b87..9fb5c00ef 100644 --- a/src/Elastic.ApiExplorer/Landing/LandingNavigationItem.cs +++ b/src/Elastic.ApiExplorer/Landing/LandingNavigationItem.cs @@ -52,7 +52,7 @@ public LandingNavigationItem(string url) } /// - public bool IsUsingNavigationDropdown => NavigationItems.OfType().Any(); + public bool IsUsingNavigationDropdown => false; } public interface IApiGroupingNavigationItem : INodeNavigationItem @@ -106,7 +106,7 @@ public class ClassificationNavigationItem(ApiClassification classification, Land public override string Id { get; } = ShortId.Create(classification.Name); /// - public bool IsUsingNavigationDropdown => true; + public bool IsUsingNavigationDropdown => false; } public class TagNavigationItem(ApiTag tag, IRootNavigationItem rootNavigation, INodeNavigationItem parent) diff --git a/src/Elastic.ApiExplorer/Landing/LandingView.cshtml b/src/Elastic.ApiExplorer/Landing/LandingView.cshtml index 767bf996d..8d81b5502 100644 --- a/src/Elastic.ApiExplorer/Landing/LandingView.cshtml +++ b/src/Elastic.ApiExplorer/Landing/LandingView.cshtml @@ -1,10 +1,92 @@ @inherits RazorSliceHttpResult +@using Elastic.ApiExplorer.Landing +@using Elastic.ApiExplorer.Operations +@using Elastic.Documentation.Site.Navigation @implements IUsesLayout @functions { public GlobalLayoutViewModel LayoutModel => Model.CreateGlobalLayoutModel(); + + private IHtmlContent RenderOp(IReadOnlyCollection endpointOperations) + { + + + return HtmlString.Empty; + } + + private IHtmlContent RenderProduct(INavigationItem item) + { + if (item is INodeNavigationItem node) + { + foreach (var navigationItem in node.NavigationItems) + { + if (navigationItem is ClassificationNavigationItem classification) + { + +

@(classification.NavigationTitle)

+ + @RenderProduct(classification) + } + else if (navigationItem is TagNavigationItem tag) + { + +

@(tag.NavigationTitle)

+ + @RenderProduct(tag) + } + else if (navigationItem is EndpointNavigationItem endpoint) + { + var endpointOperations = + endpoint is { NavigationItems.Count: > 0 } && endpoint.NavigationItems.All(n => n.Hidden) + ? endpoint.NavigationItems + : []; + if (endpointOperations.Count > 0) + { + + @(endpoint.NavigationTitle) + @RenderOp(endpointOperations) + + } + else + { + @RenderProduct(endpoint) + } + } + else if (navigationItem is OperationNavigationItem operation) + { + + @(operation.NavigationTitle) + @RenderOp([operation]) + + } + else + { + throw new Exception($"Unexpected type: {item.GetType().FullName}"); + } + } + } + + return HtmlString.Empty; + + } }

@Model.ApiInfo.Title

-

@Model.ApiInfo.Description

-

License: @Model.ApiInfo.License?.Identifier

+

@Model.RenderMarkdown(Model.ApiInfo.Description)

+

License: @Model.ApiInfo.License?.Name

+
+ + @RenderProduct(Model.CurrentNavigationItem.NavigationRoot) +
+
diff --git a/src/Elastic.ApiExplorer/Operations/OperationView.cshtml b/src/Elastic.ApiExplorer/Operations/OperationView.cshtml index a6e80d120..0c9977f23 100644 --- a/src/Elastic.ApiExplorer/Operations/OperationView.cshtml +++ b/src/Elastic.ApiExplorer/Operations/OperationView.cshtml @@ -7,10 +7,9 @@ public GlobalLayoutViewModel LayoutModel => Model.CreateGlobalLayoutModel(); } @{ - var parent = Model.CurrentNavigationItem.Parent as EndpointNavigationItem; var self = Model.CurrentNavigationItem as OperationNavigationItem; var allOperations = - parent is not null && parent.NavigationItems.Count > 0 && parent.NavigationItems.All(n => n.Hidden) + Model.CurrentNavigationItem.Parent is EndpointNavigationItem { NavigationItems.Count: > 0 } parent && parent.NavigationItems.All(n => n.Hidden) ? parent.NavigationItems : self is not null ? [self] @@ -87,4 +86,4 @@ - \ No newline at end of file + diff --git a/src/Elastic.Documentation.Site/Assets/api-docs.css b/src/Elastic.Documentation.Site/Assets/api-docs.css index 15bd423e8..5e0bf16e7 100644 --- a/src/Elastic.Documentation.Site/Assets/api-docs.css +++ b/src/Elastic.Documentation.Site/Assets/api-docs.css @@ -42,6 +42,12 @@ @apply border-grey-30 text-grey-120 bg-white; font-weight: bold; } + a.api-url-list-item-landing { + font-weight: normal !important; + } + a.api-url-list-item-landing:hover { + font-weight: normal !important; + } } li:only-child { a.current { @@ -51,53 +57,108 @@ @apply border-grey-20 bg-white; } } - .api-method { - @apply rounded-sm border; - padding-left: var(--spacing); - padding-right: var(--spacing); - font-family: var( - --default-mono-font-family, - ui-monospace, - SFMono-Regular, - Menlo, - Monaco, - Consolas, - 'Liberation Mono', - 'Courier New', - monospace - ); - font-feature-settings: var( - --default-mono-font-feature-settings, - normal - ); - font-variation-settings: var( - --default-mono-font-variation-settings, - normal - ); - font-size: 0.8em; - display: inline-block; - font-weight: bold; - } - .api-method-get { - @apply border-blue-elastic-30 bg-blue-elastic-10 text-blue-elastic; - } - .api-method-put { - @apply border-yellow-30 bg-yellow-10 text-yellow-90; - } - .api-method-post { - @apply border-green-30 bg-green-10 text-green-90; - } - .api-method-delete { - @apply border-red-30 bg-red-10 text-red-90; - } - .api-url { - margin-left: calc(var(--spacing) * 2); - display: inline-block; - } .api-url-list-item { @apply mt-4; } } +.api-overview { + .api-url-listing { + @apply mt-1; + } + .api-url-list-item { + @apply mt-1; + } + li { + a { + @apply text-grey-80 inline-block w-full p-2 pr-2 pl-2 no-underline; + @apply rounded-sm border border-white; + } + a:hover { + @apply bg-grey-10; + @apply border-grey-20; + } + a.current { + @apply text-grey-80 inline-block w-full p-2 pr-2 pl-2 no-underline; + @apply rounded-sm border border-white; + } + a.current:hover { + @apply bg-grey-10; + @apply border-grey-20; + } + } + li:only-child { + a.current { + @apply text-grey-80 inline-block w-full p-2 pr-2 pl-2 no-underline; + @apply rounded-sm border border-white; + } + a.current:hover { + @apply bg-grey-10; + } + } + table { + td { + text-align: left; + vertical-align: top; + } + td:has(h2) { + } + td:has(h3) { + @apply border-b-grey-20 mb-2 border-b-1 pb-2; + } + td.api-name { + @apply pr-2; + text-align: left; + font-weight: bold; + } + tr:has(td.api-name) { + @apply border-b-grey-10 border-b-1; + } + tr:has(td.api-name) td { + @apply mt-4 mb-4 pt-4 pb-4; + } + } +} + +.api-method { + @apply rounded-sm border; + padding-left: var(--spacing); + padding-right: var(--spacing); + font-family: var( + --default-mono-font-family, + ui-monospace, + SFMono-Regular, + Menlo, + Monaco, + Consolas, + 'Liberation Mono', + 'Courier New', + monospace + ); + font-feature-settings: var(--default-mono-font-feature-settings, normal); + font-variation-settings: var( + --default-mono-font-variation-settings, + normal + ); + font-size: 0.8em; + display: inline-block; + font-weight: bold; +} +.api-method-get { + @apply border-blue-elastic-30 bg-blue-elastic-10 text-blue-elastic; +} +.api-method-put { + @apply border-yellow-30 bg-yellow-10 text-yellow-90; +} +.api-method-post { + @apply border-green-30 bg-green-10 text-green-90; +} +.api-method-delete { + @apply border-red-30 bg-red-10 text-red-90; +} +.api-url { + margin-left: calc(var(--spacing) * 2); + display: inline-block; +} #elastic-api-v3 { dt a { @apply no-underline; diff --git a/src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml b/src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml index ac5386eb1..d54da09ea 100644 --- a/src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml +++ b/src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml @@ -6,44 +6,44 @@ var currentTopLevelItem = Model.TopLevelItems.FirstOrDefault(i => i.Id == Model.Tree.Id) ?? Model.Tree; } @if (Model.IsUsingNavigationDropdown && currentTopLevelItem is { Index: not null }) - { -
-
- + { +
+
+
@@ -57,16 +57,16 @@ @Model.Title } - -
    - @await RenderPartialAsync(_TocTreeNav.Create(new NavigationTreeItem - { - IsPrimaryNavEnabled = Model.IsPrimaryNavEnabled, - IsGlobalAssemblyBuild = Model.IsGlobalAssemblyBuild, - Level = 0, - SubTree = Model.Tree, - RootNavigationId = Model.Tree.Id, - MaxLevel = Model.MaxLevel - })) -
+ +
    + @await RenderPartialAsync(_TocTreeNav.Create(new NavigationTreeItem + { + IsPrimaryNavEnabled = Model.IsPrimaryNavEnabled, + IsGlobalAssemblyBuild = Model.IsGlobalAssemblyBuild, + Level = 0, + SubTree = Model.Tree, + RootNavigationId = Model.Tree.Id, + MaxLevel = Model.MaxLevel + })) +
diff --git a/src/tooling/docs-builder/Http/DocumentationWebHost.cs b/src/tooling/docs-builder/Http/DocumentationWebHost.cs index cbd856b70..cd93f081f 100644 --- a/src/tooling/docs-builder/Http/DocumentationWebHost.cs +++ b/src/tooling/docs-builder/Http/DocumentationWebHost.cs @@ -165,6 +165,11 @@ await context.Response.WriteAsync(@" private async Task ServeApiFile(ReloadableGeneratorState holder, string slug, Cancel ctx) { +#if DEBUG + // only reload when actually debugging + if (System.Diagnostics.Debugger.IsAttached) + await holder.ReloadApiReferences(ctx); +#endif var path = Path.Combine(holder.ApiPath.FullName, slug.Trim('/'), "index.html"); var info = _writeFileSystem.FileInfo.New(path); if (info.Exists) diff --git a/src/tooling/docs-builder/Http/ReloadableGeneratorState.cs b/src/tooling/docs-builder/Http/ReloadableGeneratorState.cs index 971cf6979..ef931880d 100644 --- a/src/tooling/docs-builder/Http/ReloadableGeneratorState.cs +++ b/src/tooling/docs-builder/Http/ReloadableGeneratorState.cs @@ -40,6 +40,8 @@ public async Task ReloadAsync(Cancel ctx) await ReloadApiReferences(generator.MarkdownStringRenderer, ctx); } + public async Task ReloadApiReferences(Cancel ctx) => await ReloadApiReferences(_generator.MarkdownStringRenderer, ctx); + private async Task ReloadApiReferences(IMarkdownStringRenderer markdownStringRenderer, Cancel ctx) { if (ApiPath.Exists)