Browse Source

Improve pdf download

pull/22922/head
SALİH ÖZKARA 1 year ago
parent
commit
729ec1ee03
  1. 16
      modules/docs/Volo.Docs.abpmdl
  2. 15
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentPdfAdminAppService.cs
  3. 4
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/IProjectAdminAppService.cs
  4. 36
      modules/docs/src/Volo.Docs.Admin.Application/BackgroundJobs/DocumentPdfGenerateJob.cs
  5. 12
      modules/docs/src/Volo.Docs.Admin.Application/BackgroundJobs/DocumentPdfGenerateJobArgs.cs
  6. 1
      modules/docs/src/Volo.Docs.Admin.Application/Volo.Docs.Admin.Application.csproj
  7. 4
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationModule.cs
  8. 67
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentPdfAdminAppService.cs
  9. 20
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs
  10. 61
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentPdfAdminClientProxy.Generated.cs
  11. 7
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentPdfAdminClientProxy.cs
  12. 16
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.Generated.cs
  13. 460
      modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/docs-admin-generate-proxy.json
  14. 60
      modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentPdfAdminController.cs
  15. 14
      modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/ProjectsAdminController.cs
  16. 68
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/GeneratePdf.cshtml
  17. 33
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/GeneratePdf.cshtml.cs
  18. 54
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/generatePdf.js
  19. 23
      modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/managePdfFiles.js
  20. 2
      modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.abppkg
  21. 60
      modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js
  22. 3
      modules/docs/src/Volo.Docs.Common.Application.Contracts/Volo.Docs.Common.Application.Contracts.abppkg
  23. 12
      modules/docs/src/Volo.Docs.Common.Application.Contracts/Volo/Docs/Common/Documents/IDocumentPdfAppService.cs
  24. 10
      modules/docs/src/Volo.Docs.Common.Application.Contracts/Volo/Docs/Common/Documents/IDocumentPdfGeneratorAppService.cs
  25. 3
      modules/docs/src/Volo.Docs.Common.Application/Volo.Docs.Common.Application.abppkg
  26. 54
      modules/docs/src/Volo.Docs.Common.Application/Volo/Docs/Common/Documents/DocumentPdfAppService.cs
  27. 52
      modules/docs/src/Volo.Docs.Common.Application/Volo/Docs/Common/Documents/DocumentPdfGeneratorAppService.cs
  28. 36
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsDocumentPdfClientProxy.Generated.cs
  29. 7
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsDocumentPdfClientProxy.cs
  30. 59
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsProjectClientProxy.Generated.cs
  31. 7
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsProjectClientProxy.cs
  32. 4
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/Volo/Docs/Documents/DocsDocumentPdfClientProxy.Generated.cs
  33. 2
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/Volo/Docs/Documents/DocsDocumentPdfClientProxy.cs
  34. 102
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/docs-common-generate-proxy.json
  35. 15
      modules/docs/src/Volo.Docs.Common.HttpApi.Client/Volo.Docs.Common.HttpApi.Client.abppkg
  36. 3
      modules/docs/src/Volo.Docs.Common.HttpApi/Volo.Docs.Common.HttpApi.abppkg
  37. 37
      modules/docs/src/Volo.Docs.Common.HttpApi/Volo/Docs/Documents/DocsDocumentPdfController.cs
  38. 32
      modules/docs/src/Volo.Docs.Common.HttpApi/Volo/Docs/Documents/DocsDocumentPdfGeneratorController.cs
  39. 6
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/BlobProjectPdfFileStore.cs
  40. 13
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/DocsProjectPdfGeneratorOptions.cs
  41. 3
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/IProjectPdfGenerator.cs
  42. 12
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/ProjectPdfGenerator.cs
  43. 31
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs
  44. 80
      modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/DocsDocumentClientProxy.Generated.cs
  45. 7
      modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/DocsDocumentClientProxy.cs
  46. 14
      modules/docs/src/Volo.Docs.HttpApi.Client/Volo.Docs.HttpApi.Client.abppkg
  47. 6
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  48. 16
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs
  49. 7
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js
  50. 13
      modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.abppkg
  51. 4
      nupkg/common.ps1

16
modules/docs/Volo.Docs.abpmdl

@ -86,6 +86,22 @@
"Volo.Docs.MongoDB.Tests": {
"path": "test/Volo.Docs.MongoDB.Tests/Volo.Docs.MongoDB.Tests.abppkg",
"folder": "test"
},
"Volo.Docs.Common.Application": {
"path": "src/Volo.Docs.Common.Application/Volo.Docs.Common.Application.abppkg",
"folder": "src"
},
"Volo.Docs.Common.Application.Contracts": {
"path": "src/Volo.Docs.Common.Application.Contracts/Volo.Docs.Common.Application.Contracts.abppkg",
"folder": "src"
},
"Volo.Docs.Common.HttpApi": {
"path": "src/Volo.Docs.Common.HttpApi/Volo.Docs.Common.HttpApi.abppkg",
"folder": "src"
},
"Volo.Docs.Common.HttpApi.Client": {
"path": "src/Volo.Docs.Common.HttpApi.Client/Volo.Docs.Common.HttpApi.Client.abppkg",
"folder": "src"
}
}
}

15
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentPdfAdminAppService.cs

@ -0,0 +1,15 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Common.Documents;
namespace Volo.Docs.Admin.Documents;
public interface IDocumentPdfAdminAppService : IDocumentPdfAppService
{
Task GeneratePdfAsync(DocumentPdfGeneratorInput input);
Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input);
Task DeletePdfFileAsync(DeletePdfFileInput input);
}

4
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Projects/IProjectAdminAppService.cs

@ -22,9 +22,5 @@ namespace Volo.Docs.Admin.Projects
Task ReindexAllAsync();
Task<List<ProjectWithoutDetailsDto>> GetListWithoutDetailsAsync();
Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input);
Task DeletePdfFileAsync(DeletePdfFileInput input);
}
}

36
modules/docs/src/Volo.Docs.Admin.Application/BackgroundJobs/DocumentPdfGenerateJob.cs

@ -0,0 +1,36 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Uow;
using Volo.Docs.Projects;
using Volo.Docs.Projects.Pdf;
namespace Volo.Docs.Admin.BackgroundJobs;
public class DocumentPdfGenerateJob : AsyncBackgroundJob<DocumentPdfGenerateJobArgs>, ITransientDependency
{
protected IProjectPdfGenerator ProjectPdfGenerator { get; }
protected IProjectRepository ProjectRepository { get; }
public DocumentPdfGenerateJob(IProjectPdfGenerator projectPdfGenerator, IProjectRepository projectRepository)
{
ProjectPdfGenerator = projectPdfGenerator;
ProjectRepository = projectRepository;
}
[UnitOfWork]
public async override Task ExecuteAsync(DocumentPdfGenerateJobArgs args)
{
try
{
var project = await ProjectRepository.GetAsync(args.ProjectId, includeDetails: true);
await ProjectPdfGenerator.GenerateAsync(project, args.Version, args.LanguageCode);
}
catch (Exception e)
{
Logger.LogError(e, "Error while generating PDF for project {ProjectId}, version {Version}, language {LanguageCode}", args.ProjectId, args.Version, args.LanguageCode);
}
}
}

12
modules/docs/src/Volo.Docs.Admin.Application/BackgroundJobs/DocumentPdfGenerateJobArgs.cs

@ -0,0 +1,12 @@
using System;
namespace Volo.Docs.Admin.BackgroundJobs;
public class DocumentPdfGenerateJobArgs
{
public Guid ProjectId { get; set; }
public string Version { get; set; }
public string LanguageCode { get; set; }
}

1
modules/docs/src/Volo.Docs.Admin.Application/Volo.Docs.Admin.Application.csproj

@ -17,6 +17,7 @@
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Caching\Volo.Abp.Caching.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.Ddd.Application\Volo.Abp.Ddd.Application.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.BackgroundJobs\Volo.Abp.BackgroundJobs.csproj" />
</ItemGroup>
</Project>

