Skip to content

Commit 2a69fc3

Browse files
committed
Merge branch 'release/3.837.0'
2 parents 5be5b9c + c159195 commit 2a69fc3

File tree

8 files changed

+103
-39
lines changed

8 files changed

+103
-39
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project>
33
<!-- These properties will be shared for all projects -->
44
<PropertyGroup>
5-
<VersionPrefix>3.836.0</VersionPrefix>
5+
<VersionPrefix>3.837.0</VersionPrefix>
66
<VersionSuffix>
77
</VersionSuffix>
88
<VersionSuffix Condition=" '$(VersionSuffix)' != '' AND '$(BuildNumber)' != '' ">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>

src/VirtoCommerce.ContentModule.Core/Services/IContentService.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,27 @@ public interface IContentService
1111
Task CopyContentAsync(string contentType, string storeId, string srcPath, string destPath);
1212
Task<ContentFile> GetFileAsync(string contentType, string storeId, string relativeUrl);
1313
Task<IndexableContentFile> GetFileContentAsync(string contentType, string storeId, string relativeUrl);
14+
15+
/// <summary>
16+
/// Asynchronously retrieves the content of a file identified by the specified ID.
17+
/// </summary>
18+
/// <param name="id">The unique identifier of the file to retrieve. Cannot be null or empty. It is used as documentId for fulltext search service.</param>
19+
/// <returns>A task that represents the asynchronous operation. The task result contains an <see
20+
/// cref="IndexableContentFile"/> representing the file content if found; otherwise, <see langword="null"/>.</returns>
21+
Task<IndexableContentFile> GetFileContentAsync(string id);
1422
Task CreateFolderAsync(string contentType, string storeId, ContentFolder folder);
1523

1624
Task<bool> ItemExistsAsync(string contentType, string storeId, string relativeUrl);
1725
Task<Stream> GetItemStreamAsync(string contentType, string storeId, string relativeUrl);
1826

27+
/// <summary>
28+
/// Asynchronously retrieves a stream for reading the content of the item with the specified identifier.
29+
/// </summary>
30+
/// <param name="id">The unique identifier of the item to retrieve. Cannot be null or empty. It is used as documentId for fulltext search service also.</param>
31+
/// <returns>A task that represents the asynchronous operation. The task result contains a stream for reading the item's
32+
/// content.</returns>
33+
Task<Stream> GetItemStreamAsync(string id);
34+
1935
Task UnpackAsync(string contentType, string storeId, string archivePath, string destPath);
2036

2137
Task<ContentFile> DownloadContentAsync(string contentType, string storeId, string srcUrl, string folderPath);

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

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,25 @@
22
using System.Text;
33
using VirtoCommerce.ContentModule.Core.Model;
44

