diff --git a/Oqtane.Client/App.razor b/Oqtane.Client/App.razor index c36313bb..701faf81 100644 --- a/Oqtane.Client/App.razor +++ b/Oqtane.Client/App.razor @@ -1,6 +1,8 @@ +@using Microsoft.AspNetCore.Http @inject IInstallationService InstallationService @inject IJSRuntime JSRuntime @inject SiteState SiteState +@inject IServiceProvider ServiceProvider @if (_initialized) { @@ -30,35 +32,47 @@ } @code { - [Parameter] - public string AntiForgeryToken { get; set; } + [Parameter] + public string AntiForgeryToken { get; set; } - [Parameter] - public string Runtime { get; set; } + [Parameter] + public string Runtime { get; set; } - [Parameter] - public string RenderMode { get; set; } + [Parameter] + public string RenderMode { get; set; } - [Parameter] - public int VisitorId { get; set; } + [Parameter] + public int VisitorId { get; set; } - [Parameter] - public string RemoteIPAddress { get; set; } + [Parameter] + public string RemoteIPAddress { get; set; } - [Parameter] - public string AuthorizationToken { get; set; } + [Parameter] + public string AuthorizationToken { get; set; } - private bool _initialized = false; - private string _display = "display: none;"; - private Installation _installation = new Installation { Success = false, Message = "" }; + private bool _initialized = false; + private string _display = "display: none;"; + private Installation _installation = new Installation { Success = false, Message = "" }; - private PageState PageState { get; set; } + private PageState PageState { get; set; } - protected override async Task OnParametersSetAsync() - { - SiteState.RemoteIPAddress = RemoteIPAddress; - SiteState.AntiForgeryToken = AntiForgeryToken; - SiteState.AuthorizationToken = AuthorizationToken; + private IHttpContextAccessor accessor; + + protected override async Task OnParametersSetAsync() + { + SiteState.RemoteIPAddress = RemoteIPAddress; + SiteState.AntiForgeryToken = AntiForgeryToken; + SiteState.AuthorizationToken = AuthorizationToken; + + accessor = (IHttpContextAccessor)ServiceProvider.GetService(typeof(IHttpContextAccessor)); + if (accessor != null) + { + SiteState.IsPrerendering = !accessor.HttpContext.Response.HasStarted; + } + else + { + SiteState.IsPrerendering = true; + } _installation = await InstallationService.IsInstalled(); if (_installation.Alias != null) @@ -72,6 +86,7 @@ { if (firstRender) { + // prevents flash on initial page load _display = ""; StateHasChanged(); } diff --git a/Oqtane.Client/Head.razor b/Oqtane.Client/Head.razor new file mode 100644 index 00000000..18207178 --- /dev/null +++ b/Oqtane.Client/Head.razor @@ -0,0 +1,64 @@ +@using System.ComponentModel +@using Oqtane.Shared +@inject SiteState SiteState + +@if (!string.IsNullOrEmpty(_title)) +{ + @((MarkupString)_title) +} +@if (!string.IsNullOrEmpty(_content)) +{ + @((MarkupString)_content) +} + +@code { + private string _title = ""; + private string _content = ""; + + protected override void OnInitialized() + { + ((INotifyPropertyChanged)SiteState.Properties).PropertyChanged += PropertyChanged; + } + + private void PropertyChanged(object sender, PropertyChangedEventArgs e) + { + switch (e.PropertyName) + { + case "PageTitle": + var title = "\n" + SiteState.Properties.PageTitle + ""; + if (title != _title) + { + _title = title; + StateHasChanged(); + } + break; + case "HeadContent": + var content = RemoveScripts(SiteState.Properties.HeadContent) + "\n"; + if (content != _content) + { + _content = content; + StateHasChanged(); + } + break; + } + } + + private string RemoveScripts(string headcontent) + { + if (!string.IsNullOrEmpty(headcontent)) + { + var index = headcontent.IndexOf("= 0) + { + headcontent = headcontent.Remove(index, headcontent.IndexOf("") + 9 - index); + index = headcontent.IndexOf(" Localizer @inject IStringLocalizer SharedLocalizer +@inject SiteState SiteState
-
@SharedLocalizer["Version"] @Constants.Version
+
@SharedLocalizer["Version"] @Constants.Version (.NET 7)

@@ -61,7 +63,7 @@
} - +

@Localizer["ApplicationAdmin"]


@@ -96,6 +98,20 @@
+
+ +
+ @if (_templates != null) + { + + } +
+
@@ -103,7 +119,13 @@


- + @if (!string.IsNullOrEmpty(_message)) + { + + }
@@ -115,29 +137,35 @@ @code { - private List _databases; - private string _databaseName; - private Type _databaseConfigType; - private object _databaseConfig; - private RenderFragment DatabaseConfigComponent { get; set; } - private bool _showConnectionString = false; - private string _connectionString = string.Empty; + private List _databases; + private string _databaseName; + private Type _databaseConfigType; + private object _databaseConfig; + private RenderFragment DatabaseConfigComponent { get; set; } + private bool _showConnectionString = false; + private string _connectionString = string.Empty; - private string _hostUsername = string.Empty; - private string _hostPassword = string.Empty; - private string _passwordType = "password"; - private string _confirmPasswordType = "password"; - private string _togglePassword = string.Empty; - private string _toggleConfirmPassword = string.Empty; - private string _confirmPassword = string.Empty; - private string _hostEmail = string.Empty; - private bool _register = true; + private string _hostUsername = string.Empty; + private string _hostPassword = string.Empty; + private string _passwordType = "password"; + private string _confirmPasswordType = "password"; + private string _togglePassword = string.Empty; + private string _toggleConfirmPassword = string.Empty; + private string _confirmPassword = string.Empty; + private string _hostEmail = string.Empty; + private List _templates; + private string _template = Constants.DefaultSiteTemplate; + private bool _register = true; private string _message = string.Empty; private string _loadingDisplay = "display: none;"; protected override async Task OnInitializedAsync() { - _togglePassword = SharedLocalizer["ShowPassword"]; + // include CSS + var content = ""; + SiteState.AppendHeadContent(content); + + _togglePassword = SharedLocalizer["ShowPassword"]; _toggleConfirmPassword = SharedLocalizer["ShowPassword"]; _databases = await DatabaseService.GetDatabasesAsync(); @@ -150,7 +178,9 @@ _databaseName = "LocalDB"; } LoadDatabaseConfigComponent(); - } + + _templates = await SiteTemplateService.GetSiteTemplatesAsync(); + } private void DatabaseChanged(ChangeEventArgs eventArgs) { @@ -185,9 +215,9 @@ { if (firstRender) { + // include JavaScript var interop = new Interop(JSRuntime); - await interop.IncludeLink("", "stylesheet", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/css/bootstrap.min.css", "text/css", "sha512-XWTTruHZEYJsxV3W/lSXG1n3Q39YIWOstqvmFsdNEEQfHoZ6vm6E9GK2OrF6DSJSpIbRbi+Nn0WDPID9O7xB2Q==", "anonymous", ""); - await interop.IncludeScript("", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/js/bootstrap.bundle.min.js", "sha512-9GacT4119eY3AcosfWtHMsT5JyZudrexyEVzTBWV3viP/YfB9e2pEy3N7WXL3SV6ASXpTU0vzzSxsbfsuUH4sQ==", "anonymous", "", "head"); + await interop.IncludeScript("", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js", "sha512-VK2zcvntEufaimc+efOYi622VN5ZacdnufnmX7zIhCPmjhKnOi9ZDMtg1/ug5l183f19gG1/cBstPO4D8N/Img==", "anonymous", "", "head"); } } @@ -229,7 +259,8 @@ TenantName = TenantNames.Master, IsNewTenant = true, SiteName = Constants.DefaultSite, - Register = _register + Register = _register, + SiteTemplate = _template }; var installation = await InstallationService.Install(config); @@ -291,4 +322,9 @@ _showConnectionString = !_showConnectionString; } + private void DismissModal() + { + _message = ""; + StateHasChanged(); + } } diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index bd5689f6..6785292a 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -195,7 +195,7 @@ else if (_owner != "" && _module != "" && _template != "-") { var template = _templates.FirstOrDefault(item => item.Name == _template); - _location = template.Location + _owner + "." + _module; + _location = template.Location + _owner + ".Module." + _module; } StateHasChanged(); diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index a209342e..d030299c 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -33,7 +33,16 @@ - +
+ +
+ +
+
+
@@ -199,6 +208,7 @@ private string _name; private string _description = ""; private string _categories; + private string _isenabled; private string _moduledefinitionname = ""; private string _version; private string _packagename = ""; @@ -234,6 +244,7 @@ _name = moduleDefinition.Name; _description = moduleDefinition.Description; _categories = moduleDefinition.Categories; + _isenabled = moduleDefinition.IsEnabled.ToString(); _moduledefinitionname = moduleDefinition.ModuleDefinitionName; _version = moduleDefinition.Version; _packagename = moduleDefinition.PackageName; @@ -297,6 +308,7 @@ { moduledefinition.Categories = _categories; } + moduledefinition.IsEnabled = (_isenabled == null ? true : bool.Parse(_isenabled)); moduledefinition.PermissionList = _permissionGrid.GetPermissionList(); await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition); await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition); diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index 1df05879..ff9a96cc 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -43,6 +43,7 @@ else   @SharedLocalizer["Name"] @SharedLocalizer["Version"] + @Localizer["Enabled"] @Localizer["InUse"] @SharedLocalizer["Expires"]   @@ -57,6 +58,16 @@ else @context.Name @context.Version + + @if (context.IsEnabled) + { + @SharedLocalizer["Yes"] + } + else + { + @SharedLocalizer["No"] + } + @if (context.AssemblyName == Constants.ClientId || PageState.Modules.Where(m => m.ModuleDefinition?.ModuleDefinitionId == context.ModuleDefinitionId).FirstOrDefault() != null) { diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index 68df3167..a3133216 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -44,12 +44,20 @@
@@ -90,37 +98,35 @@ @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 _themes; - private List _containers = new List(); - private string _title; - private string _containerType; - private string _allPages = "false"; - private string _permissionNames = ""; - private List _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 _containers = new List(); + private string _title; + private string _containerType; + private string _allPages = "false"; + private string _permissionNames = ""; + private List _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; @@ -165,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); diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index ae722343..5832f45d 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -6,12 +6,11 @@ @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer - -
- - - @if (_themeList != null) - { +@if (_initialized) +{ + + +
@@ -19,42 +18,67 @@
-
- -
- -
-
-
- -
- - @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) - { - + + @foreach (Page page in PageState.Pages) { - + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, page.PermissionList)) + { + + } } - } +
-
+
+ +
+ + @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) + { + + } +
+
+ } + else + { +
+ +
+ +
+
+
+ +
+ +
+
+ }
@@ -85,9 +109,24 @@
+
+ +
+ +
+
+
+ +
+ +
+
-
+
@@ -95,16 +134,10 @@
-
- -
- -
-
- @foreach (var theme in _themes) { @@ -116,7 +149,6 @@
+
+
+
+
- +
- +
- +
- +
- } - - -
-
- -
-
-
- @if (_themeSettingsType != null) - { - - @ThemeSettingsComponent - } - -
- - - + +
+
+ +
+
+
+ @if (_themeSettingsType != null) + { + + @ThemeSettingsComponent + + } + +
+ + + +} @code { - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; - private List _themeList; - private List _themes = new List(); - private List _containers = new List(); - private string _name; - private string _title; - private string _meta; - private string _path = string.Empty; - private string _parentid = "-1"; - private string _insert = ">>"; - private List _children; - private int _childid = -1; - private string _isnavigation = "True"; - private string _isclickable = "True"; - private string _url; - private string _ispersonalizable = "False"; - private string _themetype = string.Empty; - private string _containertype = string.Empty; - private string _icon = string.Empty; - private string _permissions = null; - private PermissionGrid _permissionGrid; - private Type _themeSettingsType; - private object _themeSettings; - private RenderFragment ThemeSettingsComponent { get; set; } - private bool _refresh = false; - private ElementReference form; - private bool validated = false; + private bool _initialized = false; + private ElementReference form; + private bool validated = false; + private List _themes = new List(); + private List _containers = new List(); + private int _pageId; + private string _name; + private string _parentid = "-1"; + private string _insert = ">>"; + private List _children; + private int _childid = -1; + private string _isnavigation = "True"; + private string _isclickable = "True"; + private string _path = string.Empty; + private string _url; + private string _ispersonalizable = "False"; + private string _title; + private string _icon = string.Empty; + private string _themetype = string.Empty; + private string _containertype = string.Empty; + private string _headcontent; + private string _bodycontent; + private string _permissions = null; + private PermissionGrid _permissionGrid; + private Type _themeSettingsType; + private object _themeSettings; + private RenderFragment ThemeSettingsComponent { get; set; } + private bool _refresh = false; + protected Page _parent = null; - protected override async Task OnInitializedAsync() - { - try - { - _themeList = await ThemeService.GetThemesAsync(); - _themes = ThemeService.GetThemeControls(_themeList); - _themetype = PageState.Site.DefaultThemeType; - _containers = ThemeService.GetContainerControls(_themeList, _themetype); - _containertype = PageState.Site.DefaultContainerType; - _children = PageState.Pages.Where(item => item.ParentId == null).ToList(); - ThemeSettings(); - } + protected override async Task OnInitializedAsync() + { + try + { + if (PageState.QueryString.ContainsKey("id")) + { + _pageId = Int32.Parse(PageState.QueryString["id"]); + _parent = await PageService.GetPageAsync(_pageId); + if (_parent != null) + { + _parentid = _parent.PageId.ToString(); + } + } + + // if admin or user has edit access to parent page + if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin) || (_parent != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _parent.PermissionList))) + { + _themetype = PageState.Site.DefaultThemeType; + _themes = ThemeService.GetThemeControls(PageState.Site.Themes, _themetype); + _containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype); + _containertype = PageState.Site.DefaultContainerType; + _children = PageState.Pages.Where(item => item.ParentId == null).ToList(); + ThemeSettings(); + _initialized = true; + } + else + { + await logger.LogWarning("Error Loading Page {ParentId}", _parentid); + AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error); + } + } catch (Exception ex) { - await logger.LogError(ex, "Error Initializing Page {Error}", ex.Message); - AddModuleMessage(Localizer["Error.Page.Initialize"], MessageType.Error); + await logger.LogError(ex, "Error Loading Page {Error}", ex.Message); + AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error); } } @@ -246,27 +301,10 @@ } } - private async void ThemeChanged(ChangeEventArgs e) - { - try - { - _themetype = (string)e.Value; - _containers = ThemeService.GetContainerControls(_themeList, _themetype); - _containertype = "-"; - ThemeSettings(); - StateHasChanged(); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); - AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error); - } - } - 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); @@ -292,12 +330,11 @@ Page page = null; try { - if (!string.IsNullOrEmpty(_themetype) && _containertype != "-") + if (!string.IsNullOrEmpty(_themetype) && !string.IsNullOrEmpty(_containertype)) { page = new Page(); page.SiteId = PageState.Page.SiteId; page.Name = _name; - page.Title = _title; if (string.IsNullOrEmpty(_path)) { @@ -365,34 +402,42 @@ page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation)); page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable)); - page.Url = _url; - page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; + page.Url = _url; + page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable)); + page.UserId = null; + + // appearance + page.Title = _title; + page.Icon = (_icon == null ? string.Empty : _icon); + page.ThemeType = _themetype; if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) { page.ThemeType = string.Empty; } - page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty; + page.DefaultContainerType = _containertype; if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType) { page.DefaultContainerType = string.Empty; } - page.Icon = (_icon == null ? string.Empty : _icon); + + // page content + page.HeadContent = _headcontent; + page.BodyContent = _bodycontent; + + // permissions page.PermissionList = _permissionGrid.GetPermissionList(); - page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable)); - page.UserId = null; - page.Meta = _meta; page = await PageService.AddPageAsync(page); await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId); await logger.LogInformation("Page Added {Page}", page); - if (PageState.QueryString.ContainsKey("cp")) + if (!string.IsNullOrEmpty(PageState.ReturnUrl)) { - NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + NavigationManager.NavigateTo(page.Path); // redirect to new page } else { - NavigationManager.NavigateTo(NavigateUrl(page.Path)); + NavigationManager.NavigateTo(NavigateUrl()); // redirect to page management } } else @@ -415,9 +460,9 @@ private void Cancel() { - if (PageState.QueryString.ContainsKey("cp")) + if (!string.IsNullOrEmpty(PageState.ReturnUrl)) { - NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + NavigationManager.NavigateTo(PageState.ReturnUrl); } else { diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 4f0c1166..f77c3970 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -8,133 +8,123 @@ @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer -
- - - @if (_themeList != null) - { -
-
- -
- -
-
-
- -
- -
-
-
- -
- - @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) - { - - } -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
+@if (_initialized) +{ + + @if (_page.UserId == null) + { + +
- +
- +
-
- -
- + @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) + { +
+ +
+ +
-
-
- -
- + @if (_parentid == _currentparentid) + { + + } + + @if (_children != null && _children.Count > 0) + { + + + } + + + @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) { - + } +
+
+ } + else + { +
+ +
+ +
+
+
+ +
+ +
+
+ } +
+ +
+
- +
- + +
+
+ +
+ +
+
+
+ +
+ +
+
- +
@@ -147,382 +137,470 @@
-
-
-
- - } -
- - @if (_permissions != null) - { -
-
- +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+ + + +
+
+ +
-
- } - - - @if(_pageModules != null) - { - -
+ + + +
    @Localizer["ModuleTitle"] @Localizer["ModuleDefinition"] -
- - - - @context.Title - @context.ModuleDefinition?.Name - -
- } -
- @if (_themeSettingsType != null) - { - - @ThemeSettingsComponent - -
+
+ + + + @context.Title + @context.ModuleDefinition?.Name + +
+
+ @if (_themeSettingsType != null) + { + + @ThemeSettingsComponent + +
+ } + } - -
- - - + else + { + + +
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ @if (_themeSettingsType != null) + { + + @ThemeSettingsComponent + +
+ } +
+ } +
+ + + +} @code { - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; - private ElementReference form; - private bool validated = false; - private List _themeList; - private List _themes = new List(); - private List _containers = new List(); - private List _pageModules; - private int _pageId; - private string _name; - private string _title; - private string _meta; - private string _path; - private string _currentparentid; - private string _parentid = "-1"; - private string _insert = "="; - private List _children; - private int _childid = -1; - private string _isnavigation; - private string _isclickable; - private string _url; - private string _ispersonalizable; - private string _themetype; - private string _containertype = "-"; - private string _icon; - private List _permissions = null; - private string _createdby; - private DateTime _createdon; - private string _modifiedby; - private DateTime _modifiedon; - private string _deletedby; - private DateTime? _deletedon; - private PermissionGrid _permissionGrid; - private Type _themeSettingsType; - private object _themeSettings; - private RenderFragment ThemeSettingsComponent { get; set; } - private bool _refresh = false; - protected Page page; + private bool _initialized = false; + private ElementReference form; + private bool validated = false; + private List _themes = new List(); + private List _containers = new List(); + private int _pageId; + private string _name; + private string _currentparentid; + private string _parentid = "-1"; + private string _insert = "="; + private List _children; + private int _childid = -1; + private string _isnavigation; + private string _isclickable; + private string _path; + private string _url; + private string _ispersonalizable; + private string _title; + private string _icon; + private string _themetype; + private string _containertype = "-"; + private Type _themeSettingsType; + private object _themeSettings; + private RenderFragment ThemeSettingsComponent { get; set; } + private string _headcontent; + private string _bodycontent; + private List _permissions = null; + private PermissionGrid _permissionGrid; + private List _pageModules; + private string _createdby; + private DateTime _createdon; + private string _modifiedby; + private DateTime _modifiedon; + private string _deletedby; + private DateTime? _deletedon; + private bool _refresh = false; + protected Page _page = null; + protected Page _parent = null; - protected override async Task OnInitializedAsync() - { - try - { - _children = PageState.Pages.Where(item => item.ParentId == null).ToList(); - _themeList = await ThemeService.GetThemesAsync(); - _themes = ThemeService.GetThemeControls(_themeList); + protected override async Task OnInitializedAsync() + { + try + { + _children = PageState.Pages.Where(item => item.ParentId == null).ToList(); + _pageId = Int32.Parse(PageState.QueryString["id"]); + _page = await PageService.GetPageAsync(_pageId); - _pageId = Int32.Parse(PageState.QueryString["id"]); - page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId); - - if (page != null) - { - _name = page.Name; - _title = page.Title; - _meta = page.Meta; - _path = page.Path; - _pageModules = PageState.Modules.Where(m => m.PageId == page.PageId).ToList(); - - if (string.IsNullOrEmpty(_path)) - { - _path = "/"; - } - else - { - if (_path.Contains("/")) - { - _path = _path.Substring(_path.LastIndexOf("/") + 1); - } - } - - if (page.ParentId == null) - { - _parentid = "-1"; - } - else - { - _parentid = page.ParentId.ToString(); - } - - _currentparentid = _parentid; - _isnavigation = page.IsNavigation.ToString(); - _isclickable = page.IsClickable.ToString(); - _url = page.Url; - _ispersonalizable = page.IsPersonalizable.ToString(); - _themetype = page.ThemeType; - if (string.IsNullOrEmpty(_themetype)) - { - _themetype = PageState.Site.DefaultThemeType; - } - _containers = ThemeService.GetContainerControls(_themeList, _themetype); - _containertype = page.DefaultContainerType; - if (string.IsNullOrEmpty(_containertype)) - { - _containertype = PageState.Site.DefaultContainerType; - } - _icon = page.Icon; - _permissions = page.PermissionList; - _createdby = page.CreatedBy; - _createdon = page.CreatedOn; - _modifiedby = page.ModifiedBy; - _modifiedon = page.ModifiedOn; - _deletedby = page.DeletedBy; - _deletedon = page.DeletedOn; - - ThemeSettings(); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message); - AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error); - } - } - - private async Task DeleteModule(Module module) - { - try - { - PageModule pagemodule = await PageModuleService.GetPageModuleAsync(page.PageId, module.ModuleId); - pagemodule.IsDeleted = true; - await PageModuleService.UpdatePageModuleAsync(pagemodule); - await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title); - _pageModules.RemoveAll(item => item.PageModuleId == pagemodule.PageModuleId); - StateHasChanged(); - NavigationManager.NavigateTo(NavigationManager.Uri + "&tab=PageModules"); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Deleting Module {Title} {Error}", module.Title, ex.Message); - AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error); - } - } - - private async void ParentChanged(ChangeEventArgs e) - { - try - { - _parentid = (string)e.Value; - _children = new List(); - if (_parentid == "-1") - { - foreach (Page p in PageState.Pages.Where(item => item.ParentId == null)) - { - if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList)) - { - _children.Add(p); - } - } - } - else - { - foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid))) - { - if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList)) - { - _children.Add(p); - } - } - } - if (_parentid == _currentparentid) - { - _insert = "="; - } - else - { - _insert = ">>"; - } - StateHasChanged(); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message); - AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error); - } - } - - private async void ThemeChanged(ChangeEventArgs e) - { - try - { - _themetype = (string)e.Value; - _containers = ThemeService.GetContainerControls(_themeList, _themetype); - _containertype = "-"; - ThemeSettings(); - StateHasChanged(); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); - AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error); - } - } - - private void ThemeSettings() - { - _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))); - if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType)) - { - _themeSettingsType = Type.GetType(theme.ThemeSettingsType); - if (_themeSettingsType != null) - { - ThemeSettingsComponent = builder => - { - builder.OpenComponent(0, _themeSettingsType); - builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); }); - builder.CloseComponent(); - }; - } - _refresh = true; - } - } - } - - private async Task SavePage() - { - validated = true; - var interop = new Interop(JSRuntime); - if (await interop.FormValid(form)) - { - Page page = null; - try - { - if (!string.IsNullOrEmpty(_themetype) && _containertype != "-") - { - page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId); - string currentPath = page.Path; - - page.Name = _name; - page.Title = _title; - - if (string.IsNullOrEmpty(_path)) - { - _path = _name; - } - if (_path.Contains("/")) - { - if (_path.EndsWith("/") && _path != "/") - { - _path = _path.Substring(0, _path.Length - 1); - } - _path = _path.Substring(_path.LastIndexOf("/") + 1); - } - - if (_parentid == "-1") - { - page.ParentId = null; - page.Path = Utilities.GetFriendlyUrl(_path); - } - else - { - page.ParentId = Int32.Parse(_parentid); - Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId); - if (parent.Path == string.Empty) - { - page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); - } - else - { - page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); - } - } - - var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId); - if (_pages.Any(item => item.Path == page.Path && item.PageId != page.PageId)) - { - AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning); - return; - } - - if (page.ParentId == null && Constants.ReservedRoutes.Contains(page.Name.ToLower())) - { - AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning); - return; - } - - if (_insert != "=") - { - Page child; - switch (_insert) - { - case "<<": - page.Order = 0; - break; - case "<": - child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); - if (child != null) page.Order = child.Order - 1; - break; - case ">": - child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); - if (child != null) page.Order = child.Order + 1; - break; - case ">>": - page.Order = int.MaxValue; - break; - } - } - page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); - page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable)); - page.Url = _url; - page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; - if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) - { - page.ThemeType = string.Empty; - } - page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty; - if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType) - { - page.DefaultContainerType = string.Empty; - } - page.Icon = _icon ?? string.Empty; - page.PermissionList = _permissionGrid.GetPermissionList(); - page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable)); - page.UserId = null; - page.Meta = _meta; - - page = await PageService.UpdatePageAsync(page); - await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId); - if (_currentparentid == string.Empty) + if (_page != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _page.PermissionList)) + { + _name = _page.Name; + if (_page.ParentId == null) + { + _parentid = "-1"; + } + else + { + _parentid = _page.ParentId.ToString(); + _parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId); + } + _currentparentid = _parentid; + _isnavigation = _page.IsNavigation.ToString(); + _isclickable = _page.IsClickable.ToString(); + _path = _page.Path; + if (string.IsNullOrEmpty(_path)) + { + _path = "/"; + } + else + { + if (_path.Contains("/")) { - await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, null); + _path = _path.Substring(_path.LastIndexOf("/") + 1); + } + } + _url = _page.Url; + _icon = _page.Icon; + _ispersonalizable = _page.IsPersonalizable.ToString(); + + // appearance + _title = _page.Title; + _themetype = _page.ThemeType; + if (string.IsNullOrEmpty(_themetype) || ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName) + { + _themetype = PageState.Site.DefaultThemeType; + } + _themes = ThemeService.GetThemeControls(PageState.Site.Themes, _themetype); + _containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype); + _containertype = _page.DefaultContainerType; + if (string.IsNullOrEmpty(_containertype)) + { + _containertype = PageState.Site.DefaultContainerType; + } + + // page content + _headcontent = _page.HeadContent; + _bodycontent = _page.BodyContent; + + // permissions + _permissions = _page.PermissionList; + + // page modules + _pageModules = PageState.Modules.Where(m => m.PageId == _page.PageId).ToList(); + + // audit + _createdby = _page.CreatedBy; + _createdon = _page.CreatedOn; + _modifiedby = _page.ModifiedBy; + _modifiedon = _page.ModifiedOn; + _deletedby = _page.DeletedBy; + _deletedon = _page.DeletedOn; + + ThemeSettings(); + _initialized = true; + } + else + { + await logger.LogWarning("Error Loading Page {PageId}", _pageId); + AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message); + AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error); + } + } + + private async Task DeleteModule(Module module) + { + try + { + PageModule pagemodule = await PageModuleService.GetPageModuleAsync(_page.PageId, module.ModuleId); + pagemodule.IsDeleted = true; + await PageModuleService.UpdatePageModuleAsync(pagemodule); + await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title); + _pageModules.RemoveAll(item => item.PageModuleId == pagemodule.PageModuleId); + StateHasChanged(); + NavigationManager.NavigateTo(NavigationManager.Uri + "&tab=PageModules"); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Deleting Module {Title} {Error}", module.Title, ex.Message); + AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error); + } + } + + private async void ParentChanged(ChangeEventArgs e) + { + try + { + _parentid = (string)e.Value; + _children = new List(); + if (_parentid == "-1") + { + foreach (Page p in PageState.Pages.Where(item => item.ParentId == null)) + { + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList)) + { + _children.Add(p); + } + } + } + else + { + foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid))) + { + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList)) + { + _children.Add(p); + } + } + } + if (_parentid == _currentparentid) + { + _insert = "="; + } + else + { + _insert = ">>"; + } + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message); + AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error); + } + } + + private void ThemeSettings() + { + _themeSettingsType = null; + 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); + if (_themeSettingsType != null) + { + ThemeSettingsComponent = builder => + { + builder.OpenComponent(0, _themeSettingsType); + builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); }); + builder.CloseComponent(); + }; + } + _refresh = true; + } + } + + private async Task SavePage() + { + validated = true; + var interop = new Interop(JSRuntime); + if (await interop.FormValid(form)) + { + try + { + if (!string.IsNullOrEmpty(_themetype) && _containertype != "-") + { + string currentPath = _page.Path; + + _page.Name = _name; + + if (string.IsNullOrEmpty(_path)) + { + _path = _name; + } + if (_path.Contains("/")) + { + if (_path.EndsWith("/") && _path != "/") + { + _path = _path.Substring(0, _path.Length - 1); + } + _path = _path.Substring(_path.LastIndexOf("/") + 1); + } + + if (_parentid == "-1") + { + _page.ParentId = null; + _page.Path = Utilities.GetFriendlyUrl(_path); } else { - await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(_currentparentid)); + _page.ParentId = Int32.Parse(_parentid); + Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId); + if (parent.Path == string.Empty) + { + _page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); + } + else + { + _page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); + } + } + + var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId); + if (_pages.Any(item => item.Path == _page.Path && item.PageId != _page.PageId)) + { + AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning); + return; + } + + if (_page.ParentId == null && Constants.ReservedRoutes.Contains(_page.Name.ToLower())) + { + AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], _page.Name), MessageType.Warning); + return; + } + + if (_insert != "=") + { + Page child; + switch (_insert) + { + case "<<": + _page.Order = 0; + break; + case "<": + child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); + if (child != null) _page.Order = child.Order - 1; + break; + case ">": + child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); + if (child != null) _page.Order = child.Order + 1; + break; + case ">>": + _page.Order = int.MaxValue; + break; + } + } + _page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); + _page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable)); + _page.Url = _url; + _page.Icon = _icon ?? string.Empty; + _page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable)); + + // appearance + _page.Title = _title; + _page.ThemeType = _themetype; + if (!string.IsNullOrEmpty(_page.ThemeType) && _page.ThemeType == PageState.Site.DefaultThemeType) + { + _page.ThemeType = string.Empty; + } + _page.DefaultContainerType = _containertype; + if (!string.IsNullOrEmpty(_page.DefaultContainerType) && _page.DefaultContainerType == PageState.Site.DefaultContainerType) + { + _page.DefaultContainerType = string.Empty; + } + + // page content + _page.HeadContent = _headcontent; + _page.BodyContent = _bodycontent; + + // permissions + if (_page.UserId == null) + { + _page.PermissionList = _permissionGrid.GetPermissionList(); + } + + _page = await PageService.UpdatePageAsync(_page); + await PageService.UpdatePageOrderAsync(_page.SiteId, _page.PageId, _page.ParentId); + if (_currentparentid == string.Empty) + { + await PageService.UpdatePageOrderAsync(_page.SiteId, _page.PageId, null); + } + else + { + await PageService.UpdatePageOrderAsync(_page.SiteId, _page.PageId, int.Parse(_currentparentid)); } // update child paths @@ -530,7 +608,7 @@ { foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath))) { - p.Path = p.Path.Replace(currentPath, page.Path); + p.Path = p.Path.Replace(currentPath, _page.Path); await PageService.UpdatePageAsync(p); } } @@ -540,14 +618,14 @@ await themeSettingsControl.UpdateSettings(); } - await logger.LogInformation("Page Saved {Page}", page); - if (PageState.QueryString.ContainsKey("cp")) + await logger.LogInformation("Page Saved {Page}", _page); + if (!string.IsNullOrEmpty(PageState.ReturnUrl)) { - NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + NavigationManager.NavigateTo(PageState.ReturnUrl); } else { - NavigationManager.NavigateTo(NavigateUrl(page.Path)); + NavigationManager.NavigateTo(NavigateUrl()); } } else @@ -557,7 +635,7 @@ } catch (Exception ex) { - await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message); + await logger.LogError(ex, "Error Saving Page {Page} {Error}", _page, ex.Message); AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error); } } @@ -569,9 +647,9 @@ private void Cancel() { - if (PageState.QueryString.ContainsKey("cp")) + if (!string.IsNullOrEmpty(PageState.ReturnUrl)) { - NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + NavigationManager.NavigateTo(PageState.ReturnUrl); } else { diff --git a/Oqtane.Client/Modules/Admin/Pages/Index.razor b/Oqtane.Client/Modules/Admin/Pages/Index.razor index 198e3678..d71dc964 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Index.razor @@ -5,7 +5,7 @@ @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer -@if (PageState.Pages != null) +@if (PageState.Pages != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) { diff --git a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor index 1c149c5e..9620a396 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor @@ -64,6 +64,12 @@
+
+ +
+ +
+
@@ -97,6 +103,7 @@ private string _maxlength = "0"; private string _defaultvalue = string.Empty; private string _options = string.Empty; + private string _validation = string.Empty; private string _isrequired = "False"; private string _isprivate = "False"; private string createdby; @@ -126,6 +133,7 @@ _maxlength = profile.MaxLength.ToString(); _defaultvalue = profile.DefaultValue; _options = profile.Options; + _validation = profile.Validation; _isrequired = profile.IsRequired.ToString(); _isprivate = profile.IsPrivate.ToString(); createdby = profile.CreatedBy; @@ -169,6 +177,7 @@ profile.MaxLength = int.Parse(_maxlength); profile.DefaultValue = _defaultvalue; profile.Options = _options; + profile.Validation = _validation; profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired)); profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate)); if (_profileid != -1) diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index cb9fb716..acf61a87 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -76,8 +76,8 @@ else } @code { - private List _pages; - private List _modules; + private List _pages; + private List _modules; private int _pagePage = 1; private int _pageModule = 1; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; @@ -184,13 +184,6 @@ else try { await PageModuleService.DeletePageModuleAsync(module.PageModuleId); - - // check if there are any remaining module instances in the site - if (!_modules.Exists (item => item.ModuleId == module.ModuleId && item.PageModuleId != module.PageModuleId)) - { - await ModuleService.DeleteModuleAsync(module.ModuleId); - } - await logger.LogInformation("Module Permanently Deleted {Module}", module); await Load(); StateHasChanged(); @@ -210,16 +203,7 @@ else foreach (Module module in _modules.Where(item => item.IsDeleted).ToList()) { await PageModuleService.DeletePageModuleAsync(module.PageModuleId); - - // DeletePageModuleAsync does not update _modules so remove it. - _modules.Remove(module); - // check if there are any remaining module instances in the site - if (!_modules.Exists(item => item.ModuleId == module.ModuleId && item.PageModuleId != module.PageModuleId)) - { - await ModuleService.DeleteModuleAsync(module.ModuleId); - } } - await logger.LogInformation("Modules Permanently Deleted"); await Load(); ModuleInstance.HideProgressIndicator(); diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index bc7a68e2..49579b57 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -22,55 +22,6 @@
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
@@ -101,7 +52,80 @@
- +
+ +
+ +
+
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
@@ -124,9 +148,9 @@
- +
- @@ -162,7 +186,16 @@
-
+
+ +
+ +
+
+
@@ -306,222 +339,234 @@ } @code { - private ElementReference form; - private bool validated = false; - private bool _initialized = false; - private List _themeList; - private List _themes = new List(); - private List _containers = new List(); - private string _name = string.Empty; - private List _aliases; - private int _aliasid = -1; - private string _aliasname; - private string _defaultalias; - private string _runtime = ""; - private string _prerender = ""; - private int _logofileid = -1; - private FileManager _logofilemanager; - private int _faviconfileid = -1; - private FileManager _faviconfilemanager; - private string _themetype = "-"; - private string _containertype = "-"; - private string _admincontainertype = "-"; - private string _homepageid = "-"; - private string _sitemap = ""; - private string _smtphost = string.Empty; - private string _smtpport = string.Empty; - private string _smtpssl = "False"; - private string _smtpusername = string.Empty; - private string _smtppassword = string.Empty; - private string _smtppasswordtype = "password"; - private string _togglesmtppassword = string.Empty; - private string _smtpsender = string.Empty; - private string _smtprelay = "False"; - private string _retention = string.Empty; - private string _pwaisenabled; - private int _pwaappiconfileid = -1; - private FileManager _pwaappiconfilemanager; - private int _pwasplashiconfileid = -1; - private FileManager _pwasplashiconfilemanager; - private string _tenant = string.Empty; - private string _database = string.Empty; - private string _connectionstring = string.Empty; - private string _createdby; - private DateTime _createdon; - private string _modifiedby; - private DateTime _modifiedon; - private string _deletedby; - private DateTime? _deletedon; - private string _isdeleted; + private ElementReference form; + private bool validated = false; + private bool _initialized = false; + private List _themes = new List(); + private List _containers = new List(); + private string _name = string.Empty; + private string _homepageid = "-"; + private string _isdeleted; + private string _sitemap = ""; + private string _version = ""; + private int _logofileid = -1; + private FileManager _logofilemanager; + private int _faviconfileid = -1; + private FileManager _faviconfilemanager; + private string _themetype = ""; + private string _containertype = ""; + private string _admincontainertype = ""; + private string _headcontent = string.Empty; + private string _bodycontent = string.Empty; + private string _smtphost = string.Empty; + private string _smtpport = string.Empty; + private string _smtpssl = "False"; + private string _smtpusername = string.Empty; + private string _smtppassword = string.Empty; + private string _smtppasswordtype = "password"; + private string _togglesmtppassword = string.Empty; + private string _smtpsender = string.Empty; + private string _smtprelay = "False"; + private string _smtpenabled = "True"; + private string _retention = string.Empty; + private string _pwaisenabled; + private int _pwaappiconfileid = -1; + private FileManager _pwaappiconfilemanager; + private int _pwasplashiconfileid = -1; + private FileManager _pwasplashiconfilemanager; + private List _aliases; + private int _aliasid = -1; + private string _aliasname; + private string _defaultalias; + private string _runtime = ""; + private string _prerender = ""; + private string _tenant = string.Empty; + private string _database = string.Empty; + private string _connectionstring = string.Empty; + private string _createdby; + private DateTime _createdon; + private string _modifiedby; + private DateTime _modifiedon; + private string _deletedby; + private DateTime? _deletedon; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - protected override async Task OnInitializedAsync() - { - try - { - _themeList = await ThemeService.GetThemesAsync(); - Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId); - if (site != null) - { - _name = site.Name; - _runtime = site.Runtime; - _prerender = site.RenderMode.Replace(_runtime, ""); - _isdeleted = site.IsDeleted.ToString(); - _sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml"; + protected override async Task OnInitializedAsync() + { + try + { + Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId); + if (site != null) + { + _name = site.Name; + if (site.HomePageId != null) + { + _homepageid = site.HomePageId.Value.ToString(); + } + _isdeleted = site.IsDeleted.ToString(); + _sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml"; + _version = site.Version; - await GetAliases(); + // appearance + if (site.LogoFileId != null) + { + _logofileid = site.LogoFileId.Value; + } - if (site.LogoFileId != null) - { - _logofileid = site.LogoFileId.Value; - } + if (site.FaviconFileId != null) + { + _faviconfileid = site.FaviconFileId.Value; + } + _themes = ThemeService.GetThemeControls(PageState.Site.Themes); + _themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme; + _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; - if (site.FaviconFileId != null) - { - _faviconfileid = site.FaviconFileId.Value; - } + // page content + _headcontent = site.HeadContent; + _bodycontent = site.BodyContent; - _themes = ThemeService.GetThemeControls(_themeList); - _themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme; - _containers = ThemeService.GetContainerControls(_themeList, _themetype); - _containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer; - _admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer; + // PWA + _pwaisenabled = site.PwaIsEnabled.ToString(); + if (site.PwaAppIconFileId != null) + { + _pwaappiconfileid = site.PwaAppIconFileId.Value; + } + if (site.PwaSplashIconFileId != null) + { + _pwasplashiconfileid = site.PwaSplashIconFileId.Value; + } - if (site.HomePageId != null) - { - _homepageid = site.HomePageId.Value.ToString(); - } + // SMTP + var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); + _smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty); + _smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty); + _smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "False"); + _smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty); + _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty); + _togglesmtppassword = SharedLocalizer["ShowPassword"]; + _smtpsender = SettingService.GetSetting(settings, "SMTPSender", string.Empty); + _smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False"); + _smtpenabled = SettingService.GetSetting(settings, "SMTPEnabled", "True"); + _retention = SettingService.GetSetting(settings, "NotificationRetention", "30"); - _pwaisenabled = site.PwaIsEnabled.ToString(); - if (site.PwaAppIconFileId != null) - { - _pwaappiconfileid = site.PwaAppIconFileId.Value; - } - if (site.PwaSplashIconFileId != null) - { - _pwasplashiconfileid = site.PwaSplashIconFileId.Value; - } + // aliases + await GetAliases(); - var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); - _smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty); - _smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty); - _smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "False"); - _smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty); - _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty); - _togglesmtppassword = SharedLocalizer["ShowPassword"]; - _smtpsender = SettingService.GetSetting(settings, "SMTPSender", string.Empty); - _smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False"); - _retention = SettingService.GetSetting(settings, "NotificationRetention", "30"); + // hosting model + _runtime = site.Runtime; + _prerender = site.RenderMode.Replace(_runtime, ""); - if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) - { - var tenants = await TenantService.GetTenantsAsync(); - var _databases = await DatabaseService.GetDatabasesAsync(); - var tenant = tenants.Find(item => item.TenantId == site.TenantId); - if (tenant != null) - { - _tenant = tenant.Name; - _database = _databases.Find(item => item.DBType == tenant.DBType)?.Name; - _connectionstring = tenant.DBConnectionString; - } - } + // database + if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) + { + var tenants = await TenantService.GetTenantsAsync(); + var _databases = await DatabaseService.GetDatabasesAsync(); + var tenant = tenants.Find(item => item.TenantId == site.TenantId); + if (tenant != null) + { + _tenant = tenant.Name; + _database = _databases.Find(item => item.DBType == tenant.DBType)?.Name; + _connectionstring = tenant.DBConnectionString; + } + } - _createdby = site.CreatedBy; - _createdon = site.CreatedOn; - _modifiedby = site.ModifiedBy; - _modifiedon = site.ModifiedOn; - _deletedby = site.DeletedBy; - _deletedon = site.DeletedOn; + // audit + _createdby = site.CreatedBy; + _createdon = site.CreatedOn; + _modifiedby = site.ModifiedBy; + _modifiedon = site.ModifiedOn; + _deletedby = site.DeletedBy; + _deletedon = site.DeletedOn; - _initialized = true; - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); - AddModuleMessage(ex.Message, MessageType.Error); - } - } + _initialized = true; + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); + AddModuleMessage(ex.Message, MessageType.Error); + } + } - private async void ThemeChanged(ChangeEventArgs e) - { - try - { - _themetype = (string)e.Value; - if (_themetype != "-") - { - _containers = ThemeService.GetContainerControls(_themeList, _themetype); - } - else - { - _containers = new List(); - } - _containertype = "-"; - _admincontainertype = Constants.DefaultAdminContainer; - StateHasChanged(); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Containers For Theme {ThemeType} {Error}", _themetype, ex.Message); - AddModuleMessage(Localizer["Error.Theme.LoadPane"], MessageType.Error); - } - } + private async void ThemeChanged(ChangeEventArgs e) + { + try + { + _themetype = (string)e.Value; + _containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype); + _containertype = _containers.First().TypeName; + _admincontainertype = Constants.DefaultAdminContainer; + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Containers For Theme {ThemeType} {Error}", _themetype, ex.Message); + AddModuleMessage(Localizer["Error.Theme.LoadPane"], MessageType.Error); + } + } - private async Task SaveSite() - { - validated = true; - var interop = new Interop(JSRuntime); - if (await interop.FormValid(form)) - { - try - { - if (_name != string.Empty && _themetype != "-" && _containertype != "-") - { - var site = await SiteService.GetSiteAsync(PageState.Site.SiteId); - if (site != null) - { - bool refresh = false; - bool reload = false; + private async Task SaveSite() + { + validated = true; + var interop = new Interop(JSRuntime); + if (await interop.FormValid(form)) + { + try + { + if (_name != string.Empty && _themetype != "-" && _containertype != "-") + { + var site = await SiteService.GetSiteAsync(PageState.Site.SiteId); + if (site != null) + { + bool refresh = false; + bool reload = false; - site.Name = _name; - if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) - { - if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender) - { - site.Runtime = _runtime; - site.RenderMode = _runtime + _prerender; - reload = true; // needs to be reloaded on server - } - } - site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); + site.Name = _name; + site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null); + site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); - site.LogoFileId = null; - var logofileid = _logofilemanager.GetFileId(); - if (logofileid != -1) - { - site.LogoFileId = logofileid; - } - int? faviconFieldId = _faviconfilemanager.GetFileId(); - if (faviconFieldId == -1) faviconFieldId = null; - if (site.FaviconFileId != faviconFieldId) - { - site.FaviconFileId = faviconFieldId; - reload = true; // needs to be reloaded on server - } - if (site.DefaultThemeType != _themetype) - { - site.DefaultThemeType = _themetype; - refresh = true; // needs to be refreshed on client - } - if (site.DefaultContainerType != _containertype) - { - site.DefaultContainerType = _containertype; - refresh = true; // needs to be refreshed on client - } - site.AdminContainerType = _admincontainertype; - site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null); + // appearance + site.LogoFileId = null; + var logofileid = _logofilemanager.GetFileId(); + if (logofileid != -1) + { + site.LogoFileId = logofileid; + } + int? faviconFieldId = _faviconfilemanager.GetFileId(); + if (faviconFieldId == -1) faviconFieldId = null; + if (site.FaviconFileId != faviconFieldId) + { + site.FaviconFileId = faviconFieldId; + reload = true; // needs to be reloaded on server + } + if (site.DefaultThemeType != _themetype) + { + site.DefaultThemeType = _themetype; + refresh = true; // needs to be refreshed on client + } + if (site.DefaultContainerType != _containertype) + { + site.DefaultContainerType = _containertype; + refresh = true; // needs to be refreshed on client + } + site.AdminContainerType = _admincontainertype; + // page content + if (site.HeadContent != _headcontent) + { + site.HeadContent = _headcontent; + reload = true; + } + if (site.BodyContent != _bodycontent) + { + site.BodyContent = _bodycontent; + reload = true; + } + + // PWA if (site.PwaIsEnabled.ToString() != _pwaisenabled) { site.PwaIsEnabled = Boolean.Parse(_pwaisenabled); @@ -542,8 +587,20 @@ reload = true; // needs to be reloaded on server } + // hosting model + if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) + { + if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender) + { + site.Runtime = _runtime; + site.RenderMode = _runtime + _prerender; + reload = true; // needs to be reloaded on server + } + } + site = await SiteService.UpdateSiteAsync(site); + // SMTP var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true); settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true); @@ -552,7 +609,8 @@ settings = SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true); settings = SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true); settings = SettingService.SetSetting(settings, "SMTPRelay", _smtprelay, true); - settings = SettingService.SetSetting(settings, "NotificationRetention", _retention, true); + settings = SettingService.SetSetting(settings, "SMTPEnabled", _smtpenabled, true); + settings = SettingService.SetSetting(settings, "NotificationRetention", _retention, true); await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); await logger.LogInformation("Site Settings Saved {Site}", site); @@ -564,8 +622,8 @@ else { AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success); - await interop.ScrollTo(0, 0, "smooth"); - } + await ScrollToPageTop(); + } } } else @@ -633,9 +691,8 @@ await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly.")); AddModuleMessage(Localizer["Info.Smtp.SaveSettings"], MessageType.Info); - var interop = new Interop(JSRuntime); - await interop.ScrollTo(0, 0, "smooth"); - } + await ScrollToPageTop(); + } catch (Exception ex) { await logger.LogError(ex, "Error Testing SMTP Configuration"); diff --git a/Oqtane.Client/Modules/Admin/Themes/Create.razor b/Oqtane.Client/Modules/Admin/Themes/Create.razor index e685e3e1..b318026d 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Create.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Create.razor @@ -142,7 +142,7 @@ if (_owner != "" && _theme != "" && _template != "-") { var template = _templates.FirstOrDefault(item => item.Name == _template); - _location = template.Location + _owner + "." + _theme; + _location = template.Location + _owner + ".Theme." + _theme; } StateHasChanged(); diff --git a/Oqtane.Client/Modules/Admin/Themes/Edit.razor b/Oqtane.Client/Modules/Admin/Themes/Edit.razor new file mode 100644 index 00000000..00e22f29 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Themes/Edit.razor @@ -0,0 +1,162 @@ +@namespace Oqtane.Modules.Admin.Themes +@using System.Net +@inherits ModuleBase +@inject IThemeService ThemeService +@inject NavigationManager NavigationManager +@inject IStringLocalizer Localizer +@inject IStringLocalizer SharedLocalizer + +@if (_initialized) +{ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ + @SharedLocalizer["Cancel"] +
+
+ +} + +@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.Name = _name; + 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); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 61b25d58..08895c8f 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -23,11 +23,12 @@ else   @SharedLocalizer["Name"] @SharedLocalizer["Version"] + @Localizer["Enabled"] @SharedLocalizer["Expires"]   - + @if (context.AssemblyName != Constants.ClientId) { @@ -36,6 +37,16 @@ else @context.Name @context.Version + + @if (context.IsEnabled) + { + @SharedLocalizer["Yes"] + } + else + { + @SharedLocalizer["No"] + } + @((MarkupString)PurchaseLink(context.PackageName)) diff --git a/Oqtane.Client/Modules/Admin/Themes/View.razor b/Oqtane.Client/Modules/Admin/Themes/View.razor deleted file mode 100644 index db38748b..00000000 --- a/Oqtane.Client/Modules/Admin/Themes/View.razor +++ /dev/null @@ -1,97 +0,0 @@ -@namespace Oqtane.Modules.Admin.Themes -@using System.Net -@inherits ModuleBase -@inject IThemeService ThemeService -@inject NavigationManager NavigationManager -@inject IStringLocalizer Localizer -@inject IStringLocalizer SharedLocalizer - -
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-@SharedLocalizer["Cancel"] - -@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); - } - } -} diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor index 70aa3487..e1eabc2c 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor @@ -1,4 +1,5 @@ @namespace Oqtane.Modules.Admin.UserProfile +@using System.Text.RegularExpressions; @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -227,140 +228,140 @@ else