4
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/DocsAdminApplicationModule.cs

@ -4,6 +4,7 @@ using Volo.Abp.AutoMapper;
using Volo.Abp.Caching;
using Volo.Abp.Modularity;
using Volo.Docs.Common;
using Volo.Abp.BackgroundJobs;
namespace Volo.Docs.Admin
{
@ -13,7 +14,8 @@ namespace Volo.Docs.Admin
typeof(DocsCommonApplicationModule),
typeof(AbpCachingModule),
typeof(AbpAutoMapperModule),
typeof(AbpDddApplicationModule)
typeof(AbpDddApplicationModule),
typeof(AbpBackgroundJobsModule)
)]
public class DocsAdminApplicationModule : AbpModule
{

67
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentPdfAdminAppService.cs

@ -0,0 +1,67 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.BackgroundJobs;
using Volo.Abp.DistributedLocking;
using Volo.Docs.Admin.BackgroundJobs;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Common;
using Volo.Docs.Common.Documents;
using Volo.Docs.Projects;
using Volo.Docs.Projects.Pdf;
namespace Volo.Docs.Admin.Documents;
[Authorize(DocsCommonPermissions.Projects.PdfGeneration)]
public class DocumentPdfAdminAppService : DocumentPdfAppService, IDocumentPdfAdminAppService
{
protected IBackgroundJobManager BackgroundJobManager { get; }
protected IAbpDistributedLock DistributedLock { get; }
public DocumentPdfAdminAppService(
IProjectPdfGenerator projectPdfGenerator,
IProjectRepository projectRepository,
IProjectPdfFileStore projectPdfFileStore,
IOptions<DocsProjectPdfGeneratorOptions> options,
IBackgroundJobManager backgroundJobManager,
IAbpDistributedLock distributedLock) :
base(projectPdfGenerator, projectRepository, projectPdfFileStore, options)
{
BackgroundJobManager = backgroundJobManager;
DistributedLock = distributedLock;
}
public virtual async Task GeneratePdfAsync(DocumentPdfGeneratorInput input)
{
var project = await ProjectRepository.GetAsync(input.ProjectId, includeDetails: true);
await BackgroundJobManager.EnqueueAsync(new DocumentPdfGenerateJobArgs
{
Version = project.GetFullVersion(input.Version),
LanguageCode = input.LanguageCode,
ProjectId = input.ProjectId,
});
}
public virtual async Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input)
{
var project = await ProjectRepository.GetAsync(input.ProjectId, includeDetails: true);
var pdfFiles = project.PdfFiles.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
return new PagedResultDto<ProjectPdfFileDto>(
project.PdfFiles.Count,
ObjectMapper.Map<List<ProjectPdfFile>, List<ProjectPdfFileDto>>(pdfFiles)
);
}
[Authorize(DocsAdminPermissions.Projects.ManagePdfFiles)]
public virtual async Task DeletePdfFileAsync(DeletePdfFileInput input)
{
var project = await ProjectRepository.GetAsync(input.ProjectId, includeDetails: true);
await ProjectPdfFileStore.DeleteAsync(project, input.Version, input.LanguageCode);
}
}

20
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Projects/ProjectAdminAppService.cs

@ -181,25 +181,5 @@ namespace Volo.Docs.Admin.Projects
var projects = await _projectRepository.GetListWithoutDetailsAsync();
return ObjectMapper.Map<List<ProjectWithoutDetails>, List<ProjectWithoutDetailsDto>>(projects);
}
[Authorize(DocsAdminPermissions.Projects.ManagePdfFiles)]
public virtual async Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId, includeDetails: true);
var pdfFiles = project.PdfFiles.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
return new PagedResultDto<ProjectPdfFileDto>(
project.PdfFiles.Count,
ObjectMapper.Map<List<ProjectPdfFile>, List<ProjectPdfFileDto>>(pdfFiles)
);
}
[Authorize(DocsAdminPermissions.Projects.ManagePdfFiles)]
public virtual async Task DeletePdfFileAsync(DeletePdfFileInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId, includeDetails: true);
await _projectPdfFileStore.DeleteAsync(project, input.Version, input.LanguageCode);
}
}
}

61
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentPdfAdminClientProxy.Generated.cs

@ -0,0 +1,61 @@
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Content;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Http.Modeling;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Common.Documents;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Admin;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IDocumentPdfAppService), typeof(DocumentPdfAdminClientProxy))]
public partial class DocumentPdfAdminClientProxy : ClientProxyBase<IDocumentPdfAppService>, IDocumentPdfAppService
{
public virtual async Task GeneratePdfAsync(DocumentPdfGeneratorInput input)
{
await RequestAsync(nameof(GeneratePdfAsync), new ClientProxyRequestTypeValue
{
{ typeof(DocumentPdfGeneratorInput), input }
});
}
public virtual async Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input)
{
return await RequestAsync<PagedResultDto<ProjectPdfFileDto>>(nameof(GetPdfFilesAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetPdfFilesInput), input }
});
}
public virtual async Task DeletePdfFileAsync(DeletePdfFileInput input)
{
await RequestAsync(nameof(DeletePdfFileAsync), new ClientProxyRequestTypeValue
{
{ typeof(DeletePdfFileInput), input }
});
}
public virtual async Task<IRemoteStreamContent> DownloadPdfAsync(DocumentPdfGeneratorInput input)
{
return await RequestAsync<IRemoteStreamContent>(nameof(DownloadPdfAsync), new ClientProxyRequestTypeValue
{
{ typeof(DocumentPdfGeneratorInput), input }
});
}
public virtual async Task<bool> ExistsAsync(DocumentPdfGeneratorInput input)
{
return await RequestAsync<bool>(nameof(ExistsAsync), new ClientProxyRequestTypeValue
{
{ typeof(DocumentPdfGeneratorInput), input }
});
}
}

7
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/DocumentPdfAdminClientProxy.cs

@ -0,0 +1,7 @@
// This file is part of DocumentPdfAdminClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Admin;
public partial class DocumentPdfAdminClientProxy
{
}

16
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/ProjectsAdminClientProxy.Generated.cs