5-
namespace VirtoCommerce.ContentModule.Data.Search
5+
namespace VirtoCommerce.ContentModule.Data.Search;
6+
7+
internal static class DocumentIdentifierHelper
68
{
7-
internal static class DocumentIdentifierHelper
9+
public static string GenerateId(string storeId, string contentType, ContentItem file)
810
{
9-
public static string GenerateId(string storeId, string contentType, ContentItem file)
10-
{
11-
return Convert.ToBase64String(Encoding.ASCII.GetBytes($"{storeId}::{contentType}::{file.RelativeUrl}")).Replace('=', '-');
12-
}
13-
14-
public static (string storeId, string contentType, string relativeUrl) ParseId(string id)
15-
{
16-
var decoded = Encoding.ASCII.GetString(Convert.FromBase64String(id.Replace('-', '=')));
17-
var result = decoded.Split(["::"], StringSplitOptions.RemoveEmptyEntries);
11+
return Convert.ToBase64String(Encoding.ASCII.GetBytes($"{storeId}::{contentType}::{file.RelativeUrl}")).Replace('=', '-');
12+
}
1813

19-
if (result.Length == 3)
20-
{
21-
return (result[0], result[1], result[2]);
22-
}
14+
public static (string storeId, string contentType, string relativeUrl) ParseId(string id)
15+
{
16+
var decoded = Encoding.ASCII.GetString(Convert.FromBase64String(id.Replace('-', '=')));
17+
var result = decoded.Split(["::"], StringSplitOptions.RemoveEmptyEntries);
2318

24-
return (null, null, null);
19+
if (result.Length == 3)
20+
{
21+
return (result[0], result[1], result[2]);
2522
}
23+
24+
return (null, null, null);
2625
}
2726
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ protected virtual async Task<IList<IndexableContentFile>> GetItemsByPathsAsync(I
9191

9292
foreach (var document in documents)
9393
{
94-
var (storeId, contentType, relativeUrl) = DocumentIdentifierHelper.ParseId(document.Id);
95-
var contentItem = await _contentService.GetFileContentAsync(contentType, storeId, relativeUrl);
94+
var contentItem = await _contentService.GetFileContentAsync(document.Id);
9695
if (contentItem != null)
9796
{
9897
contentItem.Id = document.Id;

src/VirtoCommerce.ContentModule.Data/Services/ContentService.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using VirtoCommerce.ContentModule.Core.Services;
1212
using VirtoCommerce.ContentModule.Data.Extensions;
1313
using VirtoCommerce.ContentModule.Data.Model;
14+
using VirtoCommerce.ContentModule.Data.Search;
1415
using VirtoCommerce.Platform.Core.Common;
1516
using VirtoCommerce.Platform.Core.Events;
1617
using UrlHelperExtensions = VirtoCommerce.Platform.Core.Extensions.UrlHelperExtensions;
@@ -102,6 +103,12 @@ public async Task<IndexableContentFile> GetFileContentAsync(string contentType,
102103
return result;
103104
}
104105

106+
public async Task<IndexableContentFile> GetFileContentAsync(string id)
107+
{
108+
var (storeId, contentType, relativeUrl) = DocumentIdentifierHelper.ParseId(id);
109+
return await GetFileContentAsync(contentType, storeId, relativeUrl);
110+
}
111+
105112
public async Task CreateFolderAsync(string contentType, string storeId, ContentFolder folder)
106113
{
107114
var storageProvider = GetStorageProvider(contentType, storeId);
@@ -123,6 +130,12 @@ public async Task<Stream> GetItemStreamAsync(string contentType, string storeId,
123130
return fileStream;
124131
}
125132

133+
public async Task<Stream> GetItemStreamAsync(string id)
134+
{
135+
var (storeId, contentType, relativeUrl) = DocumentIdentifierHelper.ParseId(id);
136+
return await GetItemStreamAsync(contentType, storeId, relativeUrl);
137+
}
138+
126139
public async Task UnpackAsync(string contentType, string storeId, string archivePath, string destPath)
127140
{
128141
var storageProvider = GetStorageProvider(contentType, storeId);

src/VirtoCommerce.ContentModule.Web/Scripts/blades/pages/page-detail.js

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ angular.module('virtoCommerce.contentModule')
305305
canExecuteMethod: function () { return !isDirty(); }
306306
};
307307

308-
309308
if (!blade.isNew) {
310309
toolbarCommands = [
311310
{
@@ -351,17 +350,21 @@ angular.module('virtoCommerce.contentModule')
351350
name: "content.commands.preview-page",
352351
icon: 'fa fa-eye',
353352
executeMethod: function () {
354-
const urlListBlade = {
355-
id: "storeUrlList",
356-
storeId: blade.storeId,
357-
contentType: blade.contentType,
358-
relativeUrl: blade.currentEntity.relativeUrl,
359-
headIcon: 'fa-plus-square-o',
360-
controller: 'virtoCommerce.contentModule.storeUrlListController',
361-
template: 'Modules/$(VirtoCommerce.Content)/Scripts/blades/pages/store-url-list.tpl.html'
353+
var showPreview = function () {
354+
var storeUrl = blade.storeUrl?.replace(/\/$/, '');
355+
if (storeUrl) {
356+
var documentId = filesDraftService.getDocumentId(blade, true);
357+
window.open(`${storeUrl}/designer-preview?pageId=${encodeURIComponent(documentId)}`, '_blank');
358+
} else {
359+
var dialog = {
360+
id: "noUrlInStore",
361+
title: "content.dialogs.set-store-url.title",
362+
message: "content.dialogs.set-store-url.message"
363+
};
364+
dialogService.showNotificationDialog(dialog);
365+
}
362366
};
363-
364-
bladeNavigationService.showBlade(urlListBlade, blade);
367+
showPreview();
365368
},
366369
canExecuteMethod: function () { return true; }
367370
}
@@ -404,8 +407,12 @@ angular.module('virtoCommerce.contentModule')
404407
executeMethod: function () {
405408
getDocumentIndex(function (data) {
406409
var doc = getSearchDocumentInfo();
410+
if (!doc) {
411+
console.log('Document id error', blade);
412+
return;
413+
}
407414
const searchBlade = {
408-
id: 'sesarchDetails',
415+
id: 'searchDetails',
409416
currentEntityId: doc.documentId,
410417
currentEntity: blade.currentEntity,
411418
data: $scope.index,
@@ -418,11 +425,15 @@ angular.module('virtoCommerce.contentModule')
418425
bladeNavigationService.showBlade(searchBlade, blade);
419426
});
420427
},
421-
canExecuteMethod: function () { return true; }
428+
canExecuteMethod: function () { return !!$scope.index; }
422429
});
423430
}
424431

425432
function updateIndexStatus(data, doc) {
433+
if (!doc || !_.any(data)) {
434+
$scope.index = null;
435+
return;
436+
}
426437
if (_.any(data)) {
427438
$scope.index = data[0];
428439
$scope.indexDate = moment.utc($scope.index.indexationdate, momentFormat);
@@ -439,19 +450,25 @@ angular.module('virtoCommerce.contentModule')
439450
}
440451

441452
function getSearchDocumentInfo() {
442-
var relativeUrl = filesDraftService.undraftUrl(blade.currentEntity.relativeUrl);
443-
var documentId = btoa(`${blade.storeId}::${blade.contentType}::${relativeUrl}`).replaceAll('=', '-');
453+
var documentId = filesDraftService.getDocumentId(blade);
454+
if (!documentId) {
455+
return null;
456+
}
444457
var documentType = 'ContentFile';
445458
return { documentType: documentType, documentId: documentId };
446459
}
447460

448461
function getDocumentIndex(callback) {
449462
if ($scope.searchEnabled) {
450463
var doc = getSearchDocumentInfo();
451-
searchApi.getDocIndex(doc, function (data) {
452-
updateIndexStatus(data, doc);
453-
callback && _.any(data) && callback();
454-
});
464+
if (!!doc) {
465+
searchApi.getDocIndex(doc, function (data) {
466+
updateIndexStatus(data, doc);
467+
callback && _.any(data) && callback();
468+
});
469+
} else {
470+
updateIndexStatus(null, null);
471+
}
455472
}
456473
}
457474

src/VirtoCommerce.ContentModule.Web/Scripts/services/files-draft.service.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,26 @@ angular.module('virtoCommerce.contentModule')
33

44
var $this = this;
55

6+
this.getDocumentId = function (blade, real) {
7+
if (!blade || !blade.currentEntity) {
8+
return null;
9+
}
10+
const relativeUrl = real ? $this.getRealFileName(blade) : $this.undraftUrl(blade.currentEntity.relativeUrl);
11+
return btoa(`${blade.storeId}::${blade.contentType}::${relativeUrl}`).replaceAll('=', '-');
12+
}
13+
14+
this.getRealFileName = function (blade) {
15+
var relativeUrl = blade.currentEntity.relativeUrl;
16+
var isDraft = blade.currentEntity.hasChanges;
17+
if (!isDraft) {
18+
return $this.undraftUrl(relativeUrl);
19+
}
20+
if (!relativeUrl.endsWith('-draft')) {
21+
return $this.getDraftFileName(blade);
22+
}
23+
return relativeUrl;
24+
}
25+
626
this.getDraftFileName = function (blade) {
727
var relativeUrl = blade.currentEntity.relativeUrl;
828
// the draft page should be under editing in the designer

src/VirtoCommerce.ContentModule.Web/module.manifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<module xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
33
<id>VirtoCommerce.Content</id>
4-
<version>3.836.0</version>
4+
<version>3.837.0</version>
55
<version-tag />
66

77
<platformVersion>3.919.0</platformVersion>

0 commit comments

Comments
 (0)