Browse Source

Cache documents in the local database for the documents module.

pull/2826/head
maliming 6 years ago
parent
commit
232186aada
  1. 4
      modules/docs/Volo.Docs.sln
  2. 465
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20181225134002_Initial20181225.Designer.cs
  3. 670
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20200212135141_init.Designer.cs
  4. 68
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20200212135141_init.cs
  5. 323
      modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs
  6. 7
      modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj
  7. 23
      modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs
  8. 3
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminPermissionDefinitionProvider.cs
  9. 6
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminPermissions.cs
  10. 12
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs
  11. 17
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullAllDocumentInput.cs
  12. 20
      modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullDocumentInput.cs
  13. 99
      modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs
  14. 36
      modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs
  15. 26
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentWithDetailsDto.cs
  16. 2
      modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs
  17. 76
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs
  18. 10
      modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs
  19. 8
      modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentConsts.cs
  20. 24
      modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs
  21. 6
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs
  22. 104
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs
  23. 30
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentContributor.cs
  24. 16
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentSourceFactory.cs
  25. 15
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentSourceOptions.cs
  26. 15
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentStoreOptions.cs
  27. 13
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs
  28. 2
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSource.cs
  29. 7
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSourceFactory.cs
  30. 7
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentStoreFactory.cs
  31. 30
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs
  32. 2
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Projects/ProjectFileSystemExtensions.cs
  33. 47
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs
  34. 11
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs
  35. 1
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubRepositoryManager.cs
  36. 2
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Projects/ProjectGithubExtensions.cs
  37. 5
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json
  38. 5
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json
  39. 5
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json
  40. 5
      modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json
  41. 6
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo.Docs.EntityFrameworkCore.csproj
  42. 23
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs
  43. 5
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContext.cs
  44. 33
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs
  45. 2
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsEntityFrameworkCoreModule.cs
  46. 5
      modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/IDocsDbContext.cs
  47. 2
      modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs
  48. 25
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs
  49. 2
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/BloggingMongoDbModule.cs
  50. 2
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/DocsMongoDbContext.cs
  51. 6
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/DocsMongoDbContextExtensions.cs
  52. 3
      modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/IDocsMongoDbContext.cs
  53. 17
      modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs
  54. 3
      modules/docs/src/Volo.Docs.Web/DocsWebAutoMapperProfile.cs
  55. 30
      modules/docs/src/Volo.Docs.Web/Models/NavigationWithDetailsDto.cs
  56. 8
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml
  57. 8
      modules/docs/src/Volo.Docs.Web/Pages/Documents/Project/Index.cshtml.cs
  58. 8
      modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/DocumentStoreFactory_Tests.cs
  59. 18
      modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/GithubDocumentStore_Tests.cs
  60. 2
      modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs

4
modules/docs/Volo.Docs.sln

