From a0de880b8df11fc745d83171edf99fa817f59d0f Mon Sep 17 00:00:00 2001 From: liangshiwei Date: Mon, 23 Dec 2024 20:07:17 +0800 Subject: [PATCH] Add DocumentNavigationController --- .../Documents/DocumentNavigationController.cs | 80 +++++++++++++++++++ .../GetNavigationNodeWithLinkModel.cs | 28 +++++++ .../Pages/Documents/Project/Index.cshtml | 10 +-- .../Pages/Documents/Project/index.js | 77 +++++------------- 4 files changed, 132 insertions(+), 63 deletions(-) create mode 100644 modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentNavigationController.cs create mode 100644 modules/docs/src/Volo.Docs.Web/Areas/Models/DocumentNavigation/GetNavigationNodeWithLinkModel.cs diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentNavigationController.cs b/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentNavigationController.cs new file mode 100644 index 0000000000..cac52e8d5f --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Areas/Documents/DocumentNavigationController.cs @@ -0,0 +1,80 @@ +using System; +using System.Threading.Tasks; +using Asp.Versioning; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Docs.Areas.Models.DocumentNavigation; +using Volo.Docs.Documents; +using Volo.Docs.Utils; + +namespace Volo.Docs.Areas.Documents; + +[RemoteService(Name = DocsRemoteServiceConsts.RemoteServiceName)] +[Area(DocsRemoteServiceConsts.ModuleName)] +[ControllerName("DocumentNavigation")] +[Route("/docs/document-navigation")] +public class DocumentNavigationController : AbpController +{ + private readonly IDocumentAppService _documentAppService; + private readonly IDocsLinkGenerator _docsLinkGenerator; + + public DocumentNavigationController(IDocumentAppService documentAppService, IDocsLinkGenerator docsLinkGenerator) + { + _documentAppService = documentAppService; + _docsLinkGenerator = docsLinkGenerator; + } + + [HttpGet] + [Route("")] + public virtual async Task GetNavigationAsync(GetNavigationNodeWithLinkModel input) + { + var navigationNode = await _documentAppService.GetNavigationAsync(new GetNavigationDocumentInput + { + LanguageCode = input.LanguageCode, + Version = input.Version, + ProjectId = input.ProjectId + }); + + NormalPath(navigationNode, input); + + return navigationNode; + } + + protected virtual void NormalPath(NavigationNode node, GetNavigationNodeWithLinkModel input) + { + if (node.HasChildItems) + { + foreach (var item in node.Items) + { + NormalPath(item, input); + } + } + + if (UrlHelper.IsExternalLink(node.Path)) + { + return; + } + + node.Path = RemoveFileExtensionFromPath(node.Path, input.ProjectFormat); + if (node.Path.IsNullOrWhiteSpace()) + { + node.Path = "javascript:;"; + return; + } + + node.Path = _docsLinkGenerator.GenerateLink(input.ProjectName, input.LanguageCode, input.RouteVersion, node.Path); + } + + private string RemoveFileExtensionFromPath(string path, string projectFormat) + { + if (path == null) + { + return null; + } + + return path.EndsWith("." + projectFormat) + ? path.Left(path.Length - projectFormat.Length - 1) + : path; + } +} \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Web/Areas/Models/DocumentNavigation/GetNavigationNodeWithLinkModel.cs b/modules/docs/src/Volo.Docs.Web/Areas/Models/DocumentNavigation/GetNavigationNodeWithLinkModel.cs new file mode 100644 index 0000000000..085cc2de0e --- /dev/null +++ b/modules/docs/src/Volo.Docs.Web/Areas/Models/DocumentNavigation/GetNavigationNodeWithLinkModel.cs @@ -0,0 +1,28 @@ +using System; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; +using Volo.Docs.Language; +using Volo.Docs.Projects; + +namespace Volo.Docs.Areas.Models.DocumentNavigation; + +public class GetNavigationNodeWithLinkModel +{ + public Guid ProjectId { get; set; } + + [DynamicStringLength(typeof(ProjectConsts), nameof(ProjectConsts.MaxVersionNameLength))] + public string Version { get; set; } + + [Required] + [DynamicStringLength(typeof(LanguageConsts), nameof(LanguageConsts.MaxLanguageCodeLength))] + public string LanguageCode { get; set; } + + [Required] + public string ProjectName { get; set; } + + [Required] + public string ProjectFormat { get; set; } + + [Required] + public string RouteVersion { get; set; } +} \ No newline at end of file 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 8d36e55bd2..fb1f232cb3 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 @@ -57,15 +57,11 @@ var doc = doc || {}; doc.project = { id: '@Model.Project.Id', - name: '@Model.Project.Name', + name: '@Model.Project.ShortName', languageCode: '@Model.LanguageCode', version: '@Model.Version', - routeVersion: '@(Model.LatestVersionInfo == null || Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version)', - } - doc.uiOptions = { - routePrefix: '@DocsUiOptions.Value.RoutePrefix', - multiLanguageMode : `@DocsUiOptions.Value.MultiLanguageMode`, - singleProjectMode : `@DocsUiOptions.Value.SingleProjectMode.Enable`, + format: '@Model.Project.Format', + routeVersion: '@(Model.LatestVersionInfo == null || Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version)' } 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 22993a0c4f..730fe0116a 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 @@ -3,17 +3,15 @@ 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){ + findNode : function(text, href, node){ + if(node.text === text && node.path === href && 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]); + var result = doc.lazyExpandableNavigation.findNode(text, href, node.items[i]); if(result){ return result; } @@ -26,12 +24,12 @@ var doc = doc || {}; return; } - var textCss = node.path ? "": "tree-toggle"; + var textCss = node.path === "javascript:;" ? "": "tree-toggle"; var uiCss = isRootLazyNode ? "" : "style='display: none;'"; var $ul = $(``); var $li = $(`
  • `); - $li.append(` ${node.text}`) + $li.append(` ${node.text}`) if(node.isLazyExpandable){ $li.addClass("lazy-expand"); @@ -45,48 +43,6 @@ var doc = doc || {}; $lazyLiElement.append($ul) window.Toc.helpers.initNavEvent(); - 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){ @@ -95,7 +51,8 @@ var doc = doc || {}; 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); + var $a = $li.find("a"); + var node = doc.lazyExpandableNavigation.findNode($a.text(), $a.attr("href"), doc.project.navigation); node.items.forEach(item => { doc.lazyExpandableNavigation.renderNodeAsHtml($li, item, true); }) @@ -215,11 +172,18 @@ var doc = doc || {}; }; var initDocProject = function(){ - _documentAppService.getNavigation({ - projectId: doc.project.id, - version: doc.project.version, - languageCode: doc.project.languageCode - }).done((data) => { + abp.ajax({ + type :"GET", + url: '/docs/document-navigation', + data: { + projectId: doc.project.id, + version: doc.project.version, + routeVersion: doc.project.routeVersion, + languageCode: doc.project.languageCode, + projectName: doc.project.name, + projectFormat: doc.project.format + } + }).done(data => { doc.project.navigation = data; }) } @@ -405,7 +369,8 @@ var doc = doc || {}; return; } - var node = doc.lazyExpandableNavigation.findNode($this.find("a").text(), doc.project.navigation); + var $a = $this.find("a"); + var node = doc.lazyExpandableNavigation.findNode($a.text(), $a.attr("href") , doc.project.navigation); node.items.forEach(item => { doc.lazyExpandableNavigation.renderNodeAsHtml($this, item, true); })