Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ public static bool IsContentFullTextSearchEnabled(this IConfiguration configurat
var value = configuration["Search:ContentFullTextSearchEnabled"];
return value.TryParse(false);
}

public static bool IsContentStatisticEnabled(this IConfiguration configuration)
{
var value = configuration["Content:StatisticEnabled"];
return value.TryParse(false);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using VirtoCommerce.ContentModule.Core.Model;
Expand Down Expand Up @@ -39,9 +41,9 @@ public Task BuildSchemaAsync(IndexDocument schema)

public virtual async Task<IList<IndexDocument>> GetDocumentsAsync(IList<string> documentIds)
{
var result = new List<IndexDocument>();
var result = new ConcurrentBag<IndexDocument>();

foreach (var documentId in documentIds)
await Parallel.ForEachAsync(documentIds, async (documentId, cancellationToken) =>
{
try
{
Expand All @@ -59,9 +61,9 @@ public virtual async Task<IList<IndexDocument>> GetDocumentsAsync(IList<string>
{
_log.LogError(e, "Cannot create document for ID '{DocumentId}'", documentId);
}
}
});

return result;
return result.ToList();
}

private async Task<(string, string, ContentFile)> GetFile(string documentId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
using VirtoCommerce.ContentModule.Core;
using VirtoCommerce.ContentModule.Core.Model;
using VirtoCommerce.ContentModule.Core.Services;
using VirtoCommerce.ContentModule.Data.Model;
using VirtoCommerce.Platform.Core.Caching;
using VirtoCommerce.Platform.Core.Common;
using VirtoCommerce.SearchModule.Core.Model;
using VirtoCommerce.SearchModule.Core.Services;
Expand All @@ -19,15 +22,18 @@ public class ContentIndexDocumentChangesProvider : IIndexDocumentChangesProvider
private readonly IContentFileService _contentFileService;
private readonly IStoreSearchService _storeSearchService;
private readonly IContentStatisticService _contentStatisticService;
private readonly IPlatformMemoryCache _platformMemoryCache;

public ContentIndexDocumentChangesProvider(
IContentFileService contentFileService,
IStoreSearchService storeSearchService,
IContentStatisticService contentStatisticService)
IContentStatisticService contentStatisticService,
IPlatformMemoryCache platformMemoryCache)
{
_contentFileService = contentFileService;
_storeSearchService = storeSearchService;
_contentStatisticService = contentStatisticService;
_platformMemoryCache = platformMemoryCache;
}

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

private async Task<IList<(ContentFile File, IndexDocumentChange Document)>> GetFiles(Store store, string contentType, DateTime now)
private Task<IList<(ContentFile File, IndexDocumentChange Document)>> GetFiles(Store store, string contentType, DateTime now)
{
var filter = AbstractTypeFactory<FilterItemsCriteria>.TryCreateInstance();
filter.ContentType = contentType;
filter.StoreId = store.Id;
var files = await _contentFileService.EnumerateFiles(filter);
return files.Select(x => (x, new IndexDocumentChange
var cacheKey = CacheKey.With(GetType(), nameof(GetFiles), store.Id, contentType);
return _platformMemoryCache.GetOrCreateAsync<IList<(ContentFile File, IndexDocumentChange Document)>>(cacheKey, async (cacheEntry) =>
{
DocumentId = DocumentIdentifierHelper.GenerateId(store.Id, contentType, x),
ChangeType = IndexDocumentChangeType.Modified,
ChangeDate = x.ModifiedDate ?? now,
})).ToList();
cacheEntry.AddExpirationToken(ContentCacheRegion.CreateChangeToken());
cacheEntry.SetAbsoluteExpiration(TimeSpan.FromHours(3));

var filter = AbstractTypeFactory<FilterItemsCriteria>.TryCreateInstance();
filter.ContentType = contentType;
filter.StoreId = store.Id;
var files = await _contentFileService.EnumerateFiles(filter);
return files.Select(x => (x, new IndexDocumentChange
{
DocumentId = DocumentIdentifierHelper.GenerateId(store.Id, contentType, x),
ChangeType = IndexDocumentChangeType.Modified,
ChangeDate = x.ModifiedDate ?? now,
})).ToList();
});
}
}
}
53 changes: 51 additions & 2 deletions src/VirtoCommerce.ContentModule.Web/Content/css/themes.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,53 @@
.form-input.__expanded textarea {
max-height: 500px;
min-height: 500px;
max-height: 500px;
min-height: 500px;
}

/* Content widgets (tiles with icon + text) */
.vc-content-widget {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 16px 12px;
text-align: center;
cursor: pointer;
border-radius: 4px;
background-color: #ffffff;
transition: box-shadow 0.15s ease, transform 0.15s ease, background-color 0.15s ease;
}

.vc-content-widget__icon {
width: 42px;
height: 42px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
/*background-color: #f0f2f5;*/
color: #a5a5a5;
margin-bottom: 10px;
font-size: 32px;
}

.vc-content-widget__title {
font-size: 12px;
font-weight: 500;
color: #161d25;
line-height: 1.4;
margin-bottom: 2px;
}

.vc-content-widget__counter {
font-size: 11px;
font-weight: 600;
color: #a0a4b5;
}

.vc-content-widget:hover {
}

.vc-content-widget:active {
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
transform: translateY(0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,40 @@ public class ContentController(
[Authorize(Permissions.Read)]
public async Task<ActionResult<ContentStatistic>> GetStoreContentStats(string storeId)
{
var pagesTask = contentStats.GetStorePagesCountAsync(storeId);
var blogsTask = contentStats.GetStoreBlogsCountAsync(storeId);
var themesTask = contentStats.GetStoreThemesCountAsync(storeId);
var store = await storeService.GetNoCloneAsync(storeId, StoreResponseGroup.DynamicProperties.ToString());

var storeTask = storeService.GetNoCloneAsync(storeId, StoreResponseGroup.DynamicProperties.ToString());

await Task.WhenAll(themesTask, blogsTask, pagesTask, storeTask);
if (store == null)
{
return NotFound();
}

var activeThemeProperty = storeTask.Result.DynamicProperties.FirstOrDefault(x => x.Name == "DefaultThemeName");
var activeThemeProperty = store.DynamicProperties.FirstOrDefault(x => x.Name == "DefaultThemeName");
var activeTheme = activeThemeProperty?.Values?.FirstOrDefault()?.Value?.ToString();

var result = new ContentStatistic
{
PagesCount = pagesTask.Result,
BlogsCount = blogsTask.Result,
ThemesCount = themesTask.Result,
ActiveThemeName = activeTheme ?? ContentConstants.DefaultTheme,

ActiveThemeName = activeTheme ?? ContentConstants.DefaultTheme
PagesCount = -1,
BlogsCount = -1,
ThemesCount = -1,
};

if (!configuration.IsContentStatisticEnabled())
{
return Ok(result);
}

var pagesTask = contentStats.GetStorePagesCountAsync(storeId);
var blogsTask = contentStats.GetStoreBlogsCountAsync(storeId);
var themesTask = contentStats.GetStoreThemesCountAsync(storeId);

await Task.WhenAll(themesTask, blogsTask, pagesTask);

result.PagesCount = pagesTask.Result;
result.BlogsCount = blogsTask.Result;
result.ThemesCount = themesTask.Result;

return Ok(result);
}

Expand Down
Loading