Skip to content

Commit 3044703

Browse files
authored
VCST-4291: Enhance indexation performance and UI (#204)
1 parent e8a70a6 commit 3044703

File tree

9 files changed

+417
-317
lines changed

9 files changed

+417
-317
lines changed

src/VirtoCommerce.ContentModule.Core/Extensions/ConfigurationExtensions.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,11 @@ public static bool IsContentFullTextSearchEnabled(this IConfiguration configurat
1010
var value = configuration["Search:ContentFullTextSearchEnabled"];
1111
return value.TryParse(false);
1212
}
13+
14+
public static bool IsContentStatisticEnabled(this IConfiguration configuration)
15+
{
16+
var value = configuration["Content:StatisticEnabled"];
17+
return value.TryParse(false);
18+
}
1319
}
1420
}

src/VirtoCommerce.ContentModule.Data/Search/ContentIndexDocumentBuilder.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.Collections.Generic;
34
using System.IO;
5+
using System.Linq;
46
using System.Threading.Tasks;
57
using Microsoft.Extensions.Logging;
68
using VirtoCommerce.ContentModule.Core.Model;
@@ -40,9 +42,9 @@ public Task BuildSchemaAsync(IndexDocument schema)
4042

4143
public virtual async Task<IList<IndexDocument>> GetDocumentsAsync(IList<string> documentIds)
4244
{
43-
var result = new List<IndexDocument>();
45+
var result = new ConcurrentBag<IndexDocument>();
4446

45-
foreach (var documentId in documentIds)
47+
await Parallel.ForEachAsync(documentIds, async (documentId, cancellationToken) =>
4648
{
4749
try
4850
{
@@ -60,9 +62,9 @@ public virtual async Task<IList<IndexDocument>> GetDocumentsAsync(IList<string>
6062
{
6163
_log.LogError(e, "Cannot create document for ID '{DocumentId}'", documentId);
6264
}
63-
}
65+
});
6466

65-
return result;
67+
return result.ToList();
6668
}
6769

6870
private async Task<(string, string, ContentFile)> GetFile(string documentId)

src/VirtoCommerce.ContentModule.Data/Search/ContentIndexDocumentChangesProvider.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Threading.Tasks;
5+
using Microsoft.Extensions.Caching.Memory;
56
using VirtoCommerce.ContentModule.Core;
67
using VirtoCommerce.ContentModule.Core.Model;
78
using VirtoCommerce.ContentModule.Core.Services;
9+
using VirtoCommerce.ContentModule.Data.Model;
10+
using VirtoCommerce.Platform.Core.Caching;
811
using VirtoCommerce.Platform.Core.Common;
912
using VirtoCommerce.SearchModule.Core.Model;
1013
using VirtoCommerce.SearchModule.Core.Services;
@@ -19,15 +22,18 @@ public class ContentIndexDocumentChangesProvider : IIndexDocumentChangesProvider
1922
private readonly IContentFileService _contentFileService;
2023
private readonly IStoreSearchService _storeSearchService;
2124
private readonly IContentStatisticService _contentStatisticService;
25+
private readonly IPlatformMemoryCache _platformMemoryCache;
2226

2327
public ContentIndexDocumentChangesProvider(
2428
IContentFileService contentFileService,
2529
IStoreSearchService storeSearchService,
26-
IContentStatisticService contentStatisticService)
30+
IContentStatisticService contentStatisticService,
31+
IPlatformMemoryCache platformMemoryCache)
2732
{
2833
_contentFileService = contentFileService;
2934
_storeSearchService = storeSearchService;
3035
_contentStatisticService = contentStatisticService;
36+
_platformMemoryCache = platformMemoryCache;
3137
}
3238

3339
public virtual async Task<IList<IndexDocumentChange>> GetChangesAsync(DateTime? startDate, DateTime? endDate, long skip, long take)
@@ -90,18 +96,25 @@ private async Task<StoreSearchResult> GetStores(int skip, int take)
9096
return stores;
9197
}
9298