@ -57,9 +57,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VoloDocs.Web", "app\VoloDoc
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VoloDocs.Migrator", "app\VoloDocs.Migrator\VoloDocs.Migrator.csproj", "{8A5E5001-C017-44A8-ADDA-DC66C102556E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.MongoDB", "src\Volo.Docs.MongoDB\Volo.Docs.MongoDB.csproj", "{DBE846CD-1BED-4F2C-ABF2-94F6240BCB9B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.MongoDB", "src\Volo.Docs.MongoDB\Volo.Docs.MongoDB.csproj", "{DBE846CD-1BED-4F2C-ABF2-94F6240BCB9B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Docs.MongoDB.Tests", "test\Volo.Docs.MongoDB.Tests\Volo.Docs.MongoDB.Tests.csproj", "{C5E2A2A3-D54D-4C2E-97BA-EA50A49ED7AD}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Docs.MongoDB.Tests", "test\Volo.Docs.MongoDB.Tests\Volo.Docs.MongoDB.Tests.csproj", "{C5E2A2A3-D54D-4C2E-97BA-EA50A49ED7AD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution

465
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20181225134002_Initial20181225.Designer.cs

@ -1,465 +0,0 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using VoloDocs.EntityFrameworkCore;
namespace VoloDocs.EntityFrameworkCore.Migrations
{
[DbContext(typeof(VoloDocsDbContext))]
[Migration("20181225134002_Initial20181225")]
partial class Initial20181225
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasMaxLength(256);
b.Property<string>("Description")
.HasMaxLength(256);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsStatic");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("Regex")
.HasMaxLength(512);
b.Property<string>("RegexDescription")
.HasMaxLength(128);
b.Property<bool>("Required");
b.Property<int>("ValueType");
b.HasKey("Id");
b.ToTable("AbpClaimTypes");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasMaxLength(256);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDefault")
.HasColumnName("IsDefault");
b.Property<bool>("IsPublic")
.HasColumnName("IsPublic");
b.Property<bool>("IsStatic")
.HasColumnName("IsStatic");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.IsRequired()
.HasMaxLength(256);
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("NormalizedName");
b.ToTable("AbpRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasMaxLength(1024);
b.Property<Guid>("RoleId");
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount")
.ValueGeneratedOnAdd()
.HasColumnName("AccessFailedCount")
.HasDefaultValue(0);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime");
b.Property<string>("Email")
.HasColumnName("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("EmailConfirmed")
.HasDefaultValue(false);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("LockoutEnabled")
.HasDefaultValue(false);
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("Name")
.HasColumnName("Name")
.HasMaxLength(64);
b.Property<string>("NormalizedEmail")
.HasColumnName("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.IsRequired()
.HasColumnName("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash")
.HasColumnName("PasswordHash")
.HasMaxLength(256);
b.Property<string>("PhoneNumber")
.HasColumnName("PhoneNumber")
.HasMaxLength(16);
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("PhoneNumberConfirmed")
.HasDefaultValue(false);
b.Property<string>("SecurityStamp")
.IsRequired()
.HasColumnName("SecurityStamp")
.HasMaxLength(256);
b.Property<string>("Surname")
.HasColumnName("Surname")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId");
b.Property<bool>("TwoFactorEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("TwoFactorEnabled")
.HasDefaultValue(false);
b.Property<string>("UserName")
.IsRequired()
.HasColumnName("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("Email");
b.HasIndex("NormalizedEmail");
b.HasIndex("NormalizedUserName");
b.HasIndex("UserName");
b.ToTable("AbpUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType")
.IsRequired()
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasMaxLength(1024);
b.Property<Guid?>("TenantId");
b.Property<Guid>("UserId");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AbpUserClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.Property<Guid>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(64);
b.Property<string>("ProviderDisplayName")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(196);
b.Property<Guid?>("TenantId");
b.HasKey("UserId", "LoginProvider");
b.HasIndex("LoginProvider", "ProviderKey");
b.ToTable("AbpUserLogins");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.Property<Guid>("UserId");
b.Property<Guid>("RoleId");
b.Property<Guid?>("TenantId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId", "UserId");
b.ToTable("AbpUserRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.Property<Guid>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(64);
b.Property<string>("Name")
.HasMaxLength(128);
b.Property<Guid?>("TenantId");
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AbpUserTokens");
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasMaxLength(64);
b.Property<string>("ProviderName")
.IsRequired()
.HasMaxLength(64);
b.Property<Guid?>("TenantId");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpPermissionGrants");
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.HasMaxLength(64);
b.Property<string>("Value")
.IsRequired()
.HasMaxLength(2048);
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Docs.Projects.Project", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp");
b.Property<string>("DefaultDocumentName")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("DocumentStoreType");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
b.Property<string>("Format");
b.Property<string>("LatestVersionBranchName")
.HasMaxLength(128);
b.Property<string>("MainWebsiteUrl");
b.Property<string>("MinimumVersion");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("NavigationDocumentName")
.IsRequired()
.HasMaxLength(128);
b.Property<string>("ShortName")
.IsRequired()
.HasMaxLength(32);
b.HasKey("Id");
b.ToTable("DocsProjects");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")
.WithMany("Claims")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Claims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
.WithMany("Tokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

670
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20200212135141_init.Designer.cs

@ -0,0 +1,670 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using VoloDocs.EntityFrameworkCore;
namespace VoloDocs.EntityFrameworkCore.Migrations
{
[DbContext(typeof(VoloDocsDbContext))]
[Migration("20200212135141_init")]
partial class init
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("Description")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsStatic")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("Regex")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("RegexDescription")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<bool>("Required")
.HasColumnType("bit");
b.Property<int>("ValueType")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("AbpClaimTypes");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDefault")
.HasColumnName("IsDefault")
.HasColumnType("bit");
b.Property<bool>("IsPublic")
.HasColumnName("IsPublic")
.HasColumnType("bit");
b.Property<bool>("IsStatic")
.HasColumnName("IsStatic")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("NormalizedName");
b.ToTable("AbpRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("ClaimType")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(1024)")
.HasMaxLength(1024);
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AbpRoleClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<int>("AccessFailedCount")
.ValueGeneratedOnAdd()
.HasColumnName("AccessFailedCount")
.HasColumnType("int")
.HasDefaultValue(0);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime")
.HasColumnType("datetime2");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime")
.HasColumnType("datetime2");
b.Property<string>("Email")
.IsRequired()
.HasColumnName("Email")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("EmailConfirmed")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime")
.HasColumnType("datetime2");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("LockoutEnabled")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("Name")
.HasColumnName("Name")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("NormalizedEmail")
.IsRequired()
.HasColumnName("NormalizedEmail")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.IsRequired()
.HasColumnName("NormalizedUserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("PasswordHash")
.HasColumnName("PasswordHash")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("PhoneNumber")
.HasColumnName("PhoneNumber")
.HasColumnType("nvarchar(16)")
.HasMaxLength(16);
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("PhoneNumberConfirmed")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("SecurityStamp")
.IsRequired()
.HasColumnName("SecurityStamp")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("Surname")
.HasColumnName("Surname")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("TwoFactorEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("TwoFactorEnabled")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("UserName")
.IsRequired()
.HasColumnName("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("Email");
b.HasIndex("NormalizedEmail");
b.HasIndex("NormalizedUserName");
b.HasIndex("UserName");
b.ToTable("AbpUsers");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uniqueidentifier");
b.Property<string>("ClaimType")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(1024)")
.HasMaxLength(1024);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AbpUserClaims");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasColumnType("nvarchar(196)")
.HasMaxLength(196);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("UserId", "LoginProvider");
b.HasIndex("LoginProvider", "ProviderKey");
b.ToTable("AbpUserLogins");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId", "UserId");
b.ToTable("AbpUserRoles");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("Name")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AbpUserTokens");
});
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.IsRequired()
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpPermissionGrants");
});
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("Value")
.IsRequired()
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.HasKey("Id");
b.HasIndex("Name", "ProviderName", "ProviderKey");
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Docs.Documents.Document", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(max)");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EditLink")
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("FileName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("Format")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("LanguageCode")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<DateTime>("LastCachedTime")
.HasColumnType("datetime2");
b.Property<DateTime>("LastUpdatedTime")
.HasColumnType("datetime2");
b.Property<string>("LocalDirectory")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<string>("RawRootUrl")
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.Property<string>("RootUrl")
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.Property<int>("UpdatedCount")
.HasColumnType("int");
b.Property<string>("Version")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.HasKey("Id");
b.ToTable("DocsDocuments");
});
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
{
b.Property<Guid>("DocumentId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Username")
.HasColumnType("nvarchar(450)");
b.Property<string>("AvatarUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserProfileUrl")
.HasColumnType("nvarchar(max)");
b.HasKey("DocumentId", "Username");
b.ToTable("DocsDocumentContributors");
});
modelBuilder.Entity("Volo.Docs.Projects.Project", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultDocumentName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("DocumentStoreType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Format")
.HasColumnType("nvarchar(max)");
b.Property<string>("LatestVersionBranchName")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("MainWebsiteUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("MinimumVersion")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("NavigationDocumentName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ParametersDocumentName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("nvarchar(32)")
.HasMaxLength(32);
b.HasKey("Id");
b.ToTable("DocsProjects");
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany("Claims")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Claims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Tokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
{
b.HasOne("Volo.Docs.Documents.Document", null)
.WithMany("Contributors")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}

68
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20181225134002_Initial20181225.cs → modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/20200212135141_init.cs

@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
namespace VoloDocs.EntityFrameworkCore.Migrations
{
public partial class Initial20181225 : Migration
public partial class init : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
@ -95,8 +95,8 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: false),
Name = table.Column<string>(maxLength: 64, nullable: true),
Surname = table.Column<string>(maxLength: 64, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: false),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: false),
EmailConfirmed = table.Column<bool>(nullable: false, defaultValue: false),
PasswordHash = table.Column<string>(maxLength: 256, nullable: true),
SecurityStamp = table.Column<string>(maxLength: 256, nullable: false),
@ -112,6 +112,33 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
table.PrimaryKey("PK_AbpUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "DocsDocuments",
columns: table => new
{
Id = table.Column<Guid>(nullable: false),
ExtraProperties = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
ProjectId = table.Column<Guid>(nullable: false),
Name = table.Column<string>(maxLength: 255, nullable: false),
Version = table.Column<string>(maxLength: 128, nullable: false),
LanguageCode = table.Column<string>(maxLength: 128, nullable: false),
FileName = table.Column<string>(maxLength: 128, nullable: false),
Content = table.Column<string>(nullable: false),
Format = table.Column<string>(maxLength: 128, nullable: true),
EditLink = table.Column<string>(maxLength: 2048, nullable: true),
RootUrl = table.Column<string>(maxLength: 2048, nullable: true),
RawRootUrl = table.Column<string>(maxLength: 2048, nullable: true),
LocalDirectory = table.Column<string>(maxLength: 512, nullable: true),
LastUpdatedTime = table.Column<DateTime>(nullable: false),
UpdatedCount = table.Column<int>(nullable: false),
LastCachedTime = table.Column<DateTime>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DocsDocuments", x => x.Id);
});
migrationBuilder.CreateTable(
name: "DocsProjects",
columns: table => new
@ -124,6 +151,7 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
Format = table.Column<string>(nullable: true),
DefaultDocumentName = table.Column<string>(maxLength: 128, nullable: false),
NavigationDocumentName = table.Column<string>(maxLength: 128, nullable: false),
ParametersDocumentName = table.Column<string>(maxLength: 128, nullable: false),
MinimumVersion = table.Column<string>(nullable: true),
DocumentStoreType = table.Column<string>(nullable: true),
MainWebsiteUrl = table.Column<string>(nullable: true),
@ -180,9 +208,9 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
name: "AbpUserLogins",
columns: table => new
{
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
LoginProvider = table.Column<string>(maxLength: 64, nullable: false),
TenantId = table.Column<Guid>(nullable: true),
ProviderKey = table.Column<string>(maxLength: 196, nullable: false),
ProviderDisplayName = table.Column<string>(maxLength: 128, nullable: true)
},
@ -201,9 +229,9 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
name: "AbpUserRoles",
columns: table => new
{
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
RoleId = table.Column<Guid>(nullable: false)
RoleId = table.Column<Guid>(nullable: false),
TenantId = table.Column<Guid>(nullable: true)
},
constraints: table =>
{
@ -226,10 +254,10 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
name: "AbpUserTokens",
columns: table => new
{
TenantId = table.Column<Guid>(nullable: true),
UserId = table.Column<Guid>(nullable: false),
LoginProvider = table.Column<string>(maxLength: 64, nullable: false),
Name = table.Column<string>(maxLength: 128, nullable: false),
TenantId = table.Column<Guid>(nullable: true),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
@ -243,6 +271,26 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "DocsDocumentContributors",
columns: table => new
{
DocumentId = table.Column<Guid>(nullable: false),
Username = table.Column<string>(nullable: false),
UserProfileUrl = table.Column<string>(nullable: true),
AvatarUrl = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_DocsDocumentContributors", x => new { x.DocumentId, x.Username });
table.ForeignKey(
name: "FK_DocsDocumentContributors_DocsDocuments_DocumentId",
column: x => x.DocumentId,
principalTable: "DocsDocuments",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AbpPermissionGrants_Name_ProviderName_ProviderKey",
table: "AbpPermissionGrants",
@ -325,6 +373,9 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
migrationBuilder.DropTable(
name: "AbpUserTokens");
migrationBuilder.DropTable(
name: "DocsDocumentContributors");
migrationBuilder.DropTable(
name: "DocsProjects");
@ -333,6 +384,9 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
migrationBuilder.DropTable(
name: "AbpUsers");
migrationBuilder.DropTable(
name: "DocsDocuments");
}
}
}

323
modules/docs/app/VoloDocs.EntityFrameworkCore/Migrations/VoloDocsDbContextModelSnapshot.cs

@ -15,42 +15,52 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.1-rtm-30846")
.HasAnnotation("ProductVersion", "3.1.1")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("Description")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsStatic");
b.Property<bool>("IsStatic")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("Regex")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("RegexDescription")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<bool>("Required");
b.Property<bool>("Required")
.HasColumnType("bit");
b.Property<int>("ValueType");
b.Property<int>("ValueType")
.HasColumnType("int");
b.HasKey("Id");
@ -60,35 +70,44 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.IsRequired()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDefault")
.HasColumnName("IsDefault");
.HasColumnName("IsDefault")
.HasColumnType("bit");
b.Property<bool>("IsPublic")
.HasColumnName("IsPublic");
.HasColumnName("IsPublic")
.HasColumnType("bit");
b.Property<bool>("IsStatic")
.HasColumnName("IsStatic");
.HasColumnName("IsStatic")
.HasColumnType("bit");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
@ -100,18 +119,22 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.HasColumnType("uniqueidentifier");
b.Property<string>("ClaimType")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(1024)")
.HasMaxLength(1024);
b.Property<Guid>("RoleId");
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
@ -123,105 +146,133 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<int>("AccessFailedCount")
.ValueGeneratedOnAdd()
.HasColumnName("AccessFailedCount")
.HasColumnType("int")
.HasDefaultValue(0);
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp");
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreationTime")
.HasColumnName("CreationTime");
.HasColumnName("CreationTime")
.HasColumnType("datetime2");
b.Property<Guid?>("CreatorId")
.HasColumnName("CreatorId");
.HasColumnName("CreatorId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("DeleterId")
.HasColumnName("DeleterId");
.HasColumnName("DeleterId")
.HasColumnType("uniqueidentifier");
b.Property<DateTime?>("DeletionTime")
.HasColumnName("DeletionTime");
.HasColumnName("DeletionTime")
.HasColumnType("datetime2");
b.Property<string>("Email")
.IsRequired()
.HasColumnName("Email")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("EmailConfirmed")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnName("IsDeleted")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTime?>("LastModificationTime")
.HasColumnName("LastModificationTime");
.HasColumnName("LastModificationTime")
.HasColumnType("datetime2");
b.Property<Guid?>("LastModifierId")
.HasColumnName("LastModifierId");
.HasColumnName("LastModifierId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("LockoutEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("LockoutEnabled")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetimeoffset");
b.Property<string>("Name")
.HasColumnName("Name")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("NormalizedEmail")
.IsRequired()
.HasColumnName("NormalizedEmail")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.IsRequired()
.HasColumnName("NormalizedUserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("PasswordHash")
.HasColumnName("PasswordHash")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("PhoneNumber")
.HasColumnName("PhoneNumber")
.HasColumnType("nvarchar(16)")
.HasMaxLength(16);
b.Property<bool>("PhoneNumberConfirmed")
.ValueGeneratedOnAdd()
.HasColumnName("PhoneNumberConfirmed")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("SecurityStamp")
.IsRequired()
.HasColumnName("SecurityStamp")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("Surname")
.HasColumnName("Surname")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId");
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<bool>("TwoFactorEnabled")
.ValueGeneratedOnAdd()
.HasColumnName("TwoFactorEnabled")
.HasColumnType("bit")
.HasDefaultValue(false);
b.Property<string>("UserName")
.IsRequired()
.HasColumnName("UserName")
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.HasKey("Id");
@ -240,18 +291,22 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.HasColumnType("uniqueidentifier");
b.Property<string>("ClaimType")
.IsRequired()
.HasColumnType("nvarchar(256)")
.HasMaxLength(256);
b.Property<string>("ClaimValue")
.HasColumnType("nvarchar(1024)")
.HasMaxLength(1024);
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("UserId");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
@ -262,19 +317,24 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.Property<Guid>("UserId");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderDisplayName")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasColumnType("nvarchar(196)")
.HasMaxLength(196);
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("UserId", "LoginProvider");
@ -285,11 +345,14 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.Property<Guid>("UserId");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<Guid>("RoleId");
b.Property<Guid>("RoleId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("UserId", "RoleId");
@ -300,17 +363,22 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.Property<Guid>("UserId");
b.Property<Guid>("UserId")
.HasColumnType("uniqueidentifier");
b.Property<string>("LoginProvider")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("Name")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Value");
b.Property<string>("Value")
.HasColumnType("nvarchar(max)");
b.HasKey("UserId", "LoginProvider", "Name");
@ -320,21 +388,26 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.IsRequired()
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.IsRequired()
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<Guid?>("TenantId");
b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
@ -346,20 +419,25 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("ProviderName")
.HasColumnType("nvarchar(64)")
.HasMaxLength(64);
b.Property<string>("Value")
.IsRequired()
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.HasKey("Id");
@ -369,43 +447,155 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
b.ToTable("AbpSettings");
});
modelBuilder.Entity("Volo.Docs.Documents.Document", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(max)");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EditLink")
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("FileName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("Format")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("LanguageCode")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<DateTime>("LastCachedTime")
.HasColumnType("datetime2");
b.Property<DateTime>("LastUpdatedTime")
.HasColumnType("datetime2");
b.Property<string>("LocalDirectory")
.HasColumnType("nvarchar(512)")
.HasMaxLength(512);
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(255)")
.HasMaxLength(255);
b.Property<Guid>("ProjectId")
.HasColumnType("uniqueidentifier");
b.Property<string>("RawRootUrl")
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.Property<string>("RootUrl")
.HasColumnType("nvarchar(2048)")
.HasMaxLength(2048);
b.Property<int>("UpdatedCount")
.HasColumnType("int");
b.Property<string>("Version")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.HasKey("Id");
b.ToTable("DocsDocuments");
});
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
{
b.Property<Guid>("DocumentId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Username")
.HasColumnType("nvarchar(450)");
b.Property<string>("AvatarUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("UserProfileUrl")
.HasColumnType("nvarchar(max)");
b.HasKey("DocumentId", "Username");
b.ToTable("DocsDocumentContributors");
});
modelBuilder.Entity("Volo.Docs.Projects.Project", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd();
.ValueGeneratedOnAdd()
.HasColumnType("uniqueidentifier");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnName("ConcurrencyStamp");
.HasColumnName("ConcurrencyStamp")
.HasColumnType("nvarchar(max)");
b.Property<string>("DefaultDocumentName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("DocumentStoreType");
b.Property<string>("DocumentStoreType")
.HasColumnType("nvarchar(max)");
b.Property<string>("ExtraProperties")
.HasColumnName("ExtraProperties");
.HasColumnName("ExtraProperties")
.HasColumnType("nvarchar(max)");
b.Property<string>("Format");
b.Property<string>("Format")
.HasColumnType("nvarchar(max)");
b.Property<string>("LatestVersionBranchName")
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("MainWebsiteUrl");
b.Property<string>("MainWebsiteUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("MinimumVersion");
b.Property<string>("MinimumVersion")
.HasColumnType("nvarchar(max)");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("NavigationDocumentName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ParametersDocumentName")
.IsRequired()
.HasColumnType("nvarchar(128)")
.HasMaxLength(128);
b.Property<string>("ShortName")
.IsRequired()
.HasColumnType("nvarchar(32)")
.HasMaxLength(32);
b.HasKey("Id");
@ -415,47 +605,62 @@ namespace VoloDocs.EntityFrameworkCore.Migrations
modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany("Claims")
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Claims")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Logins")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityRole")
b.HasOne("Volo.Abp.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Volo.Abp.Identity.IdentityUser")
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Roles")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b =>
{
b.HasOne("Volo.Abp.Identity.IdentityUser")
b.HasOne("Volo.Abp.Identity.IdentityUser", null)
.WithMany("Tokens")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Volo.Docs.Documents.DocumentContributor", b =>
{
b.HasOne("Volo.Docs.Documents.Document", null)
.WithMany("Contributors")
.HasForeignKey("DocumentId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}

7
modules/docs/app/VoloDocs.Web/VoloDocs.Web.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="..\..\..\..\configureawait.props" />
@ -19,6 +19,10 @@
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
@ -34,6 +38,7 @@
<ProjectReference Include="..\..\..\..\modules\identity\src\Volo.Abp.PermissionManagement.Domain.Identity\Volo.Abp.PermissionManagement.Domain.Identity.csproj" />
<ProjectReference Include="..\..\..\..\modules\permission-management\src\Volo.Abp.PermissionManagement.Application\Volo.Abp.PermissionManagement.Application.csproj" />
<ProjectReference Include="..\..\..\..\modules\account\src\Volo.Abp.Account.Web\Volo.Abp.Account.Web.csproj" />
<ProjectReference Include="..\..\..\..\modules\account\src\Volo.Abp.Account.Application\Volo.Abp.Account.Application.csproj" />
</ItemGroup>
<ItemGroup>

23
modules/docs/app/VoloDocs.Web/VoloDocsWebModule.cs

@ -31,6 +31,7 @@ using VoloDocs.EntityFrameworkCore;
using Localization.Resources.AbpUi;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
using Volo.Abp.Account;
using Volo.Abp.Validation.Localization;
namespace VoloDocs.Web
@ -43,6 +44,7 @@ namespace VoloDocs.Web
typeof(VoloDocsEntityFrameworkCoreModule),
typeof(AbpAutofacModule),
typeof(AbpAccountWebModule),
typeof(AbpAccountApplicationModule),
typeof(AbpIdentityWebModule),
typeof(AbpIdentityApplicationModule),
typeof(AbpPermissionManagementDomainIdentityModule),
@ -142,6 +144,12 @@ namespace VoloDocs.Web
var env = context.GetEnvironment();
app.UseVirtualFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseAbpRequestLocalization();
app.UseSwagger();
app.UseSwaggerUI(options =>
@ -149,24 +157,11 @@ namespace VoloDocs.Web
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API");
});
app.UseAuthentication();
app.UseAbpRequestLocalization();
app.UseStatusCodePagesWithReExecute("/error/{0}");
//app.UseMiddleware<GlobalExceptionHandlerMiddleware>();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "defaultWithArea",
template: "{area}/{controller=Home}/{action=Index}/{id?}");
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
app.UseMvcWithDefaultRouteAndArea();
using (var scope = context.ServiceProvider.CreateScope())
{

3
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminPermissionDefinitionProvider.cs

@ -14,6 +14,9 @@ namespace Volo.Docs.Admin
projects.AddChild(DocsAdminPermissions.Projects.Update, L("Permission:Edit"));
projects.AddChild(DocsAdminPermissions.Projects.Delete, L("Permission:Delete"));
projects.AddChild(DocsAdminPermissions.Projects.Create, L("Permission:Create"));
group.AddPermission(DocsAdminPermissions.Documents.Default, L("Permission:Documents"));
}
private static LocalizableString L(string name)

6
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/DocsAdminPermissions.cs

@ -14,6 +14,12 @@ namespace Volo.Docs.Admin
public const string Create = Default + ".Create";
}
public static class Documents
{
public const string Default = GroupName + ".Documents";
}
public static string[] GetAll()
{
return ReflectionHelper.GetPublicConstantsRecursively(typeof(DocsAdminPermissions));

12
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/IDocumentAdminAppService.cs

@ -0,0 +1,12 @@
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace Volo.Docs.Admin.Documents
{
public interface IDocumentAdminAppService : IApplicationService
{
Task PullAllAsync(PullAllDocumentInput input);
Task PullAsync(PullDocumentInput input);
}
}

17
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullAllDocumentInput.cs

@ -0,0 +1,17 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Docs.Documents;
namespace Volo.Docs.Admin.Documents
{
public class PullAllDocumentInput
{
public Guid ProjectId { get; set; }
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)]
public string LanguageCode { get; set; }
[StringLength(DocumentConsts.MaxVersionNameLength)]
public string Version { get; set; }
}
}

20
modules/docs/src/Volo.Docs.Admin.Application.Contracts/Volo/Docs/Admin/Documents/PullDocumentInput.cs

@ -0,0 +1,20 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Docs.Documents;
namespace Volo.Docs.Admin.Documents
{
public class PullDocumentInput
{
public Guid ProjectId { get; set; }
[StringLength(DocumentConsts.MaxNameLength)]
public string Name { get; set; }
[StringLength(DocumentConsts.MaxLanguageCodeNameLength)]
public string LanguageCode { get; set; }
[StringLength(DocumentConsts.MaxVersionNameLength)]
public string Version { get; set; }
}
}

99
modules/docs/src/Volo.Docs.Admin.Application/Volo/Docs/Admin/Documents/DocumentAdminAppService.cs

@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Newtonsoft.Json;
using Volo.Abp.Application.Services;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.Admin.Documents
{
[Authorize(DocsAdminPermissions.Documents.Default)]
public class DocumentAdminAppService : ApplicationService, IDocumentAdminAppService
{
private readonly IProjectRepository _projectRepository;
private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory;
public DocumentAdminAppService(IProjectRepository projectRepository,
IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory)
{
_projectRepository = projectRepository;
_documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory;
}
public async Task PullAllAsync(PullAllDocumentInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
var navigationFile = await GetDocumentAsync(
project,
project.NavigationDocumentName,
input.LanguageCode,
input.Version
);
var nav = JsonConvert.DeserializeObject<NavigationNode>(navigationFile.Content);
var leafs = nav.Items.GetAllNodes(x => x.Items)
.Where(x => x.IsLeaf && !x.Path.IsNullOrWhiteSpace())
.ToList();
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var documents = new List<Document>();
foreach (var leaf in leafs)
{
var sourceDocument =
await source.GetDocumentAsync(project, leaf.Path, input.LanguageCode, input.Version);
documents.Add(sourceDocument);
}
foreach (var document in documents)
{
var oldDocument = await _documentRepository.FindAsync(document.ProjectId, document.Name,
document.LanguageCode,
document.Version);
if (oldDocument != null)
{
await _documentRepository.DeleteAsync(oldDocument);
}
await _documentRepository.InsertAsync(document);
}
}
public async Task PullAsync(PullDocumentInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var sourceDocument = await source.GetDocumentAsync(project, input.Name, input.LanguageCode, input.Version);
var oldDocument = await _documentRepository.FindAsync(sourceDocument.ProjectId, sourceDocument.Name,
sourceDocument.LanguageCode, sourceDocument.Version);
if (oldDocument != null)
{
await _documentRepository.DeleteAsync(oldDocument);
}
await _documentRepository.InsertAsync(sourceDocument);
}
private async Task<Document> GetDocumentAsync(
Project project,
string documentName,
string languageCode,
string version)
{
version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version;
var source = _documentStoreFactory.Create(project.DocumentStoreType);
return await source.GetDocumentAsync(project, documentName, languageCode, version);
}
}
}

36
modules/docs/src/Volo.Docs.Admin.HttpApi/Volo/Docs/Admin/DocumentsAdminController.cs

@ -0,0 +1,36 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Docs.Admin.Documents;
namespace Volo.Docs.Admin
{
[RemoteService]
[Area("docs")]
[ControllerName("DocumentsAdmin")]
[Route("api/docs/admin/documents")]
public class DocumentsAdminController : AbpController, IDocumentAdminAppService
{
private readonly IDocumentAdminAppService _documentAdminAppService;
public DocumentsAdminController(IDocumentAdminAppService documentAdminAppService)
{
_documentAdminAppService = documentAdminAppService;
}
[HttpPost]
[Route("PullAll")]
public Task PullAllAsync(PullAllDocumentInput input)
{
return _documentAdminAppService.PullAllAsync(input);
}
[HttpPost]
[Route("Pull")]
public Task PullAsync(PullDocumentInput input)
{
return _documentAdminAppService.PullAsync(input);
}
}
}

26
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/DocumentWithDetailsDto.cs

@ -7,23 +7,31 @@ namespace Volo.Docs.Documents
[Serializable]
public class DocumentWithDetailsDto
{
public string Title { get; set; }
public virtual string Name { get; set; }
public string Content { get; set; }
public virtual string Version { get; set; }
public string Format { get; set; }
public virtual string LanguageCode { get; set; }
public string EditLink { get; set; }
public virtual string FileName { get; set; }
public string RootUrl { get; set; }
public virtual string Content { get; set; }
public string RawRootUrl { get; set; }
public virtual string Format { get; set; }
public string Version { get; set; }
public virtual string EditLink { get; set; }
public string LocalDirectory { get; set; }
public virtual string RootUrl { get; set; }
public string FileName { get; set; }
public virtual string RawRootUrl { get; set; }
public virtual string LocalDirectory { get; set; }
public virtual DateTime LastUpdatedTime { get; set; }
public virtual int UpdatedCount { get; set; }
public virtual DateTime LastCachedTime { get; set; }
public ProjectDto Project { get; set; }

2
modules/docs/src/Volo.Docs.Application.Contracts/Volo/Docs/Documents/IDocumentAppService.cs

@ -9,7 +9,7 @@ namespace Volo.Docs.Documents
Task<DocumentWithDetailsDto> GetDefaultAsync(GetDefaultDocumentInput input);
Task<DocumentWithDetailsDto> GetNavigationAsync(GetNavigationDocumentInput input);
Task<NavigationNode> GetNavigationAsync(GetNavigationDocumentInput input);
Task<DocumentParametersDto> GetParametersAsync(GetParametersDocumentInput input);

76
modules/docs/src/Volo.Docs.Application/Volo/Docs/Documents/DocumentAppService.cs

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Hosting;
@ -13,22 +14,22 @@ namespace Volo.Docs.Documents
public class DocumentAppService : DocsAppServiceBase, IDocumentAppService
{
private readonly IProjectRepository _projectRepository;
private readonly IDocumentStoreFactory _documentStoreFactory;
protected IDistributedCache<DocumentWithDetailsDto> DocumentCache { get; }
private readonly IDocumentRepository _documentRepository;
private readonly IDocumentSourceFactory _documentStoreFactory;
protected IDistributedCache<LanguageConfig> LanguageCache { get; }
protected IDistributedCache<DocumentResourceDto> ResourceCache { get; }
protected IHostEnvironment HostEnvironment { get; }
public DocumentAppService(
IProjectRepository projectRepository,
IDocumentStoreFactory documentStoreFactory,
IDistributedCache<DocumentWithDetailsDto> documentCache,
IDocumentRepository documentRepository,
IDocumentSourceFactory documentStoreFactory,
IDistributedCache<LanguageConfig> languageCache,
IDistributedCache<DocumentResourceDto> resourceCache,
IHostEnvironment hostEnvironment)
{
_projectRepository = projectRepository;
_documentRepository = documentRepository;
_documentStoreFactory = documentStoreFactory;
DocumentCache = documentCache;
LanguageCache = languageCache;
ResourceCache = resourceCache;
HostEnvironment = hostEnvironment;
@ -58,16 +59,37 @@ namespace Volo.Docs.Documents
);
}
public virtual async Task<DocumentWithDetailsDto> GetNavigationAsync(GetNavigationDocumentInput input)
public virtual async Task<NavigationNode> GetNavigationAsync(GetNavigationDocumentInput input)
{
var project = await _projectRepository.GetAsync(input.ProjectId);
return await GetDocumentWithDetailsDtoAsync(
var navigationDocument = await GetDocumentWithDetailsDtoAsync(
project,
project.NavigationDocumentName,
input.LanguageCode,
input.Version
);
var navigationNode = JsonConvert.DeserializeObject<NavigationNode>(navigationDocument.Content);
var leafs = navigationNode.Items.GetAllNodes(x => x.Items)
.Where(x => x.IsLeaf && !x.Path.IsNullOrWhiteSpace())
.ToList();
foreach (var leaf in leafs)
{
var document = await GetDocumentWithDetailsDtoAsync(
project,
leaf.Path,
input.LanguageCode,
input.Version
);
leaf.LastUpdatedTime = document.LastUpdatedTime;
leaf.UpdatedCount = document.UpdatedCount;
}
return navigationNode;
}
public async Task<DocumentResourceDto> GetResourceAsync(GetDocumentResourceInput input)
@ -78,8 +100,8 @@ namespace Volo.Docs.Documents
async Task<DocumentResourceDto> GetResourceAsync()
{
var store = _documentStoreFactory.Create(project.DocumentStoreType);
var documentResource = await store.GetResource(project, input.Name, input.LanguageCode, input.Version);
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var documentResource = await source.GetResource(project, input.Name, input.LanguageCode, input.Version);
return ObjectMapper.Map<DocumentResource, DocumentResourceDto>(documentResource);
}
@ -136,32 +158,35 @@ namespace Volo.Docs.Documents
{
version = string.IsNullOrWhiteSpace(version) ? project.LatestVersionBranchName : version;
var cacheKey = $"Document@{project.ShortName}#{languageCode}#{documentName}#{version}";
async Task<DocumentWithDetailsDto> GetDocumentAsync()
{
Logger.LogInformation($"Not found in the cache. Requesting {documentName} from the store...");
var store = _documentStoreFactory.Create(project.DocumentStoreType);
var document = await store.GetDocumentAsync(project, documentName, languageCode, version);
Logger.LogInformation($"Not found in the cache. Requesting {documentName} from the source...");
var source = _documentStoreFactory.Create(project.DocumentStoreType);
var sourceDocument = await source.GetDocumentAsync(project, documentName, languageCode, version);
await _documentRepository.InsertAsync(sourceDocument);
Logger.LogInformation($"Document retrieved: {documentName}");
return CreateDocumentWithDetailsDto(project, document);
return CreateDocumentWithDetailsDto(project, sourceDocument);
}
/*
if (HostEnvironment.IsDevelopment())
{
return await GetDocumentAsync();
}*/
var document = await _documentRepository.FindAsync(project.Id, documentName, languageCode, version);
//TODO: Configurable cache time?
if (document == null || document.LastCachedTime + TimeSpan.FromHours(12) < DateTime.Now)
{
return await GetDocumentAsync();
}
return await DocumentCache.GetOrAddAsync(
cacheKey,
GetDocumentAsync,
() => new DistributedCacheEntryOptions
{
//TODO: Configurable?
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(2),
SlidingExpiration = TimeSpan.FromMinutes(30)
}
);
return CreateDocumentWithDetailsDto(project, document);
}
protected virtual DocumentWithDetailsDto CreateDocumentWithDetailsDto(Project project, Document document)
@ -171,6 +196,5 @@ namespace Volo.Docs.Documents
documentDto.Contributors = ObjectMapper.Map<List<DocumentContributor>, List<DocumentContributorDto>>(document.Contributors);
return documentDto;
}
}
}

10
modules/docs/src/Volo.Docs.Application/Volo/Docs/Projects/ProjectAppService.cs

@ -15,18 +15,18 @@ namespace Volo.Docs.Projects
{
private readonly IProjectRepository _projectRepository;
private readonly IDistributedCache<List<VersionInfo>> _versionCache;
private readonly IDocumentStoreFactory _documentStoreFactory;
private readonly IDocumentSourceFactory _documentSource;
protected IDistributedCache<LanguageConfig> LanguageCache { get; }
public ProjectAppService(
IProjectRepository projectRepository,
IDistributedCache<List<VersionInfo>> versionCache,
IDocumentStoreFactory documentStoreFactory,
IDocumentSourceFactory documentSource,
IDistributedCache<LanguageConfig> languageCache)
{
_projectRepository = projectRepository;
_versionCache = versionCache;
_documentStoreFactory = documentStoreFactory;
_documentSource = documentSource;
LanguageCache = languageCache;
}
@ -68,7 +68,7 @@ namespace Volo.Docs.Projects
protected virtual async Task<List<VersionInfo>> GetVersionsAsync(Project project)
{
var store = _documentStoreFactory.Create(project.DocumentStoreType);
var store = _documentSource.Create(project.DocumentStoreType);
var versions = await store.GetVersionsAsync(project);
if (!versions.Any())
@ -108,7 +108,7 @@ namespace Volo.Docs.Projects
private async Task<LanguageConfig> GetLanguageListInternalAsync(string shortName, string version)
{
var project = await _projectRepository.GetByShortNameAsync(shortName);
var store = _documentStoreFactory.Create(project.DocumentStoreType);
var store = _documentSource.Create(project.DocumentStoreType);
async Task<LanguageConfig> GetLanguagesAsync()
{

8
modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/DocumentConsts.cs

@ -3,5 +3,13 @@
public static class DocumentConsts
{
public const int MaxNameLength = 255;
public const int MaxVersionNameLength = 128;
public const int MaxLanguageCodeNameLength = 128;
public const int MaxFileNameNameLength = 128;
public const int MaxFormatNameLength = 128;
public const int MaxEditLinkLength = 2048;
public const int MaxRootUrlLength = 2048;
public const int MaxRawRootUrlLength = 2048;
public const int MaxLocalDirectoryLength = 512;
}
}

24
modules/docs/src/Volo.Docs.Web/Models/NavigationNode.cs → modules/docs/src/Volo.Docs.Domain.Shared/Volo/Docs/Documents/NavigationNode.cs

@ -22,6 +22,10 @@ namespace Volo.Docs.Documents
public bool IsEmpty => Text == null && Path == null;
public DateTime? LastUpdatedTime { get; set; }
public int UpdatedCount { get; set; }
public bool IsSelected(string documentName)
{
if (documentName == null)
@ -50,4 +54,24 @@ namespace Volo.Docs.Documents
return false;
}
}
public static class NavigationNodeExtension
{
public static IEnumerable<NavigationNode> GetAllNodes(this IEnumerable<NavigationNode> source, Func<NavigationNode, IEnumerable<NavigationNode>> selector)
{
if (source == null)
{
yield break;
}
foreach (var item in source)
{
yield return item;
foreach (var subItem in GetAllNodes(selector(item), selector))
{
yield return subItem;
}
}
}
}
}

6
modules/docs/src/Volo.Docs.Domain/Volo/Docs/DocsDomainModule.cs

@ -32,10 +32,10 @@ namespace Volo.Docs
.AddVirtualJson("/Volo/Docs/Localization/Domain");
});
Configure<DocumentStoreOptions>(options =>
Configure<DocumentSourceOptions>(options =>
{
options.Stores[GithubDocumentStore.Type] = typeof(GithubDocumentStore);
options.Stores[FileSystemDocumentStore.Type] = typeof(FileSystemDocumentStore);
options.Sources[GithubDocumentSource.Type] = typeof(GithubDocumentSource);
options.Sources[FileSystemDocumentSource.Type] = typeof(FileSystemDocumentSource);
});
context.Services.AddHttpClient(GithubRepositoryManager.HttpClientName, client =>

104
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/Document.cs

@ -1,27 +1,109 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
namespace Volo.Docs.Documents
{
public class Document
public class Document : AggregateRoot<Guid>
{
public string Title { get; set; }
public virtual Guid ProjectId { get; protected set; }
public string Content { get; set; }
public virtual string Name { get; protected set; }
public string Format { get; set; }
public virtual string Version { get; protected set; }
public string EditLink { get; set; }
public virtual string LanguageCode { get; protected set; }
public string RootUrl { get; set; }
public virtual string FileName { get; set; }
public string RawRootUrl { get; set; }
public virtual string Content { get; set; }
public string Version { get; set; }
public virtual string Format { get; set; }
public string LocalDirectory { get; set; }
public virtual string EditLink { get; set; }
public string FileName { get; set; }
public virtual string RootUrl { get; set; }
public List<DocumentContributor> Contributors { get; set; }
public virtual string RawRootUrl { get; set; }
public virtual string LocalDirectory { get; set; }
public virtual DateTime LastUpdatedTime { get; set; }
public virtual int UpdatedCount { get; set; }
public virtual DateTime LastCachedTime { get; set; }
public virtual List<DocumentContributor> Contributors { get; set; }
protected Document()
{
Contributors = new List<DocumentContributor>();
ExtraProperties = new Dictionary<string, object>();
}
public Document(
Guid id,
Guid projectId,
[NotNull] string name,
[NotNull] string version,
[NotNull] string languageCode,
[NotNull] string fileName,
[NotNull] string content,
[NotNull] string format,
[NotNull] string editLink,
[NotNull] string rootUrl,
[NotNull] string rawRootUrl,
[NotNull] string localDirectory,
DateTime lastUpdatedTime,
int updatedCount,
DateTime lastCachedTime
)
{
Id = id;
ProjectId = projectId;
Name = Check.NotNullOrWhiteSpace(name, nameof(name));
Version = Check.NotNullOrWhiteSpace(version, nameof(version));
LanguageCode = Check.NotNullOrWhiteSpace(languageCode, nameof(languageCode));
FileName = Check.NotNullOrWhiteSpace(fileName, nameof(fileName));
Content = Check.NotNullOrWhiteSpace(content, nameof(content));
Format = Check.NotNullOrWhiteSpace(format, nameof(format));
EditLink = Check.NotNullOrWhiteSpace(editLink, nameof(editLink));
RootUrl = Check.NotNullOrWhiteSpace(rootUrl, nameof(rootUrl));
RawRootUrl = Check.NotNullOrWhiteSpace(rawRootUrl, nameof(rawRootUrl));
LocalDirectory = Check.NotNull(localDirectory, nameof(localDirectory));
LastUpdatedTime = lastUpdatedTime;
UpdatedCount = updatedCount;
LastCachedTime = lastCachedTime;
Contributors = new List<DocumentContributor>();
ExtraProperties = new Dictionary<string, object>();
}
public virtual void AddContributor(string username, string userProfileUrl, string avatarUrl)
{
Contributors.AddIfNotContains(new DocumentContributor(Id, username, userProfileUrl, avatarUrl));
}
public virtual void RemoveAllContributors()
{
Contributors.Clear();
}
public virtual void RemoveContributor(string username, string userProfileUrl, string avatarUrl)
{
Contributors.RemoveAll(r =>
r.Username == username && r.UserProfileUrl == userProfileUrl && r.AvatarUrl == avatarUrl);
}
public virtual DocumentContributor FindContributor(string username, string userProfileUrl, string avatarUrl)
{
return Contributors.FirstOrDefault(r =>
r.Username == username && r.UserProfileUrl == userProfileUrl && r.AvatarUrl == avatarUrl);
}
}
}

30
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentContributor.cs

@ -1,15 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;
using Volo.Abp.Domain.Entities;
namespace Volo.Docs.Documents
{
public class DocumentContributor
public class DocumentContributor : Entity
{
public Guid DocumentId { get; set; }
public string Username { get; set; }
public string UserProfileUrl { get; set; }
public string AvatarUrl { get; set; }
protected DocumentContributor()
{
}
public virtual bool Equals(Guid documentId, string username)
{
return DocumentId == documentId && Username == username;
}
public DocumentContributor(Guid documentId, string username, string userProfileUrl, string avatarUrl)
{
DocumentId = documentId;
Username = username;
UserProfileUrl = userProfileUrl;
AvatarUrl = avatarUrl;
}
public override object[] GetKeys()
{
return new object[] { DocumentId, Username };
}
}
}

16
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentStoreFactory.cs → modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentSourceFactory.cs

@ -6,28 +6,28 @@ using Volo.Abp.DependencyInjection;
namespace Volo.Docs.Documents
{
public class DocumentStoreFactory : IDocumentStoreFactory, ITransientDependency
public class DocumentSourceFactory : IDocumentSourceFactory, ITransientDependency
{
protected DocumentStoreOptions Options { get; }
protected DocumentSourceOptions Options { get; }
protected IServiceProvider ServiceProvider { get; }
public DocumentStoreFactory(
public DocumentSourceFactory(
IServiceProvider serviceProvider,
IOptions<DocumentStoreOptions> options)
IOptions<DocumentSourceOptions> options)
{
Options = options.Value;
ServiceProvider = serviceProvider;
}
public virtual IDocumentStore Create(string storeType)
public virtual IDocumentSource Create(string sourceType)
{
var serviceType = Options.Stores.GetOrDefault(storeType);
var serviceType = Options.Sources.GetOrDefault(sourceType);
if (serviceType == null)
{
throw new ApplicationException($"Unknown document store: {storeType}");
throw new ApplicationException($"Unknown document store: {sourceType}");
}
return (IDocumentStore) ServiceProvider.GetRequiredService(serviceType);
return (IDocumentSource) ServiceProvider.GetRequiredService(serviceType);
}
}
}

15
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentSourceOptions.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace Volo.Docs.Documents
{
public class DocumentSourceOptions
{
public Dictionary<string, Type> Sources { get; set; }
public DocumentSourceOptions()
{
Sources = new Dictionary<string, Type>();
}
}
}

15
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/DocumentStoreOptions.cs

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
namespace Volo.Docs.Documents
{
public class DocumentStoreOptions
{
public Dictionary<string, Type> Stores { get; set; }
public DocumentStoreOptions()
{
Stores = new Dictionary<string, Type>();
}
}
}

13
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentRepository.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace Volo.Docs.Documents
{
public interface IDocumentRepository : IBasicRepository<Document>
{
Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version);
}
}

2
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentStore.cs → modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSource.cs

@ -6,7 +6,7 @@ using Volo.Docs.Projects;
namespace Volo.Docs.Documents
{
public interface IDocumentStore : IDomainService
public interface IDocumentSource : IDomainService
{
Task<Document> GetDocumentAsync(Project project, string documentName, string languageCode, string version);

7
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentSourceFactory.cs

@ -0,0 +1,7 @@
namespace Volo.Docs.Documents
{
public interface IDocumentSourceFactory
{
IDocumentSource Create(string sourceType);
}
}

7
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Documents/IDocumentStoreFactory.cs

@ -1,7 +0,0 @@
namespace Volo.Docs.Documents
{
public interface IDocumentStoreFactory
{
IDocumentStore Create(string storeType);
}
}

30
modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentStore.cs → modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Documents/FileSystemDocumentSource.cs

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Threading.Tasks;
@ -11,7 +12,7 @@ using Volo.Docs.Projects;
namespace Volo.Docs.FileSystem.Documents
{
public class FileSystemDocumentStore : DomainService, IDocumentStore
public class FileSystemDocumentSource : DomainService, IDocumentSource
{
public const string Type = "FileSystem";
@ -30,16 +31,21 @@ namespace Volo.Docs.FileSystem.Documents
localDirectory = documentName.Substring(0, documentName.LastIndexOf('/'));
}
return new Document
{
Content = content,
FileName = Path.GetFileName(path),
Format = project.Format,
LocalDirectory = localDirectory,
Title = documentName,
RawRootUrl = $"/document-resources?projectId={project.Id.ToString()}&version={version}&languageCode={languageCode}&name=",
RootUrl = "/"
};
return new Document(GuidGenerator.Create(),
project.Id,
documentName,
version,
languageCode,
Path.GetFileName(path),
content,
project.Format,
path,
"/",
$"/document-resources?projectId={project.Id.ToString()}&version={version}&languageCode={languageCode}&name=",
localDirectory,
File.GetLastWriteTime(path),
File.GetLastWriteTime(path) == File.GetCreationTime(path) ? 1 : 2,
DateTime.Now);
}
public Task<List<VersionInfo>> GetVersionsAsync(Project project)

2
modules/docs/src/Volo.Docs.Domain/Volo/Docs/FileSystem/Projects/ProjectFileSystemExtensions.cs

@ -24,7 +24,7 @@ namespace Volo.Docs.FileSystem.Projects
{
Check.NotNull(project, nameof(project));
if (project.DocumentStoreType != FileSystemDocumentStore.Type)
if (project.DocumentStoreType != FileSystemDocumentSource.Type)
{
throw new ApplicationException("Given project has not a FileSystem document store!");
}

47
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentStore.cs → modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubDocumentSource.cs

@ -16,13 +16,13 @@ namespace Volo.Docs.GitHub.Documents
{
//TODO: Needs more refactoring
public class GithubDocumentStore : DomainService, IDocumentStore
public class GithubDocumentSource : DomainService, IDocumentSource
{
public const string Type = "GitHub";
private readonly IGithubRepositoryManager _githubRepositoryManager;
public GithubDocumentStore(IGithubRepositoryManager githubRepositoryManager)
public GithubDocumentSource(IGithubRepositoryManager githubRepositoryManager)
{
_githubRepositoryManager = githubRepositoryManager;
}
@ -47,20 +47,23 @@ namespace Volo.Docs.GitHub.Documents
fileName = documentName.Substring(documentName.LastIndexOf('/') + 1);
}
return new Document
{
Title = documentName,
EditLink = editLink,
RootUrl = rootUrl,
RawRootUrl = rawRootUrl,
Format = project.Format,
LocalDirectory = localDirectory,
FileName = fileName,
Contributors = new List<DocumentContributor>(),
//Contributors = !isNavigationDocument && !isParameterDocument && !isPartialTemplatesDocumentName ? await GetContributors(commitHistoryUrl, token, userAgent): new List<DocumentContributor>(),
Version = version,
Content = await DownloadWebContentAsStringAsync(rawDocumentUrl, token, userAgent)
};
var fileCommits = await GetFileCommitsAsync(project, version, $"docs/{languageCode}/{documentName}");
return new Document(GuidGenerator.Create(),
project.Id,
documentName,
version,
languageCode,
fileName,
await DownloadWebContentAsStringAsync(rawDocumentUrl, token, userAgent),
project.Format,
editLink,
rootUrl,
rawRootUrl,
localDirectory,
fileCommits.FirstOrDefault()?.Commit.Author.Date.DateTime ?? DateTime.MinValue,
fileCommits.Count,
DateTime.Now);
}
public async Task<List<VersionInfo>> GetVersionsAsync(Project project)
@ -124,6 +127,15 @@ namespace Volo.Docs.GitHub.Documents
return await _githubRepositoryManager.GetReleasesAsync(ownerName, repositoryName, project.GetGitHubAccessTokenOrNull());
}
private async Task<IReadOnlyList<GitHubCommit>> GetFileCommitsAsync(Project project, string version, string filename)
{
var url = project.GetGitHubUrl();
var ownerName = GetOwnerNameFromUrl(url);
var repositoryName = GetRepositoryNameFromUrl(url);
return await _githubRepositoryManager.GetFileCommitsAsync(ownerName, repositoryName,
version, filename, project.GetGitHubAccessTokenOrNull());
}
protected virtual string GetOwnerNameFromUrl(string url)
{
try
@ -183,6 +195,7 @@ namespace Volo.Docs.GitHub.Documents
}
}
/*
private async Task<List<DocumentContributor>> GetContributors(string url, string token, string userAgent)
{
var contributors = new List<DocumentContributor>();
@ -215,7 +228,7 @@ namespace Volo.Docs.GitHub.Documents
return contributors;
}
*/
private static string CalculateRawRootUrlWithLanguageCode(string rootUrl, string languageCode)
{
return (rootUrl

11
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/GithubRepositoryManager.cs

@ -64,5 +64,16 @@ namespace Volo.Docs.GitHub.Documents
.Release
.GetAll(name, repositoryName)).ToList();
}
public async Task<IReadOnlyList<GitHubCommit>> GetFileCommitsAsync(string name, string repositoryName, string version, string filename, string token)
{
var client = token.IsNullOrWhiteSpace()
? new GitHubClient(new ProductHeaderValue(name))
: new GitHubClient(new ProductHeaderValue(name), new InMemoryCredentialStore(new Credentials(token)));
var repo = await client.Repository.Get(name, repositoryName);
var request = new CommitRequest { Path = filename, Sha = version };
return await client.Repository.Commit.GetAll(repo.Id, request);
}
}
}

1
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Documents/IGithubRepositoryManager.cs

@ -15,5 +15,6 @@ namespace Volo.Docs.GitHub.Documents
Task<IReadOnlyList<Release>> GetReleasesAsync(string name, string repositoryName, string token);
Task<IReadOnlyList<GitHubCommit>> GetFileCommitsAsync(string name, string repositoryName, string version, string filename, string token);
}
}

2
modules/docs/src/Volo.Docs.Domain/Volo/Docs/GitHub/Projects/ProjectGithubExtensions.cs

@ -57,7 +57,7 @@ namespace Volo.Docs.GitHub.Projects
{
Check.NotNull(project, nameof(project));
if (project.DocumentStoreType != GithubDocumentStore.Type)
if (project.DocumentStoreType != GithubDocumentSource.Type)
{
throw new ApplicationException("Given project has not a Github document store!");
}

5
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/en.json

@ -7,6 +7,7 @@
"ShareOn": "Share on",
"Version": "Version",
"Edit": "Edit",
"LastEditTime": "Last edit",
"Delete": "Delete",
"InThisDocument": "In this document",
"GoToTop": "Go to top",
@ -16,6 +17,8 @@
"NavigationDocumentNotFound": "This version does not have a navigation document!",
"DocumentNotFoundInSelectedLanguage": "Document in the language you wanted is not found. Document in the default language is shown.",
"FilterTopics": "Filter topics",
"MultipleVersionDocumentInfo": "This document has multiple versions. Select the options best fit for you."
"MultipleVersionDocumentInfo": "This document has multiple versions. Select the options best fit for you.",
"New": "New",
"Upd": "Upd"
}
}

5
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/tr.json

@ -7,6 +7,7 @@
"ShareOn": "Paylaş",
"Version": "Versiyon",
"Edit": "Düzenle",
"LastEditTime": "Son Düzenleme",
"Delete": "Sil",
"InThisDocument": "Bu dökümanda",
"GoToTop": "En üste çık",
@ -15,6 +16,8 @@
"DocumentNotFound": "Aradığınız döküman bulunamadı!",
"NavigationDocumentNotFound": "Bu döküman için menü bulunamadı!",
"DocumentNotFoundInSelectedLanguage": "İstediğiniz dilde belge bulunamadı. Varsayılan dilde belge gösterilir.",
"MultipleVersionDocumentInfo": "Bu dökümanın birden çok versiyonu bulunmaktadır. Sizin için en uygun olan seçenekleri seçiniz."
"MultipleVersionDocumentInfo": "Bu dökümanın birden çok versiyonu bulunmaktadır. Sizin için en uygun olan seçenekleri seçiniz.",
"New": "Yeni",
"Upd": "güncellenmiş"
}
}

5
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json

@ -7,6 +7,7 @@
"ShareOn": "分享到",
"Version": "版本",
"Edit": "编辑",
"LastEditTime": "上次编辑",
"Delete": "删除",
"InThisDocument": "在本文中",
"GoToTop": "到顶部",
@ -15,6 +16,8 @@
"DocumentNotFound": "找不到请求的文档!",
"NavigationDocumentNotFound": "这个版本没有导航文件!",
"DocumentNotFoundInSelectedLanguage": "本文档不适用于所选语言, 将以默认语言显示文档.",
"FilterTopics": "过滤主题"
"FilterTopics": "过滤主题",
"New": "新文档",
"Upd": "更新"
}
}

5
modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hant.json

@ -7,6 +7,7 @@
"ShareOn": "分享到",
"Version": "版本",
"Edit": "編輯",
"LastEditTime": "上次編輯",
"Delete": "刪除",
"InThisDocument": "在此文件中",
"GoToTop": "到最上方",
@ -15,6 +16,8 @@
"DocumentNotFound": "找不到要求的文件!",
"NavigationDocumentNotFound": "這個版本沒有導覽文件!",
"DocumentNotFoundInSelectedLanguage": "本文件不適用於所選語系,將以預設語系顯示.",
"FilterTopics": "過濾主題"
"FilterTopics": "過濾主題",
"New": "新文檔",
"Upd": "更新"
}
}

6
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo.Docs.EntityFrameworkCore.csproj

@ -10,6 +10,12 @@
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<Compile Remove="Volo\Docs\NewFolder\**" />
<EmbeddedResource Remove="Volo\Docs\NewFolder\**" />
<None Remove="Volo\Docs\NewFolder\**" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Docs.Domain\Volo.Docs.Domain.csproj" />
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.EntityFrameworkCore\Volo.Abp.EntityFrameworkCore.csproj" />

23
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/Documents/EFCoreDocumentRepository.cs

@ -0,0 +1,23 @@
using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
using Volo.Docs.EntityFrameworkCore;
namespace Volo.Docs.Documents
{
public class EFCoreDocumentRepository : EfCoreRepository<IDocsDbContext, Document>, IDocumentRepository
{
public EFCoreDocumentRepository(IDbContextProvider<IDocsDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version)
{
return await DbSet.FirstOrDefaultAsync(x =>
x.ProjectId == projectId && x.Name == name && x.LanguageCode == languageCode && x.Version == version);
}
}
}

5
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContext.cs

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.EntityFrameworkCore
@ -10,6 +11,10 @@ namespace Volo.Docs.EntityFrameworkCore
{
public DbSet<Project> Projects { get; set; }
public DbSet<Document> Documents { get; set; }
public DbSet<DocumentContributor> DocumentContributors { get; set; }
public DocsDbContext(DbContextOptions<DocsDbContext> options)
: base(options)
{

33
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsDbContextModelBuilderExtensions.cs

@ -3,6 +3,7 @@ using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Volo.Abp;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.EntityFrameworkCore
@ -26,8 +27,7 @@ namespace Volo.Docs.EntityFrameworkCore
{
b.ToTable(options.TablePrefix + "Projects", options.Schema);
b.ConfigureConcurrencyStamp();
b.ConfigureExtraProperties();
b.ConfigureByConvention();
b.Property(x => x.Name).IsRequired().HasMaxLength(ProjectConsts.MaxNameLength);
b.Property(x => x.ShortName).IsRequired().HasMaxLength(ProjectConsts.MaxShortNameLength);
@ -36,6 +36,35 @@ namespace Volo.Docs.EntityFrameworkCore
b.Property(x => x.ParametersDocumentName).IsRequired().HasMaxLength(ProjectConsts.MaxParametersDocumentNameLength);
b.Property(x => x.LatestVersionBranchName).HasMaxLength(ProjectConsts.MaxLatestVersionBranchNameLength);
});
builder.Entity<Document>(b =>
{
b.ToTable(options.TablePrefix + "Documents", options.Schema);
b.ConfigureByConvention();
b.Property(x => x.Name).IsRequired().HasMaxLength(DocumentConsts.MaxNameLength);
b.Property(x => x.Version).IsRequired().HasMaxLength(DocumentConsts.MaxVersionNameLength);
b.Property(x => x.LanguageCode).IsRequired().HasMaxLength(DocumentConsts.MaxLanguageCodeNameLength);
b.Property(x => x.FileName).IsRequired().HasMaxLength(DocumentConsts.MaxFileNameNameLength);
b.Property(x => x.Content).IsRequired();
b.Property(x => x.Format).HasMaxLength(DocumentConsts.MaxFormatNameLength);
b.Property(x => x.EditLink).HasMaxLength(DocumentConsts.MaxEditLinkLength);
b.Property(x => x.RootUrl).HasMaxLength(DocumentConsts.MaxRootUrlLength);
b.Property(x => x.RawRootUrl).HasMaxLength(DocumentConsts.MaxRawRootUrlLength);
b.Property(x => x.LocalDirectory).HasMaxLength(DocumentConsts.MaxLocalDirectoryLength);
b.HasMany(x => x.Contributors).WithOne()
.HasForeignKey(x => new { x.DocumentId })
.IsRequired();
});
builder.Entity<DocumentContributor>(b =>
{
b.ToTable(options.TablePrefix + "DocumentContributors", options.Schema);
b.HasKey(x => new { x.DocumentId, x.Username });
});
}
}
}