@ -68,22 +68,6 @@ public partial class ProjectsAdminClientProxy : ClientProxyBase<IProjectAdminApp
return await RequestAsync<List<ProjectWithoutDetailsDto>>(nameof(GetListWithoutDetailsAsync));
}
public virtual async Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input)
{
return await RequestAsync<PagedResultDto<ProjectPdfFileDto>>(nameof(GetPdfFilesAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetPdfFilesInput), input }
});
}
public virtual async Task DeletePdfFileAsync(DeletePdfFileInput input)
{
await RequestAsync(nameof(DeletePdfFileAsync), new ClientProxyRequestTypeValue
{
{ typeof(DeletePdfFileInput), input }
});
}
public virtual async Task ReindexAsync(ReindexInput input)
{
await RequestAsync(nameof(ReindexAsync), new ClientProxyRequestTypeValue

460
modules/docs/src/Volo.Docs.Admin.HttpApi.Client/ClientProxies/Volo/Docs/Admin/docs-admin-generate-proxy.json

@ -4,6 +4,466 @@
"rootPath": "docs-admin",
"remoteServiceName": "AbpDocsAdmin",
"controllers": {
"Volo.Docs.Admin.DocumentPdfAdminController": {
"controllerName": "DocumentPdfAdmin",
"controllerGroupName": "DocumentsPdfAdmin",
"isRemoteService": true,
"isIntegrationService": false,
"apiVersion": null,
"type": "Volo.Docs.Admin.DocumentPdfAdminController",
"interfaces": [
{
"type": "Volo.Docs.Admin.Documents.IDocumentPdfAdminAppService",
"name": "IDocumentPdfAdminAppService",
"methods": [
{
"name": "GeneratePdfAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
}
},
{
"name": "GetPdfFilesAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Admin.Projects.GetPdfFilesInput, Volo.Docs.Admin.Application.Contracts",
"type": "Volo.Docs.Admin.Projects.GetPdfFilesInput",
"typeSimple": "Volo.Docs.Admin.Projects.GetPdfFilesInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.Docs.Admin.Projects.ProjectPdfFileDto>",
"typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.Docs.Admin.Projects.ProjectPdfFileDto>"
}
},
{
"name": "DeletePdfFileAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Admin.Projects.DeletePdfFileInput, Volo.Docs.Admin.Application.Contracts",
"type": "Volo.Docs.Admin.Projects.DeletePdfFileInput",
"typeSimple": "Volo.Docs.Admin.Projects.DeletePdfFileInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
}
},
{
"name": "DownloadPdfAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "Volo.Abp.Content.IRemoteStreamContent",
"typeSimple": "Volo.Abp.Content.IRemoteStreamContent"
}
},
{
"name": "ExistsAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Boolean",
"typeSimple": "boolean"
}
}
]
},
{
"type": "Volo.Docs.Common.Documents.IDocumentPdfAppService",
"name": "IDocumentPdfAppService",
"methods": [
{
"name": "DownloadPdfAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "Volo.Abp.Content.IRemoteStreamContent",
"typeSimple": "Volo.Abp.Content.IRemoteStreamContent"
}
},
{
"name": "ExistsAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Boolean",
"typeSimple": "boolean"
}
}
]
}
],
"actions": {
"GeneratePdfAsyncByInput": {
"uniqueName": "GeneratePdfAsyncByInput",
"name": "GeneratePdfAsync",
"httpMethod": "GET",
"url": "api/docs/admin/documents/pdf/generate",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Version",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "LanguageCode",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentPdfAdminAppService"
},
"GetPdfFilesAsyncByInput": {
"uniqueName": "GetPdfFilesAsyncByInput",
"name": "GetPdfFilesAsync",
"httpMethod": "GET",
"url": "api/docs/admin/documents/pdf/files",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Admin.Projects.GetPdfFilesInput, Volo.Docs.Admin.Application.Contracts",
"type": "Volo.Docs.Admin.Projects.GetPdfFilesInput",
"typeSimple": "Volo.Docs.Admin.Projects.GetPdfFilesInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Sorting",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "SkipCount",
"jsonName": null,
"type": "System.Int32",
"typeSimple": "number",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "MaxResultCount",
"jsonName": null,
"type": "System.Int32",
"typeSimple": "number",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.Docs.Admin.Projects.ProjectPdfFileDto>",
"typeSimple": "Volo.Abp.Application.Dtos.PagedResultDto<Volo.Docs.Admin.Projects.ProjectPdfFileDto>"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentPdfAdminAppService"
},
"DeletePdfFileAsyncByInput": {
"uniqueName": "DeletePdfFileAsyncByInput",
"name": "DeletePdfFileAsync",
"httpMethod": "DELETE",
"url": "api/docs/admin/documents/pdf/delete-file",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Admin.Projects.DeletePdfFileInput, Volo.Docs.Admin.Application.Contracts",
"type": "Volo.Docs.Admin.Projects.DeletePdfFileInput",
"typeSimple": "Volo.Docs.Admin.Projects.DeletePdfFileInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Version",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "LanguageCode",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "System.Void",
"typeSimple": "System.Void"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentPdfAdminAppService"
},
"DownloadPdfAsyncByInput": {
"uniqueName": "DownloadPdfAsyncByInput",
"name": "DownloadPdfAsync",
"httpMethod": "GET",
"url": "api/docs/admin/documents/pdf/download",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Version",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "LanguageCode",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "Volo.Abp.Content.IRemoteStreamContent",
"typeSimple": "Volo.Abp.Content.IRemoteStreamContent"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Common.Documents.IDocumentPdfAppService"
},
"ExistsAsyncByInput": {
"uniqueName": "ExistsAsyncByInput",
"name": "ExistsAsync",
"httpMethod": "GET",
"url": "api/docs/admin/documents/pdf/exists",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Version",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "LanguageCode",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "System.Boolean",
"typeSimple": "boolean"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Common.Documents.IDocumentPdfAppService"
}
}
},
"Volo.Docs.Admin.DocumentsAdminController": {
"controllerName": "DocumentsAdmin",
"controllerGroupName": "DocumentsAdmin",

60
modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentPdfAdminController.cs

@ -0,0 +1,60 @@
using System.Threading.Tasks;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Content;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Common.Documents;
namespace Volo.Docs.Admin;
[RemoteService(Name = DocsAdminRemoteServiceConsts.RemoteServiceName)]
[Area(DocsAdminRemoteServiceConsts.ModuleName)]
[ControllerName("DocumentsPdfAdmin")]
[Route("api/docs/admin/documents/pdf")]
public class DocumentPdfAdminController : AbpControllerBase, IDocumentPdfAdminAppService
{
private readonly IDocumentPdfAdminAppService _documentPdfAdminAppService;
public DocumentPdfAdminController(IDocumentPdfAdminAppService documentPdfAdminAppService)
{
_documentPdfAdminAppService = documentPdfAdminAppService;
}
[HttpGet]
[Route("generate")]
public Task GeneratePdfAsync(DocumentPdfGeneratorInput input)
{
return _documentPdfAdminAppService.GeneratePdfAsync(input);
}
[HttpGet]
[Route("files")]
public Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input)
{
return _documentPdfAdminAppService.GetPdfFilesAsync(input);
}
[HttpDelete]
[Route("delete-file")]
public Task DeletePdfFileAsync(DeletePdfFileInput input)
{
return _documentPdfAdminAppService.DeletePdfFileAsync(input);
}
[HttpGet]
[Route("download")]
public Task<IRemoteStreamContent> DownloadPdfAsync(DocumentPdfGeneratorInput input)
{
return _documentPdfAdminAppService.DownloadPdfAsync(input);
}
[HttpGet]
[Route("exists")]
public Task<bool> ExistsAsync(DocumentPdfGeneratorInput input)
{
return _documentPdfAdminAppService.ExistsAsync(input);
}
}

14
modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/ProjectsAdminController.cs

@ -70,20 +70,6 @@ namespace Volo.Docs.Admin
return _projectAppService.GetListWithoutDetailsAsync();
}
[HttpGet]
[Route("PdfFiles")]
public Task<PagedResultDto<ProjectPdfFileDto>> GetPdfFilesAsync(GetPdfFilesInput input)
{
return _projectAppService.GetPdfFilesAsync(input);
}
[HttpDelete]
[Route("DeletePdfFile")]
public Task DeletePdfFileAsync(DeletePdfFileInput input)
{
return _projectAppService.DeletePdfFileAsync(input);
}
[HttpPost]
[Route("Reindex")]
public Task ReindexAsync(ReindexInput input)

68
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/GeneratePdf.cshtml