93-
private async Task<IList<(ContentFile File, IndexDocumentChange Document)>> GetFiles(Store store, string contentType, DateTime now)
99+
private Task<IList<(ContentFile File, IndexDocumentChange Document)>> GetFiles(Store store, string contentType, DateTime now)
94100
{
95-
var filter = AbstractTypeFactory<FilterItemsCriteria>.TryCreateInstance();
96-
filter.ContentType = contentType;
97-
filter.StoreId = store.Id;
98-
var files = await _contentFileService.EnumerateFiles(filter);
99-
return files.Select(x => (x, new IndexDocumentChange
101+
var cacheKey = CacheKey.With(GetType(), nameof(GetFiles), store.Id, contentType);
102+
return _platformMemoryCache.GetOrCreateAsync<IList<(ContentFile File, IndexDocumentChange Document)>>(cacheKey, async (cacheEntry) =>
100103
{
101-
DocumentId = DocumentIdentifierHelper.GenerateId(store.Id, contentType, x),
102-
ChangeType = IndexDocumentChangeType.Modified,
103-
ChangeDate = x.ModifiedDate ?? now,
104-
})).ToList();
104+
cacheEntry.AddExpirationToken(ContentCacheRegion.CreateChangeToken());
105+
cacheEntry.SetAbsoluteExpiration(TimeSpan.FromHours(3));
106+
107+
var filter = AbstractTypeFactory<FilterItemsCriteria>.TryCreateInstance();
108+
filter.ContentType = contentType;
109+
filter.StoreId = store.Id;
110+
var files = await _contentFileService.EnumerateFiles(filter);
111+
return files.Select(x => (x, new IndexDocumentChange
112+
{
113+
DocumentId = DocumentIdentifierHelper.GenerateId(store.Id, contentType, x),
114+
ChangeType = IndexDocumentChangeType.Modified,
115+
ChangeDate = x.ModifiedDate ?? now,
116+
})).ToList();
117+
});
105118
}
106119
}
107120
}
Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,53 @@
11
.form-input.__expanded textarea {
2-
max-height: 500px;
3-
min-height: 500px;
2+
max-height: 500px;
3+
min-height: 500px;
4+
}
5+
6+
/* Content widgets (tiles with icon + text) */
7+
.vc-content-widget {
8+
display: flex;
9+
flex-direction: column;
10+
align-items: center;
11+
justify-content: center;
12+
padding: 16px 12px;
13+
text-align: center;
14+
cursor: pointer;
15+
border-radius: 4px;
16+
background-color: #ffffff;
17+
transition: box-shadow 0.15s ease, transform 0.15s ease, background-color 0.15s ease;
18+
}
19+
20+
.vc-content-widget__icon {
21+
width: 42px;
22+
height: 42px;
23+
border-radius: 50%;
24+
display: flex;
25+
align-items: center;
26+
justify-content: center;
27+
/*background-color: #f0f2f5;*/
28+
color: #a5a5a5;
29+
margin-bottom: 10px;
30+
font-size: 32px;
31+
}
32+
33+
.vc-content-widget__title {
34+
font-size: 12px;
35+
font-weight: 500;
36+
color: #161d25;
37+
line-height: 1.4;
38+
margin-bottom: 2px;
39+
}
40+
41+
.vc-content-widget__counter {
42+
font-size: 11px;
43+
font-weight: 600;
44+
color: #a0a4b5;
45+
}
46+
47+
.vc-content-widget:hover {
48+
}
49+
50+
.vc-content-widget:active {
51+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
52+
transform: translateY(0);
453
}

src/VirtoCommerce.ContentModule.Web/Controllers/Api/ContentController.cs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,40 @@ public class ContentController(
5353
[Authorize(Permissions.Read)]
5454
public async Task<ActionResult<ContentStatistic>> GetStoreContentStats(string storeId)
5555
{
56-
var pagesTask = contentStats.GetStorePagesCountAsync(storeId);
57-
var blogsTask = contentStats.GetStoreBlogsCountAsync(storeId);
58-
var themesTask = contentStats.GetStoreThemesCountAsync(storeId);
56+
var store = await storeService.GetNoCloneAsync(storeId, StoreResponseGroup.DynamicProperties.ToString());
5957

60-
var storeTask = storeService.GetNoCloneAsync(storeId, StoreResponseGroup.DynamicProperties.ToString());
61-
62-
await Task.WhenAll(themesTask, blogsTask, pagesTask, storeTask);
58+
if (store == null)
59+
{
60+
return NotFound();
61+
}
6362

64-
var activeThemeProperty = storeTask.Result.DynamicProperties.FirstOrDefault(x => x.Name == "DefaultThemeName");
63+
var activeThemeProperty = store.DynamicProperties.FirstOrDefault(x => x.Name == "DefaultThemeName");
6564
var activeTheme = activeThemeProperty?.Values?.FirstOrDefault()?.Value?.ToString();
6665

6766
var result = new ContentStatistic
6867
{
69-
PagesCount = pagesTask.Result,
70-
BlogsCount = blogsTask.Result,
71-
ThemesCount = themesTask.Result,
68+
ActiveThemeName = activeTheme ?? ContentConstants.DefaultTheme,
7269

73-
ActiveThemeName = activeTheme ?? ContentConstants.DefaultTheme
70+
PagesCount = -1,
71+
BlogsCount = -1,
72+
ThemesCount = -1,
7473
};
74+
75+
if (!configuration.IsContentStatisticEnabled())
76+
{
77+
return Ok(result);
78+
}
79+
80+
var pagesTask = contentStats.GetStorePagesCountAsync(storeId);
81+
var blogsTask = contentStats.GetStoreBlogsCountAsync(storeId);
82+
var themesTask = contentStats.GetStoreThemesCountAsync(storeId);
83+
84+
await Task.WhenAll(themesTask, blogsTask, pagesTask);
85+
86+
result.PagesCount = pagesTask.Result;
87+
result.BlogsCount = blogsTask.Result;
88+
result.ThemesCount = themesTask.Result;
89+
7590
return Ok(result);
7691
}
7792

0 commit comments

Comments
 (0)