Merge pull request #13804 from abpframework/Docs-module-improvements-discussion

Docs module improvements discussion
pull/13870/head
Alper Ebiçoğlu 3 years ago committed by GitHub
commit 66efb36ced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,6 +8,8 @@ namespace Volo.Docs.Admin.Documents
public class DocumentDto : EntityDto<Guid>
{
public virtual Guid ProjectId { get; set; }
public virtual string ProjectName { get; set; }
public virtual string Name { get; set; }

@ -0,0 +1,11 @@
using System;
namespace Volo.Docs.Admin.Documents;
public class DocumentInfoDto
{
public string Version { get; set; }
public string Format { get; set; }
public string LanguageCode { get; set; }
public Guid ProjectId { get; set; }
}

@ -19,5 +19,7 @@ namespace Volo.Docs.Admin.Documents
Task RemoveFromCacheAsync(Guid documentId);
Task ReindexAsync(Guid documentId);
Task<List<DocumentInfoDto>> GetFilterItemsAsync();
}
}

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
@ -20,5 +21,6 @@ namespace Volo.Docs.Admin.Projects
Task ReindexAsync(ReindexInput input);
Task ReindexAllAsync();
Task<List<ProjectWithoutDetailsDto>> GetListWithoutDetailsAsync();
}
}

@ -0,0 +1,9 @@
using System;
namespace Volo.Docs.Admin.Projects;
public class ProjectWithoutDetailsDto
{
public Guid Id { get; set; }
public string Name { get; set; }
}

@ -1,4 +1,5 @@
using AutoMapper;
using Volo.Abp.AutoMapper;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Admin.Projects;
using Volo.Docs.Documents;
@ -11,8 +12,10 @@ namespace Volo.Docs.Admin
public DocsAdminApplicationAutoMapperProfile()
{
CreateMap<Project, ProjectDto>();
CreateMap<Document, DocumentDto>();
CreateMap<Document, DocumentDto>().Ignore(x => x.ProjectName);
CreateMap<DocumentWithoutContent, DocumentDto>();
CreateMap<ProjectWithoutDetails, ProjectWithoutDetailsDto>();
CreateMap<DocumentInfo, DocumentInfoDto>();
}
}
}

@ -5,7 +5,6 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Uow;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
@ -217,6 +216,13 @@ namespace Volo.Docs.Admin.Documents
await _elasticSearchService.AddOrUpdateAsync(document);
}
public async Task<List<DocumentInfoDto>> GetFilterItemsAsync()
{
var documents = await _documentRepository.GetUniqueListDocumentInfoAsync();
return ObjectMapper.Map<List<DocumentInfo>, List<DocumentInfoDto>>(documents);
}
private async Task UpdateDocumentUpdateInfoCache(Document document)
{
var cacheKey = $"DocumentUpdateInfo{document.ProjectId}#{document.Name}#{document.LanguageCode}#{document.Version}";

@ -156,5 +156,11 @@ namespace Volo.Docs.Admin.Projects
await ReindexProjectAsync(project.Id);
}
}
public async Task<List<ProjectWithoutDetailsDto>> GetListWithoutDetailsAsync()
{
var projects = await _projectRepository.GetListWithoutDetailsAsync();
return ObjectMapper.Map<List<ProjectWithoutDetails>, List<ProjectWithoutDetailsDto>>(projects);
}
}
}

@ -7,6 +7,7 @@ using Volo.Abp.Http.Modeling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Docs.Admin.Documents;
using System.Collections.Generic;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Admin.ClientProxies;
@ -62,4 +63,9 @@ public partial class DocumentsAdminClientProxy : ClientProxyBase<IDocumentAdminA
{ typeof(Guid), documentId }
});
}
public virtual async Task<List<DocumentInfoDto>> GetFilterItemsAsync()
{
return await RequestAsync<List<DocumentInfoDto>>(nameof(GetFilterItemsAsync));
}
}

