Merge pull request #2828 from sbwalker/dev

ability to specify Resources in IModule and ITheme interfaces,, fixed module settings error for personalized pages
This commit is contained in:
Shaun Walker 2023-05-19 18:08:40 -04:00 committed by GitHub
commit 1ee9c2cf0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 506 additions and 446 deletions

View File

@ -44,13 +44,21 @@
<Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
<div class="col-sm-9">
<select id="page" class="form-select" @bind="@_pageId" required>
@foreach (Page p in PageState.Pages)
@if (PageState.Page.UserId != null)
{
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
<option value="@PageState.Page.PageId">@(PageState.Page.Name)</option>
}
else
{
foreach (Page p in PageState.Pages)
{
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, p.PermissionList))
{
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
}
}
}
</select>
</div>
</div>

View File

@ -210,10 +210,10 @@
if (UserSecurity.IsAuthorized(user, PermissionNames.View, page.PermissionList))
{
// load additional metadata for current page
page = await ProcessPage(page, site, user);
page = await ProcessPage(page, site, user, SiteState.Alias);
// load additional metadata for modules
(page, site.Modules) = ProcessModules(page, site.Modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
(page, site.Modules) = ProcessModules(page, site.Modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType, SiteState.Alias);
// populate page state (which acts as a client-side cache for subsequent requests)
_pagestate = new PageState
@ -328,7 +328,7 @@
return querystring;
}
private async Task<Page> ProcessPage(Page page, Site site, User user)
private async Task<Page> ProcessPage(Page page, Site site, User user, Alias alias)
{
try
{
@ -346,6 +346,13 @@
page.Panes = new List<string>();
page.Resources = new List<Resource>();
// get theme resources
var theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
if (theme != null)
{
page.Resources = ManagePageResources(page.Resources, theme.Resources, ResourceLevel.Page, alias, "Themes", Utilities.GetTypeName(theme.ThemeName));
}
string panes = "";
Type themetype = Type.GetType(page.ThemeType);
if (themetype == null)
@ -363,7 +370,7 @@
{
panes = themeobject.Panes;
}
page.Resources = ManagePageResources(page.Resources, themeobject.Resources, ResourceLevel.Page);
page.Resources = ManagePageResources(page.Resources, themeobject.Resources, ResourceLevel.Page, alias, "Themes", themetype.Namespace);
}
}
if (!string.IsNullOrEmpty(panes))
@ -388,7 +395,7 @@
return page;
}
private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string action, string defaultcontainertype)
private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string action, string defaultcontainertype, Alias alias)
{
var paneindex = new Dictionary<string, int>();
foreach (Module module in modules)
@ -425,6 +432,9 @@
}
}
}
// get module resources
page.Resources = ManagePageResources(page.Resources, module.ModuleDefinition.Resources, ResourceLevel.Module, alias, "Modules", Utilities.GetTypeName(module.ModuleDefinition.ModuleDefinitionName));
}
// ensure component exists and implements IModuleControl
@ -448,7 +458,7 @@
{
// retrieve module component resources
var moduleobject = Activator.CreateInstance(moduletype) as IModuleControl;
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module);
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module, alias, "Modules", moduletype.Namespace);
if (action.ToLower() == "settings" && module.ModuleDefinition != null)
{
// settings components are embedded within a framework settings module
@ -456,7 +466,7 @@
if (moduletype != null)
{
moduleobject = Activator.CreateInstance(moduletype) as IModuleControl;
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module);
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module, alias, "Modules", moduletype.Namespace);
}
}
@ -515,12 +525,18 @@
return (page, modules);
}
private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources, ResourceLevel level)
private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources, ResourceLevel level, Alias alias, string type, string name)
{
if (resources != null)
{
foreach (var resource in resources)
{
if (!resource.Url.Contains("://") && resource.Url.StartsWith("~/"))
{
// create local path
resource.Url = resource.Url.Replace("~", alias.BaseUrl + "/" + type + "/" + name);
}
// ensure resource does not exist already
if (pageresources.Find(item => item.Url == resource.Url) == null)
{

View File

@ -21,6 +21,7 @@ namespace Oqtane.Controllers
{
private readonly ISiteRepository _sites;
private readonly IPageRepository _pages;
private readonly IThemeRepository _themes;
private readonly IModuleRepository _modules;
private readonly IPageModuleRepository _pageModules;
private readonly IModuleDefinitionRepository _moduleDefinitions;
@ -32,10 +33,11 @@ namespace Oqtane.Controllers
private readonly IMemoryCache _cache;
private readonly Alias _alias;
public SiteController(ISiteRepository sites, IPageRepository pages, IModuleRepository modules, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache)
public SiteController(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IModuleRepository modules, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache)
{
_sites = sites;
_pages = pages;
_themes = themes;
_modules = modules;
_pageModules = pageModules;
_moduleDefinitions = moduleDefinitions;
@ -144,6 +146,9 @@ namespace Oqtane.Controllers
var defaultCulture = CultureInfo.GetCultureInfo(Constants.DefaultCulture);
site.Languages.Add(new Language { Code = defaultCulture.Name, Name = defaultCulture.DisplayName, Version = Constants.Version, IsDefault = !site.Languages.Any(l => l.IsDefault) });
// themes
site.Themes = _themes.FilterThemes(_themes.GetThemes().ToList());
return site;
}
else

View File

@ -6,6 +6,7 @@ namespace Oqtane.Repository
public interface IThemeRepository
{
IEnumerable<Theme> GetThemes();
List<Theme> FilterThemes(List<Theme> themes);
void DeleteTheme(string ThemeName);
}
}

View File

@ -79,6 +79,7 @@ namespace Oqtane.Repository
ModuleDefinition.SettingsType = moduleDefinition.SettingsType;
ModuleDefinition.ControlTypeTemplate = moduleDefinition.ControlTypeTemplate;
ModuleDefinition.IsPortable = moduleDefinition.IsPortable;
ModuleDefinition.Resources = moduleDefinition.Resources;
}
return ModuleDefinition;

View File

@ -144,6 +144,24 @@ namespace Oqtane.Repository
return themes;
}
public List<Theme> FilterThemes(List<Theme> themes)
{
var Themes = new List<Theme>();
foreach (Theme theme in themes)
{
var Theme = new Theme();
Theme.ThemeName = theme.ThemeName;
Theme.Name = theme.Name;
Theme.Resources = theme.Resources;
Theme.Themes = theme.Themes;
Theme.Containers = theme.Containers;
Themes.Add(Theme);
}
return Themes;
}
public void DeleteTheme(string ThemeName)
{
_cache.Remove("themes");

View File

@ -34,6 +34,7 @@ namespace Oqtane.Models
PackageName = "";
Runtimes = "";
Template = "";
Resources = null;
}
/// <summary>
@ -106,6 +107,9 @@ namespace Oqtane.Models
[NotMapped]
public string PackageName { get; set; } // added in 2.1.0
[NotMapped]
public List<Resource> Resources { get; set; } // added in 4.0.0
// internal properties
[NotMapped]
public int SiteId { get; set; }

View File

@ -23,7 +23,7 @@ namespace Oqtane.Models
get => _url;
set
{
_url = (value.Contains("://")) ? value : (!value.StartsWith("/") ? "/" : "") + value;
_url = (value.Contains("://")) ? value : (!value.StartsWith("/") && !value.StartsWith("~") ? "/" : "") + value;
}
}

View File

@ -105,6 +105,9 @@ namespace Oqtane.Models
[NotMapped]
public List<Language> Languages { get; set; }
[NotMapped]
public List<Theme> Themes { get; set; }
#region IDeletable Properties
public string DeletedBy { get; set; }

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
namespace Oqtane.Models
{
@ -21,6 +22,7 @@ namespace Oqtane.Models
ThemeSettingsType = "";
ContainerSettingsType = "";
PackageName = "";
Resources = null;
}
/// <summary>
@ -67,6 +69,8 @@ namespace Oqtane.Models
public string ThemeSettingsType { get; set; } // added in 2.0.2
public string ContainerSettingsType { get; set; } // added in 2.0.2
public string PackageName { get; set; } // added in 2.1.0
public List<Resource> Resources { get; set; } // added in 4.0.0
// internal properties
public string AssemblyName { get; set; }