From 32e5dff12600a8edcb49a96b9253472e6b1138cf Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Thu, 19 Dec 2024 23:55:14 +0800 Subject: [PATCH] Lazy expandable feature for documentation --- docs/en/docs-nav.json | 2 + .../Volo/Docs/Documents/NavigationNode.cs | 3 + .../Documents/TagHelpers/TreeTagHelper.cs | 16 +- .../Pages/Documents/Project/Index.cshtml | 15 ++ .../Pages/Documents/Project/index.js | 144 ++++++++++++++++++ 5 files changed, 176 insertions(+), 4 deletions(-) diff --git a/docs/en/docs-nav.json b/docs/en/docs-nav.json index 6967e1f9ee..d2a928561d 100644 --- a/docs/en/docs-nav.json +++ b/docs/en/docs-nav.json @@ -71,6 +71,8 @@ }, { "text": "Book Store Application", + "isLazyExpandable": true, + "path": "tutorials/book-store", "items": [ { "text": "Overview", diff --git a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs index 231a8cddba..f19b9f41df 100644 --- a/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs +++ b/modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs @@ -16,6 +16,9 @@ namespace Volo.Docs.Documents [JsonPropertyName("items")] public List Items { get; set; } + [JsonPropertyName("isLazyExpandable")] + public bool IsLazyExpandable { get; set; } + [JsonPropertyName("isIndex")] public bool IsIndex { get; set; } diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs index 6d2cb8c9ba..e6c75d0161 100644 --- a/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs @@ -72,11 +72,14 @@ namespace Volo.Docs.Areas.Documents.TagHelpers var isAnyNodeOpenedInThisLevel = IsAnyNodeOpenedInThisLevel(node); - node.Items?.ForEach(innerNode => + if (!node.IsLazyExpandable || isAnyNodeOpenedInThisLevel) { - content += GetParentNode(innerNode, isAnyNodeOpenedInThisLevel); - }); - + node.Items?.ForEach(innerNode => + { + content += GetParentNode(innerNode, isAnyNodeOpenedInThisLevel); + }); + } + var result = node.IsEmpty ? content : GetLeafNode(node, content); return result; @@ -121,6 +124,11 @@ namespace Volo.Docs.Areas.Documents.TagHelpers listItemCss += " selected-tree"; } + if (node.IsLazyExpandable) + { + listItemCss += " lazy-expand"; + } + string listInnerItem; if (node.Path.IsNullOrEmpty() && node.IsLeaf) { diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml index 976154c630..8d36e55bd2 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml @@ -53,6 +53,21 @@ @if (Model.LoadSuccess) { + diff --git a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js index 41896bb2fd..4d8e036a71 100644 --- a/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js +++ b/modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js @@ -1,5 +1,116 @@ +var doc = doc || {}; + (function ($) { $(function () { + + var _documentAppService = volo.docs.documents.docsDocument; + + doc.lazyExpandableNavigation = { + isAllLoaded: false, + findNode : function(text, node){ + if(node.text === text && node.isLazyExpandable){ + return node; + } + if(node.items){ + for (let i = 0; i < node.items.length; i++) { + var result = doc.lazyExpandableNavigation.findNode(text, node.items[i]); + if(result){ + return result; + } + } + } + return null; + }, + renderNodeAsHtml : function($lazyLiElement, node){ + if(node.isEmpty){ + return; + } + + var $ul = $(``); + var $li = $(`
  • `); + + $li.append(` ${node.text}`) + + if(node.isLazyExpandable){ + $li.addClass("lazy-expand"); + }else if(node.hasChildItems){ + node.items.forEach(function(item){ + doc.lazyExpandableNavigation.renderNodeAsHtml($li, item); + }); + } + + $ul.append($li); + $lazyLiElement.append($ul) + + function normalPath(path){ + var pathWithoutFileExtension = removeFileExtensionFromPath(path); + + if (!pathWithoutFileExtension) + { + return "javascript:;"; + } + + if (path.toLowerCase().startsWith("http://") || path.toLowerCase().startsWith("https://")) + { + return path; + } + + path = abp.appPath + doc.uiOptions.routePrefix; + + if(doc.uiOptions.multiLanguageMode === `True`){ + path += doc.project.languageCode; + } + + if(doc.uiOptions.singleProjectMode === `False`){ + path += "/" + doc.project.name + } + + path += "/" + doc.project.routeVersion; + path += "/" + pathWithoutFileExtension; + return path.replace("//","/"); + } + + function removeFileExtensionFromPath(path){ + if (!path) + { + return null; + } + + var lastDotIndex = path.lastIndexOf("."); + if (lastDotIndex < 0) + { + return path; + } + + return path.substring(0, lastDotIndex); + } + }, + loadAll : function(lazyLiElements){ + if(doc.lazyExpandableNavigation.isAllLoaded){ + return; + } + for(var i = 0; i < lazyLiElements.length; i++){ + var $li = $(lazyLiElements[i]); + if($li.has("ul").length === 0){ + var node = doc.lazyExpandableNavigation.findNode($li.find("a").text(), doc.project.navigation); + node.items.forEach(item => { + doc.lazyExpandableNavigation.renderNodeAsHtml($li, item); + }) + } + + var childLazyLiElements = $li.find("li.lazy-expand"); + if(childLazyLiElements.length > 0){ + doc.lazyExpandableNavigation.loadAll(childLazyLiElements); + } + + $("li .lazy-expand").off('click'); + initLazyExpandNavigation(); + } + + doc.lazyExpandableNavigation.isAllLoaded = true; + } + } + var initNavigationFilter = function (navigationContainerId) { var $navigation = $('#' + navigationContainerId); @@ -23,6 +134,8 @@ return; } + doc.lazyExpandableNavigation.loadAll($navigation.find("li.lazy-expand")); + var filteredItems = $navigation .find('li > a') .filter(function () { @@ -98,6 +211,16 @@ }); }; + var initDocProject = function(){ + _documentAppService.getNavigation({ + projectId: doc.project.id, + version: doc.project.version, + languageCode: doc.project.languageCode + }).done((data) => { + doc.project.navigation = data; + }) + } + var initSocialShareLinks = function () { var pageHeader = $('.docs-body').find('h1, h2').first().text(); @@ -272,6 +395,25 @@ } }; + var initLazyExpandNavigation = function(){ + $("li .lazy-expand").on('click', function(){ + var $this = $(this); + if($this.has("ul").length > 0){ + return; + } + + var node = doc.lazyExpandableNavigation.findNode($this.find("a").text(), doc.project.navigation); + node.items.forEach(item => { + doc.lazyExpandableNavigation.renderNodeAsHtml($this, item); + }) + + $("li .lazy-expand").off('click'); + initLazyExpandNavigation(); + }); + } + + initDocProject(); + initNavigationFilter('sidebar-scroll'); initAnchorTags('.docs-page .docs-body'); @@ -279,6 +421,8 @@ initSocialShareLinks(); initSections(); + + initLazyExpandNavigation(); Element.prototype.querySelector = function (selector) { var result = $(this).find(decodeURI(selector));