ability to specify if a theme is enabled for a site
This commit is contained in:
parent
666f9c2db9
commit
98c2f012ee
|
@ -308,7 +308,7 @@
|
|||
{
|
||||
moduledefinition.Categories = _categories;
|
||||
}
|
||||
moduledefinition.IsEnabled = (_isenabled == null ? true : Boolean.Parse(_isenabled));
|
||||
moduledefinition.IsEnabled = (_isenabled == null ? true : bool.Parse(_isenabled));
|
||||
moduledefinition.PermissionList = _permissionGrid.GetPermissionList();
|
||||
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
|
||||
await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
|
||||
|
|
|
@ -98,37 +98,35 @@
|
|||
</form>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
public override string Title => "Module Settings";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
public override string Title => "Module Settings";
|
||||
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private List<Theme> _themes;
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _title;
|
||||
private string _containerType;
|
||||
private string _allPages = "false";
|
||||
private string _permissionNames = "";
|
||||
private List<Permission> _permissions = null;
|
||||
private string _pageId;
|
||||
private PermissionGrid _permissionGrid;
|
||||
private Type _moduleSettingsType;
|
||||
private object _moduleSettings;
|
||||
private string _moduleSettingsTitle = "Module Settings";
|
||||
private RenderFragment ModuleSettingsComponent { get; set; }
|
||||
private Type _containerSettingsType;
|
||||
private object _containerSettings;
|
||||
private RenderFragment ContainerSettingsComponent { get; set; }
|
||||
private string createdby;
|
||||
private DateTime createdon;
|
||||
private string modifiedby;
|
||||
private DateTime modifiedon;
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _title;
|
||||
private string _containerType;
|
||||
private string _allPages = "false";
|
||||
private string _permissionNames = "";
|
||||
private List<Permission> _permissions = null;
|
||||
private string _pageId;
|
||||
private PermissionGrid _permissionGrid;
|
||||
private Type _moduleSettingsType;
|
||||
private object _moduleSettings;
|
||||
private string _moduleSettingsTitle = "Module Settings";
|
||||
private RenderFragment ModuleSettingsComponent { get; set; }
|
||||
private Type _containerSettingsType;
|
||||
private object _containerSettings;
|
||||
private RenderFragment ContainerSettingsComponent { get; set; }
|
||||
private string createdby;
|
||||
private DateTime createdon;
|
||||
private string modifiedby;
|
||||
private DateTime modifiedon;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_title = ModuleState.Title;
|
||||
_themes = await ThemeService.GetThemesAsync();
|
||||
_containers = ThemeService.GetContainerControls(_themes, PageState.Page.ThemeType);
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_title = ModuleState.Title;
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||
_containerType = ModuleState.ContainerType;
|
||||
_allPages = ModuleState.AllPages.ToString();
|
||||
_permissions = ModuleState.PermissionList;
|
||||
|
@ -173,7 +171,7 @@
|
|||
AddModuleMessage(string.Format(Localizer["Error.Module.Load"], ModuleState.ModuleDefinitionName), MessageType.Error);
|
||||
}
|
||||
|
||||
var theme = _themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType)));
|
||||
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ContainerSettingsType))
|
||||
{
|
||||
_containerSettingsType = Type.GetType(theme.ContainerSettingsType);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||
<TabStrip Refresh="@_refresh">
|
||||
<TabPanel Name="Settings" ResourceKey="Settings">
|
||||
@if (_themeList != null)
|
||||
@if (PageState.Site.Themes != null)
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
|
@ -175,7 +175,6 @@
|
|||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _name;
|
||||
|
@ -207,10 +206,9 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_themes = ThemeService.GetThemeControls(PageState.Site.Themes);
|
||||
_themetype = PageState.Site.DefaultThemeType;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||
_containertype = PageState.Site.DefaultContainerType;
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
ThemeSettings();
|
||||
|
@ -262,7 +260,7 @@
|
|||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||
_containertype = "-";
|
||||
ThemeSettings();
|
||||
StateHasChanged();
|
||||
|
@ -277,7 +275,7 @@
|
|||
private void ThemeSettings()
|
||||
{
|
||||
_themeSettingsType = null;
|
||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||
{
|
||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||
<TabStrip Refresh="@_refresh">
|
||||
<TabPanel Name="Settings" ResourceKey="Settings" Heading=@Localizer["Settings.Heading"]>
|
||||
@if (_themeList != null)
|
||||
@if (PageState.Site.Themes != null)
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
|
@ -210,7 +210,6 @@
|
|||
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private int _pageId;
|
||||
|
@ -251,8 +250,7 @@
|
|||
try
|
||||
{
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_themes = ThemeService.GetThemeControls(PageState.Site.Themes);
|
||||
|
||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
|
@ -294,7 +292,7 @@
|
|||
{
|
||||
_themetype = PageState.Site.DefaultThemeType;
|
||||
}
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||
_containertype = page.DefaultContainerType;
|
||||
if (string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
|
@ -396,7 +394,7 @@
|
|||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||
_containertype = "-";
|
||||
ThemeSettings();
|
||||
StateHasChanged();
|
||||
|
@ -413,7 +411,7 @@
|
|||
_themeSettingsType = null;
|
||||
if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel
|
||||
{
|
||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||
{
|
||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||
|
|
|
@ -330,7 +330,6 @@
|
|||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private bool _initialized = false;
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _name = string.Empty;
|
||||
|
@ -383,7 +382,6 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
|
@ -405,9 +403,9 @@
|
|||
{
|
||||
_faviconfileid = site.FaviconFileId.Value;
|
||||
}
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_themes = ThemeService.GetThemeControls(PageState.Site.Themes);
|
||||
_themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme;
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
|
||||
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
|
||||
|
||||
|
@ -484,7 +482,7 @@
|
|||
_themetype = (string)e.Value;
|
||||
if (_themetype != "-")
|
||||
{
|
||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
161
Oqtane.Client/Modules/Admin/Themes/Edit.razor
Normal file
161
Oqtane.Client/Modules/Admin/Themes/Edit.razor
Normal file
|
@ -0,0 +1,161 @@
|
|||
@namespace Oqtane.Modules.Admin.Themes
|
||||
@using System.Net
|
||||
@inherits ModuleBase
|
||||
@inject IThemeService ThemeService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IStringLocalizer<Edit> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
@if (_initialized)
|
||||
{
|
||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="name" class="form-control" @bind="@_name" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="isenabled" HelpText="Is theme enabled for this site?" ResourceKey="IsEnabled">Enabled? </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="isenabled" class="form-select" @bind="@_isenabled" required>
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
<option value="False">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<Section Name="Information" ResourceKey="Information">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="themename" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="themename" class="form-control" @bind="@_themeName" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="version" HelpText="The version of the theme" ResourceKey="Version">Version: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the theme" ResourceKey="Owner">Owner: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the theme" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="contact" HelpText="The contact for the theme" ResourceKey="Contact">Contact: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="license" HelpText="The license of the theme" ResourceKey="License">License: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveTheme">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
}
|
||||
|
||||
@code {
|
||||
private bool _initialized = false;
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private int _themeId;
|
||||
private string _themeName = "";
|
||||
private string _isenabled;
|
||||
private string _name;
|
||||
private string _version;
|
||||
private string _packagename;
|
||||
private string _owner = "";
|
||||
private string _url = "";
|
||||
private string _contact = "";
|
||||
private string _license = "";
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_themeId = Int32.Parse(PageState.QueryString["id"]);
|
||||
var theme = await ThemeService.GetThemeAsync(_themeId, ModuleState.SiteId);
|
||||
if (theme != null)
|
||||
{
|
||||
_name = theme.Name;
|
||||
_isenabled =theme.IsEnabled.ToString();
|
||||
_version = theme.Version;
|
||||
_packagename = theme.PackageName;
|
||||
_owner = theme.Owner;
|
||||
_url = theme.Url;
|
||||
_contact = theme.Contact;
|
||||
_license = theme.License;
|
||||
_createdby = theme.CreatedBy;
|
||||
_createdon = theme.CreatedOn;
|
||||
_modifiedby = theme.ModifiedBy;
|
||||
_modifiedon = theme.ModifiedOn;
|
||||
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Theme.Loading"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveTheme()
|
||||
{
|
||||
validated = true;
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
try
|
||||
{
|
||||
var theme = await ThemeService.GetThemeAsync(_themeId, ModuleState.SiteId);
|
||||
theme.IsEnabled = (_isenabled == null ? true : bool.Parse(_isenabled));
|
||||
await ThemeService.UpdateThemeAsync(theme);
|
||||
await logger.LogInformation("Theme Saved {Theme}", theme);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Theme {ThemeId} {Error}", _themeId, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,11 +23,12 @@ else
|
|||
<th style="width: 1px;"> </th>
|
||||
<th>@SharedLocalizer["Name"]</th>
|
||||
<th>@SharedLocalizer["Version"]</th>
|
||||
<th>@Localizer["Enabled"]</th>
|
||||
<th>@SharedLocalizer["Expires"]</th>
|
||||
<th> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" ResourceKey="ViewTheme" /></td>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ThemeId.ToString())" ResourceKey="EditModule" /></td>
|
||||
<td>
|
||||
@if (context.AssemblyName != Constants.ClientId)
|
||||
{
|
||||
|
@ -36,6 +37,16 @@ else
|
|||
</td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
@if (context.IsEnabled)
|
||||
{
|
||||
<span>@SharedLocalizer["Yes"]</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@SharedLocalizer["No"]</span>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@((MarkupString)PurchaseLink(context.PackageName))
|
||||
</td>
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
@namespace Oqtane.Modules.Admin.Themes
|
||||
@using System.Net
|
||||
@inherits ModuleBase
|
||||
@inject IThemeService ThemeService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IStringLocalizer<View> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="name" HelpText="The name of the theme" ResourceKey="Name">Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="name" class="form-control" @bind="@_name" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="themename" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="themename" class="form-control" @bind="@_themeName" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="version" HelpText="The version of the theme" ResourceKey="Version">Version: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the theme" ResourceKey="Owner">Owner: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the theme" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="contact" HelpText="The contact for the theme" ResourceKey="Contact">Contact: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="license" HelpText="The license of the theme" ResourceKey="License">License: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
|
||||
@code {
|
||||
private string _themeName = "";
|
||||
private string _name;
|
||||
private string _version;
|
||||
private string _packagename;
|
||||
private string _owner = "";
|
||||
private string _url = "";
|
||||
private string _contact = "";
|
||||
private string _license = "";
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_themeName = WebUtility.UrlDecode(PageState.QueryString["name"]);
|
||||
var themes = await ThemeService.GetThemesAsync();
|
||||
var theme = themes.FirstOrDefault(item => item.ThemeName == _themeName);
|
||||
if (theme != null)
|
||||
{
|
||||
_name = theme.Name;
|
||||
_version = theme.Version;
|
||||
_packagename = theme.PackageName;
|
||||
_owner = theme.Owner;
|
||||
_url = theme.Url;
|
||||
_contact = theme.Contact;
|
||||
_license = theme.License;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Theme.Loading"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -168,4 +168,13 @@
|
|||
<data name="PackageName.Text" xml:space="preserve">
|
||||
<value>Package Name:</value>
|
||||
</data>
|
||||
<data name="Information.Heading" xml:space="preserve">
|
||||
<value>Information</value>
|
||||
</data>
|
||||
<data name="IsEnabled.HelpText" xml:space="preserve">
|
||||
<value>Is theme enabled for this site?</value>
|
||||
</data>
|
||||
<data name="IsEnabled.Text" xml:space="preserve">
|
||||
<value>Enabled?</value>
|
||||
</data>
|
||||
</root>
|
|
@ -144,4 +144,7 @@
|
|||
<data name="ViewTheme.Text" xml:space="preserve">
|
||||
<value>View</value>
|
||||
</data>
|
||||
<data name="Enabled" xml:space="preserve">
|
||||
<value>Enabled?</value>
|
||||
</data>
|
||||
</root>
|
|
@ -16,6 +16,14 @@ namespace Oqtane.Services
|
|||
/// <returns></returns>
|
||||
Task<List<Theme>> GetThemesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a specific thenme
|
||||
/// </summary>
|
||||
/// <param name="themeId"></param>
|
||||
/// <param name="siteId"></param>
|
||||
/// <returns></returns>
|
||||
Task<Theme> GetThemeAsync(int themeId, int siteId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of <see cref="ThemeControl"/>s from the given themes
|
||||
/// </summary>
|
||||
|
@ -39,6 +47,13 @@ namespace Oqtane.Services
|
|||
/// <returns></returns>
|
||||
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
|
||||
|
||||
/// <summary>
|
||||
/// Updates a existing theem
|
||||
/// </summary>
|
||||
/// <param name="theme"></param>
|
||||
/// <returns></returns>
|
||||
Task UpdateThemeAsync(Theme theme);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a theme
|
||||
/// </summary>
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace Oqtane.Services
|
|||
List<Theme> themes = await GetJsonAsync<List<Theme>>(ApiUrl);
|
||||
return themes.OrderBy(item => item.Name).ToList();
|
||||
}
|
||||
public async Task<Theme> GetThemeAsync(int themeId, int siteId)
|
||||
{
|
||||
return await GetJsonAsync<Theme>($"{ApiUrl}/{themeId}?siteid={siteId}");
|
||||
}
|
||||
|
||||
public List<ThemeControl> GetThemeControls(List<Theme> themes)
|
||||
{
|
||||
|
@ -38,6 +42,11 @@ namespace Oqtane.Services
|
|||
.SelectMany(item => item.Containers).ToList();
|
||||
}
|
||||
|
||||
public async Task UpdateThemeAsync(Theme theme)
|
||||
{
|
||||
await PutJsonAsync($"{ApiUrl}/{theme.ThemeId}", theme);
|
||||
}
|
||||
|
||||
public async Task DeleteThemeAsync(string themeName)
|
||||
{
|
||||
await DeleteAsync($"{ApiUrl}/{themeName}");
|
||||
|
|
|
@ -256,7 +256,7 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
|
||||
// remove module definition
|
||||
_moduleDefinitions.DeleteModuleDefinition(id, siteid);
|
||||
_moduleDefinitions.DeleteModuleDefinition(id);
|
||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, SyncEventActions.Delete);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ using Oqtane.Infrastructure;
|
|||
using Oqtane.Repository;
|
||||
using System.Text.Json;
|
||||
using System.Net;
|
||||
using System.Reflection.Metadata;
|
||||
using System;
|
||||
|
||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||
|
||||
|
@ -23,14 +25,20 @@ namespace Oqtane.Controllers
|
|||
private readonly IThemeRepository _themes;
|
||||
private readonly IInstallationManager _installationManager;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
private readonly ITenantManager _tenantManager;
|
||||
private readonly ISyncManager _syncManager;
|
||||
private readonly ILogManager _logger;
|
||||
private readonly Alias _alias;
|
||||
|
||||
public ThemeController(IThemeRepository themes, IInstallationManager installationManager, IWebHostEnvironment environment, ILogManager logger)
|
||||
public ThemeController(IThemeRepository themes, IInstallationManager installationManager, IWebHostEnvironment environment, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
||||
{
|
||||
_themes = themes;
|
||||
_installationManager = installationManager;
|
||||
_environment = environment;
|
||||
_tenantManager = tenantManager;
|
||||
_syncManager = syncManager;
|
||||
_logger = logger;
|
||||
_alias = tenantManager.GetAlias();
|
||||
}
|
||||
|
||||
// GET: api/<controller>
|
||||
|
@ -41,6 +49,41 @@ namespace Oqtane.Controllers
|
|||
return _themes.GetThemes();
|
||||
}
|
||||
|
||||
// GET api/<controller>/5?siteid=x
|
||||
[HttpGet("{id}")]
|
||||
public Theme Get(int id, string siteid)
|
||||
{
|
||||
int SiteId;
|
||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
||||
{
|
||||
return _themes.GetTheme(id, SiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Theme Get Attempt {ThemeId} {SiteId}", id, siteid);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// PUT api/<controller>/5
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
public void Put(int id, [FromBody] Theme theme)
|
||||
{
|
||||
if (ModelState.IsValid && theme.SiteId == _alias.SiteId && _themes.GetTheme(theme.ThemeId,theme.SiteId) != null)
|
||||
{
|
||||
_themes.UpdateTheme(theme);
|
||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Theme, theme.ThemeId, SyncEventActions.Update);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Theme Updated {Theme}", theme);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Theme Put Attempt {Theme}", theme);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE api/<controller>/xxx
|
||||
[HttpDelete("{themename}")]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
|
@ -74,7 +117,7 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
|
||||
// remove theme
|
||||
_themes.DeleteTheme(theme.ThemeName);
|
||||
//_themes.DeleteTheme(theme.ThemeName);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Removed For {ThemeName}", theme.ThemeName);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
||||
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable UnusedAutoPropertyAccessor.Global
|
||||
|
||||
namespace Oqtane.Migrations.EntityBuilders
|
||||
{
|
||||
public class ThemeEntityBuilder : AuditableBaseEntityBuilder<ThemeEntityBuilder>
|
||||
{
|
||||
private const string _entityTableName = "Theme";
|
||||
private readonly PrimaryKey<ThemeEntityBuilder> _primaryKey = new("PK_Theme", x => x.ThemeId);
|
||||
|
||||
public ThemeEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database)
|
||||
{
|
||||
EntityTableName = _entityTableName;
|
||||
PrimaryKey = _primaryKey;
|
||||
}
|
||||
|
||||
protected override ThemeEntityBuilder BuildTable(ColumnsBuilder table)
|
||||
{
|
||||
ThemeId = AddAutoIncrementColumn(table, "ThemeId");
|
||||
ThemeName = AddStringColumn(table, "ThemeName", 200);
|
||||
|
||||
AddAuditableColumns(table);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public OperationBuilder<AddColumnOperation> ThemeId { get; private set; }
|
||||
|
||||
public OperationBuilder<AddColumnOperation> ThemeName { get; private set; }
|
||||
}
|
||||
}
|
28
Oqtane.Server/Migrations/Master/04000001_AddThemeTable.cs
Normal file
28
Oqtane.Server/Migrations/Master/04000001_AddThemeTable.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Oqtane.Databases.Interfaces;
|
||||
using Oqtane.Migrations.EntityBuilders;
|
||||
using Oqtane.Repository;
|
||||
|
||||
namespace Oqtane.Migrations.Master
|
||||
{
|
||||
[DbContext(typeof(MasterDBContext))]
|
||||
[Migration("Master.04.00.00.01")]
|
||||
public class AddThemeTable : MultiDatabaseMigration
|
||||
{
|
||||
public AddThemeTable(IDatabase database) : base(database)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
var themeEntityBuilder = new ThemeEntityBuilder(migrationBuilder, ActiveDatabase);
|
||||
themeEntityBuilder.Create();
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,6 +68,7 @@ namespace Oqtane.Repository
|
|||
public virtual DbSet<Job> Job { get; set; }
|
||||
public virtual DbSet<JobLog> JobLog { get; set; }
|
||||
public virtual DbSet<Setting> Setting { get; set; }
|
||||
public virtual DbSet<Theme> Theme { get; set; }
|
||||
|
||||
public override int SaveChanges()
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace Oqtane.Repository
|
|||
IEnumerable<ModuleDefinition> GetModuleDefinitions(int siteId);
|
||||
ModuleDefinition GetModuleDefinition(int moduleDefinitionId, int siteId);
|
||||
void UpdateModuleDefinition(ModuleDefinition moduleDefinition);
|
||||
void DeleteModuleDefinition(int moduleDefinitionId, int siteId);
|
||||
void DeleteModuleDefinition(int moduleDefinitionId);
|
||||
ModuleDefinition FilterModuleDefinition(ModuleDefinition moduleDefinition);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ namespace Oqtane.Repository
|
|||
public interface IThemeRepository
|
||||
{
|
||||
IEnumerable<Theme> GetThemes();
|
||||
Theme GetTheme(int themeId, int siteId);
|
||||
void UpdateTheme(Theme theme);
|
||||
void DeleteTheme(int themeId);
|
||||
List<Theme> FilterThemes(List<Theme> themes);
|
||||
void DeleteTheme(string ThemeName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Oqtane.Repository
|
|||
_cache.Remove($"moduledefinitions:{_tenants.GetAlias().SiteKey}");
|
||||
}
|
||||
|
||||
public void DeleteModuleDefinition(int moduleDefinitionId,int siteId)
|
||||
public void DeleteModuleDefinition(int moduleDefinitionId)
|
||||
{
|
||||
ModuleDefinition moduleDefinition = _db.ModuleDefinition.Find(moduleDefinitionId);
|
||||
_settings.DeleteSettings(EntityNames.ModuleDefinition, moduleDefinitionId);
|
||||
|
@ -126,48 +126,48 @@ namespace Oqtane.Repository
|
|||
private List<ModuleDefinition> ProcessModuleDefinitions(int siteId)
|
||||
{
|
||||
// get module assemblies
|
||||
List<ModuleDefinition> moduleDefinitions = LoadModuleDefinitionsFromAssemblies();
|
||||
List<ModuleDefinition> ModuleDefinitions = LoadModuleDefinitionsFromAssemblies();
|
||||
|
||||
// get module definitions in database
|
||||
List<ModuleDefinition> moduledefs = _db.ModuleDefinition.ToList();
|
||||
List<ModuleDefinition> moduledefinitions = _db.ModuleDefinition.ToList();
|
||||
|
||||
// sync module assemblies with database
|
||||
foreach (ModuleDefinition moduledefinition in moduleDefinitions)
|
||||
foreach (ModuleDefinition ModuleDefinition in ModuleDefinitions)
|
||||
{
|
||||
ModuleDefinition moduledef = moduledefs.Where(item => item.ModuleDefinitionName == moduledefinition.ModuleDefinitionName).FirstOrDefault();
|
||||
if (moduledef == null)
|
||||
ModuleDefinition moduledefinition = moduledefinitions.Where(item => item.ModuleDefinitionName == ModuleDefinition.ModuleDefinitionName).FirstOrDefault();
|
||||
if (moduledefinition == null)
|
||||
{
|
||||
// new module definition
|
||||
moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName };
|
||||
_db.ModuleDefinition.Add(moduledef);
|
||||
moduledefinition = new ModuleDefinition { ModuleDefinitionName = ModuleDefinition.ModuleDefinitionName };
|
||||
_db.ModuleDefinition.Add(moduledefinition);
|
||||
_db.SaveChanges();
|
||||
moduledefinition.Version = "";
|
||||
ModuleDefinition.Version = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
// override user customizable property values
|
||||
moduledefinition.Name = (!string.IsNullOrEmpty(moduledef.Name)) ? moduledef.Name : moduledefinition.Name;
|
||||
moduledefinition.Description = (!string.IsNullOrEmpty(moduledef.Description)) ? moduledef.Description : moduledefinition.Description;
|
||||
moduledefinition.Categories = (!string.IsNullOrEmpty(moduledef.Categories)) ? moduledef.Categories : moduledefinition.Categories;
|
||||
ModuleDefinition.Name = (!string.IsNullOrEmpty(moduledefinition.Name)) ? moduledefinition.Name : ModuleDefinition.Name;
|
||||
ModuleDefinition.Description = (!string.IsNullOrEmpty(moduledefinition.Description)) ? moduledefinition.Description : ModuleDefinition.Description;
|
||||
ModuleDefinition.Categories = (!string.IsNullOrEmpty(moduledefinition.Categories)) ? moduledefinition.Categories : ModuleDefinition.Categories;
|
||||
// manage releaseversions in cases where it was not provided or is lower than the module version
|
||||
if (string.IsNullOrEmpty(moduledefinition.ReleaseVersions) || Version.Parse(moduledefinition.Version).CompareTo(Version.Parse(moduledefinition.ReleaseVersions.Split(',').Last())) > 0)
|
||||
if (string.IsNullOrEmpty(ModuleDefinition.ReleaseVersions) || Version.Parse(ModuleDefinition.Version).CompareTo(Version.Parse(ModuleDefinition.ReleaseVersions.Split(',').Last())) > 0)
|
||||
{
|
||||
moduledefinition.ReleaseVersions = moduledefinition.Version;
|
||||
ModuleDefinition.ReleaseVersions = ModuleDefinition.Version;
|
||||
}
|
||||
moduledefinition.Version = moduledef.Version;
|
||||
ModuleDefinition.Version = moduledefinition.Version;
|
||||
// remove module definition from list as it is already synced
|
||||
moduledefs.Remove(moduledef);
|
||||
moduledefinitions.Remove(moduledefinition);
|
||||
}
|
||||
|
||||
moduledefinition.ModuleDefinitionId = moduledef.ModuleDefinitionId;
|
||||
moduledefinition.CreatedBy = moduledef.CreatedBy;
|
||||
moduledefinition.CreatedOn = moduledef.CreatedOn;
|
||||
moduledefinition.ModifiedBy = moduledef.ModifiedBy;
|
||||
moduledefinition.ModifiedOn = moduledef.ModifiedOn;
|
||||
ModuleDefinition.ModuleDefinitionId = moduledefinition.ModuleDefinitionId;
|
||||
ModuleDefinition.CreatedBy = moduledefinition.CreatedBy;
|
||||
ModuleDefinition.CreatedOn = moduledefinition.CreatedOn;
|
||||
ModuleDefinition.ModifiedBy = moduledefinition.ModifiedBy;
|
||||
ModuleDefinition.ModifiedOn = moduledefinition.ModifiedOn;
|
||||
}
|
||||
|
||||
// any remaining module definitions are orphans
|
||||
foreach (ModuleDefinition moduledefinition in moduledefs)
|
||||
foreach (ModuleDefinition moduledefinition in moduledefinitions)
|
||||
{
|
||||
_db.ModuleDefinition.Remove(moduledefinition); // delete
|
||||
_db.SaveChanges();
|
||||
|
@ -181,8 +181,8 @@ namespace Oqtane.Repository
|
|||
// get settings for site
|
||||
var settings = _settings.GetSettings(EntityNames.ModuleDefinition).ToList();
|
||||
|
||||
// populate module definition permissions
|
||||
foreach (ModuleDefinition moduledefinition in moduleDefinitions)
|
||||
// populate module definition site settings and permissions
|
||||
foreach (ModuleDefinition moduledefinition in ModuleDefinitions)
|
||||
{
|
||||
moduledefinition.SiteId = siteId;
|
||||
|
||||
|
@ -218,7 +218,7 @@ namespace Oqtane.Repository
|
|||
}
|
||||
|
||||
// clean up any orphaned permissions
|
||||
var ids = new HashSet<int>(moduleDefinitions.Select(item => item.ModuleDefinitionId));
|
||||
var ids = new HashSet<int>(ModuleDefinitions.Select(item => item.ModuleDefinitionId));
|
||||
foreach (var permission in permissions.Where(item => !ids.Contains(item.EntityId)))
|
||||
{
|
||||
try
|
||||
|
@ -232,7 +232,7 @@ namespace Oqtane.Repository
|
|||
}
|
||||
}
|
||||
|
||||
return moduleDefinitions;
|
||||
return ModuleDefinitions;
|
||||
}
|
||||
|
||||
private List<ModuleDefinition> LoadModuleDefinitionsFromAssemblies()
|
||||
|
|
|
@ -4,39 +4,168 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Security;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Themes;
|
||||
using System.Reflection.Metadata;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
{
|
||||
public class ThemeRepository : IThemeRepository
|
||||
{
|
||||
private MasterDBContext _db;
|
||||
private readonly IMemoryCache _cache;
|
||||
private readonly ITenantManager _tenants;
|
||||
private readonly ISettingRepository _settings;
|
||||
private readonly string settingprefix = "SiteEnabled:";
|
||||
|
||||
public ThemeRepository(IMemoryCache cache)
|
||||
public ThemeRepository(MasterDBContext context, IMemoryCache cache, ITenantManager tenants, ISettingRepository settings)
|
||||
{
|
||||
_db = context;
|
||||
_cache = cache;
|
||||
_tenants = tenants;
|
||||
_settings = settings;
|
||||
}
|
||||
|
||||
public IEnumerable<Theme> GetThemes()
|
||||
{
|
||||
return LoadThemes();
|
||||
// for consistency siteid should be passed in as parameter, but this would require breaking change
|
||||
return LoadThemes(_tenants.GetAlias().SiteId);
|
||||
}
|
||||
|
||||
private List<Theme> LoadThemes()
|
||||
public Theme GetTheme(int themeId, int siteId)
|
||||
{
|
||||
// get module definitions
|
||||
List<Theme> themes = _cache.GetOrCreate("themes", entry =>
|
||||
List<Theme> themes = LoadThemes(siteId);
|
||||
return themes.Find(item => item.ThemeId == themeId);
|
||||
}
|
||||
|
||||
public void UpdateTheme(Theme theme)
|
||||
{
|
||||
_db.Entry(theme).State = EntityState.Modified;
|
||||
_db.SaveChanges();
|
||||
|
||||
var settingname = $"{settingprefix}{_tenants.GetAlias().SiteKey}";
|
||||
var setting = _settings.GetSetting(EntityNames.Theme, theme.ThemeId, settingname);
|
||||
if (setting == null)
|
||||
{
|
||||
_settings.AddSetting(new Setting { EntityName = EntityNames.Theme, EntityId = theme.ThemeId, SettingName = settingname, SettingValue = theme.IsEnabled.ToString(), IsPrivate = true });
|
||||
}
|
||||
else
|
||||
{
|
||||
setting.SettingValue = theme.IsEnabled.ToString();
|
||||
_settings.UpdateSetting(setting);
|
||||
}
|
||||
|
||||
_cache.Remove($"themes:{_tenants.GetAlias().SiteKey}");
|
||||
}
|
||||
|
||||
public void DeleteTheme(int themeId)
|
||||
{
|
||||
Theme theme = _db.Theme.Find(themeId);
|
||||
_settings.DeleteSettings(EntityNames.Theme, themeId);
|
||||
_db.Theme.Remove(theme);
|
||||
_db.SaveChanges();
|
||||
_cache.Remove($"themes:{_tenants.GetAlias().SiteKey}");
|
||||
}
|
||||
|
||||
public List<Theme> FilterThemes(List<Theme> themes)
|
||||
{
|
||||
var Themes = new List<Theme>();
|
||||
|
||||
foreach (Theme theme in themes.Where(item => item.IsEnabled))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
private List<Theme> LoadThemes(int siteId)
|
||||
{
|
||||
// get themes
|
||||
List<Theme> themes = _cache.GetOrCreate($"themes:{_tenants.GetAlias().SiteKey}", entry =>
|
||||
{
|
||||
entry.SlidingExpiration = TimeSpan.FromMinutes(30);
|
||||
return LoadThemesFromAssemblies();
|
||||
return ProcessThemes(siteId);
|
||||
});
|
||||
|
||||
return themes;
|
||||
}
|
||||
|
||||
private List<Theme> ProcessThemes(int siteId)
|
||||
{
|
||||
// get themes
|
||||
List<Theme> Themes = LoadThemesFromAssemblies();
|
||||
|
||||
// get themes in database
|
||||
List<Theme> themes = _db.Theme.ToList();
|
||||
|
||||
// sync theme assemblies with database
|
||||
foreach (Theme Theme in Themes)
|
||||
{
|
||||
Theme theme = themes.Where(item => item.ThemeName == Theme.ThemeName).FirstOrDefault();
|
||||
if (theme == null)
|
||||
{
|
||||
// new theme
|
||||
theme = new Theme { ThemeName = Theme.ThemeName };
|
||||
_db.Theme.Add(theme);
|
||||
_db.SaveChanges();
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove theme from list as it is already synced
|
||||
themes.Remove(theme);
|
||||
}
|
||||
|
||||
Theme.ThemeId = theme.ThemeId;
|
||||
Theme.CreatedBy = theme.CreatedBy;
|
||||
Theme.CreatedOn = theme.CreatedOn;
|
||||
Theme.ModifiedBy = theme.ModifiedBy;
|
||||
Theme.ModifiedOn = theme.ModifiedOn;
|
||||
}
|
||||
|
||||
// any remaining themes are orphans
|
||||
foreach (Theme theme in themes)
|
||||
{
|
||||
_db.Theme.Remove(theme); // delete
|
||||
_db.SaveChanges();
|
||||
}
|
||||
|
||||
if (siteId != -1)
|
||||
{
|
||||
// get settings for site
|
||||
var settings = _settings.GetSettings(EntityNames.Theme).ToList();
|
||||
|
||||
// populate theme site settings
|
||||
foreach (Theme theme in Themes)
|
||||
{
|
||||
theme.SiteId = siteId;
|
||||
|
||||
var setting = settings.FirstOrDefault(item => item.EntityId == theme.ThemeId && item.SettingName == $"{settingprefix}{_tenants.GetAlias().SiteKey}");
|
||||
if (setting != null)
|
||||
{
|
||||
theme.IsEnabled = bool.Parse(setting.SettingValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
theme.IsEnabled = theme.IsAutoEnabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Themes;
|
||||
}
|
||||
|
||||
private List<Theme> LoadThemesFromAssemblies()
|
||||
{
|
||||
List<Theme> themes = new List<Theme>();
|
||||
|
@ -143,28 +272,5 @@ 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ namespace Oqtane.Models
|
|||
/// <summary>
|
||||
/// Information about a Theme in Oqtane.
|
||||
/// </summary>
|
||||
public class Theme
|
||||
public class Theme : ModelBase
|
||||
{
|
||||
public Theme()
|
||||
{
|
||||
|
@ -25,68 +25,81 @@ namespace Oqtane.Models
|
|||
Resources = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the <see cref="Theme"/>.
|
||||
/// </summary>
|
||||
public int ThemeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Full Namespace / Identifier of the Theme.
|
||||
/// </summary>
|
||||
public string ThemeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Nice Name of the Theme.
|
||||
/// </summary>
|
||||
// additional ITheme properties
|
||||
[NotMapped]
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Version as determined by the DLL / NuGet Package.
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string Version { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Author / Creator of the Theme.
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string Owner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URL (in NuGet) of the Theme
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Author Contact information
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string Contact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Theme License, like `MIT` etc.
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string License { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Theme Dependencies (DLLs) which the system will check if they exist
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public string Dependencies { get; set; }
|
||||
|
||||
|
||||
[NotMapped]
|
||||
public string ThemeSettingsType { get; set; } // added in 2.0.2
|
||||
|
||||
[NotMapped]
|
||||
public string ContainerSettingsType { get; set; } // added in 2.0.2
|
||||
|
||||
[NotMapped]
|
||||
public string PackageName { get; set; } // added in 2.1.0
|
||||
|
||||
[NotMapped]
|
||||
public List<Resource> Resources { get; set; } // added in 4.0.0
|
||||
|
||||
[NotMapped]
|
||||
public bool IsAutoEnabled { get; set; } = true; // added in 4.0.0
|
||||
|
||||
|
||||
// internal properties
|
||||
[NotMapped]
|
||||
public int SiteId { get; set; }
|
||||
[NotMapped]
|
||||
public bool IsEnabled { get; set; }
|
||||
[NotMapped]
|
||||
public string AssemblyName { get; set; }
|
||||
[NotMapped]
|
||||
public List<ThemeControl> Themes { get; set; }
|
||||
[NotMapped]
|
||||
public List<ThemeControl> Containers { get; set; }
|
||||
[NotMapped]
|
||||
public string Template { get; set; }
|
||||
|
||||
#region Obsolete Properties
|
||||
|
||||
[Obsolete("This property is obsolete. Use Themes instead.", false)]
|
||||
[NotMapped]
|
||||
public string ThemeControls { get; set; }
|
||||
[Obsolete("This property is obsolete. Use Layouts instead.", false)]
|
||||
[NotMapped]
|
||||
public string PaneLayouts { get; set; }
|
||||
[Obsolete("This property is obsolete. Use Containers instead.", false)]
|
||||
[NotMapped]
|
||||
public string ContainerControls { get; set; }
|
||||
[Obsolete("This property is obsolete.", false)]
|
||||
[NotMapped]
|
||||
public List<ThemeControl> Layouts { get; set; }
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace Oqtane.Shared
|
|||
public const string Setting = "Setting";
|
||||
public const string Site = "Site";
|
||||
public const string Tenant = "Tenant";
|
||||
public const string Theme = "Theme";
|
||||
public const string UrlMapping = "UrlMapping";
|
||||
public const string User = "User";
|
||||
public const string UserRole = "UserRole";
|
||||
|
|
Loading…
Reference in New Issue
Block a user