@ -8,40 +8,34 @@
@{
Layout = null;
}
<abp-modal>
<abp-modal-header title="@(L["GeneratePdf"].Value + " - " + Model.ViewModel.ShortName)"></abp-modal-header>
<abp-modal-body>
<input id="ProjectId" name="ProjectId" value="@Model.ViewModel.ProjectId" hidden/>
<input id="ShortName" name="ShortName" value="@Model.ViewModel.ShortName" hidden/>
<div class="mb-3">
<label class="form-label" for="Version">@L["Version"]</label>
<select name="Version" id="Version" class="form-select mt-2">
@foreach (var version in Model.ViewModel.Versions)
{
<option value="@version.Value">@version.Value</option>
}
</select>
</div>
<div class="mb-3">
<label class="form-label" for="Language">@L["Language"]</label>
<select name="Language" id="Language" class="form-select mt-2">
@foreach (var language in Model.ViewModel.Languages)
{
<option value="@language.Value">@language.Value</option>
}
</select>
</div>
<div class="form-check mb-3">
<label class="form-check-label" for="ForceToGenerate">
<input id="ForceToGenerate" type="checkbox" class="form-check-input" />
@L["ForceToGenerateNewPdf"]
</label>
</div>
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.None)">
<button type="button" class="btn btn-sm btn-link" data-bs-dismiss="modal">@L["Close"]</button>
<button type="button" class="btn btn-sm btn-outline-primary" id="GenerateBtn" data-busy-text="@L["Generating"].Value"><span>@L["GeneratePdf"]</span></button>
<button type="button" class="btn btn-sm btn-primary" id="GenerateAndDownloadPdfBtn">@L["GenerateAndDownloadPdf"]</button>
</abp-modal-footer>
</abp-modal>
<form method="post" asp-page="/Docs/Admin/Projects/GeneratePdf">
<abp-modal>
<abp-modal-header title="@(L["GeneratePdf"].Value + " - " + Model.ViewModel.ShortName)"></abp-modal-header>
<abp-modal-body>
<input id="ProjectId" asp-for="ProjectId" hidden/>
<input id="ShortName" name="ShortName" value="@Model.ViewModel.ShortName" hidden/>
<div class="mb-3">
<label class="form-label" asp-for="Version">@L["Version"]</label>
<select asp-for="Version" class="form-select mt-2">
@foreach (var version in Model.ViewModel.Versions)
{
<option value="@version.Value">@version.Value</option>
}
</select>
</div>
<div class="mb-3">
<label class="form-label" asp-for="Language">@L["Language"]</label>
<select asp-for="Language" class="form-select mt-2">
@foreach (var language in Model.ViewModel.Languages)
{
<option value="@language.Value">@language.Value</option>
}
</select>
</div>
</abp-modal-body>
<abp-modal-footer buttons="@(AbpModalButtons.None)">
<button type="button" class="btn btn-sm btn-link" data-bs-dismiss="modal">@L["Close"]</button>
<button type="submit" class="btn btn-sm btn-primary" id="GenerateBtn" data-busy-text="@L["Generating"].Value"><span>@L["GeneratePdf"]</span></button>
</abp-modal-footer>
</abp-modal>
</form>

33
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/GeneratePdf.cshtml.cs

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Common.Documents;
using Volo.Docs.Common.Projects;
@ -15,20 +16,32 @@ public class GeneratePdfModal : DocsAdminPageModel
{
protected IProjectAppService ProjectAppService { get; }
protected IProjectAdminAppService ProjectAdminAppService { get; }
protected IDocumentPdfAdminAppService DocumentPdfAdminAppService { get; }
public GeneratePdfViewModel ViewModel { get; set; }
[BindProperty(SupportsGet = true)]
public Guid ProjectId { get; set; }
[BindProperty(SupportsGet = true)]
public string Version { get; set; }
[BindProperty(SupportsGet = true)]
public string Language { get; set; }
public GeneratePdfModal(
IProjectAppService projectAppService,
IProjectAdminAppService projectAdminAppService)
IProjectAdminAppService projectAdminAppService,
IDocumentPdfAdminAppService documentPdfAdminAppService)
{
ProjectAppService = projectAppService;
ProjectAdminAppService = projectAdminAppService;
DocumentPdfAdminAppService = documentPdfAdminAppService;
}
public virtual async Task<IActionResult> OnGetAsync(Guid id)
public virtual async Task<IActionResult> OnGetAsync()
{
var project = await ProjectAdminAppService.GetAsync(id);
var project = await ProjectAdminAppService.GetAsync(ProjectId);
var versions = await ProjectAppService.GetVersionsAsync(project.ShortName);
if(versions.Items.Count == 0)
{
@ -40,7 +53,6 @@ public class GeneratePdfModal : DocsAdminPageModel
var languages = await ProjectAppService.GetLanguageListAsync(project.ShortName, versions.Items.FirstOrDefault()?.Name);
ViewModel = new GeneratePdfViewModel
{
ProjectId = id,
ShortName = project.ShortName,
Versions = versions.Items.Select(x => new SelectListItem(x.DisplayName, x.Name)).ToList(),
Languages = languages.Languages.Select(x => new SelectListItem(x.DisplayName, x.Code)).ToList()
@ -49,9 +61,20 @@ public class GeneratePdfModal : DocsAdminPageModel
return Page();
}
public virtual async Task<IActionResult> OnPostAsync()
{
await DocumentPdfAdminAppService.GeneratePdfAsync(new DocumentPdfGeneratorInput
{
ProjectId = ProjectId,
Version = Version,
LanguageCode = Language
});
return NoContent();
}
public class GeneratePdfViewModel
{
public Guid ProjectId { get; set; }
public string ShortName { get; set; }
public List<SelectListItem> Versions { get; set; }
public List<SelectListItem> Languages { get; set; }

54
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/generatePdf.js

@ -4,8 +4,6 @@ $(function () {
var l = abp.localization.getResource('Docs');
var projectAppService = volo.docs.projects.docsProject;
var pdfGeneratorAppService = volo.docs.documents.docsDocumentPdfGenerator;
var projectAdminAppService = volo.docs.admin.projectsAdmin;
var initModal = function (publicApi, args) {
@ -22,58 +20,6 @@ $(function () {
});
})
$("#GenerateBtn").click(function () {
var $btn = $(this);
$btn.buttonBusy(true);
$("#GenerateAndDownloadPdfBtn").buttonBusy(true);
var input = {
projectId: $("#ProjectId").val(),
version: $("#Version").val(),
languageCode: $("#Language").val(),
}
function generatePdf(input) {
pdfGeneratorAppService.generatePdf(input, {
abpHandleError : false,
error: function (jqXHR) {
if (jqXHR.status === 200) {
abp.message.success(l('PdfFileGeneratedSuccessfully'));
$btn.buttonBusy(false);
$("#GenerateAndDownloadPdfBtn").buttonBusy(false);
} else {
abp.ajax.handleErrorStatusCode(jqXHR.status);
}
}
});
}
if(shouldForceToGenerate(input)){
projectAdminAppService.deletePdfFile(input).done(() =>{
generatePdf(input);
});
}else{
generatePdf(input);
}
})
$("#GenerateAndDownloadPdfBtn").click(function () {
var input = {
projectId: $("#ProjectId").val(),
version: $("#Version").val(),
languageCode: $("#Language").val(),
}
if(shouldForceToGenerate(input)){
projectAdminAppService.deletePdfFile(input).done(() =>{
window.open(abp.appPath + 'api/docs/documents/pdf' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]), '_blank');
});
}else{
window.open(abp.appPath + 'api/docs/documents/pdf' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]), '_blank');
}
})
function shouldForceToGenerate(input) {
return $("#ForceToGenerate").is(":checked");
}
return {
initModal: initModal,
};

23
modules/docs/src/Volo.Docs.Admin.Web/Pages/Docs/Admin/Projects/managePdfFiles.js