2
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/DocsEntityFrameworkCoreModule.cs

@ -1,6 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.Modularity;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.EntityFrameworkCore
@ -15,6 +16,7 @@ namespace Volo.Docs.EntityFrameworkCore
context.Services.AddAbpDbContext<DocsDbContext>(options =>
{
options.AddRepository<Project, EfCoreProjectRepository>();
options.AddRepository<Document, EFCoreDocumentRepository>();
});
}
}

5
modules/docs/src/Volo.Docs.EntityFrameworkCore/Volo/Docs/EntityFrameworkCore/IDocsDbContext.cs

@ -1,6 +1,7 @@
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Data;
using Volo.Abp.EntityFrameworkCore;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.EntityFrameworkCore
@ -9,5 +10,9 @@ namespace Volo.Docs.EntityFrameworkCore
public interface IDocsDbContext : IEfCoreDbContext
{
DbSet<Project> Projects { get; set; }
DbSet<Document> Documents { get; set; }
DbSet<DocumentContributor> DocumentContributors { get; set; }
}
}

2
modules/docs/src/Volo.Docs.HttpApi/Volo/Docs/Documents/DocsDocumentController.cs

@ -34,7 +34,7 @@ namespace Volo.Docs.Documents
[HttpGet]
[Route("navigation")]
public virtual Task<DocumentWithDetailsDto> GetNavigationAsync(GetNavigationDocumentInput input)
public Task<NavigationNode> GetNavigationAsync(GetNavigationDocumentInput input)
{
return DocumentAppService.GetNavigationAsync(input);
}

