
Added support for friendly names and thumbnails in theme, layout, and container components. Added fallback support during loading for themes, layout, and containers.
542 lines
22 KiB
Plaintext
542 lines
22 KiB
Plaintext
@namespace Oqtane.Themes.Controls
|
|
@inherits ThemeControlBase
|
|
@attribute [OqtaneIgnore]
|
|
@inject NavigationManager NavigationManager
|
|
@inject IUserService UserService
|
|
@inject IModuleDefinitionService ModuleDefinitionService
|
|
@inject IThemeService ThemeService
|
|
@inject IModuleService ModuleService
|
|
@inject IPageService PageService
|
|
@inject IPageModuleService PageModuleService
|
|
@inject ILogService logger
|
|
@inject ISettingService SettingService
|
|
|
|
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
|
{
|
|
<div class="app-controlpanel" style="@_display">
|
|
|
|
<div class="@CardClass">
|
|
<div class="@HeaderClass">
|
|
<span class="font-weight-bold">Control Panel</span>
|
|
<button type="button" class="close" @onclick="HideControlPanel" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
<div class="@BodyClass">
|
|
|
|
@if (UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole))
|
|
{
|
|
<div class="row">
|
|
<div class="col">
|
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick=@(async () => Navigate("Admin"))>Admin Dashboard</button>
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="app-rule"/>
|
|
|
|
<div class="row">
|
|
<div class="col text-center">
|
|
<label class="control-label">Page Management: </label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick=@(async () => Navigate("Add"))>Add</button>
|
|
</div>
|
|
<div class="col">
|
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick=@(async () => Navigate("Edit"))>Edit</button>
|
|
</div>
|
|
<div class="col">
|
|
<button class="btn btn-danger btn-block mx-auto" @onclick="ConfirmDelete">Delete</button>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@if (_deleteConfirmation)
|
|
{
|
|
<div class="app-admin-modal">
|
|
<div class="modal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">Delete Page</h5>
|
|
<button type="button" class="close" @onclick="ConfirmDelete" aria-label="Close">×</button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p>Are You Sure You Want To Delete This Page?</p>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-danger" @onclick="DeletePage">Delete</button>
|
|
<button type="button" class="btn btn-secondary" @onclick="ConfirmDelete">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
<hr class="app-rule"/>
|
|
|
|
<div class="row">
|
|
<div class="col text-center">
|
|
<label for="Module" class="control-label">Module Management: </label>
|
|
<select class="form-control" @bind="@ModuleType">
|
|
<option value="new">Add New Module</option>
|
|
<option value="existing">Add Existing Module</option>
|
|
</select>
|
|
@if (ModuleType == "new")
|
|
{
|
|
@if (_moduleDefinitions != null)
|
|
{
|
|
<select class="form-control" @onchange="(e => CategoryChanged(e))">
|
|
@foreach (var category in _categories)
|
|
{
|
|
if (category == Category)
|
|
{
|
|
<option value="@category" selected>@category Modules</option>
|
|
}
|
|
else
|
|
{
|
|
<option value="@category">@category Modules</option>
|
|
}
|
|
}
|
|
</select>
|
|
<select class="form-control" @onchange="(e => ModuleChanged(e))">
|
|
@if (ModuleDefinitionName == "-")
|
|
{
|
|
<option value="-" selected><Select Module></option>
|
|
}
|
|
else
|
|
{
|
|
<option value="-"><Select Module></option>
|
|
}
|
|
@foreach (var moduledefinition in _moduleDefinitions)
|
|
{
|
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
|
|
{
|
|
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
|
}
|
|
}
|
|
</select>
|
|
@((MarkupString) Description)
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<select class="form-control" @onchange="(e => PageChanged(e))">
|
|
<option value="-"><Select Page></option>
|
|
@foreach (Page p in _pages)
|
|
{
|
|
<option value="@p.PageId">@p.Name</option>
|
|
}
|
|
</select>
|
|
<select class="form-control" @bind="@ModuleId">
|
|
<option value="-"><Select Module></option>
|
|
@foreach (Module module in _modules)
|
|
{
|
|
<option value="@module.ModuleId">@module.Title</option>
|
|
}
|
|
</select>
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col text-center">
|
|
<label for="Title" class="control-label">Title: </label>
|
|
<input type="text" name="Title" class="form-control" @bind="@Title"/>
|
|
</div>
|
|
</div>
|
|
@if (_pane.Length > 1)
|
|
{
|
|
<div class="row">
|
|
<div class="col text-center">
|
|
<label for="Pane" class="control-label">Pane: </label>
|
|
<select class="form-control" @bind="@Pane">
|
|
@foreach (string pane in PageState.Page.Panes)
|
|
{
|
|
<option value="@pane">@pane Pane</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div class="row">
|
|
<div class="col text-center">
|
|
<label for="Container" class="control-label">Container: </label>
|
|
<select class="form-control" @bind="@ContainerType">
|
|
@foreach (var container in _containers)
|
|
{
|
|
<option value="@container.TypeName">@container.Name</option>
|
|
}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<br/>
|
|
|
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">Add Module To Page</button>
|
|
@((MarkupString) Message)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
|
|
{
|
|
@if (PageState.Page.EditMode)
|
|
{
|
|
<button type="button" class="btn @ButtonClass active" aria-pressed="true" autocomplete="off">
|
|
<span class="oi oi-pencil"></span>
|
|
</button>
|
|
}
|
|
else
|
|
{
|
|
if (PageState.EditMode)
|
|
{
|
|
<button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
|
<span class="oi oi-pencil"></span>
|
|
</button>
|
|
}
|
|
else
|
|
{
|
|
<button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
|
<span class="oi oi-pencil"></span>
|
|
</button>
|
|
}
|
|
}
|
|
}
|
|
|
|
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
|
{
|
|
<button type="button" class="btn @ButtonClass" @onclick="ShowControlPanel">
|
|
<span class="oi oi-cog"></span>
|
|
</button>
|
|
}
|
|
|
|
@code{
|
|
|
|
private bool _deleteConfirmation = false;
|
|
private List<string> _categories = new List<string>();
|
|
private List<ModuleDefinition> _allModuleDefinitions;
|
|
private List<ModuleDefinition> _moduleDefinitions;
|
|
private List<Page> _pages = new List<Page>();
|
|
private List<Module> _modules = new List<Module>();
|
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
|
private string _display = "display: none;";
|
|
private string _category = "Common";
|
|
|
|
protected string PageId { get; private set; } = "-";
|
|
protected string ModuleId { get; private set; } = "-";
|
|
protected string ModuleType { get; private set; } = "new";
|
|
protected string ModuleDefinitionName { get; private set; } = "-";
|
|
|
|
protected string Category
|
|
{
|
|
get => _category;
|
|
private set
|
|
{
|
|
if (_category != value)
|
|
{
|
|
_category = value;
|
|
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
|
ModuleDefinitionName = "-";
|
|
Description = "";
|
|
StateHasChanged();
|
|
_ = UpdateSettingsAsync();
|
|
}
|
|
}
|
|
}
|
|
|
|
protected string Pane
|
|
{
|
|
get => _pane;
|
|
private set
|
|
{
|
|
if (_pane != value)
|
|
{
|
|
_pane = value;
|
|
_ = UpdateSettingsAsync();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
protected string Description { get; private set; } = "";
|
|
|
|
protected string Title { get; private set; } = "";
|
|
protected string ContainerType { get; private set; } = "";
|
|
protected string Message { get; private set; } = "";
|
|
|
|
[Parameter]
|
|
public string ButtonClass { get; set; } = "btn-outline-secondary";
|
|
|
|
[Parameter]
|
|
public string CardClass { get; set; } = "card border-secondary mb-3";
|
|
|
|
[Parameter]
|
|
public string HeaderClass { get; set; } = "card-header";
|
|
|
|
[Parameter]
|
|
public string BodyClass { get; set; } = "card-body";
|
|
|
|
|
|
protected override async Task OnInitializedAsync()
|
|
{
|
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
|
{
|
|
_pages?.Clear();
|
|
|
|
foreach (Page p in PageState.Pages)
|
|
{
|
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
|
{
|
|
_pages.Add(p);
|
|
}
|
|
}
|
|
await LoadSettingsAsync();
|
|
|
|
var themes = await ThemeService.GetThemesAsync();
|
|
_containers = ThemeService.GetContainerControls(themes, PageState.Page.ThemeType);
|
|
ContainerType = PageState.Site.DefaultContainerType;
|
|
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
|
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
|
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
|
|
}
|
|
}
|
|
|
|
private void CategoryChanged(ChangeEventArgs e)
|
|
{
|
|
Category = (string) e.Value;
|
|
}
|
|
|
|
private void ModuleChanged(ChangeEventArgs e)
|
|
{
|
|
ModuleDefinitionName = (string) e.Value;
|
|
if (ModuleDefinitionName != "-")
|
|
{
|
|
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName);
|
|
Description = "<br /><div class=\"alert alert-info\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
|
}
|
|
else
|
|
{
|
|
Description = "";
|
|
}
|
|
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void PageChanged(ChangeEventArgs e)
|
|
{
|
|
PageId = (string) e.Value;
|
|
if (PageId != "-")
|
|
{
|
|
_modules = PageState.Modules
|
|
.Where(module => module.PageId == int.Parse(PageId)
|
|
&& !module.IsDeleted
|
|
&& UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
|
.ToList();
|
|
}
|
|
ModuleId = "-";
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task AddModule()
|
|
{
|
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
|
{
|
|
if ((ModuleType == "new" && ModuleDefinitionName != "-") || (ModuleType != "new" && ModuleId != "-"))
|
|
{
|
|
if (ModuleType == "new")
|
|
{
|
|
Module module = new Module();
|
|
module.SiteId = PageState.Site.SiteId;
|
|
module.PageId = PageState.Page.PageId;
|
|
module.ModuleDefinitionName = ModuleDefinitionName;
|
|
module.AllPages = false;
|
|
module.Permissions = PageState.Page.Permissions;
|
|
module = await ModuleService.AddModuleAsync(module);
|
|
ModuleId = module.ModuleId.ToString();
|
|
}
|
|
|
|
var pageModule = new PageModule
|
|
{
|
|
PageId = PageState.Page.PageId,
|
|
ModuleId = int.Parse(ModuleId),
|
|
Title = Title
|
|
};
|
|
if (pageModule.Title == "")
|
|
{
|
|
if (ModuleType == "new")
|
|
{
|
|
pageModule.Title = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName)?.Name;
|
|
}
|
|
else
|
|
{
|
|
pageModule.Title = _modules.FirstOrDefault(item => item.ModuleId == int.Parse(ModuleId))?.Title;
|
|
}
|
|
}
|
|
|
|
pageModule.Pane = Pane;
|
|
pageModule.Order = int.MaxValue;
|
|
pageModule.ContainerType = ContainerType;
|
|
|
|
if (pageModule.ContainerType == PageState.Site.DefaultContainerType)
|
|
{
|
|
pageModule.ContainerType = "";
|
|
}
|
|
|
|
await PageModuleService.AddPageModuleAsync(pageModule);
|
|
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
|
|
|
Message = "<br /><div class=\"alert alert-success\" role=\"alert\">Module Added To Page</div>";
|
|
NavigationManager.NavigateTo(NavigateUrl());
|
|
}
|
|
else
|
|
{
|
|
Message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select A Module</div>";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Message = "<br /><div class=\"alert alert-error\" role=\"alert\">Not Authorized</div>";
|
|
}
|
|
}
|
|
|
|
private async Task ToggleEditMode(bool EditMode)
|
|
{
|
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
|
{
|
|
if (EditMode)
|
|
{
|
|
PageState.EditMode = false;
|
|
}
|
|
else
|
|
{
|
|
PageState.EditMode = true;
|
|
}
|
|
|
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
|
}
|
|
else
|
|
{
|
|
if (PageState.Page.IsPersonalizable && PageState.User != null)
|
|
{
|
|
await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
|
PageState.EditMode = true;
|
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ShowControlPanel()
|
|
{
|
|
Message = "";
|
|
_display = "width: 25%; min-width: 375px;";
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void HideControlPanel()
|
|
{
|
|
Message = "";
|
|
_display = "width: 0%;";
|
|
StateHasChanged();
|
|
}
|
|
|
|
private void Navigate(string location)
|
|
{
|
|
HideControlPanel();
|
|
Module module;
|
|
switch (location)
|
|
{
|
|
case "Admin":
|
|
// get admin dashboard moduleid
|
|
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.AdminDashboardModule);
|
|
|
|
if (module != null)
|
|
{
|
|
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, module.ModuleId, "Index", ""));
|
|
}
|
|
|
|
break;
|
|
case "Add":
|
|
case "Edit":
|
|
string url = "";
|
|
// get page management moduleid
|
|
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.PageManagementModule);
|
|
|
|
if (module != null)
|
|
{
|
|
switch (location)
|
|
{
|
|
case "Add":
|
|
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "");
|
|
break;
|
|
case "Edit":
|
|
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "id=" + PageState.Page.PageId.ToString());
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (url != "")
|
|
{
|
|
NavigationManager.NavigateTo(url);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ConfirmDelete()
|
|
{
|
|
_deleteConfirmation = !_deleteConfirmation;
|
|
StateHasChanged();
|
|
}
|
|
|
|
private async Task DeletePage()
|
|
{
|
|
ConfirmDelete();
|
|
|
|
var page = PageState.Page;
|
|
try
|
|
{
|
|
if (page.UserId == null)
|
|
{
|
|
page.IsDeleted = true;
|
|
await PageService.UpdatePageAsync(page);
|
|
await logger.Log(page.PageId, null, PageState.User.UserId, GetType().AssemblyQualifiedName, "ControlPanel", LogFunction.Delete, LogLevel.Information, null, "Page Deleted {Page}", page);
|
|
NavigationManager.NavigateTo(NavigateUrl(""));
|
|
}
|
|
else // personalized page
|
|
{
|
|
await PageService.DeletePageAsync(page.PageId);
|
|
await logger.Log(page.PageId, null, PageState.User.UserId, GetType().AssemblyQualifiedName, "ControlPanel", LogFunction.Delete, LogLevel.Information, null, "Page Deleted {Page}", page);
|
|
NavigationManager.NavigateTo(NavigateUrl());
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await logger.Log(page.PageId, null, PageState.User.UserId, GetType().AssemblyQualifiedName, "ControlPanel", LogFunction.Delete, LogLevel.Information, ex, "Page Deleted {Page} {Error}", page, ex.Message);
|
|
}
|
|
}
|
|
|
|
private string settingCategory = "CP-category";
|
|
private string settingPane = "CP-pane";
|
|
private string _pane = "";
|
|
|
|
private async Task LoadSettingsAsync()
|
|
{
|
|
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
|
_category = SettingService.GetSetting(settings, settingCategory, "Common");
|
|
var pane = SettingService.GetSetting(settings, settingPane, "");
|
|
_pane = PageState.Page.Panes.Contains(pane) ? pane : PageState.Page.Panes.FirstOrDefault();
|
|
}
|
|
|
|
private async Task UpdateSettingsAsync()
|
|
{
|
|
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
|
SettingService.SetSetting(settings, settingCategory, _category);
|
|
SettingService.SetSetting(settings, settingPane, _pane);
|
|
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
|
}
|
|
|
|
}
|