From 6b78e3b44cc221af87fe17c8ef67ca39894c3d48 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 18 Jun 2025 13:46:25 +0200 Subject: [PATCH 1/3] Move new version dropdown to sidebar and add missing behaviour from the old dropdown --- .../Endpoints/EndpointView.cshtml | 2 - .../Landing/LandingView.cshtml | 2 - .../Operations/OperationView.cshtml | 2 - .../Assets/web-components/VersionDropdown.tsx | 169 +++++++++++++----- .../Layout/_SecondaryNav.cshtml | 7 - src/Elastic.Documentation.Site/_ViewModels.cs | 3 - src/Elastic.Markdown/Slices/HtmlWriter.cs | 6 + src/Elastic.Markdown/Slices/Index.cshtml | 3 +- src/Elastic.Markdown/Slices/IndexViewModel.cs | 2 + .../Slices/Layout/_LandingPage.cshtml | 12 ++ .../Slices/Layout/_TableOfContents.cshtml | 16 +- .../Slices/MarkdownLayoutViewModel.cs | 6 + 12 files changed, 168 insertions(+), 62 deletions(-) diff --git a/src/Elastic.ApiExplorer/Endpoints/EndpointView.cshtml b/src/Elastic.ApiExplorer/Endpoints/EndpointView.cshtml index b8487e1fb..95bc519ec 100644 --- a/src/Elastic.ApiExplorer/Endpoints/EndpointView.cshtml +++ b/src/Elastic.ApiExplorer/Endpoints/EndpointView.cshtml @@ -12,8 +12,6 @@ Next = null, NavigationHtml = Model.NavigationHtml, UrlPathPrefix = null, - VersionDropdown = null, - CurrentVersion = null, AllowIndexing = false, CanonicalBaseUrl = null, GoogleTagManager = new GoogleTagManagerConfiguration(), diff --git a/src/Elastic.ApiExplorer/Landing/LandingView.cshtml b/src/Elastic.ApiExplorer/Landing/LandingView.cshtml index f6af0e1d7..d24553791 100644 --- a/src/Elastic.ApiExplorer/Landing/LandingView.cshtml +++ b/src/Elastic.ApiExplorer/Landing/LandingView.cshtml @@ -12,8 +12,6 @@ Next = null, NavigationHtml = Model.NavigationHtml, UrlPathPrefix = null, - VersionDropdown = null, - CurrentVersion = "9.0+", AllowIndexing = false, CanonicalBaseUrl = null, GoogleTagManager = new GoogleTagManagerConfiguration(), diff --git a/src/Elastic.ApiExplorer/Operations/OperationView.cshtml b/src/Elastic.ApiExplorer/Operations/OperationView.cshtml index bf2593d1c..12d821176 100644 --- a/src/Elastic.ApiExplorer/Operations/OperationView.cshtml +++ b/src/Elastic.ApiExplorer/Operations/OperationView.cshtml @@ -12,8 +12,6 @@ Next = null, NavigationHtml = Model.NavigationHtml, UrlPathPrefix = null, - VersionDropdown = null, - CurrentVersion = null, AllowIndexing = false, CanonicalBaseUrl = null, GoogleTagManager = new GoogleTagManagerConfiguration(), diff --git a/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx b/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx index bc5b17576..236129665 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx +++ b/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx @@ -1,3 +1,5 @@ +'strict' + import { EuiButton, EuiContextMenu, @@ -6,7 +8,12 @@ import { EuiIcon, EuiPopover, EuiText, + EuiPanel, + EuiLink, + useEuiOverflowScroll, useGeneratedHtmlId, + useEuiTheme, + useEuiFontSize, } from '@elastic/eui' import { icon as EuiIconVisualizeApp } from '@elastic/eui/es/components/icon/assets/app_visualize' import { icon as EuiIconArrowDown } from '@elastic/eui/es/components/icon/assets/arrow_down' @@ -50,12 +57,18 @@ type VersionDropdownItem = { } type VersionDropdownProps = { - currentVersion: string - items: VersionDropdownItem[] + currentVersion?: string + allVersionsUrl?: string + items?: VersionDropdownItem[] } -const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => { +const VersionDropdown = ({ + allVersionsUrl, + currentVersion, + items, +}: VersionDropdownProps) => { const [isPopoverOpen, setPopover] = useState(false) + const { euiTheme } = useEuiTheme() const contextMenuPopoverId = useGeneratedHtmlId({ prefix: 'contextMenuPopover', @@ -84,60 +97,112 @@ const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => { const convertToPanels = ( items: VersionDropdownItem[] ): EuiContextMenuPanelDescriptor[] => { - return items.flatMap((item, index) => { - if (item.children == null) { - return [] - } else { - return { - id: index + 1, - title: item.name, - initialFocusedItemIndex: 0, - width: WIDTH, - disabled: item.disabled, - size: 's', - items: item.children ? convertItems(item.children) : [], - } - } - }) + return items == null + ? [] + : items.flatMap((item, index) => { + if (item.children == null) { + return [] + } else { + return { + id: index + 1, + title: item.name, + initialFocusedItemIndex: 0, + width: WIDTH, + disabled: item.disabled, + size: 's', + items: item.children + ? convertItems(item.children) + : [], + } + } + }) } const WIDTH = 175 - const topLevelItems = items.map((item, index) => { - return { - name: item.name, - panel: item.children?.length ? index + 1 : undefined, - href: item.href, - disabled: item.disabled, - } - }) + const topLevelItems = () => + items.map((item, index) => { + return { + name: item.name, + panel: item.children?.length ? index + 1 : undefined, + href: item.href, + disabled: item.disabled, + } + }) - const subpanels = convertToPanels(items) + const subpanels = () => convertToPanels(items) - const panels: EuiContextMenuPanelDescriptor[] = [ + const panels = (): EuiContextMenuPanelDescriptor[] => [ { id: 0, title: ( - + - Current ({currentVersion}) + {currentVersion} ), width: WIDTH, size: 's', items: [ - ...topLevelItems, - { - name: 'All versions', - href: 'https://elastic.co', - }, + ...(items == null + ? [ + { + renderItem: () => ( + + + There are no other versions available + for this page. + + + ), + }, + ] + : topLevelItems()), + ...(items?.length === 0 + ? [ + { + renderItem: () => ( + + + This page was fully migrated to the + current version. + + + ), + }, + ] + : []), + ...(allVersionsUrl != null + ? [ + { + renderItem: () => ( + + + + View all versions + + + + ), + }, + ] + : []), ], }, - ...subpanels, + ...(items != null ? subpanels() : []), ] const button = ( @@ -150,13 +215,12 @@ const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => { style={{ borderRadius: 9999 }} > - Current ({currentVersion}) + Current version ({currentVersion}) ) @@ -168,10 +232,30 @@ const VersionDropdown = ({ currentVersion, items }: VersionDropdownProps) => { isOpen={isPopoverOpen} closePopover={closePopover} panelPaddingSize="none" - anchorPosition="downLeft" + anchorPosition="downRight" repositionOnScroll={true} > - + ) } @@ -182,6 +266,7 @@ customElements.define( props: { items: 'json', currentVersion: 'string', + allVersionsUrl: 'string', }, }) ) diff --git a/src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml b/src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml index 528317811..f4bd99a58 100644 --- a/src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml +++ b/src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml @@ -13,13 +13,6 @@ } Docs - - @if (Model.Features.IsVersionDropdownEnabled && Model.VersionDropdown is not null) - { -
- -
- }
  • diff --git a/src/Elastic.Documentation.Site/_ViewModels.cs b/src/Elastic.Documentation.Site/_ViewModels.cs index 0a7250d90..20d7521af 100644 --- a/src/Elastic.Documentation.Site/_ViewModels.cs +++ b/src/Elastic.Documentation.Site/_ViewModels.cs @@ -25,9 +25,6 @@ public class GlobalLayoutViewModel public required INavigationItem? Previous { get; init; } public required INavigationItem? Next { get; init; } - public required string? VersionDropdown { get; init; } - public required string? CurrentVersion { get; init; } - public required string NavigationHtml { get; init; } public required string? UrlPathPrefix { get; init; } public required Uri? CanonicalBaseUrl { get; init; } diff --git a/src/Elastic.Markdown/Slices/HtmlWriter.cs b/src/Elastic.Markdown/Slices/HtmlWriter.cs index c3b02c3b5..6beb147da 100644 --- a/src/Elastic.Markdown/Slices/HtmlWriter.cs +++ b/src/Elastic.Markdown/Slices/HtmlWriter.cs @@ -85,6 +85,11 @@ private async Task RenderLayout(MarkdownFile markdown, MarkdownDocument .Distinct() .ToHashSet(); + string? allVersionsUrl = null; + + if (PositionalNavigation.MarkdownNavigationLookup.TryGetValue("docs-content://versions.md", out var item)) + allVersionsUrl = item.Url; + var slice = Index.Create(new IndexViewModel { SiteName = siteName, @@ -111,6 +116,7 @@ private async Task RenderLayout(MarkdownFile markdown, MarkdownDocument StaticFileContentHashProvider = StaticFileContentHashProvider, ReportIssueUrl = reportUrl, CurrentVersion = legacyPages?.Count > 0 ? legacyPages.ElementAt(0).Version : "9.0+", + AllVersionsUrl = allVersionsUrl, LegacyPages = legacyPages?.Skip(1).ToArray(), VersionDropdownItems = VersionDrownDownItemViewModel.FromLegacyPageMappings(legacyPages?.Skip(1).ToArray()), Products = allProducts diff --git a/src/Elastic.Markdown/Slices/Index.cshtml b/src/Elastic.Markdown/Slices/Index.cshtml index ddf03ef17..18c53c873 100644 --- a/src/Elastic.Markdown/Slices/Index.cshtml +++ b/src/Elastic.Markdown/Slices/Index.cshtml @@ -31,7 +31,8 @@ ReportIssueUrl = Model.ReportIssueUrl, LegacyPages = Model.LegacyPages, CurrentVersion = Model.CurrentVersion, - VersionDropdown = JsonSerializer.Serialize(Model.VersionDropdownItems, + AllVersionsUrl = Model.AllVersionsUrl, + VersionDropdownSerializedModel = JsonSerializer.Serialize(Model.VersionDropdownItems, ViewModelSerializerContext.Default.VersionDrownDownItemViewModelArray), }; protected override Task ExecuteSectionAsync(string name) diff --git a/src/Elastic.Markdown/Slices/IndexViewModel.cs b/src/Elastic.Markdown/Slices/IndexViewModel.cs index 77bcf9f45..066ba4835 100644 --- a/src/Elastic.Markdown/Slices/IndexViewModel.cs +++ b/src/Elastic.Markdown/Slices/IndexViewModel.cs @@ -34,6 +34,8 @@ public class IndexViewModel public required string NavigationHtml { get; init; } public required string CurrentVersion { get; init; } + + public required string? AllVersionsUrl { get; init; } public required LegacyPageMapping[]? LegacyPages { get; init; } public required VersionDrownDownItemViewModel[]? VersionDropdownItems { get; init; } public required string? UrlPathPrefix { get; init; } diff --git a/src/Elastic.Markdown/Slices/Layout/_LandingPage.cshtml b/src/Elastic.Markdown/Slices/Layout/_LandingPage.cshtml index aa9e65d88..a74d73262 100644 --- a/src/Elastic.Markdown/Slices/Layout/_LandingPage.cshtml +++ b/src/Elastic.Markdown/Slices/Layout/_LandingPage.cshtml @@ -19,6 +19,18 @@ Upgrade versions + @if (Model.AllVersionsUrl is not null) + { + + }
    diff --git a/src/Elastic.Markdown/Slices/Layout/_TableOfContents.cshtml b/src/Elastic.Markdown/Slices/Layout/_TableOfContents.cshtml index 649641a72..ff16bdcd2 100644 --- a/src/Elastic.Markdown/Slices/Layout/_TableOfContents.cshtml +++ b/src/Elastic.Markdown/Slices/Layout/_TableOfContents.cshtml @@ -1,7 +1,15 @@ @inherits RazorSlice
  • } @if (Model.LegacyPages is null) // This means there is no mapping because the page is new in v3 @@ -75,7 +83,8 @@ There is no previous version of this page. - } else if (Model.LegacyPages.Length == 0) // This means there is a legacy page mapping with 0 entries, which means the page was fully migrated and is also redirecting to the new system. + } + else if (Model.LegacyPages.Length == 0) // This means there is a legacy page mapping with 0 entries, which means the page was fully migrated and is also redirecting to the new system. {
  • @@ -86,6 +95,7 @@
+ }
    @if (Model.GithubEditUrl is not null) diff --git a/src/Elastic.Markdown/Slices/MarkdownLayoutViewModel.cs b/src/Elastic.Markdown/Slices/MarkdownLayoutViewModel.cs index 9fa71f785..493f73f83 100644 --- a/src/Elastic.Markdown/Slices/MarkdownLayoutViewModel.cs +++ b/src/Elastic.Markdown/Slices/MarkdownLayoutViewModel.cs @@ -21,6 +21,12 @@ public class MarkdownLayoutViewModel : GlobalLayoutViewModel public required IReadOnlyCollection PageTocItems { get; init; } public required LayoutName? Layout { get; init; } + + public required string? VersionDropdownSerializedModel { get; init; } + + public required string? CurrentVersion { get; init; } + + public required string? AllVersionsUrl { get; init; } } public record PageTocItem From 14eb6c42dea7671028f1e61a53be7cc4e5879620 Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 18 Jun 2025 14:01:15 +0200 Subject: [PATCH 2/3] Add comment --- .../Assets/web-components/VersionDropdown.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx b/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx index 236129665..be7dc2c6e 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx +++ b/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx @@ -241,6 +241,8 @@ const VersionDropdown = ({ panels={panels()} css={css` max-height: 70vh; + // This is needed because the CSS reset we are using + // is probably not fully compatible with the EUI button { cursor: pointer; &:disabled { From 4a0344d71095bde119036f0ab72e512546a0a68e Mon Sep 17 00:00:00 2001 From: Jan Calanog Date: Wed, 18 Jun 2025 14:02:18 +0200 Subject: [PATCH 3/3] Add comment --- .../Assets/web-components/VersionDropdown.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx b/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx index be7dc2c6e..c4d77844a 100644 --- a/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx +++ b/src/Elastic.Documentation.Site/Assets/web-components/VersionDropdown.tsx @@ -252,6 +252,9 @@ const VersionDropdown = ({ .euiContextMenuPanel__title { position: sticky; top: 0; + // !important because clicking on the title + // makes the background transparent + // and you unexpectedly see the items behind it. background-color: ${euiTheme.colors .backgroundBasePlain} !important; }