25
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/Documents/MongoDocumentRepository.cs

@ -0,0 +1,25 @@
using System;
using System.Threading.Tasks;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.Docs.MongoDB;
namespace Volo.Docs.Documents
{
public class MongoDocumentRepository : MongoDbRepository<IDocsMongoDbContext, Document, Guid>, IDocumentRepository
{
public MongoDocumentRepository(IMongoDbContextProvider<IDocsMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<Document> FindAsync(Guid projectId, string name, string languageCode, string version)
{
return await GetMongoQueryable().FirstOrDefaultAsync(x => x.ProjectId == projectId &&
x.Name == name &&
x.LanguageCode == languageCode &&
x.Version == version);
}
}
}

2
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/BloggingMongoDbModule.cs

@ -2,6 +2,7 @@
using Volo.Abp.MongoDB;
using Volo.Docs.Projects;
using Microsoft.Extensions.DependencyInjection;
using Volo.Docs.Documents;
namespace Volo.Docs.MongoDB
{
@ -16,6 +17,7 @@ namespace Volo.Docs.MongoDB
context.Services.AddMongoDbContext<DocsMongoDbContext>(options =>
{
options.AddRepository<Project, MongoProjectRepository>();
options.AddRepository<Document, MongoDocumentRepository>();
});
}
}