@ -7,6 +7,7 @@ using Volo.Abp.Http.Modeling;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Http.Client.ClientProxying;
using Volo.Docs.Admin.Projects;
using System.Collections.Generic;
// ReSharper disable once CheckNamespace
namespace Volo.Docs.Admin.ClientProxies;
@ -61,6 +62,11 @@ public partial class ProjectsAdminClientProxy : ClientProxyBase<IProjectAdminApp
await RequestAsync(nameof(ReindexAllAsync));
}
public virtual async Task<List<ProjectWithoutDetailsDto>> GetListWithoutDetailsAsync()
{
return await RequestAsync<List<ProjectWithoutDetailsDto>>(nameof(GetListWithoutDetailsAsync));
}
public virtual async Task ReindexAsync(ReindexInput input)
{
await RequestAsync(nameof(ReindexAsync), new ClientProxyRequestTypeValue

@ -7,6 +7,8 @@
"Volo.Docs.Admin.DocumentsAdminController": {
"controllerName": "DocumentsAdmin",
"controllerGroupName": "DocumentsAdmin",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Docs.Admin.DocumentsAdminController",
"interfaces": [
{
@ -427,12 +429,29 @@
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentAdminAppService"
},
"GetFilterItemsAsync": {
"uniqueName": "GetFilterItemsAsync",
"name": "GetFilterItemsAsync",
"httpMethod": "GET",
"url": "api/docs/admin/documents/GetFilterItems",
"supportedVersions": [],
"parametersOnMethod": [],
"parameters": [],
"returnValue": {
"type": "System.Collections.Generic.List<Volo.Docs.Admin.Documents.DocumentInfoDto>",
"typeSimple": "[Volo.Docs.Admin.Documents.DocumentInfoDto]"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Documents.IDocumentAdminAppService"
}
}
},
"Volo.Docs.Admin.ProjectsAdminController": {
"controllerName": "ProjectsAdmin",
"controllerGroupName": "ProjectsAdmin",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Docs.Admin.ProjectsAdminController",
"interfaces": [
{
@ -684,6 +703,21 @@
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Projects.IProjectAdminAppService"
},
"GetListWithoutDetailsAsync": {
"uniqueName": "GetListWithoutDetailsAsync",
"name": "GetListWithoutDetailsAsync",
"httpMethod": "GET",
"url": "api/docs/admin/projects/GetListProjectWithoutDetailsAsync",
"supportedVersions": [],
"parametersOnMethod": [],
"parameters": [],
"returnValue": {
"type": "System.Collections.Generic.List<Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto>",
"typeSimple": "[Volo.Docs.Admin.Projects.ProjectWithoutDetailsDto]"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Admin.Projects.IProjectAdminAppService"
},
"ReindexAsyncByInput": {
"uniqueName": "ReindexAsyncByInput",
"name": "ReindexAsync",

@ -63,5 +63,12 @@ namespace Volo.Docs.Admin
{
await _documentAdminAppService.ReindexAsync(documentId);
}
[HttpGet]
[Route("GetFilterItems")]
public async Task<List<DocumentInfoDto>> GetFilterItemsAsync()
{
return await _documentAdminAppService.GetFilterItemsAsync();
}
}
}

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
@ -61,6 +62,13 @@ namespace Volo.Docs.Admin
return _projectAppService.ReindexAllAsync();
}
[HttpGet]
[Route("GetListProjectWithoutDetailsAsync")]
public Task<List<ProjectWithoutDetailsDto>> GetListWithoutDetailsAsync()
{
return _projectAppService.GetListWithoutDetailsAsync();
}
[HttpPost]
[Route("Reindex")]
public Task ReindexAsync(ReindexInput input)

@ -34,50 +34,70 @@
<abp-row>
<abp-column size="_4">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["Project"].Value</div>
<input type="text"
id="ProjectId"
name="ProjectId"
class="form-control">
<select
id="ProjectId"
name="ProjectId"
class="form-select">
<option></option>
@foreach (var project in Model.Projects)
{
<option value="@project.Id">@project.Name</option>
}
</select>
</div>
</abp-column>
<abp-column size="_4">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["Name"].Value</div>
<div class="input-group-text">@L["Version"].Value</div>
<input type="text"
id="Name"
name="Name"
class="form-control">
<select
id="Version"
name="Version"
class="form-select">
<option></option>
@* @foreach (var version in Model.FilterItems.Versions) *@
@* { *@
@* <option value="@version.Version" style="display: none;" data-project-id="@version.ProjectId" data-language-code="@version.LanguageCode">@version.Version</option> *@
@* } *@
</select>
</div>
</abp-column>
<abp-column size="_2">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["Version"].Value</div>
<div class="input-group-text">@L["Name"].Value</div>
<input type="text"
id="Version"
name="Version"
id="Name"
name="Name"
class="form-control">
</div>
</abp-column>
<abp-column size="_3">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["LanguageCode"].Value</div>
<input type="text"
id="LanguageCode"
name="LanguageCode"
class="form-control">
<select
id="LanguageCode"
name="LanguageCode"
class="form-select">
<option></option>
@* @foreach (var language in Model.FilterItems.Versions) *@
@* { *@
@* <option value="@language.LanguageCode" style="display: none;" data-project-id="@language.ProjectId" d>@language.LanguageCode</option> *@
@* } *@
</select>
</div>
</abp-column>
<abp-column size="Auto">
<abp-button button-type="Primary" icon="search" id="SearchButton" style="line-height: 25px;" text="@L["Search"].Value"></abp-button>
</abp-column>
<abp-row class="mt-3 mb-3">
<abp-column size-md="_12">
<a href="javascript:;" id="AdvancedFilterSectionToggler" class="text-decoration-none">@L["AdvancedFilters"]</a>
@ -85,7 +105,7 @@
</abp-row>
<abp-row id="AdvancedFilterSection" style="display: none;">
<abp-column size="_4">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["CreationTime"].Value</div>
@ -103,7 +123,7 @@
</div>
</abp-column>
<abp-column size="_4">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["LastUpdateTime"].Value</div>
<input type="date"
@ -111,7 +131,6 @@
name="LastUpdatedTimeMin"
class="form-control datepicker"
placeholder="@L["StartDate"].Value">
<span>-</span>
<input type="date"
id="LastUpdatedTimeMax"
name="LastUpdatedTimeMax"
@ -120,7 +139,7 @@
</div>
</abp-column>
<abp-column size="_4">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["LastCachedTime"].Value</div>
@ -138,21 +157,22 @@
</div>
</abp-column>
<abp-column size="_2">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["Format"].Value</div>
<input type="text"
id="Format"
name="Format"
class="form-control">
<select
id="Format"
name="Format"
class="form-select">
</select>
</div>
</abp-column>
<abp-column size="_2">
<abp-column size="Auto">
</abp-column>
<abp-column size="_5">
<abp-column size="Auto">
<div class="input-group mb-2">
<div class="input-group-text">@L["LastSignificantUpdateTime"].Value</div>
@ -171,10 +191,6 @@
</abp-column>
</abp-row>
<div class="col-auto">
<abp-button button-type="Primary" icon="search" id="SearchButton" style="line-height: 25px;" text="@L["Search"].Value"></abp-button>
</div>
</abp-row>
</form>
</abp-card-header>
@ -183,6 +199,7 @@
<thead>
<tr>
<th>@L["Actions"]</th>
<th>@L["ProjectName"]</th>
<th>@L["Name"]</th>
<th>@L["Version"]</th>
<th>@L["LanguageCode"]</th>

@ -1,14 +1,24 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Volo.Docs.Admin.Projects;
namespace Volo.Docs.Admin.Pages.Docs.Admin.Documents;
[Authorize(DocsAdminPermissions.Projects.Default)]
public class IndexModel : DocsAdminPageModel
{
public virtual Task<IActionResult> OnGet()
private readonly IProjectAdminAppService _projectAdminAppService;
public List<ProjectWithoutDetailsDto> Projects { get; set; }
public IndexModel(IProjectAdminAppService projectAdminAppService)
{
_projectAdminAppService = projectAdminAppService;
}
public virtual async Task<IActionResult> OnGet()
{
return Task.FromResult<IActionResult>(Page());
Projects = await _projectAdminAppService.GetListWithoutDetailsAsync();
return Page();
}
}
}

@ -6,6 +6,106 @@ $(function () {
return $datePicker.data().datepicker.getFormattedDate('yyyy-mm-dd');
};
var comboboxItems = [];
service.getFilterItems()
.then(function (result) {
comboboxItems = result;
fillOptions();
}).catch(function (error) {
abp.message.error(error);
});
var $projectId = $('#ProjectId');
$projectId.on('change', function () {
fillOptions();
});
var comboboxs = {
version: $('#Version'),
languageCode: $('#LanguageCode'),
format: $('#Format')
};
for (var key in comboboxs) {
comboboxs[key].on('change', function () {
fillOptions();
});
}
var selectedItem = getSelectedItem();
function emptyComboboxs() {
for (var key in comboboxs) {
comboboxs[key].empty();
}
}
function getSelectedItem() {
var item = {};
for (var key in comboboxs) {
item[key] = comboboxs[key].val();
}
return item;
}
function SetComboboxsValues(item) {
for (var key in comboboxs) {
comboboxs[key].val(item[key]);
}
}
function addComboboxsEmptyItem() {
for (var key in comboboxs) {
comboboxs[key].append($('<option/>').val('').text(''));
}
}
function fillOptions() {
selectedItem = getSelectedItem();
var selectedProjectId = $projectId.val();
emptyComboboxs();
addComboboxsEmptyItem();
var selectedProjectItems = comboboxItems.filter((item) => !selectedProjectId || item.projectId === selectedProjectId);
for (var key in selectedItem) {
var item = selectedProjectItems.find((item) => item[key] === selectedItem[key]);
if (item) {
selectedItem[key] = item[key];
}else {
selectedItem[key] = '';
}
}
selectedProjectItems.forEach(function (item) {
for (var key in comboboxs) {
appendComboboxItem(comboboxs[key], item, key);
}
});
SetComboboxsValues(selectedItem);
}
function appendComboboxItem($combobox, item , key) {
$.each(item, function (index, value) {
if(index !== key) {
if(selectedItem[index] && selectedItem[index] !== value) {
return ;
}}
});
if($combobox.find('option[value="' + item[key] + '"]').length === 0){
$combobox.append($('<option/>').val(item[key]).text(item[key]));
}
}
var getFilter = function () {
return {
projectId: $('#ProjectId').val(),
@ -79,6 +179,10 @@ $(function () {
],
},
},
{
target: 0,
data: 'projectName',
},
{
target: 1,
data: 'name',

@ -61,6 +61,13 @@
}, ajaxParams));
};
volo.docs.admin.documentsAdmin.getFilterItems = function(ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/documents/GetFilterItems',
type: 'GET'
}, ajaxParams));
};
})();
// controller volo.docs.admin.projectsAdmin
@ -115,6 +122,13 @@
}, ajaxParams));
};
volo.docs.admin.projectsAdmin.getListWithoutDetails = function(ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/projects/GetListProjectWithoutDetailsAsync',
type: 'GET'
}, ajaxParams));
};
volo.docs.admin.projectsAdmin.reindex = function(input, ajaxParams) {
return abp.ajax($.extend(true, {
url: abp.appPath + 'api/docs/admin/projects/Reindex',

@ -0,0 +1,11 @@
using System;
namespace Volo.Docs.Documents;
public class DocumentInfo
{
public string Version { get; set; }
public string Format { get; set; }
public string LanguageCode { get; set; }
public Guid ProjectId { get; set; }
}

@ -7,6 +7,8 @@ namespace Volo.Docs.Documents
public Guid Id { get; set; }
public virtual Guid ProjectId { get; set; }
public virtual string ProjectName { get; set; }
public virtual string Name { get; set; }

@ -9,6 +9,7 @@ namespace Volo.Docs.Documents
public interface IDocumentRepository : IBasicRepository<Document>
{
Task<List<DocumentWithoutDetails>> GetListWithoutDetailsByProjectId(Guid projectId, CancellationToken cancellationToken = default);
Task<List<DocumentInfo>> GetUniqueListDocumentInfoAsync(CancellationToken cancellationToken = default);
Task<List<Document>> GetListByProjectId(Guid projectId, CancellationToken cancellationToken = default);

@ -9,6 +9,7 @@ namespace Volo.Docs.Projects
public interface IProjectRepository : IBasicRepository<Project, Guid>
{
Task<List<Project>> GetListAsync(string sorting, int maxResultCount, int skipCount, CancellationToken cancellationToken = default);
Task<List<ProjectWithoutDetails>> GetListWithoutDetailsAsync(CancellationToken cancellationToken = default);
Task<Project> GetByShortNameAsync(string shortName, CancellationToken cancellationToken = default);

@ -0,0 +1,9 @@
using System;
namespace Volo.Docs.Projects;
public class ProjectWithoutDetails
{
public Guid Id { get; set; }
public string Name { get; set; }
}

@ -32,6 +32,23 @@ namespace Volo.Docs.Documents
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<DocumentInfo>> GetUniqueListDocumentInfoAsync(CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Select(x=> new DocumentInfo
{
ProjectId = x.ProjectId,
Version = x.Version,
LanguageCode = x.LanguageCode,
Format = x.Format,
})
.Distinct()
.OrderByDescending(x=>x.Version)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<Document>> GetListByProjectId(Guid projectId,
CancellationToken cancellationToken = default)
{
@ -67,23 +84,21 @@ namespace Volo.Docs.Documents
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var query = ApplyFilterForGetAll(
var query =await ApplyFilterForGetAll(
await GetDbSetAsync(),
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
format: format,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax
);
lastCachedTimeMin: lastCachedTimeMin, lastCachedTimeMax: lastCachedTimeMax);
query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? nameof(Document.Name) : sorting);
return await query.PageBy(skipCount, maxResultCount).ToListAsync(GetCancellationToken(cancellationToken));
@ -109,23 +124,21 @@ namespace Volo.Docs.Documents
int skipCount = 0,
CancellationToken cancellationToken = default)
{
var query = ApplyFilterForGetAll(
var query = await ApplyFilterForGetAll(
await GetDbSetAsync(),
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
format: format,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax
);
lastCachedTimeMin: lastCachedTimeMin, lastCachedTimeMax: lastCachedTimeMax);
return await query.LongCountAsync(GetCancellationToken(cancellationToken));
}
@ -153,7 +166,7 @@ namespace Volo.Docs.Documents
return await (await GetDbSetAsync()).Where(x => x.Id == id).SingleAsync(cancellationToken: GetCancellationToken(cancellationToken));
}
protected virtual IQueryable<DocumentWithoutContent> ApplyFilterForGetAll(
protected virtual async Task<IQueryable<DocumentWithoutContent>> ApplyFilterForGetAll(
IQueryable<Document> query,
Guid? projectId,
string name,
@ -200,19 +213,24 @@ namespace Volo.Docs.Documents
d => d.LastCachedTime.Date >= lastCachedTimeMin.Value.Date)
.WhereIf(lastCachedTimeMax.HasValue,
d => d.LastCachedTime.Date <= lastCachedTimeMax.Value.Date)
.Join( (await GetDbContextAsync()).Projects,
d => d.ProjectId,
p => p.Id,
(d, p) => new { d, p })
.Select(x => new DocumentWithoutContent
{
Id = x.Id,
ProjectId = x.ProjectId,
Name = x.Name,
Version = x.Version,
LanguageCode = x.LanguageCode,
FileName = x.FileName,
Format = x.Format,
CreationTime = x.CreationTime,
LastUpdatedTime = x.LastUpdatedTime,
LastSignificantUpdateTime = x.LastSignificantUpdateTime,
LastCachedTime = x.LastCachedTime
Id = x.d.Id,
ProjectId = x.d.ProjectId,
ProjectName = x.p.Name,
Name = x.d.Name,
Version = x.d.Version,
LanguageCode = x.d.LanguageCode,
FileName = x.d.FileName,
Format = x.d.Format,
CreationTime = x.d.CreationTime,
LastUpdatedTime = x.d.LastUpdatedTime,
LastSignificantUpdateTime = x.d.LastSignificantUpdateTime,
LastCachedTime = x.d.LastCachedTime
});
}
}

@ -28,6 +28,17 @@ namespace Volo.Docs.Projects
return projects;
}
public async Task<List<ProjectWithoutDetails>> GetListWithoutDetailsAsync(CancellationToken cancellationToken = default)
{
return await (await GetDbSetAsync())
.Select(x=> new ProjectWithoutDetails() {
Id = x.Id,
Name = x.Name,
})
.OrderBy(x=>x.Name)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<Project> GetByShortNameAsync(string shortName, CancellationToken cancellationToken = default)
{
var normalizeShortName = NormalizeShortName(shortName);

@ -7,6 +7,8 @@
"Volo.Docs.Projects.DocsProjectController": {
"controllerName": "DocsProject",
"controllerGroupName": "Project",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Docs.Projects.DocsProjectController",
"interfaces": [
{
@ -222,6 +224,8 @@
"Volo.Docs.Documents.DocsDocumentController": {
"controllerName": "DocsDocument",
"controllerGroupName": "Document",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Docs.Documents.DocsDocumentController",
"interfaces": [
{
@ -648,6 +652,89 @@
"implementFrom": "Volo.Docs.Documents.IDocumentAppService"
}
}
},
"Volo.Docs.Areas.Documents.DocumentResourceController": {
"controllerName": "DocumentResource",
"controllerGroupName": "DocumentResource",
"isRemoteService": true,
"apiVersion": null,
"type": "Volo.Docs.Areas.Documents.DocumentResourceController",
"interfaces": [],
"actions": {
"GetResourceByInput": {
"uniqueName": "GetResourceByInput",
"name": "GetResource",
"httpMethod": "GET",
"url": "document-resources",
"supportedVersions": [],
"parametersOnMethod": [
{
"name": "input",
"typeAsString": "Volo.Docs.Documents.GetDocumentResourceInput, Volo.Docs.Application.Contracts",
"type": "Volo.Docs.Documents.GetDocumentResourceInput",
"typeSimple": "Volo.Docs.Documents.GetDocumentResourceInput",
"isOptional": false,
"defaultValue": null
}
],
"parameters": [
{
"nameOnMethod": "input",
"name": "ProjectId",
"jsonName": null,
"type": "System.Guid",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Name",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "Version",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
},
{
"nameOnMethod": "input",
"name": "LanguageCode",
"jsonName": null,
"type": "System.String",
"typeSimple": "string",
"isOptional": false,
"defaultValue": null,
"constraintTypes": null,
"bindingSourceId": "ModelBinding",
"descriptorName": "input"
}
],
"returnValue": {
"type": "Microsoft.AspNetCore.Mvc.FileResult",
"typeSimple": "Microsoft.AspNetCore.Mvc.FileResult"
},
"allowAnonymous": null,
"implementFrom": "Volo.Docs.Areas.Documents.DocumentResourceController"
}
}
}
}
}

@ -34,6 +34,20 @@ namespace Volo.Docs.Documents
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<DocumentInfo>> GetUniqueListDocumentInfoAsync(CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(cancellationToken))
.Select(x=> new DocumentInfo {
ProjectId = x.ProjectId,
Version = x.Version,
LanguageCode = x.LanguageCode,
Format = x.Format
})
.Distinct()
.OrderByDescending(x=>x.Version)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<List<Document>> GetListByProjectId(Guid projectId, CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(cancellationToken)).Where(d => d.ProjectId == projectId).ToListAsync(GetCancellationToken(cancellationToken));
@ -88,22 +102,21 @@ namespace Volo.Docs.Documents
{
return await
ApplyFilterForGetAll(
(await ApplyFilterForGetAll(
await GetMongoQueryableAsync(cancellationToken),
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
format: format,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax)
lastCachedTimeMin: lastCachedTimeMin, lastCachedTimeMax: lastCachedTimeMax))
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As<IMongoQueryable<DocumentWithoutContent>>()
.PageBy<DocumentWithoutContent, IMongoQueryable<DocumentWithoutContent>>(skipCount, maxResultCount)
.ToListAsync(GetCancellationToken(cancellationToken));
@ -132,22 +145,21 @@ namespace Volo.Docs.Documents
return await
ApplyFilterForGetAll(
(await ApplyFilterForGetAll(
await GetMongoQueryableAsync(cancellationToken),
projectId: projectId,
name: name,
version: version,
languageCode: languageCode,
format: format,
fileName: fileName,
format: format,
creationTimeMin: creationTimeMin,
creationTimeMax: creationTimeMax,
lastUpdatedTimeMin: lastUpdatedTimeMin,
lastUpdatedTimeMax: lastUpdatedTimeMax,
lastSignificantUpdateTimeMin: lastSignificantUpdateTimeMin,
lastSignificantUpdateTimeMax: lastSignificantUpdateTimeMax,
lastCachedTimeMin: lastCachedTimeMin,
lastCachedTimeMax: lastCachedTimeMax)
lastCachedTimeMin: lastCachedTimeMin, lastCachedTimeMax: lastCachedTimeMax))
.OrderBy(string.IsNullOrWhiteSpace(sorting) ? "name asc" : sorting).As<IMongoQueryable<Document>>()
.PageBy<Document, IMongoQueryable<Document>>(skipCount, maxResultCount)
.LongCountAsync(GetCancellationToken(cancellationToken));
@ -157,8 +169,8 @@ namespace Volo.Docs.Documents
{
return await (await GetMongoQueryableAsync(cancellationToken)).Where(x => x.Id == id).SingleAsync(GetCancellationToken(cancellationToken));
}
protected virtual IMongoQueryable<DocumentWithoutContent> ApplyFilterForGetAll(
protected virtual async Task<IMongoQueryable<DocumentWithoutContent>> ApplyFilterForGetAll(
IMongoQueryable<Document> query,
Guid? projectId,
string name,
@ -200,6 +212,11 @@ namespace Volo.Docs.Documents
{
query = query.Where(d => d.FileName != null && d.FileName.Contains(fileName));
}
if (format != null)
{
query = query.Where(d => d.Format != null && d.Format == format);
}
if (creationTimeMin.HasValue)
{
@ -240,20 +257,25 @@ namespace Volo.Docs.Documents
{
query = query.Where(d => d.LastCachedTime.Date <= lastCachedTimeMax.Value.Date);
}
return query.Select(x => new DocumentWithoutContent
var join = query.Join(
(await GetDbContextAsync(cancellationToken)).Projects,
d => d.ProjectId,
p => p.Id,
(d, p) => new { Document = d, Project = p });
return join.Select(x => new DocumentWithoutContent
{
Id = x.Id,
ProjectId = x.ProjectId,
Name = x.Name,
Version = x.Version,
LanguageCode = x.LanguageCode,
FileName = x.FileName,
Format = x.Format,
CreationTime = x.CreationTime,
LastUpdatedTime = x.LastUpdatedTime,
LastSignificantUpdateTime = x.LastSignificantUpdateTime,
LastCachedTime = x.LastCachedTime
Id = x.Document.Id,
ProjectId = x.Document.ProjectId,
ProjectName = x.Project.Name,
Name = x.Document.Name,
Version = x.Document.Version,
LanguageCode = x.Document.LanguageCode,
FileName = x.Document.FileName,
Format = x.Document.Format,
CreationTime = x.Document.CreationTime,
LastUpdatedTime = x.Document.LastUpdatedTime,
LastSignificantUpdateTime = x.Document.LastSignificantUpdateTime,
LastCachedTime = x.Document.LastCachedTime
});
}
}

@ -29,6 +29,17 @@ namespace Volo.Docs.Projects
return projects;
}
public async Task<List<ProjectWithoutDetails>> GetListWithoutDetailsAsync(CancellationToken cancellationToken = default)
{
return await (await GetMongoQueryableAsync(cancellationToken))
.Select(x=> new ProjectWithoutDetails {
Id = x.Id,
Name = x.Name,
})
.OrderBy(x=>x.Name)
.ToListAsync(GetCancellationToken(cancellationToken));
}
public async Task<Project> GetByShortNameAsync(string shortName, CancellationToken cancellationToken = default)
{
var normalizeShortName = NormalizeShortName(shortName);

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Docs.Admin.Documents;
using Volo.Docs.Documents;
@ -51,5 +52,18 @@ namespace Volo.Docs
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-I.md", "en", "1.0.0")).ShouldNotBeNull();
(await _documentRepository.FindAsync(_testData.PorjectId, "Part-II.md", "en", "1.0.0")).ShouldNotBeNull();
}
[Fact]
public async Task GetFilterItemsAsync()
{
var filterItems = await _documentAdminAppService.GetFilterItemsAsync();
filterItems.ShouldNotBeEmpty();
filterItems.ShouldContain(p => p.ProjectId == _testData.PorjectId);
filterItems.ShouldContain(p => p.Version == "2.0.0" && p.ProjectId == _testData.PorjectId);
filterItems.ShouldContain(p => p.LanguageCode == "en" && p.ProjectId == _testData.PorjectId);
filterItems.ShouldContain(p => p.Format == "md");
}
}
}

@ -6,5 +6,6 @@ namespace Volo.Docs
public class DocsTestData : ISingletonDependency
{
public Guid PorjectId { get; } = Guid.NewGuid();
public Guid PorjectId2 { get; set; } = Guid.NewGuid();
}
}

@ -49,6 +49,52 @@ namespace Volo.Docs
"https://github.com/abpframework/abp/tree/2.0.0/docs/",
"https://raw.githubusercontent.com/abpframework/abp/2.0.0/docs/en/", "", DateTime.Now, DateTime.Now,
DateTime.Now));
var project2 = new Project(
_testData.PorjectId2,
"ABP vNext2",
"ABP2",
GithubDocumentSource.Type,
"md",
"index2",
"docs-nav.json",
"docs-params.json"
);
project2
.SetProperty("GitHubRootUrl", "https://github.com/abpframework/abp/tree/{version}/docs/en/")
.SetProperty("GitHubAccessToken", "123456")
.SetProperty("GitHubUserAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
await _projectRepository.InsertAsync(project2);
await _documentRepository.InsertAsync(new Document(Guid.NewGuid(), project2.Id, "CLI.md", "4.0.0", "en", "CLI.md",
"this is abp cli", "md", "https://github.com/abpframework/abp/blob/2.0.0/docs/en/CLI.md",
"https://github.com/abpframework/abp/tree/2.0.0/docs/",
"https://raw.githubusercontent.com/abpframework/abp/2.0.0/docs/en/", "", DateTime.Now, DateTime.Now,
DateTime.Now));
await _documentRepository.InsertAsync(new Document(Guid.NewGuid(), project2.Id, "CLI.md", "4.0.0", "tr", "CLI.md",
"this is abp cli", "md", "https://github.com/abpframework/abp/blob/2.0.0/docs/en/CLI.md",
"https://github.com/abpframework/abp/tree/2.0.0/docs/",
"https://raw.githubusercontent.com/abpframework/abp/2.0.0/docs/en/", "", DateTime.Now, DateTime.Now,
DateTime.Now));
await _documentRepository.InsertAsync(new Document(Guid.NewGuid(), project2.Id, "CLI.md", "4.0.0", "en", "CLI2.md",
"this is abp cli", "md", "https://github.com/abpframework/abp/blob/2.0.0/docs/en/CLI.md",
"https://github.com/abpframework/abp/tree/2.0.0/docs/",
"https://raw.githubusercontent.com/abpframework/abp/2.0.0/docs/en/", "", DateTime.Now, DateTime.Now,
DateTime.Now));
await _documentRepository.InsertAsync(new Document(Guid.NewGuid(), project2.Id, "CLI.md", "4.1.0", "en", "CLI.md",
"this is abp cli", "md", "https://github.com/abpframework/abp/blob/2.0.0/docs/en/CLI.md",
"https://github.com/abpframework/abp/tree/2.0.0/docs/",
"https://raw.githubusercontent.com/abpframework/abp/2.0.0/docs/en/", "", DateTime.Now, DateTime.Now,
DateTime.Now));
}
}
}
Loading…
Cancel
Save