@ -3,7 +3,7 @@ $(function () {
abp.modals.projectManagePdfFiles = function () {
var l = abp.localization.getResource('Docs');
var projectAdminAppService = volo.docs.admin.projectsAdmin;
var documentPdfAdminAppService = volo.docs.admin.documentPdfAdmin;
var _generatePdfModal = new abp.ModalManager({
viewUrl: abp.appPath + 'Docs/Admin/Projects/GeneratePdf',
@ -22,7 +22,7 @@ $(function () {
scrollCollapse: true,
order: [[2, 'desc']],
ajax: abp.libs.datatables.createAjax(
volo.docs.admin.projectsAdmin.getPdfFiles,
documentPdfAdminAppService.getPdfFiles,
{
projectId : args.projectId
}
@ -37,16 +37,23 @@ $(function () {
return l('PdfFileDeletionWarningMessage', data.record.fileName);
},
action: function (data) {
projectAdminAppService.deletePdfFile({
documentPdfAdminAppService.deletePdfFile({
projectId: data.record.projectId,
version: data.record.version,
languageCode: data.record.languageCode
}).then(() => {
_dataTable.ajax.reloadEx();
abp.notify.success(l('PdfGeneratedSuccessfully'));
abp.notify.success(l('PdfDeletedSuccessfully'));
})
},
}
},
{
text: l('Download'),
action: function (data) {
var url = abp.appPath + 'api/docs/admin/documents/pdf?projectId=' + data.record.projectId + '&version=' + data.record.version + '&languageCode=' + data.record.languageCode;
window.open(url, '_blank');
},
},
],
},
},
@ -78,13 +85,17 @@ $(function () {
$('#GeneratePdfBtn').click(function () {
_generatePdfModal.open({
Id: args.projectId,
ProjectId: args.projectId,
});
});
_generatePdfModal.onClose(function () {
_dataTable.ajax.reloadEx();
});
_generatePdfModal.onResult(function (){
abp.message.info(l('PdfGenerationStarted'), l('PdfGenerationStartedInfoMessage'));
});
};
return {

2
modules/docs/src/Volo.Docs.Admin.Web/Volo.Docs.Admin.Web.abppkg

@ -6,7 +6,7 @@
"applicationName": "VoloDocs.Web",
"module": "docs-admin",
"url": "https://localhost:5001",
"output": "wwwroot/client-proxies",
"output": "wwwroot/client-proxies/",
"serviceType": "application"
}
}

60
modules/docs/src/Volo.Docs.Admin.Web/wwwroot/client-proxies/docs-admin-proxy.js

@ -5,6 +5,51 @@
(function(){
// controller volo.docs.admin.documentPdfAdmin
(function(){
abp.utils.createNamespace(window, 'volo.docs.admin.documentPdfAdmin');
volo.docs.admin.documentPdfAdmin.generatePdf = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/pdf/generate' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]) + '',
type: 'GET',
dataType: null
}, ajaxParams));
};
volo.docs.admin.documentPdfAdmin.getPdfFiles = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/pdf/files' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
type: 'GET'
}, ajaxParams));
};
volo.docs.admin.documentPdfAdmin.deletePdfFile = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/pdf/delete-file' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]) + '',
type: 'DELETE',
dataType: null
}, ajaxParams));
};
volo.docs.admin.documentPdfAdmin.downloadPdf = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/pdf/download' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]) + '',
type: 'GET'
}, ajaxParams));
};
volo.docs.admin.documentPdfAdmin.exists = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/pdf/exists' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]) + '',
type: 'GET'
}, ajaxParams));
};
})();
// controller volo.docs.admin.documentsAdmin
(function(){
@ -136,21 +181,6 @@
}, ajaxParams));
};
volo.docs.admin.projectsAdmin.getPdfFiles = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/projects/PdfFiles' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'sorting', value: input.sorting }, { name: 'skipCount', value: input.skipCount }, { name: 'maxResultCount', value: input.maxResultCount }]) + '',
type: 'GET'
}, ajaxParams));
};
volo.docs.admin.projectsAdmin.deletePdfFile = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/projects/DeletePdfFile' + abp.utils.buildQueryString([{ name: 'projectId', value: input.projectId }, { name: 'version', value: input.version }, { name: 'languageCode', value: input.languageCode }]) + '',
type: 'DELETE',
dataType: null
}, ajaxParams));
};
volo.docs.admin.projectsAdmin.reindex = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/projects/Reindex',

3
modules/docs/src/Volo.Docs.Common.Application.Contracts/Volo.Docs.Common.Application.Contracts.abppkg

@ -0,0 +1,3 @@
{
"role": "Volo.Docs.Application.Contracts"
}

12
modules/docs/src/Volo.Docs.Common.Application.Contracts/Volo/Docs/Common/Documents/IDocumentPdfAppService.cs

@ -0,0 +1,12 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
namespace Volo.Docs.Common.Documents;
public interface IDocumentPdfAppService : IApplicationService
{
Task<IRemoteStreamContent> DownloadPdfAsync(DocumentPdfGeneratorInput input);
Task<bool> ExistsAsync(DocumentPdfGeneratorInput input);
}

10
modules/docs/src/Volo.Docs.Common.Application.Contracts/Volo/Docs/Common/Documents/IDocumentPdfGeneratorAppService.cs

@ -1,10 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
namespace Volo.Docs.Common.Documents;
public interface IDocumentPdfGeneratorAppService : IApplicationService
{
Task<IRemoteStreamContent> GeneratePdfAsync(DocumentPdfGeneratorInput input);
}

3
modules/docs/src/Volo.Docs.Common.Application/Volo.Docs.Common.Application.abppkg

@ -0,0 +1,3 @@
{
"role": "Volo.Docs.Application"
}

54
modules/docs/src/Volo.Docs.Common.Application/Volo/Docs/Common/Documents/DocumentPdfAppService.cs

@ -0,0 +1,54 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Volo.Abp.Content;
using Volo.Docs.Projects;
using Volo.Docs.Projects.Pdf;
namespace Volo.Docs.Common.Documents;
[Authorize(DocsCommonPermissions.Projects.PdfGeneration)]
public class DocumentPdfAppService : DocsCommonAppServiceBase, IDocumentPdfAppService
{
protected IProjectPdfGenerator ProjectPdfGenerator { get; }
protected IProjectRepository ProjectRepository { get; }
protected IProjectPdfFileStore ProjectPdfFileStore { get; }
protected IOptions<DocsProjectPdfGeneratorOptions> Options { get; }
public DocumentPdfAppService(
IProjectPdfGenerator projectPdfGenerator,
IProjectRepository projectRepository,
IProjectPdfFileStore projectPdfFileStore,
IOptions<DocsProjectPdfGeneratorOptions> options)
{
ProjectPdfGenerator = projectPdfGenerator;
ProjectRepository = projectRepository;
ProjectPdfFileStore = projectPdfFileStore;
Options = options;
}
public virtual async Task<IRemoteStreamContent> DownloadPdfAsync(DocumentPdfGeneratorInput input)
{
var project = await ProjectRepository.GetAsync(input.ProjectId);
var version = project.GetFullVersion(input.Version);
var languageCode = input.LanguageCode;
var fileName = Options.Value.CalculatePdfFileName(project, version, languageCode);
var fileStream = await ProjectPdfFileStore.GetOrNullAsync(project, version, languageCode);
if (fileStream != null)
{
return new RemoteStreamContent(fileStream, fileName, "application/pdf");
}
return null;
}
public virtual async Task<bool> ExistsAsync(DocumentPdfGeneratorInput input)
{
var project = await ProjectRepository.GetAsync(input.ProjectId);
var version = project.GetFullVersion(input.Version);
var languageCode = input.LanguageCode;
var fileName = Options.Value.CalculatePdfFileName(project, version, languageCode);
return project.FindPdfFile(fileName) != null;
}
}

52
modules/docs/src/Volo.Docs.Common.Application/Volo/Docs/Common/Documents/DocumentPdfGeneratorAppService.cs

@ -1,52 +0,0 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
using Volo.Abp.Data;
using Volo.Docs.Projects;
using Volo.Docs.Projects.Pdf;
namespace Volo.Docs.Common.Documents;
[Authorize(DocsCommonPermissions.Projects.PdfGeneration)]
public class DocumentPdfGeneratorAppService : ApplicationService, IDocumentPdfGeneratorAppService
{
protected IProjectPdfGenerator ProjectPdfGenerator { get; }
protected IProjectRepository ProjectRepository { get; }
public DocumentPdfGeneratorAppService(
IProjectPdfGenerator projectPdfGenerator,
IProjectRepository projectRepository)
{
ProjectPdfGenerator = projectPdfGenerator;
ProjectRepository = projectRepository;
}
public virtual async Task<IRemoteStreamContent> GeneratePdfAsync(DocumentPdfGeneratorInput input)
{
var project = await ProjectRepository.GetAsync(input.ProjectId, includeDetails: true);
// https://github.com/abpframework/abp/blob/e96f601641ab8a4bb7d704d3b9df2c00517d96f6/modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs#L73
var inputVersionStringBuilder = new StringBuilder();
input.Version = inputVersionStringBuilder.Append(GetProjectVersionPrefixIfExist(project)).Append(input.Version).ToString();
return await ProjectPdfGenerator.GenerateAsync(project, input.Version, input.LanguageCode);
}
private string GetProjectVersionPrefixIfExist(Project project)
{
if (GetGithubVersionProviderSource(project) != GithubVersionProviderSource.Branches)
{
return string.Empty;
}
return project.GetProperty<string>("VersionBranchPrefix");
}
private GithubVersionProviderSource GetGithubVersionProviderSource(Project project)
{
return project.HasProperty("GithubVersionProviderSource")
? project.GetProperty<GithubVersionProviderSource>("GithubVersionProviderSource")
: GithubVersionProviderSource.Releases;
}
}