2
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/DocsMongoDbContext.cs

@ -2,6 +2,7 @@
using Volo.Abp.Data;
using Volo.Docs.Projects;
using Volo.Abp.MongoDB;
using Volo.Docs.Documents;
namespace Volo.Docs.MongoDB
{
@ -9,6 +10,7 @@ namespace Volo.Docs.MongoDB
public class DocsMongoDbContext : AbpMongoDbContext, IDocsMongoDbContext
{
public IMongoCollection<Project> Projects => Collection<Project>();
public IMongoCollection<Document> Documents => Collection<Document>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{

6
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/DocsMongoDbContextExtensions.cs

@ -1,6 +1,7 @@
using System;
using Volo.Abp;
using Volo.Abp.MongoDB;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.MongoDB
@ -23,6 +24,11 @@ namespace Volo.Docs.MongoDB
{
b.CollectionName = options.CollectionPrefix + "Projects";
});
builder.Entity<Document>(b =>
{
b.CollectionName = options.CollectionPrefix + "DocumentS";
});
}
}
}

3
modules/docs/src/Volo.Docs.MongoDB/Volo/Docs/MongoDB/IDocsMongoDbContext.cs

@ -1,6 +1,7 @@
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
using Volo.Docs.Documents;
using Volo.Docs.Projects;
namespace Volo.Docs.MongoDB
@ -8,8 +9,8 @@ namespace Volo.Docs.MongoDB
[ConnectionStringName(DocsDbProperties.ConnectionStringName)]
public interface IDocsMongoDbContext : IAbpMongoDbContext
{
IMongoCollection<Project> Projects { get; }
IMongoCollection<Document> Documents { get; }
}
}

