ability to specify Resources in IModule and ITheme interfaces,, fixed module settings for personalized pages

This commit is contained in:
sbwalker 2023-05-19 18:08:15 -04:00
parent 2be48c3847
commit e41d9008b3
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; }