diff --git a/LICENSE b/LICENSE index 6b68cd26..81e8cb41 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018-2021 .NET Foundation +Copyright (c) 2018-2022 .NET Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Oqtane.Client/App.razor b/Oqtane.Client/App.razor index 14f64da5..92b73433 100644 --- a/Oqtane.Client/App.razor +++ b/Oqtane.Client/App.razor @@ -30,28 +30,32 @@ } @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; } - private bool _initialized = false; - private string _display = "display: none;"; - private Installation _installation = new Installation { Success = false, Message = "" }; + [Parameter] + public string RemoteIPAddress { get; set; } - private PageState PageState { get; set; } + private bool _initialized = false; + private string _display = "display: none;"; + private Installation _installation = new Installation { Success = false, Message = "" }; - protected override async Task OnParametersSetAsync() - { - SiteState.AntiForgeryToken = AntiForgeryToken; - InstallationService.SetAntiForgeryTokenHeader(AntiForgeryToken); + private PageState PageState { get; set; } + + protected override async Task OnParametersSetAsync() + { + SiteState.RemoteIPAddress = RemoteIPAddress; + SiteState.AntiForgeryToken = AntiForgeryToken; + InstallationService.SetAntiForgeryTokenHeader(AntiForgeryToken); _installation = await InstallationService.IsInstalled(); if (_installation.Alias != null) diff --git a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor index 6c665ba2..3e3eb82c 100644 --- a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor +++ b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor @@ -27,6 +27,6 @@ protected override void OnInitialized() { var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin"); - _pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList(); + _pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId && !item.IsDeleted).ToList(); } } diff --git a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor index 72e56897..120ede22 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor @@ -36,7 +36,9 @@ + + @@ -95,82 +97,89 @@ @code { - private ElementReference form; - private bool validated = false; - private int _jobId; - private string _name = string.Empty; - private string _jobType = string.Empty; - private string _isEnabled = "True"; - private string _interval = string.Empty; - private string _frequency = string.Empty; - private DateTime? _startDate = null; - private string _startTime = string.Empty; - private DateTime? _endDate = null; - private string _endTime = string.Empty; - private string _retentionHistory = string.Empty; - private DateTime? _nextDate = null; - private string _nextTime = string.Empty; - private string createdby; - private DateTime createdon; - private string modifiedby; - private DateTime modifiedon; + private ElementReference form; + private bool validated = false; + private int _jobId; + private string _name = string.Empty; + private string _jobType = string.Empty; + private string _isEnabled = "True"; + private string _interval = string.Empty; + private string _frequency = string.Empty; + private DateTime? _startDate = null; + private string _startTime = string.Empty; + private DateTime? _endDate = null; + private string _endTime = string.Empty; + private string _retentionHistory = string.Empty; + private DateTime? _nextDate = null; + private string _nextTime = string.Empty; + private string createdby; + private DateTime createdon; + private string modifiedby; + private DateTime modifiedon; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnInitializedAsync() - { - try - { - _jobId = Int32.Parse(PageState.QueryString["id"]); - Job job = await JobService.GetJobAsync(_jobId); - if (job != null) - { - _name = job.Name; - _jobType = job.JobType; - _isEnabled = job.IsEnabled.ToString(); - _interval = job.Interval.ToString(); - _frequency = job.Frequency; - _startDate = job.StartDate; - if (job.StartDate != null && job.StartDate.Value.TimeOfDay.TotalSeconds != 0) - { - _startTime = job.StartDate.Value.ToString("HH:mm"); - } - _endDate = job.EndDate; - if (job.EndDate != null && job.EndDate.Value.TimeOfDay.TotalSeconds != 0) - { - _endTime = job.EndDate.Value.ToString("HH:mm"); - } - _retentionHistory = job.RetentionHistory.ToString(); - _nextDate = job.NextExecution; - if (job.NextExecution != null && job.NextExecution.Value.TimeOfDay.TotalSeconds != 0) - { - _nextTime = job.NextExecution.Value.ToString("HH:mm"); - } - createdby = job.CreatedBy; - createdon = job.CreatedOn; - modifiedby = job.ModifiedBy; - modifiedon = job.ModifiedOn; - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message); - AddModuleMessage(Localizer["Error.Job.Load"], MessageType.Error); - } - } + protected override async Task OnInitializedAsync() + { + try + { + _jobId = Int32.Parse(PageState.QueryString["id"]); + Job job = await JobService.GetJobAsync(_jobId); + if (job != null) + { + _name = job.Name; + _jobType = job.JobType; + _isEnabled = job.IsEnabled.ToString(); + _interval = job.Interval.ToString(); + _frequency = job.Frequency; + _startDate = job.StartDate; + if (job.StartDate != null && job.StartDate.Value.TimeOfDay.TotalSeconds != 0) + { + _startTime = job.StartDate.Value.ToString("HH:mm"); + } + _endDate = job.EndDate; + if (job.EndDate != null && job.EndDate.Value.TimeOfDay.TotalSeconds != 0) + { + _endTime = job.EndDate.Value.ToString("HH:mm"); + } + _retentionHistory = job.RetentionHistory.ToString(); + _nextDate = job.NextExecution; + if (job.NextExecution != null && job.NextExecution.Value.TimeOfDay.TotalSeconds != 0) + { + _nextTime = job.NextExecution.Value.ToString("HH:mm"); + } + createdby = job.CreatedBy; + createdon = job.CreatedOn; + modifiedby = job.ModifiedBy; + modifiedon = job.ModifiedOn; + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message); + AddModuleMessage(Localizer["Error.Job.Load"], MessageType.Error); + } + } - private async Task SaveJob() - { - validated = true; - var interop = new Interop(JSRuntime); - if (await interop.FormValid(form)) - { - var job = await JobService.GetJobAsync(_jobId); - job.Name = _name; - job.JobType = _jobType; - job.IsEnabled = Boolean.Parse(_isEnabled); - job.Frequency = _frequency; - job.Interval = int.Parse(_interval); + private async Task SaveJob() + { + validated = true; + var interop = new Interop(JSRuntime); + if (await interop.FormValid(form)) + { + var job = await JobService.GetJobAsync(_jobId); + job.Name = _name; + job.JobType = _jobType; + job.IsEnabled = Boolean.Parse(_isEnabled); + job.Frequency = _frequency; + if (job.Frequency == "O") // once + { + job.Interval = 1; + } + else + { + job.Interval = int.Parse(_interval); + } job.StartDate = _startDate; if (job.StartDate != null) { diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index 1996d62b..ecc195e4 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -36,75 +36,75 @@ else @context.NextExecution @if (context.IsStarted) - { + { - } - else - { + } + else + { - } + } } @code { - private List _jobs; + private List _jobs; - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } - protected override async Task OnParametersSetAsync() - { - _jobs = await JobService.GetJobsAsync(); - } + protected override async Task OnParametersSetAsync() + { + _jobs = await JobService.GetJobsAsync(); + } - private string DisplayStatus(bool isEnabled, bool isExecuting) - { - var status = string.Empty; - if (!isEnabled) - { - status = Localizer["Disabled"]; - } - else - { - if (isExecuting) - { - status = Localizer["Executing"]; - } - else - { - status = Localizer["Idle"]; - } - } + private string DisplayStatus(bool isEnabled, bool isExecuting) + { + var status = string.Empty; + if (!isEnabled) + { + status = Localizer["Disabled"]; + } + else + { + if (isExecuting) + { + status = Localizer["Executing"]; + } + else + { + status = Localizer["Idle"]; + } + } - return status; - } + return status; + } - private string DisplayFrequency(int interval, string frequency) - { - var result = $"{Localizer["Every"]} {interval.ToString()} "; - switch (frequency) - { - case "m": - result += Localizer["Minute"]; - break; - case "H": - result += Localizer["Hour"]; - break; - case "d": - result += Localizer["Day"]; - break; - case "M": - result += Localizer["Month"]; - break; - } - - if (interval > 1) - { - result += Localizer["s"]; - } - + private string DisplayFrequency(int interval, string frequency) + { + var result = ""; + switch (frequency) + { + case "m": + result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Minute"]; + break; + case "H": + result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Hour"]; + break; + case "d": + result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Day"]; + break; + case "w": + result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Week"]; + break; + case "M": + result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Month"]; + break; + case "O": + result = Localizer["Once"]; + break; + } return result; } @@ -114,6 +114,7 @@ else { await JobService.DeleteJobAsync(job.JobId); await logger.LogInformation("Job Deleted {Job}", job); + _jobs = await JobService.GetJobsAsync(); StateHasChanged(); } catch (Exception ex) @@ -125,12 +126,36 @@ else private async Task StartJob(int jobId) { - await JobService.StartJobAsync(jobId); + try + { + await JobService.StartJobAsync(jobId); + await logger.LogInformation("Job Started {JobId}", jobId); + AddModuleMessage(Localizer["Message.Job.Start"], MessageType.Success); + _jobs = await JobService.GetJobsAsync(); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Starting Job {JobId} {Error}", jobId, ex.Message); + AddModuleMessage(Localizer["Error.Job.Start"], MessageType.Error); + } } private async Task StopJob(int jobId) { - await JobService.StopJobAsync(jobId); + try + { + await JobService.StopJobAsync(jobId); + await logger.LogInformation("Job Stopped {JobId}", jobId); + AddModuleMessage(Localizer["Message.Job.Stop"], MessageType.Success); + _jobs = await JobService.GetJobsAsync(); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Stopping Job {JobId} {Error}", jobId, ex.Message); + AddModuleMessage(Localizer["Error.Job.Stop"], MessageType.Error); + } } private async Task Refresh() diff --git a/Oqtane.Client/Modules/Admin/Login/Index.razor b/Oqtane.Client/Modules/Admin/Login/Index.razor index 07fafe07..2bd43685 100644 --- a/Oqtane.Client/Modules/Admin/Login/Index.razor +++ b/Oqtane.Client/Modules/Admin/Login/Index.razor @@ -177,17 +177,17 @@ { await UserService.ForgotPasswordAsync(user); await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username); - _message = "Please Check The Email Address Associated To Your User Account For A Password Reset Notification"; + _message = Localizer["Message.ForgotUser"]; } else { - _message = "User Does Not Exist"; + _message = Localizer["Message.UserDoesNotExist"]; _type = MessageType.Warning; } } else { - _message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again"; + _message = Localizer["Message.ForgotPassword"]; } StateHasChanged(); diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 311e73b0..853409cb 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Modules.Admin.Logs @inherits ModuleBase @inject ILogService LogService +@inject ISettingService SettingService @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer @@ -10,66 +11,83 @@ } else { -
-
-
-

- -
-
-

- -
-
-

- -
-
-
+ + +
+
+
+

+ +
+
+

+ +
+
+

+ +
+
+
+
- @if (_logs.Any()) - { - -
-   - @Localizer["Date"] - @Localizer["Level"] - @Localizer["Feature"] - @Localizer["Function"] -
- - - @context.LogDate - @context.Level - @context.Feature - @context.Function - -
- } - else - { -

@Localizer["NoLogs"]

- } + @if (_logs.Any()) + { + +
+   + @Localizer["Date"] + @Localizer["Level"] + @Localizer["Feature"] + @Localizer["Function"] +
+ + + @context.LogDate + @context.Level + @context.Feature + @context.Function + +
+ } + else + { +

@Localizer["NoLogs"]

+ } +
+ +
+
+ +
+ +
+
+
+
+ +
+
} @code { @@ -77,6 +95,7 @@ else private string _function = "-"; private string _rows = "10"; private List _logs; + private string _retention = ""; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; @@ -85,6 +104,7 @@ else try { await GetLogs(); + _retention = SettingService.GetSetting(PageState.Site.Settings, "LogRetention", "30"); } catch (Exception ex) { @@ -170,4 +190,22 @@ else } return classname; } + + private async Task SaveSiteSettings() + { + try + { + var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); + settings = SettingService.SetSetting(settings, "LogRetention", _retention, true); + await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); + + AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving Site Settings {Error}", ex.Message); + AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error); + } + } + } diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 27f32ea7..d81480b5 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -128,7 +128,7 @@ else var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference }; moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition); - var settings = ModuleState.Settings; + var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName); await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); diff --git a/Oqtane.Client/Modules/Admin/Reset/Index.razor b/Oqtane.Client/Modules/Admin/Reset/Index.razor index 545a573d..00eac54d 100644 --- a/Oqtane.Client/Modules/Admin/Reset/Index.razor +++ b/Oqtane.Client/Modules/Admin/Reset/Index.razor @@ -7,41 +7,49 @@
-
- - +
+ +
+ +
-
- - +
+ +
+ +
-
- - +
+ +
+ +
- -
+
+ + @code { - private ElementReference form; - private bool validated = false; - private string _username = string.Empty; - private string _password = string.Empty; - private string _confirm = string.Empty; + private ElementReference form; + private bool validated = false; + private string _username = string.Empty; + private string _password = string.Empty; + private string _confirm = string.Empty; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; - protected override void OnInitialized() - { - if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token")) + protected override async Task OnInitializedAsync() + { + if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token")) { _username = PageState.QueryString["name"]; } else { - NavigationManager.NavigateTo(NavigateUrl(string.Empty)); + await logger.LogError(LogFunction.Security, "Invalid Attempt To Access User Password Reset"); + NavigationManager.NavigateTo(NavigateUrl("")); // home page } } diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index ebe7548f..63f22032 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -1,5 +1,6 @@ @namespace Oqtane.Modules.Admin.Site @inherits ModuleBase +@using System.Text.RegularExpressions @inject NavigationManager NavigationManager @inject ISiteService SiteService @inject ITenantService TenantService @@ -22,81 +23,64 @@
- +
- @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) - { - - } - else - { - - } +
- +
- + + @foreach (var theme in _themes) + { + + }
-
-
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
+
+ +
+
-
+
+ +
+ +
+
+
+ +
+ +
+
+
@@ -174,8 +158,29 @@
- @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) + @if (_aliases != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) { +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
@@ -238,7 +243,8 @@ private List _themes = new List(); private List _containers = new List(); private string _name = string.Empty; - private List _aliasList; + private List _aliases; + private string _defaultalias = string.Empty; private string _urls = string.Empty; private string _runtime = ""; private string _prerender = ""; @@ -288,13 +294,7 @@ if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) { - _aliasList = await AliasService.GetAliasesAsync(); - foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) - { - _urls += alias.Name + ","; - } - _urls = _urls.Substring(0, _urls.Length - 1); - + await GetAliases(); } if (site.LogoFileId != null) @@ -322,7 +322,7 @@ { _pwasplashiconfileid = site.PwaSplashIconFileId.Value; } - + var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); _smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty); _smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty); @@ -398,13 +398,17 @@ var unique = true; if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) { - foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) + _urls = Regex.Replace(_urls, @"\r\n?|\n", ","); // convert line breaks to commas + var aliases = await AliasService.GetAliasesAsync(); + foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray()) { - if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId)) + var alias = aliases.Where(item => item.Name == name).FirstOrDefault(); + if (alias != null && unique) { - unique = false; + unique = (alias.TenantId == PageState.Site.TenantId && alias.SiteId == PageState.Site.SiteId); } } + if (unique && string.IsNullOrEmpty(_defaultalias)) unique = false; } if (unique) @@ -422,7 +426,6 @@ { site.Runtime = _runtime; site.RenderMode = _runtime + _prerender; - refresh = true; reload = true; // needs to be reloaded on server } } @@ -461,145 +464,173 @@ int? pwaappiconfileid = _pwaappiconfilemanager.GetFileId(); if (pwaappiconfileid == -1) pwaappiconfileid = null; if (site.PwaAppIconFileId != pwaappiconfileid) - { - site.PwaAppIconFileId = pwaappiconfileid; + { + site.PwaAppIconFileId = pwaappiconfileid; reload = true; // needs to be reloaded on server - } - int? pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId(); + } + int? pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId(); if (pwasplashiconfileid == -1) pwasplashiconfileid = null; - if (site.PwaSplashIconFileId != pwasplashiconfileid) - { - site.PwaSplashIconFileId = pwasplashiconfileid; + if (site.PwaSplashIconFileId != pwasplashiconfileid) + { + site.PwaSplashIconFileId = pwasplashiconfileid; reload = true; // needs to be reloaded on server - } + } - site = await SiteService.UpdateSiteAsync(site); + site = await SiteService.UpdateSiteAsync(site); - var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); - SettingService.SetSetting(settings, "SMTPHost", _smtphost); - SettingService.SetSetting(settings, "SMTPPort", _smtpport); - SettingService.SetSetting(settings, "SMTPSSL", _smtpssl); - SettingService.SetSetting(settings, "SMTPUsername", _smtpusername); - SettingService.SetSetting(settings, "SMTPPassword", _smtppassword); - SettingService.SetSetting(settings, "SMTPSender", _smtpsender); - await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); + var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); + SettingService.SetSetting(settings, "SMTPHost", _smtphost, true); + SettingService.SetSetting(settings, "SMTPPort", _smtpport, true); + SettingService.SetSetting(settings, "SMTPSSL", _smtpssl, true); + SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true); + SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true); + SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true); + await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); - if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) - { - var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) - { - if (!names.Contains(alias.Name)) - { - await AliasService.DeleteAliasAsync(alias.AliasId); - } - } + if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) + { + var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) + .Select(sValue => sValue.Trim()).ToArray(); + foreach (Alias alias in _aliases) + { + if (!names.Contains(alias.Name.Trim())) + { + await AliasService.DeleteAliasAsync(alias.AliasId); + } + } - foreach (string name in names) - { - if (!_aliasList.Exists(item => item.Name == name)) - { - Alias alias = new Alias(); - alias.Name = name; - alias.TenantId = site.TenantId; - alias.SiteId = site.SiteId; - await AliasService.AddAliasAsync(alias); - } - } - } + foreach (string name in names) + { + var alias = _aliases.Find(item => item.Name.Trim() == name); + if (alias == null) + { + alias = new Alias(); + alias.Name = name; + alias.TenantId = site.TenantId; + alias.SiteId = site.SiteId; + alias.IsDefault = (name == _defaultalias); + await AliasService.AddAliasAsync(alias); + } + else + { + if (alias.Name != name || alias.IsDefault != (alias.Name.Trim() == _defaultalias)) + { + alias.Name = name; + alias.IsDefault = (name == _defaultalias); + await AliasService.UpdateAliasAsync(alias); + } + } + } + await GetAliases(); + } - await logger.LogInformation("Site Settings Saved {Site}", site); + await logger.LogInformation("Site Settings Saved {Site}", site); - if (refresh) - { - NavigationManager.NavigateTo(NavigateUrl(true), reload); // refresh/reload - } - else - { - AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success); - } - } - } - else - { - AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning); - } - } - else - { - AddModuleMessage(Localizer["Message.Required.SiteName"], MessageType.Warning); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Saving Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); - AddModuleMessage(Localizer["Error.SaveSite"], MessageType.Error); - } - } - else - { - AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning); - } - } + if (refresh || reload) + { + NavigationManager.NavigateTo(NavigateUrl(true), reload); // refresh/reload + } + else + { + AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success); + await interop.ScrollTo(0, 0, "smooth"); + } + } + } + else // deuplicate alias or default alias not specified + { + AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning); + } + } + else + { + AddModuleMessage(Localizer["Message.Required.SiteName"], MessageType.Warning); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); + AddModuleMessage(Localizer["Error.SaveSite"], MessageType.Error); + } + } + else + { + AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning); + } + } - private async Task DeleteSite() - { - try - { - var sites = await SiteService.GetSitesAsync(); - if (sites.Count > 1) - { - await SiteService.DeleteSiteAsync(PageState.Site.SiteId); - await logger.LogInformation("Site Deleted {SiteId}", PageState.Site.SiteId); + private async Task DeleteSite() + { + try + { + var sites = await SiteService.GetSitesAsync(); + if (sites.Count > 1) + { + await SiteService.DeleteSiteAsync(PageState.Site.SiteId); + await logger.LogInformation("Site Deleted {SiteId}", PageState.Site.SiteId); - var aliases = await AliasService.GetAliasesAsync(); - foreach (Alias a in aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId)) - { - await AliasService.DeleteAliasAsync(a.AliasId); - } + var aliases = await AliasService.GetAliasesAsync(); + foreach (Alias a in aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId)) + { + await AliasService.DeleteAliasAsync(a.AliasId); + } - NavigationManager.NavigateTo(NavigateUrl("admin/sites")); - } - else - { - AddModuleMessage(Localizer["Message.FailAuth.DeleteSite"], MessageType.Warning); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Deleting Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); - AddModuleMessage(Localizer["Error.DeleteSite"], MessageType.Error); - } - } + NavigationManager.NavigateTo(NavigateUrl("admin/sites")); + } + else + { + AddModuleMessage(Localizer["Message.FailAuth.DeleteSite"], MessageType.Warning); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Deleting Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); + AddModuleMessage(Localizer["Error.DeleteSite"], MessageType.Error); + } + } - private async Task SendEmail() - { - if (_smtphost != "" && _smtpport != "" && _smtpsender != "") - { - try - { - var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); - SettingService.SetSetting(settings, "SMTPHost", _smtphost); - SettingService.SetSetting(settings, "SMTPPort", _smtpport); - SettingService.SetSetting(settings, "SMTPSSL", _smtpssl); - SettingService.SetSetting(settings, "SMTPUsername", _smtpusername); - SettingService.SetSetting(settings, "SMTPPassword", _smtppassword); - SettingService.SetSetting(settings, "SMTPSender", _smtpsender); - await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); - await logger.LogInformation("Site SMTP Settings Saved"); + private async Task SendEmail() + { + if (_smtphost != "" && _smtpport != "" && _smtpsender != "") + { + try + { + var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); + SettingService.SetSetting(settings, "SMTPHost", _smtphost, true); + SettingService.SetSetting(settings, "SMTPPort", _smtpport, true); + SettingService.SetSetting(settings, "SMTPSSL", _smtpssl, true); + SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true); + SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true); + SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true); + await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); + await logger.LogInformation("Site SMTP Settings Saved"); - await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User.DisplayName, PageState.User.Email, PageState.User.DisplayName, PageState.User.Email, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly.")); - AddModuleMessage(Localizer["Info.Smtp.SaveSettings"], MessageType.Info); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Testing SMTP Configuration"); - AddModuleMessage(Localizer["Error.Smtp.TestConfig"], MessageType.Error); - } - } - else - { - AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning); - } - } + await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User.DisplayName, PageState.User.Email, PageState.User.DisplayName, PageState.User.Email, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly.")); + AddModuleMessage(Localizer["Info.Smtp.SaveSettings"], MessageType.Info); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Testing SMTP Configuration"); + AddModuleMessage(Localizer["Error.Smtp.TestConfig"], MessageType.Error); + } + } + else + { + AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning); + } + } + + private async Task GetAliases() + { + _urls = string.Empty; + _defaultalias = string.Empty; + _aliases = await AliasService.GetAliasesAsync(); + _aliases = _aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId).OrderBy(item => item.AliasId).ToList(); + foreach (Alias alias in _aliases) + { + _urls += (_urls == string.Empty) ? alias.Name.Trim() : ", " + alias.Name.Trim(); + if (alias.IsDefault && string.IsNullOrEmpty(_defaultalias)) _defaultalias = alias.Name.Trim(); + } + if (string.IsNullOrEmpty(_defaultalias)) _defaultalias = _aliases.First().Name.Trim(); + } } diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index cdcef8da..14cbc5f0 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -1,5 +1,6 @@ @namespace Oqtane.Modules.Admin.Sites @using Oqtane.Interfaces +@using System.Text.RegularExpressions @inherits ModuleBase @inject NavigationManager NavigationManager @inject ITenantService TenantService @@ -282,6 +283,7 @@ else { if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-" && _sitetemplatetype != "-") { + _urls = Regex.Replace(_urls, @"\r\n?|\n", ","); var duplicates = new List(); var aliases = await AliasService.GetAliasesAsync(); foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) @@ -370,8 +372,7 @@ else if (installation.Success) { var aliasname = config.Aliases.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0]; - var uri = new Uri(NavigationManager.Uri); - NavigationManager.NavigateTo(uri.Scheme + "://" + aliasname, true); + NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + aliasname, true); } else { diff --git a/Oqtane.Client/Modules/Admin/Sites/Index.razor b/Oqtane.Client/Modules/Admin/Sites/Index.razor index 09d7946d..4ece6608 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Index.razor @@ -30,20 +30,16 @@ else @code { private List _sites; - private string _scheme; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnParametersSetAsync() { - var uri = new Uri(NavigationManager.Uri); - _scheme = uri.Scheme + "://"; - var aliases = await AliasService.GetAliasesAsync(); _sites = new List(); foreach (Alias alias in aliases) { - if (!_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId)) + if (alias.IsDefault && !_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId)) { _sites.Add(alias); } @@ -52,16 +48,11 @@ else private void Edit(string name) { - if (name.Equals("*")) - { - var uri = new Uri(NavigationManager.Uri); - name = uri.Authority; - } - NavigationManager.NavigateTo(_scheme + name + "/admin/site/?reload"); + NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + name + "/admin/site", true); } private void Browse(string name) { - NavigationManager.NavigateTo(_scheme + name + "/?reload"); + NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + name, true); } } diff --git a/Oqtane.Client/Modules/Admin/Sql/Index.razor b/Oqtane.Client/Modules/Admin/Sql/Index.razor index b22d279e..db41daaa 100644 --- a/Oqtane.Client/Modules/Admin/Sql/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sql/Index.razor @@ -57,22 +57,20 @@ else { @if (_results.Count > 0) { -
- -
- @foreach (KeyValuePair kvp in _results.First()) - { - @kvp.Key - } -
- - @foreach (KeyValuePair kvp in context) - { - @kvp.Value - } - -
-
+ +
+ @foreach (KeyValuePair kvp in _results.First()) + { + @kvp.Key + } +
+ + @foreach (KeyValuePair kvp in context) + { + @kvp.Value + } + +
} else { diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor index f28731dc..ef09cd2a 100644 --- a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor +++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor @@ -33,7 +33,7 @@
- +
@@ -99,32 +99,32 @@ @code { - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - private string _version = string.Empty; - private string _clrversion = string.Empty; - private string _osversion = string.Empty; - private string _serverpath = string.Empty; - private string _servertime = string.Empty; - private string _installationid = string.Empty; + private string _version = string.Empty; + private string _clrversion = string.Empty; + private string _osversion = string.Empty; + private string _serverpath = string.Empty; + private string _servertime = string.Empty; + private string _installationid = string.Empty; - private string _detailederrors = string.Empty; - private string _logginglevel = string.Empty; - private string _swagger = string.Empty; - private string _packageservice = string.Empty; + private string _detailederrors = string.Empty; + private string _logginglevel = string.Empty; + private string _swagger = string.Empty; + private string _packageservice = string.Empty; - protected override async Task OnInitializedAsync() - { - _version = Constants.Version; + protected override async Task OnInitializedAsync() + { + _version = Constants.Version; - Dictionary systeminfo = await SystemService.GetSystemInfoAsync(); - if (systeminfo != null) - { - _clrversion = systeminfo["clrversion"]; - _osversion = systeminfo["osversion"]; - _serverpath = systeminfo["serverpath"]; - _servertime = systeminfo["servertime"]; - _installationid = systeminfo["installationid"]; + Dictionary systeminfo = await SystemService.GetSystemInfoAsync(); + if (systeminfo != null) + { + _clrversion = systeminfo["clrversion"]; + _osversion = systeminfo["osversion"]; + _serverpath = systeminfo["serverpath"]; + _servertime = systeminfo["servertime"] + " UTC"; + _installationid = systeminfo["installationid"]; _detailederrors = systeminfo["detailederrors"]; _logginglevel = systeminfo["logginglevel"]; diff --git a/Oqtane.Client/Modules/Admin/UrlMappings/Add.razor b/Oqtane.Client/Modules/Admin/UrlMappings/Add.razor index efde8b66..e57ad13e 100644 --- a/Oqtane.Client/Modules/Admin/UrlMappings/Add.razor +++ b/Oqtane.Client/Modules/Admin/UrlMappings/Add.razor @@ -40,28 +40,46 @@ var interop = new Interop(JSRuntime); if (await interop.FormValid(form)) { - var route = new Route(_url, PageState.Alias.Path); - var url = route.SiteUrl + "/" + route.PagePath; + if (_url != _mappedurl) + { + var url = PageState.Uri.Scheme + "://" + PageState.Uri.Authority + "/"; + url = url + (!string.IsNullOrEmpty(PageState.Alias.Path) ? PageState.Alias.Path + "/" : ""); - var urlmapping = new UrlMapping(); - urlmapping.SiteId = PageState.Site.SiteId; - urlmapping.Url = url; - urlmapping.MappedUrl = _mappedurl; - urlmapping.Requests = 0; - urlmapping.CreatedOn = DateTime.UtcNow; - urlmapping.RequestedOn = DateTime.UtcNow; + _url = (_url.StartsWith("/")) ? _url.Substring(1) : _url; + _url = (!_url.StartsWith("http")) ? url + _url : _url; - try - { - urlmapping = await UrlMappingService.AddUrlMappingAsync(urlmapping); - await logger.LogInformation("UrlMapping Saved {UrlMapping}", urlmapping); - NavigationManager.NavigateTo(NavigateUrl()); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Saving UrlMapping {UrlMapping} {Error}", urlmapping, ex.Message); - AddModuleMessage(Localizer["Error.SaveUrlMapping"], MessageType.Error); - } + if (_url.StartsWith(url)) + { + var urlmapping = new UrlMapping(); + urlmapping.SiteId = PageState.Site.SiteId; + var route = new Route(_url, PageState.Alias.Path); + urlmapping.Url = route.PagePath; + urlmapping.MappedUrl = _mappedurl.Replace(url, ""); + urlmapping.Requests = 0; + urlmapping.CreatedOn = DateTime.UtcNow; + urlmapping.RequestedOn = DateTime.UtcNow; + + try + { + urlmapping = await UrlMappingService.AddUrlMappingAsync(urlmapping); + await logger.LogInformation("UrlMapping Saved {UrlMapping}", urlmapping); + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving UrlMapping {UrlMapping} {Error}", urlmapping, ex.Message); + AddModuleMessage(Localizer["Error.SaveUrlMapping"], MessageType.Error); + } + } + else + { + AddModuleMessage(Localizer["Message.SaveUrlMapping"], MessageType.Warning); + } + } + else + { + AddModuleMessage(Localizer["Message.DuplicateUrlMapping"], MessageType.Warning); + } } else { diff --git a/Oqtane.Client/Modules/Admin/UrlMappings/Edit.razor b/Oqtane.Client/Modules/Admin/UrlMappings/Edit.razor index 1ef1b79a..10c9a57f 100644 --- a/Oqtane.Client/Modules/Admin/UrlMappings/Edit.razor +++ b/Oqtane.Client/Modules/Admin/UrlMappings/Edit.razor @@ -26,55 +26,64 @@ @code { - private ElementReference form; - private bool validated = false; + private ElementReference form; + private bool validated = false; - private int _urlmappingid; - private string _url = string.Empty; - private string _mappedurl = string.Empty; + private int _urlmappingid; + private string _url = string.Empty; + private string _mappedurl = string.Empty; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - protected override async Task OnInitializedAsync() - { - try - { - _urlmappingid = Int32.Parse(PageState.QueryString["id"]); - var urlmapping = await UrlMappingService.GetUrlMappingAsync(_urlmappingid); - if (urlmapping != null) - { - _url = urlmapping.Url; - _mappedurl = urlmapping.MappedUrl; - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading UrlMapping {UrlMappingId} {Error}", _urlmappingid, ex.Message); - AddModuleMessage(Localizer["Error.LoadUrlMapping"], MessageType.Error); - } - } + protected override async Task OnInitializedAsync() + { + try + { + _urlmappingid = Int32.Parse(PageState.QueryString["id"]); + var urlmapping = await UrlMappingService.GetUrlMappingAsync(_urlmappingid); + if (urlmapping != null) + { + _url = urlmapping.Url; + _mappedurl = urlmapping.MappedUrl; + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading UrlMapping {UrlMappingId} {Error}", _urlmappingid, ex.Message); + AddModuleMessage(Localizer["Error.LoadUrlMapping"], MessageType.Error); + } + } - private async Task SaveUrlMapping() - { - validated = true; - var interop = new Interop(JSRuntime); - if (await interop.FormValid(form)) - { - var urlmapping = await UrlMappingService.GetUrlMappingAsync(_urlmappingid); - urlmapping.MappedUrl = _mappedurl; + private async Task SaveUrlMapping() + { + validated = true; + var interop = new Interop(JSRuntime); + if (await interop.FormValid(form)) + { + if (_url != _mappedurl) + { + try + { + var url = PageState.Uri.Scheme + "://" + PageState.Uri.Authority + "/"; + url = url + (!string.IsNullOrEmpty(PageState.Alias.Path) ? PageState.Alias.Path + "/" : ""); - try - { - urlmapping = await UrlMappingService.UpdateUrlMappingAsync(urlmapping); - await logger.LogInformation("UrlMapping Saved {UrlMapping}", urlmapping); - NavigationManager.NavigateTo(NavigateUrl()); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Saving UrlMapping {UrlMapping} {Error}", urlmapping, ex.Message); - AddModuleMessage(Localizer["Error.SaveUrlMapping"], MessageType.Error); - } - } + var urlmapping = await UrlMappingService.GetUrlMappingAsync(_urlmappingid); + urlmapping.MappedUrl = _mappedurl.Replace(url, ""); + urlmapping = await UrlMappingService.UpdateUrlMappingAsync(urlmapping); + await logger.LogInformation("UrlMapping Saved {UrlMapping}", urlmapping); + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving UrlMapping {UrlMappingId} {Error}", _urlmappingid, ex.Message); + AddModuleMessage(Localizer["Error.SaveUrlMapping"], MessageType.Error); + } + } + else + { + AddModuleMessage(Localizer["Message.DuplicateUrlMapping"], MessageType.Warning); + } + } else { AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning); diff --git a/Oqtane.Client/Modules/Admin/UrlMappings/Index.razor b/Oqtane.Client/Modules/Admin/UrlMappings/Index.razor index 327f7a37..28478589 100644 --- a/Oqtane.Client/Modules/Admin/UrlMappings/Index.razor +++ b/Oqtane.Client/Modules/Admin/UrlMappings/Index.razor @@ -40,10 +40,10 @@ else - @context.Url + @context.Url @if (_mapped) { - @((MarkupString)"
>> ")@context.MappedUrl + @((MarkupString)"
>> ")@context.MappedUrl } @context.Requests @@ -96,11 +96,6 @@ else } } - private void BrowseUrl(string url) - { - NavigationManager.NavigateTo(url, true); - } - private async Task DeleteUrlMapping(UrlMapping urlMapping) { try diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor index 5644482d..9f3d19ae 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor @@ -12,7 +12,7 @@ @if (PageState.User != null && photo != null) { - @displayname + @displayname } else { diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index 3f138c34..1649e56e 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -89,7 +89,7 @@ else { var results = allroles.Where(item => item.Role.Name == RoleNames.Registered || (item.Role.Name == RoleNames.Host && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))); - if (string.IsNullOrEmpty(_search)) + if (!string.IsNullOrEmpty(_search)) { results = results.Where(item => ( diff --git a/Oqtane.Client/Modules/Admin/Visitors/Index.razor b/Oqtane.Client/Modules/Admin/Visitors/Index.razor index d09d8e0d..a3f97ecd 100644 --- a/Oqtane.Client/Modules/Admin/Visitors/Index.razor +++ b/Oqtane.Client/Modules/Admin/Visitors/Index.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject IVisitorService VisitorService @inject ISiteService SiteService +@inject ISettingService SettingService @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer @@ -56,18 +57,30 @@ else @context.CreatedOn - +
- +
-
+
+ +
+ +
+
+
+ +
+ +
+

@@ -79,14 +92,18 @@ else private bool _users = false; private int _days = 1; private List _visitors; - private string _visitortracking; + private string _tracking; + private string _filter = ""; + private string _retention = ""; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnParametersSetAsync() { await GetVisitors(); - _visitortracking = PageState.Site.VisitorTracking.ToString(); + _tracking = PageState.Site.VisitorTracking.ToString(); + _filter = SettingService.GetSetting(PageState.Site.Settings, "VisitorFilter", ""); + _retention = SettingService.GetSetting(PageState.Site.Settings, "VisitorRetention", "30"); } private async void TypeChanged(ChangeEventArgs e) @@ -124,15 +141,21 @@ else { _visitors = _visitors.Where(item => item.UserId != null).ToList(); } - } + } private async Task SaveSiteSettings() { try { var site = PageState.Site; - site.VisitorTracking = bool.Parse(_visitortracking); + site.VisitorTracking = bool.Parse(_tracking); await SiteService.UpdateSiteAsync(site); + + var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); + settings = SettingService.SetSetting(settings, "VisitorFilter", _filter, true); + settings = SettingService.SetSetting(settings, "VisitorRetention", _retention, true); + await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); + AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success); } catch (Exception ex) diff --git a/Oqtane.Client/Modules/Controls/Label.razor b/Oqtane.Client/Modules/Controls/Label.razor index 4362147d..a1f8bf3f 100644 --- a/Oqtane.Client/Modules/Controls/Label.razor +++ b/Oqtane.Client/Modules/Controls/Label.razor @@ -25,8 +25,8 @@ else [Parameter] public string HelpText { get; set; } // optional - tooltip for this label - private string _spanclass = "app-tooltip"; - private string _labelclass = "form-label"; + private string _spanclass; + private string _labelclass; private string _helptext = string.Empty; protected override void OnParametersSet() @@ -36,11 +36,15 @@ else if (!string.IsNullOrEmpty(HelpText)) { _helptext = Localize(nameof(HelpText), HelpText); - _spanclass += (!string.IsNullOrEmpty(Class)) ? " " + Class : ""; + _labelclass = "form-label"; + + var spanclass = (!string.IsNullOrEmpty(Class)) ? " " + Class : ""; + _spanclass = "app-tooltip" + spanclass; } else { - _labelclass += (!string.IsNullOrEmpty(Class)) ? " " + Class : ""; + var labelclass = (!string.IsNullOrEmpty(Class)) ? " " + Class : ""; + _labelclass = "form-label" + labelclass; } var text = Localize("Text", String.Empty); diff --git a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs index 773df857..711504c6 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -13,6 +13,9 @@ namespace Oqtane.Modules.Controls [Parameter] public string ResourceKey { get; set; } + [Parameter] + public string ResourceType { get; set; } + protected bool IsLocalizable { get; private set; } protected string Localize(string name) => _localizer?[name] ?? name; @@ -50,9 +53,14 @@ namespace Oqtane.Modules.Controls { IsLocalizable = false; - if (!String.IsNullOrEmpty(ResourceKey) && ModuleState?.ModuleType != null) + if (string.IsNullOrEmpty(ResourceType)) { - var moduleType = Type.GetType(ModuleState.ModuleType); + ResourceType = ModuleState?.ModuleType; + } + + if (!String.IsNullOrEmpty(ResourceKey) && !string.IsNullOrEmpty(ResourceType)) + { + var moduleType = Type.GetType(ResourceType); if (moduleType != null) { using (var scope = ServiceActivator.GetScope()) diff --git a/Oqtane.Client/Modules/Controls/Pager.razor b/Oqtane.Client/Modules/Controls/Pager.razor index 40dc54ca..99dbc1ca 100644 --- a/Oqtane.Client/Modules/Controls/Pager.razor +++ b/Oqtane.Client/Modules/Controls/Pager.razor @@ -54,21 +54,23 @@ } @if (Format == "Table" && Row != null) { - - - @Header - - - @foreach (var item in ItemList) - { - @Row(item) - @if (Detail != null) - { - @Detail(item) - } - } - -
+
+ + + @Header + + + @foreach (var item in ItemList) + { + @Row(item) + @if (Detail != null) + { + @Detail(item) + } + } + +
+
} @if (Format == "Grid" && Row != null) { @@ -107,8 +109,8 @@
  • UpdateList(1))>
  • - @if (_pages > _displayPages) - { + @if (_pages > _displayPages && _displayPages > 1) + {
  • SkipPages("back"))>
  • @@ -135,7 +137,7 @@
  • NavigateToPage("next"))>
  • - @if (_pages > _displayPages) + @if (_pages > _displayPages && _displayPages > 1) {
  • SkipPages("forward"))> @@ -145,7 +147,7 @@ UpdateList(_pages))>
  • - Page @_page of @_pages + Page @_page of @_pages
  • } diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor index 82afff0c..d926bbe0 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditor.razor +++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor @@ -120,19 +120,20 @@ new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" } }; - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { _content = Content; // raw HTML + await RefreshRichText(); } protected override async Task OnAfterRenderAsync(bool firstRender) { - var interop = new RichTextEditorInterop(JSRuntime); - - if (firstRender) + var interop = new RichTextEditorInterop(JSRuntime); + if (firstRender) { await base.OnAfterRenderAsync(firstRender); + await interop.CreateEditor( _editorElement, _toolBar, @@ -140,15 +141,14 @@ Placeholder, Theme, DebugLevel); + + await interop.LoadEditorContent(_editorElement, Content); + + _content = Content; // raw HTML + } - - await interop.LoadEditorContent(_editorElement, Content); - - _content = Content; // raw HTML - - // preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor ) - _original = await interop.GetHtml(_editorElement); - + // preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor ) + _original = await interop.GetHtml(_editorElement); } public void CloseFileManager() diff --git a/Oqtane.Client/Modules/HtmlText/Settings.razor b/Oqtane.Client/Modules/HtmlText/Settings.razor index 8aab9c77..237049a6 100644 --- a/Oqtane.Client/Modules/HtmlText/Settings.razor +++ b/Oqtane.Client/Modules/HtmlText/Settings.razor @@ -5,44 +5,45 @@ @inject IStringLocalizer Localizer @inject IStringLocalizer SharedLocalizer -
    -
    - -
    - -
    +
    +
    + +
    +
    +
    - @code { - private string _allowfilemanagement; +@code { + private string resourceType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client"; // for localization + private string _allowfilemanagement; - protected override void OnInitialized() + protected override void OnInitialized() + { + try { - try - { - _allowfilemanagement = SettingService.GetSetting(ModuleState.Settings, "AllowFileManagement", "true"); - } - catch (Exception ex) - { - ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); - } + _allowfilemanagement = SettingService.GetSetting(ModuleState.Settings, "AllowFileManagement", "true"); } - - public async Task UpdateSettings() + catch (Exception ex) { - try - { - var settings = ModuleState.Settings; - settings = SettingService.SetSetting(settings, "AllowFileManagement", _allowfilemanagement); - await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); - } - catch (Exception ex) - { - ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); - } + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); } } + + public async Task UpdateSettings() + { + try + { + var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + settings = SettingService.SetSetting(settings, "AllowFileManagement", _allowfilemanagement); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index 30adc2a1..f3f06aee 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -134,14 +134,19 @@ namespace Oqtane.Modules return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment); } - public string ImageUrl(int fileid, int width, int height, string mode) + public string ImageUrl(int fileid, int width, int height) { - return ImageUrl(fileid, width, height, mode, 0); + return ImageUrl(fileid, width, height, ""); } - public string ImageUrl(int fileid, int width, int height, string mode, int rotate) + public string ImageUrl(int fileid, int width, int height, string mode) { - return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, rotate); + return ImageUrl(fileid, width, height, mode, "", "", 0, false); + } + + public string ImageUrl(int fileid, int width, int height, string mode, string position, string background, int rotate, bool recreate) + { + return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate); } public virtual Dictionary GetUrlParameters(string parametersTemplate = "") diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index a2366502..761d52e6 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -5,7 +5,7 @@ Exe 3.0 Debug;Release - 3.0.1 + 3.0.2 Oqtane Shaun Walker .NET Foundation @@ -13,7 +13,7 @@ .NET Foundation https://www.oqtane.org https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE - https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1 + https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.2 https://github.com/oqtane/oqtane.framework Git Oqtane diff --git a/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx index eae2f962..facc630b 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Jobs/Edit.resx @@ -186,4 +186,10 @@ Next Execution: + + Week(s) + + + Execute Once + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Jobs/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Jobs/Index.resx index a3da62e9..db97ddc3 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Jobs/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Jobs/Index.resx @@ -133,19 +133,16 @@ Every - Minute + Minute(s) - Hour + Hour(s) - Day + Day(s) - Month - - - s + Month(s) Error Deleting Job @@ -177,4 +174,22 @@ Log + + An error occurred when starting the job + + + An error occurred when stopping the job + + + The process responsible for executing this job has been started. The next execution will be based on the schedule criteria for the job. + + + The process responsible for executing this job has been stopped. In order to restart the process you will need to use the Start button or restart the application. + + + Week(s) + + + Execute Once + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Login/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Login/Index.resx index feaa718f..36ae93c3 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Login/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Login/Index.resx @@ -138,4 +138,13 @@ You Are Already Signed In + + Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again + + + Please Check The Email Address Associated To Your User Account For A Password Reset Notification + + + User Does Not Exist + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Logs/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Logs/Index.resx index 84d9994a..dfd55880 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Logs/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Logs/Index.resx @@ -192,4 +192,22 @@ Details + + Error Saving Settings + + + Events + + + Number of days of events to retain + + + Retention (Days): + + + Settings + + + Settings Saved Successfully + \ 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 e6838ba4..ad6dfd25 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Pages/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Pages/Edit.resx @@ -258,9 +258,6 @@ Theme Settings - - - Select whether the link in the site navigation is enabled or disabled diff --git a/Oqtane.Client/Resources/Modules/Admin/Reset/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Reset/Index.resx index 0922f6da..a1a3fcb0 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Reset/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Reset/Index.resx @@ -117,22 +117,37 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - Confirm Password: - Passwords Entered Do Not Match - You Must Provide A Username, Password, and Email Address + You Must Provide The Password And Confirmation Reset Password - Error Resetting User Password. Please Ensure Password Meets Complexity Requirements. + Error Resetting User Password. Please Ensure The Request To Reset Your Password Was Made Within The Past 24 Hours And The New Password Meets The Complexity Requirements. Error Resetting User Password + + Confirm: + + + Enter the password again. It must exactly match the password entered above. + + + The new password. It must satisfy complexity rules for the site. + + + Password: + + + Your username will be populated from the link you received in the password reset notification + + + Username: + \ 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 cefa464f..49c4d0e7 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Site/Index.resx @@ -129,9 +129,6 @@ Default Container: - - Appearance - Default Admin Container @@ -145,7 +142,7 @@ Site Settings Saved - An Alias Specified Has Already Been Used For Another Site + The Default Alias Has Not Been Specified Or An Alias Was Specified That Has Already Been Used For Another Site You Must Provide A Site Name, Alias, And Default Theme/Container @@ -223,7 +220,7 @@ Aliases: - Is Deleted? + Deleted? Logo: @@ -318,4 +315,13 @@ Delete Site + + The default alias for the site. Requests for non-default aliases will be redirected to the default alias. + + + Default Alias: + + + Aliases + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/SystemInfo/Index.resx b/Oqtane.Client/Resources/Modules/Admin/SystemInfo/Index.resx index 724b58dd..e564fcf8 100644 --- a/Oqtane.Client/Resources/Modules/Admin/SystemInfo/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/SystemInfo/Index.resx @@ -133,7 +133,7 @@ Server Path - Server Time + Server Date/Time (in UTC) Framework Version: @@ -148,7 +148,7 @@ Server Path: - Server Time: + Server Date/Time: Restart Application diff --git a/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Add.resx b/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Add.resx index 6f983495..e1185498 100644 --- a/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Add.resx +++ b/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Add.resx @@ -121,10 +121,10 @@ Redirect To: - A fully qualified Url where the user will be redirected + A relative or absolute Url where the user will be redirected - A fully qualified Url for this site + An absolute Url identifying a path to a specific page in the site Url: @@ -135,4 +135,10 @@ Please Provide All Required Information + + The Url and Redirect To cannot be the same + + + The Url must belong to the current site + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Edit.resx b/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Edit.resx index 400ba0d5..2312ef83 100644 --- a/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Edit.resx +++ b/Oqtane.Client/Resources/Modules/Admin/UrlMappings/Edit.resx @@ -121,10 +121,10 @@ Redirect To: - A fully qualified Url where the user will be redirected + A relative or absolute Url where the user will be redirected - A fully qualified Url for this site + A relative Url identifying a path to a specific page in the site Url: @@ -138,4 +138,7 @@ Please Provide All Required Information + + The Url and Redirect To cannot be the same + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx b/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx index 7f305a74..a6e25bbc 100644 --- a/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx +++ b/Oqtane.Client/Resources/Modules/Admin/Visitors/Index.resx @@ -156,11 +156,11 @@ Visitors - + Specify if visitor tracking is enabled - - Visitor Tracking Enabled? + + Tracking Enabled? IP @@ -171,4 +171,19 @@ Created + + Details + + + Comma delimited list of terms which may exist in IP addresses, user agents, or languages which identify visitors which should not be tracked (ie. bots) + + + Filter: + + + Number of days of visitor activity to retain + + + Retention (Days): + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Themes/Controls/ControlPanel.resx b/Oqtane.Client/Resources/Themes/Controls/ControlPanel.resx index f76bc983..913e111d 100644 --- a/Oqtane.Client/Resources/Themes/Controls/ControlPanel.resx +++ b/Oqtane.Client/Resources/Themes/Controls/ControlPanel.resx @@ -177,4 +177,13 @@ Check For System Updates + + Visibility: + + + Page Editors Only + + + Same As Page + \ No newline at end of file diff --git a/Oqtane.Client/Resources/Themes/OqtaneTheme/Containers/ContainerSettings.resx b/Oqtane.Client/Resources/Themes/OqtaneTheme/ContainerSettings.resx similarity index 51% rename from Oqtane.Client/Resources/Themes/OqtaneTheme/Containers/ContainerSettings.resx rename to Oqtane.Client/Resources/Themes/OqtaneTheme/ContainerSettings.resx index 4c05a1fb..1e4a939f 100644 --- a/Oqtane.Client/Resources/Themes/OqtaneTheme/Containers/ContainerSettings.resx +++ b/Oqtane.Client/Resources/Themes/OqtaneTheme/ContainerSettings.resx @@ -1,65 +1,65 @@  - + mimetype: application/x-microsoft.net.object.bytearray.base64 + value : The object must be serialized into a byte array + : using a System.ComponentModel.TypeConverter + : and then encoded with base64 encoding. + --> + diff --git a/Oqtane.Client/Resources/Themes/OqtaneTheme/Themes/ThemeSettings.resx b/Oqtane.Client/Resources/Themes/OqtaneTheme/ThemeSettings.resx similarity index 99% rename from Oqtane.Client/Resources/Themes/OqtaneTheme/Themes/ThemeSettings.resx rename to Oqtane.Client/Resources/Themes/OqtaneTheme/ThemeSettings.resx index 7d8c7c4d..7200f2dd 100644 --- a/Oqtane.Client/Resources/Themes/OqtaneTheme/Themes/ThemeSettings.resx +++ b/Oqtane.Client/Resources/Themes/OqtaneTheme/ThemeSettings.resx @@ -121,7 +121,7 @@ Specify if a Footer pane should always be displayed in a fixed location at the bottom of the page. - Display Footer? + Display Fixed Footer? Specify if a Login option should be displayed, Note that this option does not prevent the login page from being accessible via a direct url. diff --git a/Oqtane.Client/Services/Interfaces/ISettingService.cs b/Oqtane.Client/Services/Interfaces/ISettingService.cs index e02261f8..60099fd5 100644 --- a/Oqtane.Client/Services/Interfaces/ISettingService.cs +++ b/Oqtane.Client/Services/Interfaces/ISettingService.cs @@ -206,7 +206,7 @@ namespace Oqtane.Services /// Dictionary SetSetting(Dictionary settings, string settingName, string settingValue); - Dictionary SetSetting(Dictionary settings, string settingName, string settingValue, bool isPublic); + Dictionary SetSetting(Dictionary settings, string settingName, string settingValue, bool isPrivate); Dictionary MergeSettings(Dictionary settings1, Dictionary settings2); diff --git a/Oqtane.Client/Services/Interfaces/IUrlMappingService.cs b/Oqtane.Client/Services/Interfaces/IUrlMappingService.cs index 0a8ef940..6da0bf9d 100644 --- a/Oqtane.Client/Services/Interfaces/IUrlMappingService.cs +++ b/Oqtane.Client/Services/Interfaces/IUrlMappingService.cs @@ -24,6 +24,14 @@ namespace Oqtane.Services /// Task GetUrlMappingAsync(int urlMappingId); + /// + /// Get one specific + /// + /// ID-reference of a + /// A url + /// + Task GetUrlMappingAsync(int siteId, string url); + /// /// Add / save a new to the database. /// diff --git a/Oqtane.Client/Services/SettingService.cs b/Oqtane.Client/Services/SettingService.cs index 74cf3949..1c62a41c 100644 --- a/Oqtane.Client/Services/SettingService.cs +++ b/Oqtane.Client/Services/SettingService.cs @@ -131,14 +131,21 @@ namespace Oqtane.Services foreach (KeyValuePair kvp in settings) { string value = kvp.Value; - bool ispublic = false; + bool modified = false; + bool isprivate = false; + + // manage settings modified with SetSetting method + if (value.StartsWith("[Private]")) + { + modified = true; + isprivate = true; + value = value.Substring(9); + } if (value.StartsWith("[Public]")) { - if (entityName == EntityNames.Site) - { - ispublic = true; - } - value = value.Substring(8); // remove [Public] + modified = true; + isprivate = false; + value = value.Substring(8); } Setting setting = settingsList.FirstOrDefault(item => item.SettingName.Equals(kvp.Key, StringComparison.OrdinalIgnoreCase)); @@ -149,22 +156,21 @@ namespace Oqtane.Services setting.EntityId = entityId; setting.SettingName = kvp.Key; setting.SettingValue = value; - setting.IsPublic = ispublic; + setting.IsPrivate = isprivate; setting = await AddSettingAsync(setting); } else { - if (setting.SettingValue != kvp.Value) + if (setting.SettingValue != value || (modified && setting.IsPrivate != isprivate)) { setting.SettingValue = value; - setting.IsPublic = ispublic; + setting.IsPrivate = isprivate; setting = await UpdateSettingAsync(setting); } } } } - public async Task GetSettingAsync(string entityName, int settingId) { return await GetJsonAsync($"{Apiurl}/{settingId}/{entityName}"); @@ -201,13 +207,13 @@ namespace Oqtane.Services return SetSetting(settings, settingName, settingValue, false); } - public Dictionary SetSetting(Dictionary settings, string settingName, string settingValue, bool isPublic) + public Dictionary SetSetting(Dictionary settings, string settingName, string settingValue, bool isPrivate) { if (settings == null) { settings = new Dictionary(); } - settingValue = (isPublic) ? "[Public]" + settingValue : settingValue; + settingValue = (isPrivate) ? "[Private]" + settingValue : "[Public]" + settingValue; if (settings.ContainsKey(settingName)) { settings[settingName] = settingValue; diff --git a/Oqtane.Client/Services/UrlMappingService.cs b/Oqtane.Client/Services/UrlMappingService.cs index 725149dc..121e818b 100644 --- a/Oqtane.Client/Services/UrlMappingService.cs +++ b/Oqtane.Client/Services/UrlMappingService.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Collections.Generic; using Oqtane.Documentation; using Oqtane.Shared; +using System.Net; namespace Oqtane.Services { @@ -33,6 +34,11 @@ namespace Oqtane.Services return await GetJsonAsync($"{Apiurl}/{urlMappingId}"); } + public async Task GetUrlMappingAsync(int siteId, string url) + { + return await GetJsonAsync($"{Apiurl}/url/{siteId}?url={WebUtility.UrlEncode(url)}"); + } + public async Task AddUrlMappingAsync(UrlMapping role) { return await PostJsonAsync(Apiurl, role); diff --git a/Oqtane.Client/Themes/BlazorTheme/Containers/Container.razor b/Oqtane.Client/Themes/BlazorTheme/Containers/Container.razor index 9ca3599e..15a6f398 100644 --- a/Oqtane.Client/Themes/BlazorTheme/Containers/Container.razor +++ b/Oqtane.Client/Themes/BlazorTheme/Containers/Container.razor @@ -1,13 +1,20 @@ @namespace Oqtane.Themes.BlazorTheme @inherits ContainerBase
    -
    -
    -

    -
    -
    -
    -
    + @if (ModuleState.Title != "-") + { +
    +
    +

    +
    +
    +
    + } + else + { + + } +
    diff --git a/Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor b/Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor index 758a1bef..960b2dd4 100644 --- a/Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/Theme/ControlPanel.razor @@ -46,360 +46,366 @@
    - @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) - { -
    -
    - + @if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin)) + { +
    +
    + +
    -
    -
    +
    -
    -
    - +
    +
    + +
    -
    -
    -
    - - - +
    +
    + + + +
    -
    -
    -
    -
    - @if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone)) - { - - } - else - { - - } +
    +
    + @if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone)) + { + + } + else + { + + } +
    -
    - } + } - @if (_deleteConfirmation) - { -
    -