17
modules/docs/src/Volo.Docs.Web/Areas/Documents/TagHelpers/TreeTagHelper.cs

@ -2,8 +2,10 @@
using System.Linq;
using System.Text;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Volo.Docs.Documents;
using Volo.Docs.Localization;
using Volo.Docs.Utils;
namespace Volo.Docs.Areas.Documents.TagHelpers
@ -15,6 +17,8 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
{
private readonly DocsUiOptions _uiOptions;
private readonly IStringLocalizer<DocsResource> _localizer;
private const string LiItemTemplateWithLink = @"<li class='{0}'><span class='plus-icon'><i class='fa fa-{1}'></i></span>{2}{3}</li>";
private const string ListItemAnchor = @"<a href='{0}' class='{1}'>{2}</a>";
@ -41,8 +45,9 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
[HtmlAttributeName("language")]
public string LanguageCode { get; set; }
public TreeTagHelper(IOptions<DocsUiOptions> urlOptions)
public TreeTagHelper(IOptions<DocsUiOptions> urlOptions, IStringLocalizer<DocsResource> localizer)
{
_localizer = localizer;
_uiOptions = urlOptions.Value;
}
@ -118,7 +123,15 @@ namespace Volo.Docs.Areas.Documents.TagHelpers
}
else
{
listInnerItem = string.Format(ListItemAnchor, NormalizePath(node.Path), textCss, node.Text.IsNullOrEmpty() ? "?" : node.Text);
var badge = node.Path.IsNullOrWhiteSpace()
? ""
: "<span class='badge badge-light ml-2'>" +
(node.LastUpdatedTime + TimeSpan.FromDays(30) > DateTime.Now ? (node.UpdatedCount == 1 ? _localizer["New"] : _localizer["Upd"]) : "") + "</span>";
listInnerItem = string.Format(ListItemAnchor, NormalizePath(node.Path), textCss,
node.Text.IsNullOrEmpty()
? "?"
: node.Text + badge);
}
return string.Format(LiItemTemplateWithLink,

3
modules/docs/src/Volo.Docs.Web/DocsWebAutoMapperProfile.cs

@ -8,8 +8,7 @@ namespace Volo.Docs
{
public DocsWebAutoMapperProfile()
{
CreateMap<DocumentWithDetailsDto, NavigationWithDetailsDto>()
.Ignore(x => x.RootNode);
}
}
}