36
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsDocumentPdfClientProxy.Generated.cs

@ -0,0 +1,36 @@
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Content;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Http.Modeling;
using Volo.Docs.Common.Documents;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Documents;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IDocumentPdfAppService), typeof(DocsDocumentPdfClientProxy))]
public partial class DocsDocumentPdfClientProxy : ClientProxyBase<IDocumentPdfAppService>, IDocumentPdfAppService
{
public virtual async Task<IRemoteStreamContent> DownloadPdfAsync(DocumentPdfGeneratorInput input)
{
return await RequestAsync<IRemoteStreamContent>(nameof(DownloadPdfAsync), new ClientProxyRequestTypeValue
{
{ typeof(DocumentPdfGeneratorInput), input }
});
}
public virtual async Task<bool> ExistsAsync(DocumentPdfGeneratorInput input)
{
return await RequestAsync<bool>(nameof(ExistsAsync), new ClientProxyRequestTypeValue
{
{ typeof(DocumentPdfGeneratorInput), input }
});
}
}

7
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsDocumentPdfClientProxy.cs

@ -0,0 +1,7 @@
// This file is part of DocsDocumentPdfClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Documents;
public partial class DocsDocumentPdfClientProxy
{
}

59
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsProjectClientProxy.Generated.cs

@ -0,0 +1,59 @@
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Http.Modeling;
using Volo.Docs.Common.Projects;
using Volo.Docs.Documents;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Projects;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IProjectAppService), typeof(DocsProjectClientProxy))]
public partial class DocsProjectClientProxy : ClientProxyBase<IProjectAppService>, IProjectAppService
{
public virtual async Task<ListResultDto<ProjectDto>> GetListAsync()
{
return await RequestAsync<ListResultDto<ProjectDto>>(nameof(GetListAsync));
}
public virtual async Task<ProjectDto> GetAsync(string shortName)
{
return await RequestAsync<ProjectDto>(nameof(GetAsync), new ClientProxyRequestTypeValue
{
{ typeof(string), shortName }
});
}
public virtual async Task<string> GetDefaultLanguageCodeAsync(string shortName, string version)
{
return await RequestAsync<string>(nameof(GetDefaultLanguageCodeAsync), new ClientProxyRequestTypeValue
{
{ typeof(string), shortName },
{ typeof(string), version }
});
}
public virtual async Task<ListResultDto<VersionInfoDto>> GetVersionsAsync(string shortName)
{
return await RequestAsync<ListResultDto<VersionInfoDto>>(nameof(GetVersionsAsync), new ClientProxyRequestTypeValue
{
{ typeof(string), shortName }
});
}
public virtual async Task<LanguageConfig> GetLanguageListAsync(string shortName, string version)
{
return await RequestAsync<LanguageConfig>(nameof(GetLanguageListAsync), new ClientProxyRequestTypeValue
{
{ typeof(string), shortName },
{ typeof(string), version }
});
}
}

7
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/DocsProjectClientProxy.cs

@ -0,0 +1,7 @@
// This file is part of DocsProjectClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Projects;
public partial class DocsProjectClientProxy
{
}

4
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/Volo/Docs/Documents/DocsDocumentPdfGeneratorClientProxy.Generated.cs → modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/Volo/Docs/Documents/DocsDocumentPdfClientProxy.Generated.cs