@code { - private string username = string.Empty; - private string _password = string.Empty; - private string _passwordtype = "password"; - private string _togglepassword = string.Empty; - private string confirm = string.Empty; - private bool allowtwofactor = false; - private string twofactor = "False"; - private string email = string.Empty; - private string displayname = string.Empty; - private FileManager filemanager; - private int folderid = -1; - private int photofileid = -1; - private File photo = null; - private List profiles; - private Dictionary settings; - private string category = string.Empty; - private string filter = "to"; - private List notifications; + private string username = string.Empty; + private string _password = string.Empty; + private string _passwordtype = "password"; + private string _togglepassword = string.Empty; + private string confirm = string.Empty; + private bool allowtwofactor = false; + private string twofactor = "False"; + private string email = string.Empty; + private string displayname = string.Empty; + private FileManager filemanager; + private int folderid = -1; + private int photofileid = -1; + private File photo = null; + private List profiles; + private Dictionary settings; + private string category = string.Empty; + private string filter = "to"; + private List notifications; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View; - protected override async Task OnParametersSetAsync() - { - try - { - _togglepassword = SharedLocalizer["ShowPassword"]; + protected override async Task OnParametersSetAsync() + { + try + { + _togglepassword = SharedLocalizer["ShowPassword"]; - if (PageState.Site.Settings.ContainsKey("LoginOptions:TwoFactor") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:TwoFactor"])) - { - allowtwofactor = (PageState.Site.Settings["LoginOptions:TwoFactor"] == "true"); - } + if (PageState.Site.Settings.ContainsKey("LoginOptions:TwoFactor") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:TwoFactor"])) + { + allowtwofactor = (PageState.Site.Settings["LoginOptions:TwoFactor"] == "true"); + } - if (PageState.User != null) - { - username = PageState.User.Username; - twofactor = PageState.User.TwoFactorRequired.ToString(); - email = PageState.User.Email; - displayname = PageState.User.DisplayName; + if (PageState.User != null) + { + username = PageState.User.Username; + twofactor = PageState.User.TwoFactorRequired.ToString(); + email = PageState.User.Email; + displayname = PageState.User.DisplayName; - // get user folder - var folder = await FolderService.GetFolderAsync(ModuleState.SiteId, PageState.User.FolderPath); - if (folder != null) - { - folderid = folder.FolderId; - } + // get user folder + var folder = await FolderService.GetFolderAsync(ModuleState.SiteId, PageState.User.FolderPath); + if (folder != null) + { + folderid = folder.FolderId; + } - if (PageState.User.PhotoFileId != null) - { - photofileid = PageState.User.PhotoFileId.Value; - photo = await FileService.GetFileAsync(photofileid); - } - else - { - photofileid = -1; - photo = null; - } + if (PageState.User.PhotoFileId != null) + { + photofileid = PageState.User.PhotoFileId.Value; + photo = await FileService.GetFileAsync(photofileid); + } + else + { + photofileid = -1; + photo = null; + } - profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId); - settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); + profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId); + settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); - await LoadNotificationsAsync(); - } - else - { - AddModuleMessage(Localizer["Message.User.NoLogIn"], MessageType.Warning); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); - AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error); - } - } + await LoadNotificationsAsync(); + } + else + { + AddModuleMessage(Localizer["Message.User.NoLogIn"], MessageType.Warning); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); + AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error); + } + } - private async Task LoadNotificationsAsync() - { - notifications = await NotificationService.GetNotificationsAsync(PageState.Site.SiteId, filter, PageState.User.UserId); - notifications = notifications.Where(item => item.DeletedBy != PageState.User.Username).ToList(); - } + private async Task LoadNotificationsAsync() + { + notifications = await NotificationService.GetNotificationsAsync(PageState.Site.SiteId, filter, PageState.User.UserId); + notifications = notifications.Where(item => item.DeletedBy != PageState.User.Username).ToList(); + } - private string GetProfileValue(string SettingName, string DefaultValue) - { - string value = SettingService.GetSetting(settings, SettingName, DefaultValue); - if (value.Contains("]")) - { - value = value.Substring(value.IndexOf("]") + 1); - } - return value; - } + private string GetProfileValue(string SettingName, string DefaultValue) + { + string value = SettingService.GetSetting(settings, SettingName, DefaultValue); + if (value.Contains("]")) + { + value = value.Substring(value.IndexOf("]") + 1); + } + return value; + } - private async Task Save() - { - try - { - if (username != string.Empty && email != string.Empty && ValidateProfiles()) - { - if (_password == confirm) - { - var user = PageState.User; - user.Username = username; - user.Password = _password; - user.TwoFactorRequired = bool.Parse(twofactor); - user.Email = email; - user.DisplayName = (displayname == string.Empty ? username : displayname); - user.PhotoFileId = filemanager.GetFileId(); - if (user.PhotoFileId == -1) - { - user.PhotoFileId = null; - } - if (user.PhotoFileId != null) - { - photofileid = user.PhotoFileId.Value; - photo = await FileService.GetFileAsync(photofileid); - } - else - { - photofileid = -1; - photo = null; - } + private async Task Save() + { + try + { + if (username != string.Empty && email != string.Empty && ValidateProfiles()) + { + if (_password == confirm) + { + var user = PageState.User; + user.Username = username; + user.Password = _password; + user.TwoFactorRequired = bool.Parse(twofactor); + user.Email = email; + user.DisplayName = (displayname == string.Empty ? username : displayname); + user.PhotoFileId = filemanager.GetFileId(); + if (user.PhotoFileId == -1) + { + user.PhotoFileId = null; + } + if (user.PhotoFileId != null) + { + photofileid = user.PhotoFileId.Value; + photo = await FileService.GetFileAsync(photofileid); + } + else + { + photofileid = -1; + photo = null; + } - user = await UserService.UpdateUserAsync(user); - if (user != null) - { - await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId); - await logger.LogInformation("User Profile Saved"); + user = await UserService.UpdateUserAsync(user); + if (user != null) + { + await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId); + await logger.LogInformation("User Profile Saved"); - AddModuleMessage(Localizer["Success.Profile.Update"], MessageType.Success); - StateHasChanged(); - } - else - { - AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error); - } - } + AddModuleMessage(Localizer["Success.Profile.Update"], MessageType.Success); + StateHasChanged(); + } + else + { + AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error); + } + } else { AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning); @@ -370,6 +371,8 @@ else { AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning); } + + await ScrollToPageTop(); } catch (Exception ex) { @@ -389,10 +392,15 @@ else } if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) { - if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty))) + if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty))) { valid = false; } + if (valid == true && !string.IsNullOrEmpty(profile.Validation)) + { + Regex regex = new Regex(profile.Validation); + valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success; + } } } return valid; diff --git a/Oqtane.Client/Modules/Admin/Users/Add.razor b/Oqtane.Client/Modules/Admin/Users/Add.razor index 713dab6e..54c396ee 100644 --- a/Oqtane.Client/Modules/Admin/Users/Add.razor +++ b/Oqtane.Client/Modules/Admin/Users/Add.razor @@ -1,4 +1,5 @@ @namespace Oqtane.Modules.Admin.Users +@using System.Text.RegularExpressions; @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -95,8 +96,8 @@ @code { private string username = string.Empty; private string _password = string.Empty; - private string _passwordtype = "password"; - private string _togglepassword = string.Empty; + private string _passwordtype = "password"; + private string _togglepassword = string.Empty; private string confirm = string.Empty; private string email = string.Empty; private string displayname = string.Empty; @@ -121,15 +122,15 @@ } } - private string GetProfileValue(string SettingName, string DefaultValue) - { - string value = SettingService.GetSetting(settings, SettingName, DefaultValue); - if (value.Contains("]")) - { - value = value.Substring(value.IndexOf("]") + 1); - } - return value; - } + private string GetProfileValue(string SettingName, string DefaultValue) + { + string value = SettingService.GetSetting(settings, SettingName, DefaultValue); + if (value.Contains("]")) + { + value = value.Substring(value.IndexOf("]") + 1); + } + return value; + } private async Task SaveUser() { @@ -195,9 +196,17 @@ { settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue); } - if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty))) + if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) { - valid = false; + if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty))) + { + valid = false; + } + if (valid == true && !string.IsNullOrEmpty(profile.Validation)) + { + Regex regex = new Regex(profile.Validation); + valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success; + } } } return valid; diff --git a/Oqtane.Client/Modules/Admin/Users/Edit.razor b/Oqtane.Client/Modules/Admin/Users/Edit.razor index af541617..fea1a6f0 100644 --- a/Oqtane.Client/Modules/Admin/Users/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Users/Edit.razor @@ -1,4 +1,5 @@ @namespace Oqtane.Modules.Admin.Users +@using System.Text.RegularExpressions; @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -148,124 +149,124 @@ else @code { - private int userid; - private string username = string.Empty; - private string _password = string.Empty; - private string _passwordtype = "password"; - private string _togglepassword = string.Empty; - private string confirm = string.Empty; - private string email = string.Empty; - private string displayname = string.Empty; - private FileManager filemanager; - private int photofileid = -1; - private File photo = null; - private string isdeleted; - private string lastlogin; - private string lastipaddress; + private int userid; + private string username = string.Empty; + private string _password = string.Empty; + private string _passwordtype = "password"; + private string _togglepassword = string.Empty; + private string confirm = string.Empty; + private string email = string.Empty; + private string displayname = string.Empty; + private FileManager filemanager; + private int photofileid = -1; + private File photo = null; + private string isdeleted; + private string lastlogin; + private string lastipaddress; - private List profiles; - private Dictionary settings; - private string category = string.Empty; + private List profiles; + private Dictionary settings; + private string category = string.Empty; - private string createdby; - private DateTime createdon; - private string modifiedby; - private DateTime modifiedon; - private string deletedby; - private DateTime? deletedon; + private string createdby; + private DateTime createdon; + private string modifiedby; + private DateTime modifiedon; + private string deletedby; + private DateTime? deletedon; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; - protected override async Task OnParametersSetAsync() - { - try - { - if (PageState.QueryString.ContainsKey("id")) - { - _togglepassword = SharedLocalizer["ShowPassword"]; - profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); - userid = Int32.Parse(PageState.QueryString["id"]); - var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId); - if (user != null) - { - username = user.Username; - email = user.Email; - displayname = user.DisplayName; - if (user.PhotoFileId != null) - { - photofileid = user.PhotoFileId.Value; - photo = await FileService.GetFileAsync(photofileid); - } - else - { - photofileid = -1; - photo = null; - } - isdeleted = user.IsDeleted.ToString(); - lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn); - lastipaddress = user.LastIPAddress; + protected override async Task OnParametersSetAsync() + { + try + { + if (PageState.QueryString.ContainsKey("id")) + { + _togglepassword = SharedLocalizer["ShowPassword"]; + profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); + userid = Int32.Parse(PageState.QueryString["id"]); + var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId); + if (user != null) + { + username = user.Username; + email = user.Email; + displayname = user.DisplayName; + if (user.PhotoFileId != null) + { + photofileid = user.PhotoFileId.Value; + photo = await FileService.GetFileAsync(photofileid); + } + else + { + photofileid = -1; + photo = null; + } + isdeleted = user.IsDeleted.ToString(); + lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn); + lastipaddress = user.LastIPAddress; - settings = await SettingService.GetUserSettingsAsync(user.UserId); - createdby = user.CreatedBy; - createdon = user.CreatedOn; - modifiedby = user.ModifiedBy; - modifiedon = user.ModifiedOn; - deletedby = user.DeletedBy; - deletedon = user.DeletedOn; - } - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading User {UserId} {Error}", userid, ex.Message); - AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error); - } - } + settings = await SettingService.GetUserSettingsAsync(user.UserId); + createdby = user.CreatedBy; + createdon = user.CreatedOn; + modifiedby = user.ModifiedBy; + modifiedon = user.ModifiedOn; + deletedby = user.DeletedBy; + deletedon = user.DeletedOn; + } + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading User {UserId} {Error}", userid, ex.Message); + AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error); + } + } - private string GetProfileValue(string SettingName, string DefaultValue) - { - string value = SettingService.GetSetting(settings, SettingName, DefaultValue); - if (value.Contains("]")) - { - value = value.Substring(value.IndexOf("]") + 1); - } - return value; - } + private string GetProfileValue(string SettingName, string DefaultValue) + { + string value = SettingService.GetSetting(settings, SettingName, DefaultValue); + if (value.Contains("]")) + { + value = value.Substring(value.IndexOf("]") + 1); + } + return value; + } - private async Task SaveUser() - { - try - { - if (username != string.Empty && email != string.Empty && ValidateProfiles()) - { - if (_password == confirm) - { - var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId); - user.SiteId = PageState.Site.SiteId; - user.Username = username; - user.Password = _password; - user.Email = email; - user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname; - user.PhotoFileId = null; - user.PhotoFileId = filemanager.GetFileId(); - if (user.PhotoFileId == -1) - { - user.PhotoFileId = null; - } + private async Task SaveUser() + { + try + { + if (username != string.Empty && email != string.Empty && ValidateProfiles()) + { + if (_password == confirm) + { + var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId); + user.SiteId = PageState.Site.SiteId; + user.Username = username; + user.Password = _password; + user.Email = email; + user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname; + user.PhotoFileId = null; + user.PhotoFileId = filemanager.GetFileId(); + if (user.PhotoFileId == -1) + { + user.PhotoFileId = null; + } - user.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted)); + user.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted)); - user = await UserService.UpdateUserAsync(user); - if (user != null) - { - await SettingService.UpdateUserSettingsAsync(settings, user.UserId); - await logger.LogInformation("User Saved {User}", user); - NavigationManager.NavigateTo(NavigateUrl()); - } - else - { - AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error); - } + user = await UserService.UpdateUserAsync(user); + if (user != null) + { + await SettingService.UpdateUserSettingsAsync(settings, user.UserId); + await logger.LogInformation("User Saved {User}", user); + NavigationManager.NavigateTo(NavigateUrl()); + } + else + { + AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error); + } } else { @@ -293,9 +294,17 @@ else { settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue); } - if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty))) + if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) { - valid = false; + if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty))) + { + valid = false; + } + if (valid == true && !string.IsNullOrEmpty(profile.Validation)) + { + Regex regex = new Regex(profile.Validation); + valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success; + } } } return valid; diff --git a/Oqtane.Client/Modules/HtmlText/Edit.razor b/Oqtane.Client/Modules/HtmlText/Edit.razor index bb609f80..72a9662c 100644 --- a/Oqtane.Client/Modules/HtmlText/Edit.razor +++ b/Oqtane.Client/Modules/HtmlText/Edit.razor @@ -53,7 +53,6 @@ public override List Resources => new List() { - new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }, new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.bubble.css" }, new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.snow.css" } }; diff --git a/Oqtane.Client/Modules/HtmlText/Index.razor b/Oqtane.Client/Modules/HtmlText/Index.razor index 4428d033..77f7b95d 100644 --- a/Oqtane.Client/Modules/HtmlText/Index.razor +++ b/Oqtane.Client/Modules/HtmlText/Index.razor @@ -15,11 +15,6 @@ } @code { - public override List Resources => new List() - { - new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" } - }; - private string content = ""; protected override async Task OnParametersSetAsync() diff --git a/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs b/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs index 36e674fe..59a473c4 100644 --- a/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs +++ b/Oqtane.Client/Modules/HtmlText/ModuleInfo.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using Oqtane.Documentation; using Oqtane.Models; +using Oqtane.Shared; namespace Oqtane.Modules.HtmlText { @@ -13,7 +15,11 @@ namespace Oqtane.Modules.HtmlText Version = "1.0.1", ServerManagerType = "Oqtane.Modules.HtmlText.Manager.HtmlTextManager, Oqtane.Server", ReleaseVersions = "1.0.0,1.0.1", - SettingsType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client" + SettingsType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client", + Resources = new List() + { + new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Module.css" } + } }; } } diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index 9ba0d264..8023da67 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -9,6 +9,7 @@ using Oqtane.UI; using System.Collections.Generic; using Microsoft.JSInterop; using System.Linq; +using Oqtane.Themes; namespace Oqtane.Modules { @@ -70,17 +71,33 @@ namespace Oqtane.Modules { if (firstRender) { - if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script)) + List resources = null; + var type = GetType(); + if (type.BaseType == typeof(ModuleBase)) + { + if (PageState.Page.Resources != null) + { + resources = PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Script && item.Level != ResourceLevel.Site && item.Namespace == type.Namespace).ToList(); + } + } + else // modulecontrolbase + { + if (Resources != null) + { + resources = Resources.Where(item => item.ResourceType == ResourceType.Script).ToList(); + } + } + if (resources != null &&resources.Any()) { var interop = new Interop(JSRuntime); var scripts = new List(); var inline = 0; - foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script)) + foreach (Resource resource in resources) { if (!string.IsNullOrEmpty(resource.Url)) { var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url; - scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module }); + scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module, location = resource.Location.ToString().ToLower() }); } else { @@ -104,6 +121,7 @@ namespace Oqtane.Modules } // url methods + public string NavigateUrl() { return NavigateUrl(PageState.Page.Path); @@ -273,6 +291,33 @@ namespace Oqtane.Modules SiteState.Properties.ModuleVisibility = obj; } + public void SetPageTitle(string title) + { + SiteState.Properties.PageTitle = title; + } + + // note - only supports links and meta tags - not scripts + public void AddHeadContent(string content) + { + SiteState.AppendHeadContent(content); + } + + public void AddScript(Resource resource) + { + resource.ResourceType = ResourceType.Script; + if (Resources == null) Resources = new List(); + if (!Resources.Any(item => (!string.IsNullOrEmpty(resource.Url) && item.Url == resource.Url) || (!string.IsNullOrEmpty(resource.Content) && item.Content == resource.Content))) + { + Resources.Add(resource); + } + } + + public async Task ScrollToPageTop() + { + var interop = new Interop(JSRuntime); + await interop.ScrollTo(0, 0, "smooth"); + } + // logging methods public async Task Log(Alias alias, LogLevel level, string function, Exception exception, string message, params object[] args) { diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index d75a10e8..9ea4853c 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -1,19 +1,19 @@ - net6.0 + net7.0 Exe 3.0 Debug;Release - 3.4.3 + 4.0.0 Oqtane Shaun Walker .NET Foundation - Modular Application Framework for Blazor and MAUI + CMS and Application Framework for Blazor and .NET MAUI .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.3 + https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -22,13 +22,13 @@ - - - + + + + + + - - - diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 1c89bc09..e6927c1b 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -16,7 +16,6 @@ using Microsoft.JSInterop; using Oqtane.Documentation; using Oqtane.Modules; using Oqtane.Services; -using Oqtane.Shared; using Oqtane.UI; namespace Oqtane.Client diff --git a/Oqtane.Client/Resources/Installer/Installer.resx b/Oqtane.Client/Resources/Installer/Installer.resx index ec83b9bb..23e0f7d7 100644 --- a/Oqtane.Client/Resources/Installer/Installer.resx +++ b/Oqtane.Client/Resources/Installer/Installer.resx @@ -124,7 +124,7 @@ Database: - Application Administrator + Application Administration Install Now @@ -180,4 +180,7 @@ Enter Connection String + + Select a site template + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx index 8e3bf1d4..b9f8b825 100644 --- a/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Edit.resx @@ -219,4 +219,10 @@ A Module With The Name Specified Already Exists + + Is module enabled for this site? + + + Enabled? + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Index.resx b/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Index.resx index 817b22db..9e3b9cc2 100644 --- a/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/ModuleDefinitions/Index.resx @@ -145,7 +145,7 @@ Delete Module - In Use + In Use? Edit @@ -153,4 +153,7 @@ Modules + + Enabled? + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Pages/Add.resx b/Oqtane.Client/Resources/Modules/Admin/Pages/Add.resx index 3b2128c2..a9360734 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Pages/Add.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Pages/Add.resx @@ -150,8 +150,8 @@ Select Container - - Error Initializing Page + + Error Loading Page Error Loading Child Pages For Parent @@ -228,13 +228,22 @@ Appearance - - Optionally enter meta tags (in exactly the form you want them to be included in the page output). + + Optionally enter content to be included in the page head (ie. meta, link, or script tags) - - Meta: + + Head Content: The page name {0} is reserved. Please enter a different name for your page. + + Optionally enter content to be included in the page body (ie. script tags) + + + Body Content: + + + Page Content + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Pages/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/Pages/Edit.resx index 32ffa56e..f4ae201a 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Pages/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Pages/Edit.resx @@ -264,13 +264,22 @@ Clickable? - - Optionally enter meta tags (in exactly the form you want them to be included in the page output). + + Optionally enter content to be included in the page head (ie. meta, link, or script tags) - - Meta: + + Head Content: The page name {0} is reserved. Please enter a different name for your page. + + Optionally enter content to be included in the page body (ie. script tags) + + + Body Content: + + + Page Content + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Profiles/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/Profiles/Edit.resx index 720e34f9..8a3a23ca 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Profiles/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Profiles/Edit.resx @@ -183,4 +183,10 @@ Private? + + Optionally provide a regular expression (RegExp) for validating the value entered + + + Validation: + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx index 16b840c1..e4a4c438 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx @@ -175,7 +175,7 @@ Specify a logo for the site - Specify a Favicon + Specify a Favicon. The format for the image must be 16×16, 32×32, 48×48, or 64×64 pixels in size, and 8-bit, 24-bit, or 32-bit in color depth. The format of the image must be ICO, PNG, or GIF. Select the sites default theme @@ -351,4 +351,34 @@ Site Map: + + Appearance + + + Optionally enter content to be included in the page head (ie. meta, link, or script tags) + + + Head Content: + + + Optionally enter content to be included in the page body (ie. script tags) + + + Body Content: + + + Page Content + + + Specify if SMTP is enabled for this site + + + Enabled? + + + The site version (for site content migrations) + + + Version: + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Themes/View.resx b/Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx similarity index 96% rename from Oqtane.Client/Resources/Modules/Admin/Themes/View.resx rename to Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx index f950588f..4c3fd053 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Themes/View.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Themes/Edit.resx @@ -168,4 +168,13 @@ Package Name: + + Information + + + Is theme enabled for this site? + + + Enabled? + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Themes/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Themes/Index.resx index 45824f4f..73d2a5ad 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Themes/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Themes/Index.resx @@ -144,4 +144,7 @@ View + + Enabled? + \ No newline at end of file diff --git a/Oqtane.Client/Services/FileService.cs b/Oqtane.Client/Services/FileService.cs index 584e618b..3fef5c6e 100644 --- a/Oqtane.Client/Services/FileService.cs +++ b/Oqtane.Client/Services/FileService.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -29,9 +30,9 @@ namespace Oqtane.Services public async Task> GetFilesAsync(int siteId, string folderPath) { - if (!(folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar))) + if (!(string.IsNullOrEmpty(folderPath) || folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar))) { - folderPath = Utilities.PathCombine(folderPath, System.IO.Path.DirectorySeparatorChar.ToString()); + folderPath = Utilities.UrlCombine(folderPath) + "/"; } var path = WebUtility.UrlEncode(folderPath); diff --git a/Oqtane.Client/Services/Interfaces/IPageService.cs b/Oqtane.Client/Services/Interfaces/IPageService.cs index 9981f373..2f5c4c6d 100644 --- a/Oqtane.Client/Services/Interfaces/IPageService.cs +++ b/Oqtane.Client/Services/Interfaces/IPageService.cs @@ -23,14 +23,6 @@ namespace Oqtane.Services /// Task GetPageAsync(int pageId); - /// - /// Returns a specific page personalized for the given user - /// - /// - /// - /// - Task GetPageAsync(int pageId, int userId); - /// /// Returns a specific page by its defined path /// diff --git a/Oqtane.Client/Services/Interfaces/IThemeService.cs b/Oqtane.Client/Services/Interfaces/IThemeService.cs index 4d8d17c6..4dc636c2 100644 --- a/Oqtane.Client/Services/Interfaces/IThemeService.cs +++ b/Oqtane.Client/Services/Interfaces/IThemeService.cs @@ -16,6 +16,22 @@ namespace Oqtane.Services /// Task> GetThemesAsync(); + /// + /// Returns a specific thenme + /// + /// + /// + /// + Task GetThemeAsync(int themeId, int siteId); + + /// + /// Returns a theme s containing a specific theme control type + /// + /// + /// + /// + Theme GetTheme(List themes, string themeControlType); + /// /// Returns a list of s from the given themes /// @@ -24,20 +40,27 @@ namespace Oqtane.Services List GetThemeControls(List themes); /// - /// Returns a list of layouts () from the given themes with a matching theme name + /// Returns a list of s for a theme containing a specific theme control type /// /// - /// + /// /// - List GetLayoutControls(List themes, string themeName); + List GetThemeControls(List themes, string themeControlType); /// - /// Returns a list of containers () from the given themes with a matching theme name + /// Returns a list of containers () for a theme containing a specific theme control type /// /// - /// + /// /// - List GetContainerControls(List themes, string themeName); + List GetContainerControls(List themes, string themeControlType); + + /// + /// Updates a existing theem + /// + /// + /// + Task UpdateThemeAsync(Theme theme); /// /// Deletes a theme @@ -58,5 +81,14 @@ namespace Oqtane.Services /// /// Task> GetThemeTemplatesAsync(); + + + /// + /// Returns a list of layouts () from the given themes with a matching theme name + /// + /// + /// + /// + List GetLayoutControls(List themes, string themeName); } } diff --git a/Oqtane.Client/Services/PageService.cs b/Oqtane.Client/Services/PageService.cs index 0725ccf8..934b156e 100644 --- a/Oqtane.Client/Services/PageService.cs +++ b/Oqtane.Client/Services/PageService.cs @@ -25,11 +25,6 @@ namespace Oqtane.Services return await GetJsonAsync($"{Apiurl}/{pageId}"); } - public async Task GetPageAsync(int pageId, int userId) - { - return await GetJsonAsync($"{Apiurl}/{pageId}?userid={userId}"); - } - public async Task GetPageAsync(string path, int siteId) { try diff --git a/Oqtane.Client/Services/ThemeService.cs b/Oqtane.Client/Services/ThemeService.cs index e678841c..d1c03495 100644 --- a/Oqtane.Client/Services/ThemeService.cs +++ b/Oqtane.Client/Services/ThemeService.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Oqtane.Documentation; using Oqtane.Models; using Oqtane.Shared; +using Oqtane.UI; namespace Oqtane.Services { @@ -20,22 +21,35 @@ namespace Oqtane.Services List themes = await GetJsonAsync>(ApiUrl); return themes.OrderBy(item => item.Name).ToList(); } + public async Task GetThemeAsync(int themeId, int siteId) + { + return await GetJsonAsync($"{ApiUrl}/{themeId}?siteid={siteId}"); + } + + public Theme GetTheme(List themes, string themeControlType) + { + return themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == themeControlType)); + } public List GetThemeControls(List themes) { - return themes.SelectMany(item => item.Themes).ToList(); + return themes.SelectMany(item => item.Themes).OrderBy(item => item.Name).ToList(); } - //[Obsolete("This method is deprecated.", false)] - public List GetLayoutControls(List themes, string themeName) + public List GetThemeControls(List themes, string themeControlType) { - return null; + return GetTheme(themes, themeControlType)?.Themes.OrderBy(item => item.Name).ToList(); } - public List GetContainerControls(List themes, string themeName) + + public List GetContainerControls(List themes, string themeControlType) { - return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName))) - .SelectMany(item => item.Containers).ToList(); + return GetTheme(themes, themeControlType)?.Containers.OrderBy(item => item.Name).ToList(); + } + + public async Task UpdateThemeAsync(Theme theme) + { + await PutJsonAsync($"{ApiUrl}/{theme.ThemeId}", theme); } public async Task DeleteThemeAsync(string themeName) @@ -53,5 +67,11 @@ namespace Oqtane.Services List