30
modules/docs/src/Volo.Docs.Web/Models/NavigationWithDetailsDto.cs

@ -1,30 +0,0 @@
using System;
using Newtonsoft.Json;
namespace Volo.Docs.Documents
{
public class NavigationWithDetailsDto : DocumentWithDetailsDto
{
[JsonProperty("items")]
public NavigationNode RootNode { get; set; }
public void ConvertItems()
{
if (Content.IsNullOrEmpty())
{
RootNode = new NavigationNode();
return;
}
try
{
RootNode = JsonConvert.DeserializeObject<NavigationNode>(Content);
}
catch (JsonException ex)
{
//todo: should log the exception?
RootNode = new NavigationNode();
}
}
}
}

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

@ -1,4 +1,4 @@
@page
@page
@using Microsoft.AspNetCore.Mvc.Localization
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Volo.Abp.AspNetCore.Mvc.UI.Packages.Anchor
@ -145,7 +145,7 @@
</div>
@if (Model.Navigation == null || Model.Navigation.Content.IsNullOrEmpty())
@if (Model.Navigation == null || !Model.Navigation.HasChildItems)
{
<div class="text-muted p-3">
<i class="fa fa-warning"></i> @L["NavigationDocumentNotFound"]
@ -153,7 +153,7 @@
}
else
{
<ul root-node="@Model.Navigation.RootNode"
<ul root-node="@Model.Navigation"
version="@(Model.LatestVersionInfo == null || Model.LatestVersionInfo.IsSelected ? DocsAppConsts.Latest : Model.Version)"
project-name="@Model.ProjectName"
project-format="@Model.Project.Format"
@ -187,7 +187,7 @@
<div class="float-right">
@if (!string.IsNullOrEmpty(Model.Document.EditLink))
{
<a href="@Model.Document.EditLink" target="_blank"> <i class="fa fa-edit"></i> @L["Edit"]</a>
<a href="@Model.Document.EditLink" target="_blank"> <i class="fa fa-edit"></i> @(L["Edit"]) (@L["LastEditTime"]: @Model.Document.LastUpdatedTime.ToShortDateString())</a>
}
</div>
</div>

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

@ -49,7 +49,7 @@ namespace Volo.Docs.Pages.Documents.Project
public List<SelectListItem> ProjectSelectItems { get; private set; }
public NavigationWithDetailsDto Navigation { get; private set; }
public NavigationNode Navigation { get; private set; }
public VersionInfoViewModel LatestVersionInfo { get; private set; }
@ -271,7 +271,7 @@ namespace Volo.Docs.Pages.Documents.Project
{
try
{
var document = await _documentAppService.GetNavigationAsync(
Navigation = await _documentAppService.GetNavigationAsync(
new GetNavigationDocumentInput
{
ProjectId = Project.Id,
@ -279,15 +279,11 @@ namespace Volo.Docs.Pages.Documents.Project
Version = Version
}
);
Navigation = ObjectMapper.Map<DocumentWithDetailsDto, NavigationWithDetailsDto>(document);
}
catch (DocumentNotFoundException) //TODO: What if called on a remote service which may return 404
{
return;
}
Navigation.ConvertItems();
}
public string CreateVersionLink(VersionInfoViewModel latestVersion, string version, string documentName = null)

8
modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/DocumentStoreFactory_Tests.cs

@ -8,18 +8,18 @@ namespace Volo.Docs
{
public class DocumentStoreFactory_Tests : DocsDomainTestBase
{
private readonly IDocumentStoreFactory _documentStoreFactory;
private readonly IDocumentSourceFactory _documentStoreFactory;
public DocumentStoreFactory_Tests()
{
_documentStoreFactory = GetRequiredService<IDocumentStoreFactory>();
_documentStoreFactory = GetRequiredService<IDocumentSourceFactory>();
}
[Fact]
public void Create()
{
_documentStoreFactory.Create(GithubDocumentStore.Type).GetType().ShouldBe(typeof(GithubDocumentStore));
_documentStoreFactory.Create(FileSystemDocumentStore.Type).GetType().ShouldBe(typeof(FileSystemDocumentStore));
_documentStoreFactory.Create(GithubDocumentSource.Type).GetType().ShouldBe(typeof(GithubDocumentSource));
_documentStoreFactory.Create(FileSystemDocumentSource.Type).GetType().ShouldBe(typeof(FileSystemDocumentSource));
}
}
}

18
modules/docs/test/Volo.Docs.Domain.Tests/Volo/Docs/GithubDocumentStore_Tests.cs

@ -9,13 +9,13 @@ namespace Volo.Docs
{
public class GithubDocumentStore_Tests : DocsDomainTestBase
{
private readonly IDocumentStoreFactory _documentStoreFactory;
private readonly IDocumentSourceFactory _documentStoreFactory;
private readonly IProjectRepository _projectRepository;
private readonly DocsTestData _testData;
public GithubDocumentStore_Tests()
{
_documentStoreFactory = GetRequiredService<IDocumentStoreFactory>();
_documentStoreFactory = GetRequiredService<IDocumentSourceFactory>();
_projectRepository = GetRequiredService<IProjectRepository>();
_testData = GetRequiredService<DocsTestData>();
}
@ -23,15 +23,15 @@ namespace Volo.Docs
[Fact]
public async Task GetDocumentAsync()
{
var store = _documentStoreFactory.Create(GithubDocumentStore.Type);
var source = _documentStoreFactory.Create(GithubDocumentSource.Type);
var project = await _projectRepository.FindAsync(_testData.PorjectId);
project.ShouldNotBeNull();
var document = await store.GetDocumentAsync(project, "index2", "en", "0.123.0");
var document = await source.GetDocumentAsync(project, "index2", "en", "0.123.0");
document.ShouldNotBeNull();
document.Title.ShouldBe("index2");
document.Name.ShouldBe("index2");
document.FileName.ShouldBe("index2");
document.Version.ShouldBe("0.123.0");
document.Content.ShouldBe("stringContent");
@ -40,12 +40,12 @@ namespace Volo.Docs
[Fact]
public async Task GetVersionsAsync()
{
var store = _documentStoreFactory.Create(GithubDocumentStore.Type);
var source = _documentStoreFactory.Create(GithubDocumentSource.Type);
var project = await _projectRepository.FindAsync(_testData.PorjectId);
project.ShouldNotBeNull();
var document = await store.GetVersionsAsync(project);
var document = await source.GetVersionsAsync(project);
document.ShouldNotBeNull();
document.Count.ShouldBe(1);
@ -55,12 +55,12 @@ namespace Volo.Docs
[Fact]
public async Task GetResource()
{
var store = _documentStoreFactory.Create(GithubDocumentStore.Type);
var source = _documentStoreFactory.Create(GithubDocumentSource.Type);
var project = await _projectRepository.FindAsync(_testData.PorjectId);
project.ShouldNotBeNull();
var documentResource = await store.GetResource(project, "index.md", "en", "0.123.0");
var documentResource = await source.GetResource(project, "index.md", "en", "0.123.0");
documentResource.ShouldNotBeNull();
documentResource.Content.ShouldBe(new byte[]

2
modules/docs/test/Volo.Docs.TestBase/Volo/Docs/DocsTestDataBuilder.cs

@ -25,7 +25,7 @@ namespace Volo.Docs
_testData.PorjectId,
"ABP vNext",
"ABP",
GithubDocumentStore.Type,
GithubDocumentSource.Type,
"md",
"index",
"docs-nav.json",

Loading…
Cancel
Save