@ -15,8 +15,8 @@ using Volo.Docs.Common.Documents;
namespace Volo.Docs.Documents;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IDocumentPdfGeneratorAppService), typeof(DocsDocumentPdfGeneratorClientProxy))]
public partial class DocsDocumentPdfGeneratorClientProxy : ClientProxyBase<IDocumentPdfGeneratorAppService>, IDocumentPdfGeneratorAppService
[ExposeServices(typeof(IDocumentPdfAppService), typeof(DocsDocumentPdfClientProxy))]
public partial class DocsDocumentPdfClientProxy : ClientProxyBase<IDocumentPdfAppService>, IDocumentPdfAppService
{
public virtual async Task<IRemoteStreamContent> GeneratePdfAsync(DocumentPdfGeneratorInput input)
{

2
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/Volo/Docs/Documents/DocsDocumentPdfGeneratorClientProxy.cs → modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/Volo/Docs/Documents/DocsDocumentPdfClientProxy.cs

@ -2,6 +2,6 @@
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Documents;
public partial class DocsDocumentPdfGeneratorClientProxy
public partial class DocsDocumentPdfClientProxy
{
}

102
modules/docs/src/Volo.Docs.Common.HttpApi.Client/ClientProxies/docs-common-generate-proxy.json

@ -4,20 +4,20 @@
"rootPath": "docs-common",
"remoteServiceName": "AbpDocsCommon",
"controllers": {
"Volo.Docs.Documents.DocsDocumentPdfGeneratorController": {
"controllerName": "DocsDocumentPdfGenerator",
"controllerGroupName": "Document",
"Volo.Docs.Documents.DocsDocumentPdfController": {
"controllerName": "DocsDocumentPdf",
"controllerGroupName": "DocumentPdf",
"isRemoteService": true,
"isIntegrationService": false,
"apiVersion": null,
"type": "Volo.Docs.Documents.DocsDocumentPdfGeneratorController",
"type": "Volo.Docs.Documents.DocsDocumentPdfController",
"interfaces": [
{
"type": "Volo.Docs.Common.Documents.IDocumentPdfGeneratorAppService",
"name": "IDocumentPdfGeneratorAppService",
"type": "Volo.Docs.Common.Documents.IDocumentPdfAppService",
"name": "IDocumentPdfAppService",
"methods": [
{
"name": "GeneratePdfAsync",
"name": "DownloadPdfAsync",
"parametersOnMethod": [
{
"name": "input",
@ -32,16 +32,33 @@
"type": "Volo.Abp.Content.IRemoteStreamContent",
"typeSimple": "Volo.Abp.Content.IRemoteStreamContent"
}
},
{
"name": "ExistsAsync",
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"returnValue": {
"type": "System.Boolean",
"typeSimple": "boolean"
}
}
]
}
],
"actions": {
"GeneratePdfAsyncByInput": {
"uniqueName": "GeneratePdfAsyncByInput",
"name": "GeneratePdfAsync",
"DownloadPdfAsyncByInput": {
"uniqueName": "DownloadPdfAsyncByInput",
"name": "DownloadPdfAsync",
"httpMethod": "GET",
"url": "api/docs/documents/pdf",
"url": "api/docs/documents/pdf/download",
"supportedVersions": [],
"parametersOnMethod": [
{
@ -96,7 +113,68 @@
"typeSimple": "Volo.Abp.Content.IRemoteStreamContent"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Common.Documents.IDocumentPdfGeneratorAppService"
"implementFrom": "Volo.Docs.Common.Documents.IDocumentPdfAppService"
},
"ExistsAsyncByInput": {
"uniqueName": "ExistsAsyncByInput",
"name": "ExistsAsync",
"httpMethod": "GET",
"url": "api/docs/documents/pdf/exists",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput, Volo.Docs.Common.Application.Contracts",
"type": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"typeSimple": "Volo.Docs.Common.Documents.DocumentPdfGeneratorInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Version",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "LanguageCode",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "System.Boolean",
"typeSimple": "boolean"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Common.Documents.IDocumentPdfAppService"
}
}
},

15
modules/docs/src/Volo.Docs.Common.HttpApi.Client/Volo.Docs.Common.HttpApi.Client.abppkg

@ -0,0 +1,15 @@
{
"role": "Volo.Docs.HttpApi.Client",
"proxies": {
"csharp": {
"VoloDocs.Web-docs-common": {
"applicationName": "VoloDocs.Web",
"module": "docs-common",
"url": "https://localhost:5001",
"folder": "ClientProxies",
"serviceType": "all",
"withoutContracts": true
}
}
}
}

3
modules/docs/src/Volo.Docs.Common.HttpApi/Volo.Docs.Common.HttpApi.abppkg

@ -0,0 +1,3 @@
{
"role": "Volo.Docs.HttpApi"
}

37
modules/docs/src/Volo.Docs.Common.HttpApi/Volo/Docs/Documents/DocsDocumentPdfController.cs

@ -0,0 +1,37 @@
using System.Threading.Tasks;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Content;
using Volo.Docs.Common;
using Volo.Docs.Common.Documents;
namespace Volo.Docs.Documents;
[RemoteService(Name = DocsCommonRemoteServiceConsts.RemoteServiceName)]
[Area(DocsCommonRemoteServiceConsts.ModuleName)]
[ControllerName("DocumentPdf")]
[Route("api/docs/documents/pdf")]
public class DocsDocumentPdfController : DocsControllerBase, IDocumentPdfAppService
{
protected IDocumentPdfAppService DocumentPdfAppService { get; }
public DocsDocumentPdfController(IDocumentPdfAppService documentPdfAppService)
{
DocumentPdfAppService = documentPdfAppService;
}
[HttpGet]
[Route("download")]
public Task<IRemoteStreamContent> DownloadPdfAsync(DocumentPdfGeneratorInput input)
{
return DocumentPdfAppService.DownloadPdfAsync(input);
}
[HttpGet]
[Route("exists")]
public Task<bool> ExistsAsync(DocumentPdfGeneratorInput input)
{
return DocumentPdfAppService.ExistsAsync(input);
}
}

32
modules/docs/src/Volo.Docs.Common.HttpApi/Volo/Docs/Documents/DocsDocumentPdfGeneratorController.cs

@ -1,32 +0,0 @@
using System.Threading.Tasks;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Content;
using Volo.Docs.Common;
using Volo.Docs.Common.Documents;
namespace Volo.Docs.Documents;
[RemoteService(Name = DocsCommonRemoteServiceConsts.RemoteServiceName)]
[Area(DocsCommonRemoteServiceConsts.ModuleName)]
[ControllerName("Document")]
[Route("api/docs/documents")]
public class DocsDocumentPdfGeneratorController : DocsControllerBase, IDocumentPdfGeneratorAppService
{
protected IDocumentPdfGeneratorAppService DocumentPdfGeneratorAppService { get; }
public DocsDocumentPdfGeneratorController(IDocumentPdfGeneratorAppService documentPdfGeneratorAppService)
{
DocumentPdfGeneratorAppService = documentPdfGeneratorAppService;
}
[HttpGet]
[Route("pdf")]
public async Task<IRemoteStreamContent> GeneratePdfAsync(DocumentPdfGeneratorInput input)
{
var streamContent = await DocumentPdfGeneratorAppService.GeneratePdfAsync(input);
Response.Headers.ContentDisposition = $"inline; filename=\"{streamContent.FileName}\"";
return streamContent;
}
}

6
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/BlobProjectPdfFileStore.cs

@ -53,12 +53,6 @@ public class BlobProjectPdfFileStore : IProjectPdfFileStore, ITransientDependenc
return null;
}
var lastModificationTime = pdfFile.LastModificationTime ?? pdfFile.CreationTime;
if(lastModificationTime.Add(Options.Value.PdfFileCacheExpiration) <= Clock.Now)
{
return null;
}
return await BlobContainer.GetOrNullAsync(Options.Value.CalculatePdfFileName(project, version, languageCode));
}

13
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/DocsProjectPdfGeneratorOptions.cs

@ -1,5 +1,4 @@
using System;
using Scriban.Syntax;
namespace Volo.Docs.Projects.Pdf;
@ -29,12 +28,6 @@ public class DocsProjectPdfGeneratorOptions
/// </summary>
public string IndexPagePath { get; set; }
/// <summary>
/// PDF file cache expiration time.
/// Default value is 24 hours.
/// </summary>
public TimeSpan PdfFileCacheExpiration { get; set; } = TimeSpan.FromHours(24);
/// <summary>
/// The function to calculate the PDF file name.
/// Default is "{project.ShortName}-{version}-{languageCode}.pdf".
@ -50,6 +43,12 @@ public class DocsProjectPdfGeneratorOptions
public Func<string, string> DocumentContentNormalizer { get; set; }
/// <summary>
/// The maximum number of last versions to cache.
/// If null, all versions will be cached.
/// </summary>
public int? CacheLastVersionsCount { get; set; }
public DocsProjectPdfGeneratorOptions()
{
HtmlLayout = $@"

3
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/IProjectPdfGenerator.cs

@ -1,9 +1,8 @@
using System.Threading.Tasks;
using Volo.Abp.Content;
namespace Volo.Docs.Projects.Pdf;
public interface IProjectPdfGenerator
{
Task<IRemoteStreamContent> GenerateAsync(Project project, string version, string languageCode);
Task GenerateAsync(Project project, string version, string languageCode);
}

12
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Pdf/ProjectPdfGenerator.cs

@ -52,16 +52,8 @@ public class ProjectPdfGenerator : IProjectPdfGenerator, ITransientDependency
Logger = NullLogger<ProjectPdfGenerator>.Instance;
}
public virtual async Task<IRemoteStreamContent> GenerateAsync(Project project, string version, string languageCode)
public virtual async Task GenerateAsync(Project project, string version, string languageCode)
{
var fileName = Options.Value.CalculatePdfFileName(project, version, languageCode);
var fileStream = await ProjectPdfFileStore.GetOrNullAsync(project, version, languageCode);
if (fileStream != null)
{
return new RemoteStreamContent(fileStream, fileName, "application/pdf");
}
Project = project;
DocumentSource = DocumentStoreFactory.Create(project.DocumentStoreType);
DocumentParams = await GetDocumentParamsAsync(project, version, languageCode);
@ -74,8 +66,6 @@ public class ProjectPdfGenerator : IProjectPdfGenerator, ITransientDependency
var pdfStream = await HtmlToPdfRenderer.RenderAsync(title, html, AllPdfDocuments);
await ProjectPdfFileStore.SetAsync(project, version, languageCode, pdfStream);
return new RemoteStreamContent(pdfStream, fileName, "application/pdf");
}
protected virtual async Task<string> BuildHtmlAsync()

31
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Projects/Project.cs

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
namespace Volo.Docs.Projects
@ -126,5 +128,34 @@ namespace Volo.Docs.Projects
PdfFiles.Remove(pdfFile);
}
}
public virtual string GetFullVersion(string version)
{
var prefix = GetProjectVersionPrefixIfExist(this);
if (string.IsNullOrWhiteSpace(prefix) || version.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
return version;
}
var inputVersionStringBuilder = new StringBuilder();
return inputVersionStringBuilder.Append(prefix).Append(version).ToString();
}
protected virtual string GetProjectVersionPrefixIfExist(Project project)
{
if (GetGithubVersionProviderSource(project) != GithubVersionProviderSource.Branches)
{
return string.Empty;
}
return project.GetProperty<string>("VersionBranchPrefix");
}
protected virtual GithubVersionProviderSource GetGithubVersionProviderSource(Project project)
{
return project.HasProperty("GithubVersionProviderSource")
? project.GetProperty<GithubVersionProviderSource>("GithubVersionProviderSource")
: GithubVersionProviderSource.Releases;
}
}
}

80
modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/DocsDocumentClientProxy.Generated.cs

@ -0,0 +1,80 @@
// This file is automatically generated by ABP framework to use MVC Controllers from CSharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Abp.Http.Modeling;
using Volo.Docs.Documents;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Documents;
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IDocumentAppService), typeof(DocsDocumentClientProxy))]
public partial class DocsDocumentClientProxy : ClientProxyBase<IDocumentAppService>, IDocumentAppService
{
public virtual async Task<DocumentWithDetailsDto> GetAsync(GetDocumentInput input)
{
return await RequestAsync<DocumentWithDetailsDto>(nameof(GetAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetDocumentInput), input }
});
}
public virtual async Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input)
{
return await RequestAsync<DocumentWithDetailsDto>(nameof(GetDefaultAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetDefaultDocumentInput), input }
});
}
public virtual async Task<NavigationNode> GetNavigationAsync(GetNavigationDocumentInput input)
{
return await RequestAsync<NavigationNode>(nameof(GetNavigationAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetNavigationDocumentInput), input }
});
}
public virtual async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input)
{
return await RequestAsync<DocumentResourceDto>(nameof(GetResourceAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetDocumentResourceInput), input }
});
}
public virtual async Task<PagedResultDto<DocumentSearchOutput>> SearchAsync(DocumentSearchInput input)
{
return await RequestAsync<PagedResultDto<DocumentSearchOutput>>(nameof(SearchAsync), new ClientProxyRequestTypeValue
{
{ typeof(DocumentSearchInput), input }
});
}
public virtual async Task<bool> FullSearchEnabledAsync()
{
return await RequestAsync<bool>(nameof(FullSearchEnabledAsync));
}
public virtual async Task<List<String>> GetUrlsAsync(string prefix)
{
return await RequestAsync<List<String>>(nameof(GetUrlsAsync), new ClientProxyRequestTypeValue
{
{ typeof(string), prefix }
});
}
public virtual async Task<DocumentParametersDto> GetParametersAsync(GetParametersDocumentInput input)
{
return await RequestAsync<DocumentParametersDto>(nameof(GetParametersAsync), new ClientProxyRequestTypeValue
{
{ typeof(GetParametersDocumentInput), input }
});
}
}

