-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
build(sln): v29.3.0.5 - more admin extensions
- Loading branch information
1 parent
ffc32de
commit 877d9ca
Showing
10 changed files
with
474 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
283 changes: 283 additions & 0 deletions
283
src/Kentico.Community.Portal.Admin/Features/WebsiteChannels/WebPageListingPage.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,283 @@ | ||
using CMS.Base; | ||
using CMS.ContentEngine; | ||
using CMS.ContentEngine.Internal; | ||
using CMS.Core; | ||
using CMS.DataEngine; | ||
using CMS.Membership; | ||
using CMS.Websites; | ||
using CMS.Websites.Internal; | ||
using CSharpFunctionalExtensions; | ||
using Kentico.Community.Portal.Admin.Features.WebsiteChannels; | ||
using Kentico.Xperience.Admin.Base.FormAnnotations; | ||
using Kentico.Xperience.Admin.Base; | ||
using Kentico.Xperience.Admin.Base.Filters; | ||
using Kentico.Xperience.Admin.Base.Forms; | ||
using Kentico.Xperience.Admin.Websites.UIPages; | ||
using Kentico.Community.Portal.Admin.UIPages; | ||
|
||
[assembly: UIPage( | ||
parentType: typeof(WebsiteChannelsApplicationPage), | ||
slug: "web-pages", | ||
uiPageType: typeof(WebPageListingPage), | ||
name: "Web Page List", | ||
icon: Icons.Magnifier, | ||
templateName: TemplateNames.LISTING, | ||
order: 0)] | ||
|
||
namespace Kentico.Community.Portal.Admin.Features.WebsiteChannels; | ||
|
||
public class WebPageListingPage(IPageUrlGenerator pageUrlGenerator, IConversionService conversion) : ListingPage | ||
{ | ||
private readonly IPageUrlGenerator pageUrlGenerator = pageUrlGenerator; | ||
private readonly IConversionService conversion = conversion; | ||
|
||
protected override string ObjectType => ContentItemInfo.OBJECT_TYPE; | ||
|
||
/// <summary> | ||
/// Deletes user specified by the <paramref name="id"/> parameter. | ||
/// </summary> | ||
[PageCommand(Permission = SystemPermissions.DELETE)] | ||
public override Task<ICommandResponse<RowActionResult>> Delete(int id) => base.Delete(id); | ||
|
||
public override async Task ConfigurePage() | ||
{ | ||
await base.ConfigurePage(); | ||
|
||
PageConfiguration.FilterFormModel = new WebPageListMultiFilter(); | ||
|
||
PageConfiguration.QueryModifiers | ||
.AddModifier((query, settings) => | ||
{ | ||
return query | ||
.Source(source => source | ||
.Join<WebPageItemInfo>(nameof(ContentItemInfo.ContentItemID), nameof(WebPageItemInfo.WebPageItemContentItemID)) | ||
.Join<ContentItemCommonDataInfo>(nameof(WebPageItemInfo.WebPageItemContentItemID), nameof(ContentItemCommonDataInfo.ContentItemCommonDataContentItemID)) | ||
.Join<ContentItemLanguageMetadataInfo>(nameof(ContentItemCommonDataInfo.ContentItemCommonDataContentItemID), nameof(ContentItemLanguageMetadataInfo.ContentItemLanguageMetadataContentItemID), | ||
additionalCondition: new WhereCondition($"CMS_ContentItemCommonData.ContentItemCommonDataContentLanguageID = CMS_ContentItemLanguageMetadata.ContentItemLanguageMetadataContentLanguageID")) | ||
.Join<WebsiteChannelInfo>($"CMS_WebPageItem.{nameof(WebPageItemInfo.WebPageItemWebsiteChannelID)}", nameof(WebsiteChannelInfo.WebsiteChannelID)) | ||
.Join<ChannelInfo>(nameof(WebsiteChannelInfo.WebsiteChannelChannelID), nameof(ChannelInfo.ChannelID)) | ||
.Join<DataClassInfo>($"CMS_ContentItem.{nameof(ContentItemInfo.ContentItemContentTypeID)}", nameof(DataClassInfo.ClassID)) | ||
.Join<ContentLanguageInfo>($"CMS_ContentItemLanguageMetadata.{nameof(ContentItemLanguageMetadataInfo.ContentItemLanguageMetadataContentLanguageID)}", nameof(ContentLanguageInfo.ContentLanguageID))) | ||
.AddColumn(nameof(WebsiteChannelInfo.WebsiteChannelID)) | ||
.AddColumn(nameof(ContentLanguageInfo.ContentLanguageName)) | ||
.AddColumn(nameof(DataClassInfo.ClassName)); | ||
}); | ||
|
||
PageConfiguration.ColumnConfigurations | ||
.AddColumn(nameof(WebPageItemInfo.WebPageItemID), | ||
"ID", | ||
searchable: true, | ||
maxWidth: 1) | ||
.AddComponentColumn(nameof(ContentItemLanguageMetadataInfo.ContentItemLanguageMetadataDisplayName), | ||
"@kentico-community/portal-web-admin/Link", | ||
modelRetriever: WebPageLinkModelRetriever, | ||
caption: "Name", | ||
searchable: true, | ||
minWidth: 25) | ||
.AddColumn(nameof(DataClassInfo.ClassDisplayName), | ||
"Content Type", | ||
maxWidth: 5) | ||
.AddColumn(nameof(ContentLanguageInfo.ContentLanguageDisplayName), | ||
"Language", | ||
maxWidth: 5) | ||
.AddColumn(nameof(ChannelInfo.ChannelDisplayName), | ||
"Channel", | ||
maxWidth: 10) | ||
.AddColumn(nameof(WebPageItemInfo.WebPageItemTreePath), | ||
"Path", | ||
searchable: true, | ||
minWidth: 50); | ||
} | ||
|
||
private TableRowLinkProps WebPageLinkModelRetriever(object value, IDataContainer container) | ||
{ | ||
int webPageItemID = conversion.GetInteger(container[nameof(WebPageItemInfo.WebPageItemID)], 0); | ||
int channelID = conversion.GetInteger(container[nameof(WebsiteChannelInfo.WebsiteChannelID)], 0); | ||
string languageName = conversion.GetString(container[nameof(ContentLanguageInfo.ContentLanguageName)], ""); | ||
string valueStr = value.ToString() ?? ""; | ||
|
||
if (webPageItemID == 0 || channelID == 0 || string.IsNullOrWhiteSpace(languageName)) | ||
{ | ||
return new TableRowLinkProps() { Label = valueStr, Path = "" }; | ||
} | ||
|
||
string pageUrl = pageUrlGenerator.GenerateUrl<PageBuilderTab>($"webpages-{channelID}", $"{languageName}_{webPageItemID}"); | ||
|
||
return new TableRowLinkProps() | ||
{ | ||
Label = valueStr, | ||
Path = pageUrl.StartsWith('/') | ||
? pageUrl[1..] | ||
: pageUrl | ||
}; | ||
} | ||
|
||
} | ||
|
||
public class TableRowLinkProps | ||
{ | ||
public string Path { get; set; } = ""; | ||
public string Label { get; set; } = ""; | ||
} | ||
|
||
public class WebPageListMultiFilter | ||
{ | ||
[GeneralSelectorComponent( | ||
dataProviderType: typeof(ContentTypeGeneralSelectorDataProvider), | ||
Label = "Content Types", | ||
Placeholder = "Any", | ||
Order = 0 | ||
)] | ||
[FilterCondition( | ||
BuilderType = typeof(GeneralWhereInWhereConditionBuilder), | ||
ColumnName = nameof(DataClassInfo.ClassName) | ||
)] | ||
public IEnumerable<string> ContentTypes { get; set; } = []; | ||
|
||
[GeneralSelectorComponent( | ||
dataProviderType: typeof(WebsiteChannelGeneralSelectorDataProvider), | ||
Label = "Channels", | ||
Placeholder = "Any", | ||
Order = 0 | ||
)] | ||
[FilterCondition( | ||
BuilderType = typeof(GeneralWhereInWhereConditionBuilder), | ||
ColumnName = nameof(ChannelInfo.ChannelName) | ||
)] | ||
public IEnumerable<string> Channels { get; set; } = []; | ||
|
||
[GeneralSelectorComponent( | ||
dataProviderType: typeof(ContentLanguageGeneralSelectorDataProvider), | ||
Label = "Languages", | ||
Placeholder = "Any", | ||
Order = 0 | ||
)] | ||
[FilterCondition( | ||
BuilderType = typeof(GeneralWhereInWhereConditionBuilder), | ||
ColumnName = nameof(ContentLanguageInfo.ContentLanguageName) | ||
)] | ||
public IEnumerable<string> Languages { get; set; } = []; | ||
} | ||
|
||
public class ContentTypeGeneralSelectorDataProvider | ||
: IGeneralSelectorDataProvider | ||
{ | ||
private static ObjectSelectorListItem<string> InvalidItem => new() { IsValid = false, Text = "Inavlid", Value = "" }; | ||
|
||
public async Task<PagedSelectListItems<string>> GetItemsAsync(string searchTerm, int pageIndex, CancellationToken cancellationToken) | ||
{ | ||
var items = await DataClassInfoProvider.GetClasses() | ||
.WhereEquals(nameof(DataClassInfo.ClassContentTypeType), ClassContentTypeType.WEBSITE) | ||
.GetEnumerableTypedResultAsync(); | ||
|
||
if (!string.IsNullOrEmpty(searchTerm)) | ||
{ | ||
items = items.Where(i => i.ClassDisplayName.StartsWith(searchTerm, StringComparison.OrdinalIgnoreCase)); | ||
} | ||
|
||
return new PagedSelectListItems<string>() | ||
{ | ||
NextPageAvailable = false, | ||
Items = items.Select(i => new ObjectSelectorListItem<string> { IsValid = true, Text = i.ClassDisplayName, Value = i.ClassName }), | ||
}; | ||
} | ||
|
||
public async Task<IEnumerable<ObjectSelectorListItem<string>>> GetSelectedItemsAsync(IEnumerable<string> selectedValues, CancellationToken cancellationToken) | ||
{ | ||
var items = await DataClassInfoProvider.GetClasses() | ||
.WhereEquals(nameof(DataClassInfo.ClassContentTypeType), ClassContentTypeType.WEBSITE) | ||
.GetEnumerableTypedResultAsync(); | ||
|
||
return (selectedValues ?? []).Select(GetSelectedItemByValue(items)); | ||
|
||
} | ||
|
||
private Func<string, ObjectSelectorListItem<string>> GetSelectedItemByValue(IEnumerable<DataClassInfo> websiteChannelContentTypes) => | ||
(string className) => websiteChannelContentTypes | ||
.TryFirst(c => string.Equals(c.ClassName, className)) | ||
.Map(c => new ObjectSelectorListItem<string> { IsValid = true, Text = c.ClassDisplayName, Value = c.ClassName }) | ||
.GetValueOrDefault(InvalidItem); | ||
|
||
} | ||
|
||
public class WebsiteChannelGeneralSelectorDataProvider(IInfoProvider<ChannelInfo> channelProvider) | ||
: IGeneralSelectorDataProvider | ||
{ | ||
private readonly IInfoProvider<ChannelInfo> channelProvider = channelProvider; | ||
|
||
private static ObjectSelectorListItem<string> InvalidItem => new() { IsValid = false, Text = "Inavlid", Value = "" }; | ||
|
||
public async Task<PagedSelectListItems<string>> GetItemsAsync(string searchTerm, int pageIndex, CancellationToken cancellationToken) | ||
{ | ||
var items = await channelProvider.Get() | ||
.WhereEquals(nameof(ChannelInfo.ChannelType), ChannelType.Website.ToString()) | ||
.GetEnumerableTypedResultAsync(); | ||
|
||
if (!string.IsNullOrEmpty(searchTerm)) | ||
{ | ||
items = items.Where(i => i.ChannelDisplayName.StartsWith(searchTerm, StringComparison.OrdinalIgnoreCase)); | ||
} | ||
|
||
return new PagedSelectListItems<string>() | ||
{ | ||
NextPageAvailable = false, | ||
Items = items.Select(i => new ObjectSelectorListItem<string> { IsValid = true, Text = i.ChannelDisplayName, Value = i.ChannelName }), | ||
}; | ||
} | ||
|
||
public async Task<IEnumerable<ObjectSelectorListItem<string>>> GetSelectedItemsAsync(IEnumerable<string> selectedValues, CancellationToken cancellationToken) | ||
{ | ||
var items = await channelProvider.Get() | ||
.WhereEquals(nameof(ChannelInfo.ChannelType), ChannelType.Website.ToString()) | ||
.GetEnumerableTypedResultAsync(); | ||
|
||
return (selectedValues ?? []).Select(GetSelectedItemByValue(items)); | ||
|
||
} | ||
|
||
private Func<string, ObjectSelectorListItem<string>> GetSelectedItemByValue(IEnumerable<ChannelInfo> websiteChannelContentTypes) => | ||
(string channelName) => websiteChannelContentTypes | ||
.TryFirst(c => string.Equals(c.ChannelName, channelName)) | ||
.Map(c => new ObjectSelectorListItem<string> { IsValid = true, Text = c.ChannelDisplayName, Value = c.ChannelName }) | ||
.GetValueOrDefault(InvalidItem); | ||
} | ||
|
||
public class ContentLanguageGeneralSelectorDataProvider(IInfoProvider<ContentLanguageInfo> languageProvider) | ||
: IGeneralSelectorDataProvider | ||
{ | ||
private readonly IInfoProvider<ContentLanguageInfo> languageProvider = languageProvider; | ||
|
||
private static ObjectSelectorListItem<string> InvalidItem => new() { IsValid = false, Text = "Inavlid", Value = "" }; | ||
|
||
public async Task<PagedSelectListItems<string>> GetItemsAsync(string searchTerm, int pageIndex, CancellationToken cancellationToken) | ||
{ | ||
var items = await languageProvider.Get() | ||
.GetEnumerableTypedResultAsync(); | ||
|
||
if (!string.IsNullOrEmpty(searchTerm)) | ||
{ | ||
items = items.Where(i => i.ContentLanguageDisplayName.StartsWith(searchTerm, StringComparison.OrdinalIgnoreCase)); | ||
} | ||
|
||
return new PagedSelectListItems<string>() | ||
{ | ||
NextPageAvailable = false, | ||
Items = items.Select(i => new ObjectSelectorListItem<string> { IsValid = true, Text = i.ContentLanguageDisplayName, Value = i.ContentLanguageName }), | ||
}; | ||
} | ||
|
||
public async Task<IEnumerable<ObjectSelectorListItem<string>>> GetSelectedItemsAsync(IEnumerable<string> selectedValues, CancellationToken cancellationToken) | ||
{ | ||
var items = await languageProvider.Get() | ||
.GetEnumerableTypedResultAsync(); | ||
|
||
return (selectedValues ?? []).Select(GetSelectedItemByValue(items)); | ||
|
||
} | ||
|
||
private Func<string, ObjectSelectorListItem<string>> GetSelectedItemByValue(IEnumerable<ContentLanguageInfo> languages) => | ||
(string languageName) => languages | ||
.TryFirst(c => string.Equals(c.ContentLanguageName, languageName)) | ||
.Map(c => new ObjectSelectorListItem<string> { IsValid = true, Text = c.ContentLanguageDisplayName, Value = c.ContentLanguageName }) | ||
.GetValueOrDefault(InvalidItem); | ||
} |
24 changes: 24 additions & 0 deletions
24
...Kentico.Community.Portal.Admin/Features/WebsiteChannels/WebsiteChannelsApplicationPage.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
using CMS.Membership; | ||
using Kentico.Community.Portal.Admin; | ||
using Kentico.Community.Portal.Admin.Features.WebsiteChannels; | ||
using Kentico.Xperience.Admin.Base; | ||
|
||
[assembly: UIApplication( | ||
identifier: WebsiteChannelsApplicationPage.IDENTIFIER, | ||
type: typeof(WebsiteChannelsApplicationPage), | ||
slug: "website-channels", | ||
name: "Website channels", | ||
category: PortalWebAdminModule.COMMUNITY_CATEGORY, | ||
icon: Icons.Earth, | ||
templateName: TemplateNames.SECTION_LAYOUT)] | ||
|
||
namespace Kentico.Community.Portal.Admin.Features.WebsiteChannels; | ||
|
||
[UIPermission(SystemPermissions.VIEW)] | ||
[UIPermission(SystemPermissions.CREATE)] | ||
[UIPermission(SystemPermissions.UPDATE)] | ||
[UIPermission(SystemPermissions.DELETE)] | ||
public class WebsiteChannelsApplicationPage : ApplicationPage | ||
{ | ||
public const string IDENTIFIER = "website-channels-app"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.