7
modules/docs/src/Volo.Docs.HttpApi.Client/ClientProxies/DocsDocumentClientProxy.cs

@ -0,0 +1,7 @@
// This file is part of DocsDocumentClientProxy, you can customize it here
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Documents;
public partial class DocsDocumentClientProxy
{
}

14
modules/docs/src/Volo.Docs.HttpApi.Client/Volo.Docs.HttpApi.Client.abppkg

@ -1,3 +1,15 @@
{
"role": "lib.http-api-client"
"role": "lib.http-api-client",
"proxies": {
"csharp": {
"VoloDocs.Web-docs": {
"applicationName": "VoloDocs.Web",
"module": "docs",
"url": "https://localhost:5001",
"folder": "ClientProxies",
"serviceType": "all",
"withoutContracts": true
}
}
}
}

6
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml

@ -291,12 +291,12 @@
id="sidebar-scroll"
class="nav nav-list">
</ul>
@if (Model.HasDownloadPdfPermission)
@if (Model.HasDownloadPdf)
{
<div class="docs-sidebar-footer">
<a href="@Url.Content($"~/api/docs/documents/pdf?ProjectId={Model.Project.Id}&Version={(Model.LatestVersionInfo.IsSelected ? Model.LatestVersionInfo.Version : Model.Version)}&LanguageCode={Model.LanguageCode ?? Model.DefaultLanguageCode}")" target="_blank" class="download-pdf-btn">
<button data-url="@Url.Content($"~/api/docs/documents/pdf/download?ProjectId={Model.Project.Id}&Version={(Model.LatestVersionInfo.IsSelected ? Model.LatestVersionInfo.Version : Model.Version)}&LanguageCode={Model.LanguageCode ?? Model.DefaultLanguageCode}")" class="download-pdf-btn" id="DownloadPdfBtn">
<i class="fa fa-download"></i> @L["DownloadPDF"]
</a>
</button>
</div>
}
}

16
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs

@ -18,6 +18,7 @@ using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EventBus.Local;
using Volo.Docs.Common;
using Volo.Docs.Common.Documents;
using Volo.Docs.Common.Projects;
using Volo.Docs.Documents;
using Volo.Docs.Documents.Rendering;
@ -92,7 +93,7 @@ namespace Volo.Docs.Pages.Documents.Project
public bool IsLatestVersion { get; private set; }
public bool HasDownloadPdfPermission { get; set; }
public bool HasDownloadPdf { get; set; }
public DocumentNavigationsDto DocumentNavigationsDto { get; private set; }
@ -103,6 +104,7 @@ namespace Volo.Docs.Pages.Documents.Project
private readonly IWebDocumentSectionRenderer _webDocumentSectionRenderer;
private readonly DocsUiOptions _uiOptions;
private readonly IPermissionChecker _permissionChecker;
private readonly IDocumentPdfAppService _documentPdfAppService;
protected IDocsLinkGenerator DocsLinkGenerator => LazyServiceProvider.LazyGetRequiredService<IDocsLinkGenerator>();
@ -114,7 +116,8 @@ namespace Volo.Docs.Pages.Documents.Project
IProjectAppService projectAppService,
IOptions<DocsUiOptions> options,
IWebDocumentSectionRenderer webDocumentSectionRenderer,
IPermissionChecker permissionChecker)
IPermissionChecker permissionChecker,
IDocumentPdfAppService documentPdfAppService)
{
ObjectMapperContext = typeof(DocsWebModule);
@ -123,6 +126,7 @@ namespace Volo.Docs.Pages.Documents.Project
_projectAppService = projectAppService;
_webDocumentSectionRenderer = webDocumentSectionRenderer;
_permissionChecker = permissionChecker;
_documentPdfAppService = documentPdfAppService;
_uiOptions = options.Value;
LocalizationResourceType = typeof(DocsResource);
@ -152,7 +156,7 @@ namespace Volo.Docs.Pages.Documents.Project
ShowProjectsCombobox = _uiOptions.ShowProjectsCombobox && !_uiOptions.SingleProjectMode.Enable;
ShowProjectsComboboxLabel = ShowProjectsCombobox && _uiOptions.ShowProjectsComboboxLabel;
FullSearchEnabled = await _documentAppService.FullSearchEnabledAsync();
HasDownloadPdfPermission = await _permissionChecker.IsGrantedAsync(DocsCommonPermissions.Projects.PdfGeneration);
try
{
await SetProjectAsync();
@ -210,6 +214,12 @@ namespace Volo.Docs.Pages.Documents.Project
await SetNavigationAsync();
SetLanguageSelectListItems();
HasDownloadPdf = await _permissionChecker.IsGrantedAsync(DocsCommonPermissions.Projects.PdfGeneration)
&& await _documentPdfAppService.ExistsAsync(new()
{
ProjectId = Project.Id, Version = LatestVersionInfo.IsSelected ? LatestVersionInfo.Version : Version, LanguageCode = DocumentLanguageCode
});
return Page();
}

7
modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/index.js

@ -421,5 +421,12 @@ var doc = doc || {};
return originalSet.call(this, key, value);
};
$('#DownloadPdfBtn').click(function () {
var url = $(this).data('url');
if (url) {
window.open(url, '_blank');
}
});
});
})(jQuery);

13
modules/docs/src/Volo.Docs.Web/Volo.Docs.Web.abppkg

@ -2,7 +2,18 @@
"role": "lib.mvc",
"npmDependencies": {
"@abp/docs": {
"version": ""
"version": ""
}
},
"proxies": {
"Javascript": {
"VoloDocs.Web-docs": {
"applicationName": "VoloDocs.Web",
"module": "docs",
"url": "https://localhost:5001",
"output": "wwwroot/client-proxies/",
"serviceType": "application"
}
}
}
}

4
nupkg/common.ps1

@ -323,6 +323,10 @@ $projects = (
"modules/docs/src/Volo.Docs.Admin.Web",
"modules/docs/src/Volo.Docs.Application.Contracts",
"modules/docs/src/Volo.Docs.Application",
"modules/docs/src/Volo.Docs.Common.Application.Contracts",
"modules/docs/src/Volo.Docs.Common.Application",
"modules/docs/src/Volo.Docs.Common.HttpApi",
"modules/docs/src/Volo.Docs.Common.HttpApi.Client",
"modules/docs/src/Volo.Docs.Domain",
"modules/docs/src/Volo.Docs.Domain.Shared",
"modules/docs/src/Volo.Docs.EntityFrameworkCore",

Loading…
Cancel
Save