diff --git a/.gitignore b/.gitignore index 33c751ad..8f8f91ba 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ Oqtane.Server/appsettings.json Oqtane.Server/Data/*.mdf Oqtane.Server/Data/*.ldf +/Oqtane.Server/Properties/PublishProfiles/FolderProfile.pubxml diff --git a/LICENSE b/LICENSE index 02a0812b..9a5062f7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 .NET Foundation +Copyright (c) 2018-2020 .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 66e5b15f..3d13adff 100644 --- a/Oqtane.Client/App.razor +++ b/Oqtane.Client/App.razor @@ -19,12 +19,13 @@ @code { private bool _initialized; private bool _installed; + private PageState PageState { get; set; } protected override async Task OnParametersSetAsync() { - var response = await InstallationService.IsInstalled(); - _installed = response.Success; + var installation = await InstallationService.IsInstalled(); + _installed = installation.Success; _initialized = true; } diff --git a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor index c1776600..7e3004fb 100644 --- a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor +++ b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor @@ -19,13 +19,13 @@ @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } - - List _pages; + private List _pages; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override void OnInitialized() { - Page admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin"); + var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin"); _pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList(); } } diff --git a/Oqtane.Client/Modules/Admin/Error/Index.razor b/Oqtane.Client/Modules/Admin/Error/Index.razor index 8ecd898c..9e0df574 100644 --- a/Oqtane.Client/Modules/Admin/Error/Index.razor +++ b/Oqtane.Client/Modules/Admin/Error/Index.razor @@ -3,7 +3,7 @@ @inject IModuleService ModuleService @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } } + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; protected override async Task OnInitializedAsync() { @@ -13,6 +13,7 @@ string message = "A Problem Was Encountered Loading Module " + module.ModuleDefinitionName; AddModuleMessage(message, MessageType.Error); } + await logger.LogCritical("Error Loading Module {Module}", module); } } diff --git a/Oqtane.Client/Modules/Admin/Files/Add.razor b/Oqtane.Client/Modules/Admin/Files/Add.razor index 65935a72..a01b9b1c 100644 --- a/Oqtane.Client/Modules/Admin/Files/Add.razor +++ b/Oqtane.Client/Modules/Admin/Files/Add.razor @@ -4,77 +4,59 @@ @inject IFileService FileService @inject IFolderService FolderService -@if (_folders != null) -{ -
-
- - - -
-
- - - - - -
- - - -
-
-
- - - - - - - - - -
- - - -
- - - -
- -
-
-
-
-
- Cancel -} + + + + + + + +
+ + + +
+ Cancel +
+ + @if (_folders != null) + { + + + + + + + + + +
+ + + +
+ + + +
+ + Cancel + } +
+
@code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private string url = string.Empty; + private List _folders; + private int _folderId = -1; - string url = ""; - List _folders; - int _folderId = -1; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { @@ -90,7 +72,7 @@ { try { - if (url != "" && _folderId != -1) + if (url != string.Empty && _folderId != -1) { await FileService.UploadFileAsync(url, _folderId); await logger.LogInformation("File Downloaded Successfully From Url {Url}", url); diff --git a/Oqtane.Client/Modules/Admin/Files/Edit.razor b/Oqtane.Client/Modules/Admin/Files/Edit.razor index bbe37f9b..0083cce0 100644 --- a/Oqtane.Client/Modules/Admin/Files/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Files/Edit.razor @@ -8,10 +8,10 @@ - -
- + - @if (PageState.QueryString.ContainsKey("id")) { @@ -25,18 +25,16 @@
- + - +
- - - + + +
@@ -58,24 +56,25 @@ } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } - public override string Title { get { return "Folder Management"; } } - - List _folders; - int _folderId = -1; - string _name; - int _parentId = -1; - bool _isSystem; - string _permissions = ""; - string _createdBy; - DateTime _createdOn; - string _modifiedBy; - DateTime _modifiedOn; + private List _folders; + private int _folderId = -1; + private string _name; + private int _parentId = -1; + private bool _isSystem; + private string _permissions = string.Empty; + private string _createdBy; + private DateTime _createdOn; + private string _modifiedBy; + private DateTime _modifiedOn; #pragma warning disable 649 - PermissionGrid _permissionGrid; + private PermissionGrid _permissionGrid; #pragma warning restore 649 + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + + public override string Title => "Folder Management"; + protected override async Task OnInitializedAsync() { try @@ -101,11 +100,7 @@ else { _parentId = _folders[0].FolderId; - List permissionstrings = new List(); - permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.Browse, Permissions = Constants.AdminRole }); - permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.View, Permissions = Constants.AdminRole }); - permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.Edit, Permissions = Constants.AdminRole }); - _permissions = UserSecurity.SetPermissionStrings(permissionstrings); + _permissions = string.Empty; } } catch (Exception ex) @@ -119,7 +114,7 @@ { try { - if (_name != "" && _parentId != -1) + if (_name != string.Empty && _parentId != -1) { Folder folder; if (_folderId != -1) @@ -132,6 +127,7 @@ } folder.SiteId = PageState.Site.SiteId; + if (_parentId == -1) { folder.ParentId = null; @@ -140,6 +136,7 @@ { folder.ParentId = _parentId; } + folder.Name = _name; folder.IsSystem = _isSystem; folder.Permissions = _permissionGrid.GetPermissions(); @@ -152,6 +149,7 @@ { folder = await FolderService.AddFolderAsync(folder); } + await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId); await logger.LogInformation("Folder Saved {Folder}", folder); NavigationManager.NavigateTo(NavigateUrl()); diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index 6dd27603..d92e0994 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -49,24 +49,23 @@ } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private List _folders; + private int _folderId = -1; + private List _files; - List _folders; - int _folderId = -1; - List _files; - Uri _uri; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnParametersSetAsync() { try { _folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId); + if (_folderId == -1 && _folders.Count > 0) { _folderId = _folders[0].FolderId; await GetFiles(); } - _uri = new Uri(NavigationManager.Uri); } catch (Exception ex) { diff --git a/Oqtane.Client/Modules/Admin/Jobs/Add.razor b/Oqtane.Client/Modules/Admin/Jobs/Add.razor index a333d0d5..65361e41 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Add.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Add.razor @@ -3,99 +3,100 @@ @inject NavigationManager NavigationManager @inject IJobService JobService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - - -
- - - -
- - - -
- - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + + +
+ + + +
+ + + +
+ + + +
Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + 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 string _startDate = string.Empty; + private string _endDate = string.Empty; + private string _retentionHistory = "10"; - string _name = ""; - string _jobType = ""; - string _isEnabled = "True"; - string _interval = ""; - string _frequency = ""; - string _startDate = ""; - string _endDate = ""; - string _retentionHistory = "10"; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; private async Task SaveJob() { - if (_name != "" && !string.IsNullOrEmpty(_jobType) && _frequency != "" && _interval != "" && _retentionHistory != "") + if (_name != string.Empty && !string.IsNullOrEmpty(_jobType) && _frequency != string.Empty && _interval != string.Empty && _retentionHistory != string.Empty) { - Job job = new Job(); + var job = new Job(); job.Name = _name; job.JobType = _jobType; job.IsEnabled = Boolean.Parse(_isEnabled); job.Frequency = _frequency; job.Interval = int.Parse(_interval); - if (_startDate == "") + + if (_startDate == string.Empty) { job.StartDate = null; } @@ -103,7 +104,8 @@ { job.StartDate = DateTime.Parse(_startDate); } - if (_endDate == "") + + if (_endDate == string.Empty) { job.EndDate = null; } @@ -111,6 +113,7 @@ { job.EndDate = DateTime.Parse(_endDate); } + job.RetentionHistory = int.Parse(_retentionHistory); job.IsStarted = false; job.IsExecuting = false; diff --git a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor index 205dda81..ae1f3d9b 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor @@ -3,88 +3,88 @@ @inject NavigationManager NavigationManager @inject IJobService JobService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - - -
- - - -
- - - -
- - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + + +
+ + + +
+ + + +
+ + + +
Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + 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 string _startDate = string.Empty; + private string _endDate = string.Empty; + private string _retentionHistory = string.Empty; - int _jobId; - string _name = ""; - string _jobType = ""; - string _isEnabled = "True"; - string _interval = ""; - string _frequency = ""; - string _startDate = ""; - string _endDate = ""; - string _retentionHistory = ""; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { @@ -99,8 +99,8 @@ _isEnabled = job.IsEnabled.ToString(); _interval = job.Interval.ToString(); _frequency = job.Frequency; - _startDate = (job.StartDate != null) ? job.StartDate.ToString() : ""; - _endDate = (job.EndDate != null) ? job.EndDate.ToString() : ""; + _startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty; + _endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty; _retentionHistory = job.RetentionHistory.ToString(); } } @@ -113,15 +113,16 @@ private async Task SaveJob() { - if (_name != "" && !string.IsNullOrEmpty(_jobType) && _frequency != "" && _interval != "" && _retentionHistory != "") + if (_name != string.Empty && !string.IsNullOrEmpty(_jobType) && _frequency != string.Empty && _interval != string.Empty && _retentionHistory != string.Empty) { - Job job = await JobService.GetJobAsync(_jobId); + 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); - if (_startDate == "") + + if (_startDate == string.Empty) { job.StartDate = null; } @@ -129,7 +130,8 @@ { job.StartDate = DateTime.Parse(_startDate); } - if (_endDate == "") + + if (_endDate == string.Empty) { job.EndDate = null; } @@ -137,6 +139,7 @@ { job.EndDate = DateTime.Parse(_endDate); } + job.RetentionHistory = int.Parse(_retentionHistory); try diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index 602708c9..f15c50df 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -47,10 +47,10 @@ else } @code { + private List _jobs; + public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } - List _jobs; - protected override async Task OnParametersSetAsync() { _jobs = await JobService.GetJobsAsync(); @@ -58,7 +58,7 @@ else private string DisplayStatus(bool isEnabled, bool isExecuting) { - string status = ""; + var status = string.Empty; if (!isEnabled) { status = "Disabled"; @@ -81,7 +81,7 @@ else private string DisplayFrequency(int interval, string frequency) { - string result = "Every " + interval.ToString() + " "; + var result = "Every " + interval.ToString() + " "; switch (frequency) { case "m": @@ -97,10 +97,12 @@ else result += "Month"; break; } + if (interval > 1) { result += "s"; } + return result; } diff --git a/Oqtane.Client/Modules/Admin/Jobs/Log.razor b/Oqtane.Client/Modules/Admin/Jobs/Log.razor index af0d5d5e..9efc1486 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Log.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Log.razor @@ -28,23 +28,25 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } - - List _jobLogs; + private List _jobLogs; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnParametersSetAsync() { _jobLogs = await JobLogService.GetJobLogsAsync(); + if (PageState.QueryString.ContainsKey("id")) { _jobLogs = _jobLogs.Where(item => item.JobId == Int32.Parse(PageState.QueryString["id"])).ToList(); } + _jobLogs = _jobLogs.OrderByDescending(item => item.JobLogId).ToList(); } private string DisplayStatus(bool isExecuting, bool? succeeded) { - string status = ""; + var status = string.Empty; if (isExecuting) { status = "Executing"; @@ -60,6 +62,7 @@ else status = "Failed"; } } + return status; } } diff --git a/Oqtane.Client/Modules/Admin/Login/Index.razor b/Oqtane.Client/Modules/Admin/Login/Index.razor index 5310049d..106ee57f 100644 --- a/Oqtane.Client/Modules/Admin/Login/Index.razor +++ b/Oqtane.Client/Modules/Admin/Login/Index.razor @@ -5,7 +5,7 @@ @inject IUserService UserService @inject IServiceProvider ServiceProvider -@if (_message != "") +@if (_message != string.Empty) { } @@ -14,7 +14,7 @@ ... - You are already logged in +
@@ -41,14 +41,14 @@ @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } } + private string _returnUrl = string.Empty; + private string _message = string.Empty; + private MessageType _type = MessageType.Info; + private string _username = string.Empty; + private string _password = string.Empty; + private bool _remember = false; - string _returnUrl = ""; - string _message = ""; - MessageType _type = MessageType.Info; - string _username = ""; - string _password = ""; - bool _remember = false; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; protected override async Task OnInitializedAsync() { @@ -56,13 +56,15 @@ { _returnUrl = PageState.QueryString["returnurl"]; } + if (PageState.QueryString.ContainsKey("name")) { _username = PageState.QueryString["name"]; } + if (PageState.QueryString.ContainsKey("token")) { - User user = new User(); + var user = new User(); user.SiteId = PageState.Site.SiteId; user.Username = _username; user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]); @@ -81,15 +83,15 @@ private async Task Login() { - var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); - if (authstateprovider == null) + if (PageState.Runtime == Runtime.Server) { // server-side Blazor - User user = new User(); + var user = new User(); user.SiteId = PageState.Site.SiteId; user.Username = _username; user.Password = _password; user = await UserService.LoginUserAsync(user, false, false); + if (user.IsAuthenticated) { await logger.LogInformation("Login Successful For Username {Username}", _username); @@ -97,7 +99,7 @@ var interop = new Interop(JsRuntime); string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken"); var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl }; - await interop.SubmitForm("/pages/login/", fields); + await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields); } else { @@ -108,7 +110,7 @@ else { // client-side Blazor - User user = new User(); + var user = new User(); user.SiteId = PageState.Site.SiteId; user.Username = _username; user.Password = _password; @@ -116,6 +118,7 @@ if (user.IsAuthenticated) { await logger.LogInformation("Login Successful For Username {Username}", _username); + var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); authstateprovider.NotifyAuthenticationChanged(); NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload")); } @@ -134,9 +137,9 @@ private async Task Forgot() { - if (_username != "") + if (_username != string.Empty) { - User user = await UserService.GetUserAsync(_username, PageState.Site.SiteId); + var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId); if (user != null) { await UserService.ForgotPasswordAsync(user); @@ -152,6 +155,7 @@ { _message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again"; } + StateHasChanged(); } - } +} diff --git a/Oqtane.Client/Modules/Admin/Logs/Detail.razor b/Oqtane.Client/Modules/Admin/Logs/Detail.razor index 0fd6333a..1baac265 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Detail.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Detail.razor @@ -10,156 +10,156 @@ - @if (_pageName != "") + @if (_pageName != string.Empty) { } - @if (_moduleTitle != "") + @if (_moduleTitle != string.Empty) { } - @if (_username != "") + @if (_username != string.Empty) { } @if (!string.IsNullOrEmpty(_exception)) { }
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private int _logId; + private string _logDate = string.Empty; + private string _level = string.Empty; + private string _feature = string.Empty; + private string _function = string.Empty; + private string _category = string.Empty; + private string _pageName = string.Empty; + private string _moduleTitle = string.Empty; + private string _username = string.Empty; + private string _url = string.Empty; + private string _template = string.Empty; + private string _message = string.Empty; + private string _exception = string.Empty; + private string _properties = string.Empty; + private string _server = string.Empty; - int _logId; - string _logDate = ""; - string _level = ""; - string _feature = ""; - string _function = ""; - string _category = ""; - string _pageName = ""; - string _moduleTitle = ""; - string _username = ""; - string _url = ""; - string _template = ""; - string _message = ""; - string _exception = ""; - string _properties = ""; - string _server = ""; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { try { _logId = Int32.Parse(PageState.QueryString["id"]); - Log log = await LogService.GetLogAsync(_logId); + var log = await LogService.GetLogAsync(_logId); if (log != null) { _logDate = log.LogDate.ToString(CultureInfo.CurrentCulture); @@ -167,30 +167,34 @@ _feature = log.Feature; _function = log.Function; _category = log.Category; + if (log.PageId != null) { - Page page = await PageService.GetPageAsync(log.PageId.Value); + var page = await PageService.GetPageAsync(log.PageId.Value); if (page != null) { _pageName = page.Name; } } + if (log.PageId != null && log.ModuleId != null) { - PageModule pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value); + var pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value); if (pagemodule != null) { _moduleTitle = pagemodule.Title; } } + if (log.UserId != null) { - User user = await UserService.GetUserAsync(log.UserId.Value, PageState.Site.SiteId); + var user = await UserService.GetUserAsync(log.UserId.Value, PageState.Site.SiteId); if (user != null) { _username = user.Username; } } + _url = log.Url; _template = log.MessageTemplate; _message = log.Message; diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 77fd5d4c..730c6d13 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -71,12 +71,12 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private string _level = "-"; + private string _function = "-"; + private string _rows = "10"; + private List _logs; - string _level = "-"; - string _function = "-"; - string _rows = "10"; - List _logs; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { @@ -139,12 +139,12 @@ else private async Task GetLogs() { - _logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((_level == "-") ? "" : _level), ((_function == "-") ? "" : _function), int.Parse(_rows)); + _logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((_level == "-") ? string.Empty : _level), ((_function == "-") ? string.Empty : _function), int.Parse(_rows)); } private string GetClass(string function) { - string classname = ""; + string classname = string.Empty; switch (function) { case "Create": @@ -163,7 +163,7 @@ else classname = "table-secondary"; break; default: - classname = ""; + classname = string.Empty; break; } return classname; diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor new file mode 100644 index 00000000..8b4cb758 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -0,0 +1,80 @@ +@namespace Oqtane.Modules.Admin.ModuleCreator +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject IModuleDefinitionService ModuleDefinitionService +@inject IModuleService ModuleService + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +@code { + private string _owner = string.Empty; + private string _module = string.Empty; + private string _description = string.Empty; + private string _template = string.Empty; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + + protected override void OnInitialized() + { + AddModuleMessage("Please Note That Once You Select The Create Module Button The Application Must Restart In Order To Complete The Process. If You Create An External Module You Will Need To Compile The Source Code In Order To Make It Functional.", MessageType.Info); + } + + private async Task CreateModule() + { + try + { + if (!string.IsNullOrEmpty(_owner) && !string.IsNullOrEmpty(_module) && !string.IsNullOrEmpty(_template)) + { + var moduleDefinition = new ModuleDefinition { Owner = _owner.Replace(" ",""), Name = _module.Replace(" ", ""), Description = _description, Template = _template }; + await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition, ModuleState.ModuleId); + } + else + { + AddModuleMessage("You Must Provide An Owner, Module Name, And Template", MessageType.Warning); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Creating Module"); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/ModuleInfo.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/ModuleInfo.cs new file mode 100644 index 00000000..81b82a6d --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/ModuleInfo.cs @@ -0,0 +1,15 @@ +using Oqtane.Models; + +namespace Oqtane.Modules.Admin.ModuleCreator +{ + public class ModuleInfo : IModule + { + public ModuleDefinition ModuleDefinition => new ModuleDefinition + { + Name = "Module Creator", + Description = "Enables software developers to quickly create modules by automating many of the initial module creation tasks", + Version = "1.0.0", + Categories = "Developer" + }; + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Edit.razor new file mode 100644 index 00000000..84e83aae --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Edit.razor @@ -0,0 +1,95 @@ +@using Oqtane.Modules.Controls +@using [Owner].[Module]s.Services +@using [Owner].[Module]s.Models + +@namespace [Owner].[Module]s.Modules +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject HttpClient http +@inject SiteState sitestate + + + + + + +
+ + + +
+ +Cancel +
+
+@if (PageState.Action == "Edit") +{ + +} + +@code { + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; + public override string Actions => "Add,Edit"; + + I[Module]Service [Module]Service; + int _id; + string _name; + string _createdby; + DateTime _createdon; + string _modifiedby; + DateTime _modifiedon; + + protected override async Task OnInitializedAsync() + { + try + { + [Module]Service = new [Module]Service(http, sitestate); + if (PageState.Action == "Edit") + { + _id = Int32.Parse(PageState.QueryString["id"]); + [Module] [Module] = await [Module]Service.Get[Module]Async(_id); + if ([Module] != null) + { + _name = [Module].Name; + _createdby = [Module].CreatedBy; + _createdon = [Module].CreatedOn; + _modifiedby = [Module].ModifiedBy; + _modifiedon = [Module].ModifiedOn; + } + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading [Module] {[Module]Id} {Error}", _id, ex.Message); + AddModuleMessage("Error Loading [Module]", MessageType.Error); + } + } + + private async Task Save() + { + try + { + if (PageState.Action == "Add") + { + [Module] [Module] = new [Module](); + [Module].ModuleId = ModuleState.ModuleId; + [Module].Name = _name; + [Module] = await [Module]Service.Add[Module]Async([Module]); + await logger.LogInformation("[Module] Added {[Module]}", [Module]); + } + else + { + [Module] [Module] = await [Module]Service.Get[Module]Async(_id); + [Module].Name = _name; + await [Module]Service.Update[Module]Async([Module]); + await logger.LogInformation("[Module] Updated {[Module]}", [Module]); + } + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving [Module] {Error}", ex.Message); + AddModuleMessage("Error Saving [Module]", MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Index.razor new file mode 100644 index 00000000..78e7c079 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Index.razor @@ -0,0 +1,106 @@ +@using [Owner].[Module]s.Services +@using [Owner].[Module]s.Models + +@namespace [Owner].[Module]s.Modules +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject HttpClient http +@inject SiteState sitestate + +@if (_[Module]s == null) +{ +

Loading...

+} +else +{ + +
+
+ @if (@_[Module]s.Count != 0) + { + +
+
[Module]s
+
+ +
+ + + @context.Name +
+
+
+ } + else + { +

No [Module]s To Display

+ } +} + + + +
+[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:

+[RootPath]Client\
+- [Owner].[Module]s.Module.Client.csproj - client project
+- _Imports.razor - global imports for module components
+- Edit.razor - component for adding or editing content
+- Index.razor - main component for your module **the content you are reading is in this file**
+- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module
+- Settings.razor - component for managing module settings
+- Services\I[Module]Service.cs - interface for defining service API methods
+- Services\[Module]Service.cs - implements service API interface methods

+[RootPath]Package\
+- [Owner].[Module]s.Module.nuspec - nuget manifest for packaging module
+- [Owner].[Module]s.Module.Package.csproj - packaging project
+- debug.cmd - copies assemblies to Oqtane bin folder when in Debug mode
+- release.cmd - creates nuget package and deploys to Oqtane wwwroot/modules folder when in Release mode

+[RootPath]Server\
+- [Owner].[Module]s.Module.Server.csproj - server project
+- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern
+- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content
+- Repository\I[Module]Repository.cs - interface for defining repository methods
+- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core
+- Repository\[Module]Context.cs - provides a DB Context for data access
+- Scripts\[Owner].[Module].1.0.0.sql - database schema definition script

+- Scripts\[Owner].[Module].Uninstall.sql - database uninstall script

+[RootPath]Shared\
+- [Owner].[Module]s.Module.Shared.csproj - shared project
+- Models\[Module].cs - model definition

+ + + +@code { + I[Module]Service [Module]Service; + List<[Module]> _[Module]s; + + protected override async Task OnInitializedAsync() + { + try + { + [Module]Service = new [Module]Service(http, sitestate); + _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading [Module] {Error}", ex.Message); + AddModuleMessage("Error Loading [Module]", MessageType.Error); + } + } + + private async Task Delete([Module] [Module]) + { + try + { + await [Module]Service.Delete[Module]Async([Module].[Module]Id); + await logger.LogInformation("[Module] Deleted {[Module]}", [Module]); + _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Deleting [Module] {[Module]} {Error}", [Module], ex.Message); + AddModuleMessage("Error Deleting [Module]", MessageType.Error); + } + } +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/ModuleInfo.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/ModuleInfo.cs new file mode 100644 index 00000000..a95a461e --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/ModuleInfo.cs @@ -0,0 +1,18 @@ +using Oqtane.Models; +using Oqtane.Modules; + +namespace [Owner].[Module]s.Modules +{ + public class ModuleInfo : IModule + { + public ModuleDefinition ModuleDefinition => new ModuleDefinition + { + Name = "[Module]", + Description = "[Module]", + Version = "1.0.0", + Dependencies = "[Owner].[Module]s.Module.Shared", + ServerManagerType = "[ServerManagerType]", + ReleaseVersions = "1.0.0" + }; + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Services/I[Module]Service.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Services/I[Module]Service.cs new file mode 100644 index 00000000..e98da06d --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Services/I[Module]Service.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Services +{ + public interface I[Module]Service + { + Task> Get[Module]sAsync(int ModuleId); + + Task<[Module]> Get[Module]Async(int [Module]Id); + + Task<[Module]> Add[Module]Async([Module] [Module]); + + Task<[Module]> Update[Module]Async([Module] [Module]); + + Task Delete[Module]Async(int [Module]Id); + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Services/[Module]Service.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Services/[Module]Service.cs new file mode 100644 index 00000000..f95c41b9 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Services/[Module]Service.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Oqtane.Modules; +using Oqtane.Services; +using Oqtane.Shared; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Services +{ + public class [Module]Service : ServiceBase, I[Module]Service, IService + { + private readonly SiteState _siteState; + + public [Module]Service(HttpClient http, SiteState siteState) : base(http) + { + _siteState = siteState; + } + + private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]"); + + public async Task> Get[Module]sAsync(int ModuleId) + { + List<[Module]> [Module]s = await GetJsonAsync>($"{Apiurl}?moduleid={ModuleId}"); + return [Module]s.OrderBy(item => item.Name).ToList(); + } + + public async Task<[Module]> Get[Module]Async(int [Module]Id) + { + return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}"); + } + + public async Task<[Module]> Add[Module]Async([Module] [Module]) + { + return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]); + } + + public async Task<[Module]> Update[Module]Async([Module] [Module]) + { + return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]); + } + + public async Task Delete[Module]Async(int [Module]Id) + { + await DeleteAsync($"{Apiurl}/{[Module]Id}"); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Settings.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Settings.razor new file mode 100644 index 00000000..a53dc57c --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/Settings.razor @@ -0,0 +1,47 @@ +@namespace [Owner].[Module]s.Modules +@inherits ModuleBase +@inject ISettingService SettingService + + + + + + +
+ + + +
+ +@code { + public override string Title => "[Module] Settings"; + + string _value; + + protected override async Task OnInitializedAsync() + { + try + { + Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + _value = SettingService.GetSetting(settings, "SettingName", ""); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } + + public async Task UpdateSettings() + { + try + { + Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + SettingService.SetSetting(settings, "SettingName", _value); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/[Owner].[Module]s.Module.Client.csproj b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/[Owner].[Module]s.Module.Client.csproj new file mode 100644 index 00000000..cc286603 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/[Owner].[Module]s.Module.Client.csproj @@ -0,0 +1,39 @@ + + + + netstandard2.1 + 3.0 + 1.0.0 + [Owner] + [Owner] + [Description] + [Owner].[Module]s.Module + [Owner] + + + + + + + + + + + + + + + ..\..\[RootFolder]\Oqtane.Client\bin\Debug\netstandard2.1\Oqtane.Client.dll + + + ..\..\[RootFolder]\Oqtane.Client\bin\Debug\netstandard2.1\Oqtane.Shared.dll + + + + + + false + false + + + diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/_Imports.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/_Imports.razor new file mode 100644 index 00000000..147a5eee --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Client/_Imports.razor @@ -0,0 +1,18 @@ +@using System +@using System.Linq +@using System.Collections.Generic +@using System.Net.Http + +@using Microsoft.AspNetCore.Components.Routing +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.JSInterop + +@using Oqtane.Models +@using Oqtane.Modules +@using Oqtane.Modules.Controls +@using Oqtane.Providers +@using Oqtane.Security +@using Oqtane.Services +@using Oqtane.Shared +@using Oqtane.Themes +@using Oqtane.Themes.Controls \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/[Owner].[Module]s.Module.Package.csproj b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/[Owner].[Module]s.Module.Package.csproj new file mode 100644 index 00000000..0689d66f --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/[Owner].[Module]s.Module.Package.csproj @@ -0,0 +1,19 @@ + + + + netcoreapp3.1 + false + + + + + + + + + + + + + + diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/[Owner].[Module]s.Module.nuspec b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/[Owner].[Module]s.Module.nuspec new file mode 100644 index 00000000..607f2ff3 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/[Owner].[Module]s.Module.nuspec @@ -0,0 +1,31 @@ + + + + [Owner].[Module]s.Module + 1.0.0 + [Owner] + [Owner] + [Module]s + [Module]s + [Owner] + false + MIT + https://github.com/oqtane/oqtane.framework + https://www.oqtane.org/Portals/0/icon.jpg + oqtane module + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/debug.cmd b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/debug.cmd new file mode 100644 index 00000000..37f0dd87 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/debug.cmd @@ -0,0 +1,6 @@ +XCOPY "..\Client\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Client.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y +XCOPY "..\Client\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Client.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y +XCOPY "..\Server\bin\Debug\netcoreapp3.1\[Owner].[Module]s.Module.Server.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y +XCOPY "..\Server\bin\Debug\netcoreapp3.1\[Owner].[Module]s.Module.Server.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y +XCOPY "..\Shared\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Shared.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y +XCOPY "..\Shared\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Shared.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/release.cmd b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/release.cmd new file mode 100644 index 00000000..71f2c513 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Package/release.cmd @@ -0,0 +1,2 @@ +"..\..\[RootFolder]\oqtane.package\nuget.exe" pack [Owner].[Module]s.Module.nuspec +XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Modules\" /Y diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Controllers/[Module]Controller.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Controllers/[Module]Controller.cs new file mode 100644 index 00000000..1ff6a0ab --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Controllers/[Module]Controller.cs @@ -0,0 +1,75 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using System.Collections.Generic; +using Oqtane.Shared; +using Oqtane.Enums; +using Oqtane.Infrastructure; +using [Owner].[Module]s.Models; +using [Owner].[Module]s.Repository; + +namespace [Owner].[Module]s.Controllers +{ + [Route("{site}/api/[controller]")] + public class [Module]Controller : Controller + { + private readonly I[Module]Repository _[Module]s; + private readonly ILogManager _logger; + + public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger) + { + _[Module]s = [Module]s; + _logger = logger; + } + + // GET: api/?moduleid=x + [HttpGet] + [Authorize(Roles = Constants.RegisteredRole)] + public IEnumerable<[Module]> Get(string moduleid) + { + return _[Module]s.Get[Module]s(int.Parse(moduleid)); + } + + // GET api//5 + [HttpGet("{id}")] + [Authorize(Roles = Constants.RegisteredRole)] + public [Module] Get(int id) + { + return _[Module]s.Get[Module](id); + } + + // POST api/ + [HttpPost] + [Authorize(Roles = Constants.AdminRole)] + public [Module] Post([FromBody] [Module] [Module]) + { + if (ModelState.IsValid) + { + [Module] = _[Module]s.Add[Module]([Module]); + _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]); + } + return [Module]; + } + + // PUT api//5 + [HttpPut("{id}")] + [Authorize(Roles = Constants.AdminRole)] + public [Module] Put(int id, [FromBody] [Module] [Module]) + { + if (ModelState.IsValid) + { + [Module] = _[Module]s.Update[Module]([Module]); + _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]); + } + return [Module]; + } + + // DELETE api//5 + [HttpDelete("{id}")] + [Authorize(Roles = Constants.AdminRole)] + public void Delete(int id) + { + _[Module]s.Delete[Module](id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Manager/[Module]Manager.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Manager/[Module]Manager.cs new file mode 100644 index 00000000..0b987600 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Manager/[Module]Manager.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using Oqtane.Modules; +using Oqtane.Models; +using Oqtane.Infrastructure; +using Oqtane.Repository; +using [Owner].[Module]s.Models; +using [Owner].[Module]s.Repository; + +namespace [Owner].[Module]s.Manager +{ + public class [Module]Manager : IInstallable, IPortable + { + private I[Module]Repository _[Module]s; + private ISqlRepository _sql; + + public [Module]Manager(I[Module]Repository [Module]s, ISqlRepository sql) + { + _[Module]s = [Module]s; + _sql = sql; + } + + public bool Install(Tenant tenant, string version) + { + return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module]." + version + ".sql"); + } + + public bool Uninstall(Tenant tenant) + { + return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module].Uninstall.sql"); + } + + public string ExportModule(Module module) + { + string content = ""; + List<[Module]> [Module]s = _[Module]s.Get[Module]s(module.ModuleId).ToList(); + if ([Module]s != null) + { + content = JsonSerializer.Serialize([Module]s); + } + return content; + } + + public void ImportModule(Module module, string content, string version) + { + List<[Module]> [Module]s = null; + if (!string.IsNullOrEmpty(content)) + { + [Module]s = JsonSerializer.Deserialize>(content); + } + if ([Module]s != null) + { + foreach([Module] [Module] in [Module]s) + { + [Module] _[Module] = new [Module](); + _[Module].ModuleId = module.ModuleId; + _[Module].Name = [Module].Name; + _[Module]s.Add[Module](_[Module]); + } + } + } + } +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/I[Module]Repository.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/I[Module]Repository.cs new file mode 100644 index 00000000..f38a60d5 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/I[Module]Repository.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Repository +{ + public interface I[Module]Repository + { + IEnumerable<[Module]> Get[Module]s(int ModuleId); + [Module] Get[Module](int [Module]Id); + [Module] Add[Module]([Module] [Module]); + [Module] Update[Module]([Module] [Module]); + void Delete[Module](int [Module]Id); + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/[Module]Context.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/[Module]Context.cs new file mode 100644 index 00000000..2a14bbf4 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/[Module]Context.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Http; +using Oqtane.Modules; +using Oqtane.Repository; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Repository +{ + public class [Module]Context : DBContextBase, IService + { + public virtual DbSet<[Module]> [Module] { get; set; } + + public [Module]Context(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor) + { + // ContextBase handles multi-tenant database connections + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/[Module]Repository.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/[Module]Repository.cs new file mode 100644 index 00000000..9b83b239 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Repository/[Module]Repository.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Collections.Generic; +using Oqtane.Modules; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Repository +{ + public class [Module]Repository : I[Module]Repository, IService + { + private readonly [Module]Context _db; + + public [Module]Repository([Module]Context context) + { + _db = context; + } + + public IEnumerable<[Module]> Get[Module]s(int ModuleId) + { + return _db.[Module].Where(item => item.ModuleId == ModuleId); + } + + public [Module] Get[Module](int [Module]Id) + { + return _db.[Module].Find([Module]Id); + } + + public [Module] Add[Module]([Module] [Module]) + { + _db.[Module].Add([Module]); + _db.SaveChanges(); + return [Module]; + } + + public [Module] Update[Module]([Module] [Module]) + { + _db.Entry([Module]).State = EntityState.Modified; + _db.SaveChanges(); + return [Module]; + } + + public void Delete[Module](int [Module]Id) + { + [Module] [Module] = _db.[Module].Find([Module]Id); + _db.[Module].Remove([Module]); + _db.SaveChanges(); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Scripts/[Owner].[Module].1.0.0.sql b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Scripts/[Owner].[Module].1.0.0.sql new file mode 100644 index 00000000..7a1b99ea --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Scripts/[Owner].[Module].1.0.0.sql @@ -0,0 +1,26 @@ +/* +Create [Owner][Module] table +*/ + +CREATE TABLE [dbo].[[Owner][Module]]( + [[Module]Id] [int] IDENTITY(1,1) NOT NULL, + [ModuleId] [int] NOT NULL, + [Name] [nvarchar](256) NOT NULL, + [CreatedBy] [nvarchar](256) NOT NULL, + [CreatedOn] [datetime] NOT NULL, + [ModifiedBy] [nvarchar](256) NOT NULL, + [ModifiedOn] [datetime] NOT NULL, + CONSTRAINT [PK_[Owner][Module]] PRIMARY KEY CLUSTERED + ( + [[Module]Id] ASC + ) +) +GO + +/* +Create foreign key relationships +*/ +ALTER TABLE [dbo].[[Owner][Module]] WITH CHECK ADD CONSTRAINT [FK_[Owner][Module]_Module] FOREIGN KEY([ModuleId]) +REFERENCES [dbo].Module ([ModuleId]) +ON DELETE CASCADE +GO \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Scripts/[Owner].[Module].Uninstall.sql b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Scripts/[Owner].[Module].Uninstall.sql new file mode 100644 index 00000000..47baecc9 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/Scripts/[Owner].[Module].Uninstall.sql @@ -0,0 +1,6 @@ +/* +Remove [Owner][Module] table +*/ + +DROP TABLE [dbo].[[Owner][Module]] +GO diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/[Owner].[Module]s.Module.Server.csproj b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/[Owner].[Module]s.Module.Server.csproj new file mode 100644 index 00000000..96d4154f --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Server/[Owner].[Module]s.Module.Server.csproj @@ -0,0 +1,41 @@ + + + + netcoreapp3.1 + 7.3 + true + 1.0.0 + [Owner].[Module]s.Module + [Owner] + [Owner] + [Description] + [Owner] + + + + + + + + + + + + + + + + + + + + + + ..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\Oqtane.Server.dll + + + ..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\Oqtane.Shared.dll + + + + diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Shared/Models/[Module].cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Shared/Models/[Module].cs new file mode 100644 index 00000000..5a6d7896 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Shared/Models/[Module].cs @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Oqtane.Models; + +namespace [Owner].[Module]s.Models +{ + [Table("[Owner][Module]")] + public class [Module] : IAuditable + { + public int [Module]Id { get; set; } + public int ModuleId { get; set; } + public string Name { get; set; } + + public string CreatedBy { get; set; } + public DateTime CreatedOn { get; set; } + public string ModifiedBy { get; set; } + public DateTime ModifiedOn { get; set; } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Shared/[Owner].[Module]s.Module.Shared.csproj b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Shared/[Owner].[Module]s.Module.Shared.csproj new file mode 100644 index 00000000..2482b4fa --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/Shared/[Owner].[Module]s.Module.Shared.csproj @@ -0,0 +1,24 @@ + + + + netstandard2.1 + 7.3 + 1.0.0 + [Owner].[Module].Module + [Owner] + [Owner] + [Description] + [Owner] + + + + + + + + + ..\..\[RootFolder]\Oqtane.Shared\bin\Debug\netstandard2.1\Oqtane.Shared.dll + + + + diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/[Owner].[Module]s.Module.sln b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/[Owner].[Module]s.Module.sln new file mode 100644 index 00000000..9879eac6 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/[Owner].[Module]s.Module.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28621.142 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Module]s.Module.Client", "Client\[Owner].[Module]s.Module.Client.csproj", "{AA8E58A1-CD09-4208-BF66-A8BB341FD669}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Module]s.Module.Server", "Server\[Owner].[Module]s.Module.Server.csproj", "{04B05448-788F-433D-92C0-FED35122D45A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Module]s.Module.Shared", "Shared\[Owner].[Module]s.Module.Shared.csproj", "{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "[Owner].[Module]s.Module.Package", "Package\[Owner].[Module]s.Module.Package.csproj", "{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + Wasm|Any CPU = Wasm|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.Build.0 = Release|Any CPU + {AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Wasm|Any CPU.ActiveCfg = Release|Any CPU + {AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Wasm|Any CPU.Build.0 = Release|Any CPU + {04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.Build.0 = Release|Any CPU + {04B05448-788F-433D-92C0-FED35122D45A}.Wasm|Any CPU.ActiveCfg = Release|Any CPU + {04B05448-788F-433D-92C0-FED35122D45A}.Wasm|Any CPU.Build.0 = Release|Any CPU + {18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.Build.0 = Release|Any CPU + {18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Wasm|Any CPU.ActiveCfg = Release|Any CPU + {18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Wasm|Any CPU.Build.0 = Release|Any CPU + {C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.Build.0 = Release|Any CPU + {C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Wasm|Any CPU.ActiveCfg = Debug|Any CPU + {C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Wasm|Any CPU.Build.0 = Debug|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1D016F15-46FE-4726-8DFD-2E4FD4DC7668} + EndGlobalSection +EndGlobal diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/wwwroot/resources.txt b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/wwwroot/resources.txt new file mode 100644 index 00000000..2542de03 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/External/wwwroot/resources.txt @@ -0,0 +1 @@ +This is the location where static resources such as images or style sheets should be located \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Edit.razor new file mode 100644 index 00000000..84e83aae --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Edit.razor @@ -0,0 +1,95 @@ +@using Oqtane.Modules.Controls +@using [Owner].[Module]s.Services +@using [Owner].[Module]s.Models + +@namespace [Owner].[Module]s.Modules +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject HttpClient http +@inject SiteState sitestate + + + + + + +
+ + + +
+ +Cancel +
+
+@if (PageState.Action == "Edit") +{ + +} + +@code { + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; + public override string Actions => "Add,Edit"; + + I[Module]Service [Module]Service; + int _id; + string _name; + string _createdby; + DateTime _createdon; + string _modifiedby; + DateTime _modifiedon; + + protected override async Task OnInitializedAsync() + { + try + { + [Module]Service = new [Module]Service(http, sitestate); + if (PageState.Action == "Edit") + { + _id = Int32.Parse(PageState.QueryString["id"]); + [Module] [Module] = await [Module]Service.Get[Module]Async(_id); + if ([Module] != null) + { + _name = [Module].Name; + _createdby = [Module].CreatedBy; + _createdon = [Module].CreatedOn; + _modifiedby = [Module].ModifiedBy; + _modifiedon = [Module].ModifiedOn; + } + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading [Module] {[Module]Id} {Error}", _id, ex.Message); + AddModuleMessage("Error Loading [Module]", MessageType.Error); + } + } + + private async Task Save() + { + try + { + if (PageState.Action == "Add") + { + [Module] [Module] = new [Module](); + [Module].ModuleId = ModuleState.ModuleId; + [Module].Name = _name; + [Module] = await [Module]Service.Add[Module]Async([Module]); + await logger.LogInformation("[Module] Added {[Module]}", [Module]); + } + else + { + [Module] [Module] = await [Module]Service.Get[Module]Async(_id); + [Module].Name = _name; + await [Module]Service.Update[Module]Async([Module]); + await logger.LogInformation("[Module] Updated {[Module]}", [Module]); + } + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving [Module] {Error}", ex.Message); + AddModuleMessage("Error Saving [Module]", MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Index.razor new file mode 100644 index 00000000..fdb11b98 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Index.razor @@ -0,0 +1,97 @@ +@using [Owner].[Module]s.Services +@using [Owner].[Module]s.Models + +@namespace [Owner].[Module]s.Modules +@inherits ModuleBase +@inject NavigationManager NavigationManager +@inject HttpClient http +@inject SiteState sitestate + +@if (_[Module]s == null) +{ +

Loading...

+} +else +{ + +
+
+ @if (@_[Module]s.Count != 0) + { + +
+
[Module]s
+
+ +
+ + + @context.Name +
+
+
+ } + else + { +

No [Module]s To Display

+ } +} + + + +
+[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:

+[RootPath]Oqtane.Client\Modules\[Module]\
+- Edit.razor - component for adding or editing content
+- Index.razor - main component for your module **the content you are reading is in this file**
+- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module
+- Settings.razor - component for managing module settings
+- Services\I[Module]Service.cs - interface for defining service API methods
+- Services\[Module]Service.cs - implements service API interface methods

+[RootPath]Oqtane.Server\Modules\[Module]\
+- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern
+- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content
+- Repository\I[Module]Repository.cs - interface for defining repository methods
+- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core
+- Repository\[Module]Context.cs - provides a DB Context for data access
+- Scripts\[Owner].[Module].1.0.0.sql - database schema definition script

+- Scripts\[Owner].[Module].Uninstall.sql - database uninstall script

+[RootPath]Oqtane.Shared\Modules\[Module]\
+- Models\[Module].cs - model definition

+ + + +@code { + I[Module]Service [Module]Service; + List<[Module]> _[Module]s; + + protected override async Task OnInitializedAsync() + { + try + { + [Module]Service = new [Module]Service(http, sitestate); + _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading [Module] {Error}", ex.Message); + AddModuleMessage("Error Loading [Module]", MessageType.Error); + } + } + + private async Task Delete([Module] [Module]) + { + try + { + await [Module]Service.Delete[Module]Async([Module].[Module]Id); + await logger.LogInformation("[Module] Deleted {[Module]}", [Module]); + _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Deleting [Module] {[Module]} {Error}", [Module], ex.Message); + AddModuleMessage("Error Deleting [Module]", MessageType.Error); + } + } +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/ModuleInfo.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/ModuleInfo.cs new file mode 100644 index 00000000..a95a461e --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/ModuleInfo.cs @@ -0,0 +1,18 @@ +using Oqtane.Models; +using Oqtane.Modules; + +namespace [Owner].[Module]s.Modules +{ + public class ModuleInfo : IModule + { + public ModuleDefinition ModuleDefinition => new ModuleDefinition + { + Name = "[Module]", + Description = "[Module]", + Version = "1.0.0", + Dependencies = "[Owner].[Module]s.Module.Shared", + ServerManagerType = "[ServerManagerType]", + ReleaseVersions = "1.0.0" + }; + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Services/I[Module]Service.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Services/I[Module]Service.cs new file mode 100644 index 00000000..e98da06d --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Services/I[Module]Service.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Services +{ + public interface I[Module]Service + { + Task> Get[Module]sAsync(int ModuleId); + + Task<[Module]> Get[Module]Async(int [Module]Id); + + Task<[Module]> Add[Module]Async([Module] [Module]); + + Task<[Module]> Update[Module]Async([Module] [Module]); + + Task Delete[Module]Async(int [Module]Id); + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Services/[Module]Service.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Services/[Module]Service.cs new file mode 100644 index 00000000..f95c41b9 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Services/[Module]Service.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Oqtane.Modules; +using Oqtane.Services; +using Oqtane.Shared; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Services +{ + public class [Module]Service : ServiceBase, I[Module]Service, IService + { + private readonly SiteState _siteState; + + public [Module]Service(HttpClient http, SiteState siteState) : base(http) + { + _siteState = siteState; + } + + private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]"); + + public async Task> Get[Module]sAsync(int ModuleId) + { + List<[Module]> [Module]s = await GetJsonAsync>($"{Apiurl}?moduleid={ModuleId}"); + return [Module]s.OrderBy(item => item.Name).ToList(); + } + + public async Task<[Module]> Get[Module]Async(int [Module]Id) + { + return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}"); + } + + public async Task<[Module]> Add[Module]Async([Module] [Module]) + { + return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]); + } + + public async Task<[Module]> Update[Module]Async([Module] [Module]) + { + return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]); + } + + public async Task Delete[Module]Async(int [Module]Id) + { + await DeleteAsync($"{Apiurl}/{[Module]Id}"); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Settings.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Settings.razor new file mode 100644 index 00000000..a53dc57c --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Client/Modules/[Module]/Settings.razor @@ -0,0 +1,47 @@ +@namespace [Owner].[Module]s.Modules +@inherits ModuleBase +@inject ISettingService SettingService + + + + + + +
+ + + +
+ +@code { + public override string Title => "[Module] Settings"; + + string _value; + + protected override async Task OnInitializedAsync() + { + try + { + Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + _value = SettingService.GetSetting(settings, "SettingName", ""); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } + + public async Task UpdateSettings() + { + try + { + Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId); + SettingService.SetSetting(settings, "SettingName", _value); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + } + catch (Exception ex) + { + ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Controllers/[Module]Controller.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Controllers/[Module]Controller.cs new file mode 100644 index 00000000..1ff6a0ab --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Controllers/[Module]Controller.cs @@ -0,0 +1,75 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using System.Collections.Generic; +using Oqtane.Shared; +using Oqtane.Enums; +using Oqtane.Infrastructure; +using [Owner].[Module]s.Models; +using [Owner].[Module]s.Repository; + +namespace [Owner].[Module]s.Controllers +{ + [Route("{site}/api/[controller]")] + public class [Module]Controller : Controller + { + private readonly I[Module]Repository _[Module]s; + private readonly ILogManager _logger; + + public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger) + { + _[Module]s = [Module]s; + _logger = logger; + } + + // GET: api/?moduleid=x + [HttpGet] + [Authorize(Roles = Constants.RegisteredRole)] + public IEnumerable<[Module]> Get(string moduleid) + { + return _[Module]s.Get[Module]s(int.Parse(moduleid)); + } + + // GET api//5 + [HttpGet("{id}")] + [Authorize(Roles = Constants.RegisteredRole)] + public [Module] Get(int id) + { + return _[Module]s.Get[Module](id); + } + + // POST api/ + [HttpPost] + [Authorize(Roles = Constants.AdminRole)] + public [Module] Post([FromBody] [Module] [Module]) + { + if (ModelState.IsValid) + { + [Module] = _[Module]s.Add[Module]([Module]); + _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]); + } + return [Module]; + } + + // PUT api//5 + [HttpPut("{id}")] + [Authorize(Roles = Constants.AdminRole)] + public [Module] Put(int id, [FromBody] [Module] [Module]) + { + if (ModelState.IsValid) + { + [Module] = _[Module]s.Update[Module]([Module]); + _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]); + } + return [Module]; + } + + // DELETE api//5 + [HttpDelete("{id}")] + [Authorize(Roles = Constants.AdminRole)] + public void Delete(int id) + { + _[Module]s.Delete[Module](id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Manager/[Module]Manager.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Manager/[Module]Manager.cs new file mode 100644 index 00000000..0b987600 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Manager/[Module]Manager.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; +using System.Text.Json; +using Oqtane.Modules; +using Oqtane.Models; +using Oqtane.Infrastructure; +using Oqtane.Repository; +using [Owner].[Module]s.Models; +using [Owner].[Module]s.Repository; + +namespace [Owner].[Module]s.Manager +{ + public class [Module]Manager : IInstallable, IPortable + { + private I[Module]Repository _[Module]s; + private ISqlRepository _sql; + + public [Module]Manager(I[Module]Repository [Module]s, ISqlRepository sql) + { + _[Module]s = [Module]s; + _sql = sql; + } + + public bool Install(Tenant tenant, string version) + { + return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module]." + version + ".sql"); + } + + public bool Uninstall(Tenant tenant) + { + return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module].Uninstall.sql"); + } + + public string ExportModule(Module module) + { + string content = ""; + List<[Module]> [Module]s = _[Module]s.Get[Module]s(module.ModuleId).ToList(); + if ([Module]s != null) + { + content = JsonSerializer.Serialize([Module]s); + } + return content; + } + + public void ImportModule(Module module, string content, string version) + { + List<[Module]> [Module]s = null; + if (!string.IsNullOrEmpty(content)) + { + [Module]s = JsonSerializer.Deserialize>(content); + } + if ([Module]s != null) + { + foreach([Module] [Module] in [Module]s) + { + [Module] _[Module] = new [Module](); + _[Module].ModuleId = module.ModuleId; + _[Module].Name = [Module].Name; + _[Module]s.Add[Module](_[Module]); + } + } + } + } +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/I[Module]Repository.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/I[Module]Repository.cs new file mode 100644 index 00000000..f38a60d5 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/I[Module]Repository.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Repository +{ + public interface I[Module]Repository + { + IEnumerable<[Module]> Get[Module]s(int ModuleId); + [Module] Get[Module](int [Module]Id); + [Module] Add[Module]([Module] [Module]); + [Module] Update[Module]([Module] [Module]); + void Delete[Module](int [Module]Id); + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/[Module]Context.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/[Module]Context.cs new file mode 100644 index 00000000..2a14bbf4 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/[Module]Context.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Http; +using Oqtane.Modules; +using Oqtane.Repository; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Repository +{ + public class [Module]Context : DBContextBase, IService + { + public virtual DbSet<[Module]> [Module] { get; set; } + + public [Module]Context(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor) + { + // ContextBase handles multi-tenant database connections + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/[Module]Repository.cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/[Module]Repository.cs new file mode 100644 index 00000000..9b83b239 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Repository/[Module]Repository.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore; +using System.Linq; +using System.Collections.Generic; +using Oqtane.Modules; +using [Owner].[Module]s.Models; + +namespace [Owner].[Module]s.Repository +{ + public class [Module]Repository : I[Module]Repository, IService + { + private readonly [Module]Context _db; + + public [Module]Repository([Module]Context context) + { + _db = context; + } + + public IEnumerable<[Module]> Get[Module]s(int ModuleId) + { + return _db.[Module].Where(item => item.ModuleId == ModuleId); + } + + public [Module] Get[Module](int [Module]Id) + { + return _db.[Module].Find([Module]Id); + } + + public [Module] Add[Module]([Module] [Module]) + { + _db.[Module].Add([Module]); + _db.SaveChanges(); + return [Module]; + } + + public [Module] Update[Module]([Module] [Module]) + { + _db.Entry([Module]).State = EntityState.Modified; + _db.SaveChanges(); + return [Module]; + } + + public void Delete[Module](int [Module]Id) + { + [Module] [Module] = _db.[Module].Find([Module]Id); + _db.[Module].Remove([Module]); + _db.SaveChanges(); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Scripts/[Owner].[Module].1.0.0.sql b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Scripts/[Owner].[Module].1.0.0.sql new file mode 100644 index 00000000..7a1b99ea --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Scripts/[Owner].[Module].1.0.0.sql @@ -0,0 +1,26 @@ +/* +Create [Owner][Module] table +*/ + +CREATE TABLE [dbo].[[Owner][Module]]( + [[Module]Id] [int] IDENTITY(1,1) NOT NULL, + [ModuleId] [int] NOT NULL, + [Name] [nvarchar](256) NOT NULL, + [CreatedBy] [nvarchar](256) NOT NULL, + [CreatedOn] [datetime] NOT NULL, + [ModifiedBy] [nvarchar](256) NOT NULL, + [ModifiedOn] [datetime] NOT NULL, + CONSTRAINT [PK_[Owner][Module]] PRIMARY KEY CLUSTERED + ( + [[Module]Id] ASC + ) +) +GO + +/* +Create foreign key relationships +*/ +ALTER TABLE [dbo].[[Owner][Module]] WITH CHECK ADD CONSTRAINT [FK_[Owner][Module]_Module] FOREIGN KEY([ModuleId]) +REFERENCES [dbo].Module ([ModuleId]) +ON DELETE CASCADE +GO \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Scripts/[Owner].[Module].Uninstall.sql b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Scripts/[Owner].[Module].Uninstall.sql new file mode 100644 index 00000000..47baecc9 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Server/Modules/[Module]/Scripts/[Owner].[Module].Uninstall.sql @@ -0,0 +1,6 @@ +/* +Remove [Owner][Module] table +*/ + +DROP TABLE [dbo].[[Owner][Module]] +GO diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Shared/Modules/[Module]/Models/[Module].cs b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Shared/Modules/[Module]/Models/[Module].cs new file mode 100644 index 00000000..5a6d7896 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Templates/Internal/Oqtane.Shared/Modules/[Module]/Models/[Module].cs @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel.DataAnnotations.Schema; +using Oqtane.Models; + +namespace [Owner].[Module]s.Models +{ + [Table("[Owner][Module]")] + public class [Module] : IAuditable + { + public int [Module]Id { get; set; } + public int ModuleId { get; set; } + public string Name { get; set; } + + public string CreatedBy { get; set; } + public DateTime CreatedOn { get; set; } + public string ModifiedBy { get; set; } + public DateTime ModifiedOn { get; set; } + } +} diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor index bce9e1eb..a63784bc 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor @@ -5,54 +5,60 @@ @inject IModuleDefinitionService ModuleDefinitionService @inject IPackageService PackageService - - - - - -
- - - -
- @if (_packages != null) { -
-

Available Modules

+ + @if (_packages.Count > 0) + { + + + +
+ Name + Version + +
+ + @context.Name + @context.Version + + + + +
+
+ } + + + + + + +
+ + + +
+
+
- -
- Name - Version - -
- - @context.Name - @context.Version - - - - -
+ + Cancel } - -Cancel - - @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private List _packages; - List _packages; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { try { - List moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId); + var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId); _packages = await PackageService.GetPackagesAsync("module"); - foreach(Package package in _packages.ToArray()) + + foreach (Package package in _packages.ToArray()) { if (moduledefinitions.Exists(item => Utilities.GetTypeName(item.ModuleDefinitionName) == package.PackageId)) { @@ -80,18 +86,18 @@ } } - private async Task DownloadModule(string moduledefinitionname, string version) + private async Task DownloadModule(string packageid, string version) { try { - await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules"); - await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", moduledefinitionname, version); - AddModuleMessage("Module Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); + await PackageService.DownloadPackageAsync(packageid, version, "Modules"); + await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", packageid, version); + AddModuleMessage("Modules Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version}", moduledefinitionname, version); + await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version}", packageid, version); AddModuleMessage("Error Downloading Module", MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index 3b4ad4df..743938bf 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -3,54 +3,142 @@ @inject IModuleDefinitionService ModuleDefinitionService @inject NavigationManager NavigationManager - - - - - - - - - -
- - - -
- - - -
+ + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+
+ + + + + +
+ +
+
+
Cancel -
-
+

@code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } - - int _moduleDefinitionId; - string _name; - string _permissions; - string _createdby; - DateTime _createdon; - string _modifiedby; - DateTime _modifiedon; + private int _moduleDefinitionId; + private string _name; + private string _version; + private string _categories; + private string _moduledefinitionname = ""; + private string _description = ""; + private string _owner = ""; + private string _url = ""; + private string _contact = ""; + private string _license = ""; + private string _permissions; + private string _createdby; + private DateTime _createdon; + private string _modifiedby; + private DateTime _modifiedon; #pragma warning disable 649 - PermissionGrid _permissionGrid; + private PermissionGrid _permissionGrid; #pragma warning restore 649 + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + protected override async Task OnInitializedAsync() { try { _moduleDefinitionId = Int32.Parse(PageState.QueryString["id"]); - ModuleDefinition moduleDefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId); + var moduleDefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId); if (moduleDefinition != null) { _name = moduleDefinition.Name; + _version = moduleDefinition.Version; + _categories = moduleDefinition.Categories; + _moduledefinitionname = moduleDefinition.ModuleDefinitionName; + _description = moduleDefinition.Description; + _owner = moduleDefinition.Owner; + _url = moduleDefinition.Url; + _contact = moduleDefinition.Contact; + _license = moduleDefinition.License; _permissions = moduleDefinition.Permissions; _createdby = moduleDefinition.CreatedBy; _createdon = moduleDefinition.CreatedOn; @@ -69,7 +157,19 @@ { try { - ModuleDefinition moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId); + var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId); + if (moduledefinition.Name != _name) + { + moduledefinition.Name = _name; + } + if (moduledefinition.Description != _description) + { + moduledefinition.Description = _description; + } + if (moduledefinition.Categories != _categories) + { + moduledefinition.Categories = _categories; + } moduledefinition.Permissions = _permissionGrid.GetPermissions(); 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 3efd4ff8..d348ddb4 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -41,10 +41,10 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private List _moduleDefinitions; + private List _packages; - List _moduleDefinitions; - List _packages; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { @@ -62,12 +62,13 @@ else private bool UpgradeAvailable(string moduledefinitionname, string version) { - bool upgradeavailable = false; - Package package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault(); + var upgradeavailable = false; + var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault(); if (package != null) { upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0); } + return upgradeavailable; } diff --git a/Oqtane.Client/Modules/Admin/Modules/Export.razor b/Oqtane.Client/Modules/Admin/Modules/Export.razor index 5ac95386..eaa0bc92 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Export.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Export.razor @@ -7,10 +7,10 @@ - + - + @@ -20,10 +20,11 @@ @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } - public override string Title { get { return "Export Module"; } } + private string _content = string.Empty; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override string Title => "Export Module"; - string _content = ""; private async Task ExportModule() { diff --git a/Oqtane.Client/Modules/Admin/Modules/Import.razor b/Oqtane.Client/Modules/Admin/Modules/Import.razor index 5fe730fd..e341ad78 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Import.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Import.razor @@ -7,10 +7,10 @@ - + - + @@ -20,15 +20,14 @@ @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } - public override string Title { get { return "Import Module"; } } - - string _content = ""; + private string _content = string.Empty; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + public override string Title => "Import Module"; private async Task ImportModule() { - if (_content != "") + if (_content != string.Empty) { try { diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index ae515412..c8a90d23 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -5,77 +5,90 @@ @inject IModuleService ModuleService @inject IPageModuleService PageModuleService - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- -@DynamicComponent - + + + @if (_containers != null) + { + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ } +
+ + @if (_containers != null) + { + + + + +
+ +
+ } +
+ @if (_settingsModuleType != null) + { + + @DynamicComponent + + } +
Cancel - @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Edit; } } - public override string Title { get { return "Module Settings"; } } + private Dictionary _containers; + private string _title; + private string _containerType; + private string _permissionNames = ""; + private string _permissions; + private string _pageId; + private PermissionGrid _permissionGrid; + private Type _settingsModuleType; + private string _settingstitle = "Other Settings"; + private object _settings; - Dictionary _containers = new Dictionary(); - string _title; - string _containerType; - string _permissionNames = ""; - string _permissions; - string _pageId; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; + public override string Title => "Module Settings"; -#pragma warning disable 649 - PermissionGrid _permissionGrid; -#pragma warning restore 649 - - RenderFragment DynamicComponent { get; set; } - object _settings; + private RenderFragment DynamicComponent { get; set; } protected override async Task OnInitializedAsync() { @@ -86,35 +99,46 @@ _permissionNames = ModuleState.ModuleDefinition.PermissionNames; _pageId = ModuleState.PageId.ToString(); - DynamicComponent = builder => + _settingsModuleType = Type.GetType(ModuleState.ModuleType); + if (_settingsModuleType != null) { - Type moduleType = Type.GetType(ModuleState.ModuleType); - if (moduleType != null) + var moduleobject = Activator.CreateInstance(_settingsModuleType); + _settingstitle = (string)_settingsModuleType.GetProperty("Title").GetValue(moduleobject, null); + if (string.IsNullOrEmpty(_settingstitle)) { - builder.OpenComponent(0, moduleType); - builder.AddComponentReferenceCapture(1, inst => { _settings = Convert.ChangeType(inst, moduleType); }); - builder.CloseComponent(); + _settingstitle = "Other Settings"; } - }; + + DynamicComponent = builder => + { + builder.OpenComponent(0, _settingsModuleType); + builder.AddComponentReferenceCapture(1, inst => { _settings = Convert.ChangeType(inst, _settingsModuleType); }); + builder.CloseComponent(); + }; + } } private async Task SaveModule() { - Module module = ModuleState; + var module = ModuleState; module.Permissions = _permissionGrid.GetPermissions(); await ModuleService.UpdateModuleAsync(module); - PageModule pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId); + var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId); pagemodule.PageId = int.Parse(_pageId); pagemodule.Title = _title; pagemodule.ContainerType = _containerType; + await PageModuleService.UpdatePageModuleAsync(pagemodule); await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane); - Type moduleType = Type.GetType(ModuleState.ModuleType); - if (moduleType != null) + if (_settingsModuleType != null) { - moduleType.GetMethod("UpdateSettings")?.Invoke(_settings, null); // method must be public in settings component + var moduleType = Type.GetType(ModuleState.ModuleType); + if (moduleType != null) + { + moduleType.GetMethod("UpdateSettings")?.Invoke(_settings, null); // method must be public in settings component + } } NavigationManager.NavigateTo(NavigateUrl()); diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index 17a785dc..f7e3c20f 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -4,189 +4,225 @@ @inject IPageService PageService @inject IThemeService ThemeService -@if (Themes != null) -{ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + +
- - - -
- - - -
- - - -
- - - - @if (children != null && children.Count > 0 && (insert == "<" || insert == ">")) - { - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + +
+ + + +
+ + + + @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) { - + } - - } -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - Cancel -} +
+ + + +
+ + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ } + + + + + + +
+ +
+
+ + +Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private Dictionary _themes; + private Dictionary _panelayouts; + private List _themeList; + private List _pageList; + private string _name; + private string _title; + private string _path = string.Empty; + private string _parentid; + private string _insert = ">>"; + private List _children; + private int _childid = -1; + private string _isnavigation = "True"; + private string _url; + private string _ispersonalizable = "False"; + private string _mode = "view"; + private string _themetype = "-"; + private string _layouttype = "-"; + private string _icon = string.Empty; + private string _permissions = string.Empty; + private PermissionGrid _permissionGrid; - Dictionary themes = new Dictionary(); - Dictionary panelayouts = new Dictionary(); - - List Themes; - List pages; - string name; - string path = ""; - string parentid; - string insert = ">>"; - List children; - int childid = -1; - string isnavigation = "True"; - string ispersonalizable = "False"; - string mode = "view"; - string themetype = ""; - string layouttype = ""; - string icon = ""; - string permissions = ""; - - PermissionGrid permissiongrid; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { try { - Themes = await ThemeService.GetThemesAsync(); - pages = PageState.Pages; - children = PageState.Pages.Where(item => item.ParentId == null).ToList(); + _themeList = await ThemeService.GetThemesAsync(); + _pageList = PageState.Pages; + _children = PageState.Pages.Where(item => item.ParentId == null).ToList(); - themes = ThemeService.GetThemeTypes(Themes); - themetype = PageState.Site.DefaultThemeType; + _themetype = PageState.Site.DefaultThemeType; + _layouttype = PageState.Site.DefaultLayoutType; - panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); - layouttype = PageState.Site.DefaultLayoutType; + _themes = ThemeService.GetThemeTypes(_themeList); + _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); - List permissionstrings = new List(); - permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.View, Permissions = Constants.AdminRole }); - permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.Edit, Permissions = Constants.AdminRole }); - permissions = UserSecurity.SetPermissionStrings(permissionstrings); + _permissions = string.Empty; } catch (Exception ex) { @@ -199,20 +235,33 @@ { try { - parentid = (string)e.Value; - if (parentid == "-1") + _parentid = (string)e.Value; + _children = new List(); + if (_parentid == "-1") { - children = PageState.Pages.Where(item => item.ParentId == null).ToList(); + foreach (Page p in PageState.Pages.Where(item => item.ParentId == null)) + { + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions)) + { + _children.Add(p); + } + } } else { - children = PageState.Pages.Where(item => item.ParentId == int.Parse(parentid)).ToList(); + foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid))) + { + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions)) + { + _children.Add(p); + } + } } StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", parentid, ex.Message); + await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message); AddModuleMessage("Error Loading Child Pages For Parent", MessageType.Error); } } @@ -221,20 +270,20 @@ { try { - themetype = (string)e.Value; - if (themetype != "") + _themetype = (string)e.Value; + if (_themetype != "-") { - panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); + _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); } else { - panelayouts = new Dictionary(); + _panelayouts = new Dictionary(); } StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message); + await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error); } } @@ -244,71 +293,77 @@ Page page = null; try { - if (name != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype))) + if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype))) { page = new Page(); page.SiteId = PageState.Page.SiteId; - page.Name = name; - if (path == "") + page.Name = _name; + page.Title = _title; + if (_path == "") { - path = name; + _path = _name; } - if (path.Contains("/")) + + if (_path.Contains("/")) { - path = path.Substring(path.LastIndexOf("/") + 1); + _path = _path.Substring(_path.LastIndexOf("/") + 1); } - if (string.IsNullOrEmpty(parentid)) + + if (string.IsNullOrEmpty(_parentid)) { page.ParentId = null; - page.Path = Utilities.GetFriendlyUrl(path); + page.Path = Utilities.GetFriendlyUrl(_path); } else { - page.ParentId = Int32.Parse(parentid); - Page parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault(); - if (parent.Path == "") + page.ParentId = Int32.Parse(_parentid); + var parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault(); + if (parent.Path == string.Empty) { - page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(path); + page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); } else { - page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(path); + page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); } } + Page child; - switch (insert) + switch (_insert) { case "<<": page.Order = 0; break; case "<": - child = PageState.Pages.Where(item => item.PageId == childid).FirstOrDefault(); + child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault(); page.Order = child.Order - 1; break; case ">": - child = PageState.Pages.Where(item => item.PageId == childid).FirstOrDefault(); + child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault(); page.Order = child.Order + 1; break; case ">>": page.Order = int.MaxValue; break; } - page.IsNavigation = (isnavigation == null ? true : Boolean.Parse(isnavigation)); - page.EditMode = (mode == "edit" ? true : false); - page.ThemeType = themetype; - page.LayoutType = (layouttype == null ? "" : layouttype); - page.Icon = (icon == null ? "" : icon); - page.Permissions = permissiongrid.GetPermissions(); + page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation)); + page.Url = _url; + page.EditMode = (_mode == "edit" ? true : false); + page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; + page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty; if (page.ThemeType == PageState.Site.DefaultThemeType) { - page.ThemeType = ""; + page.ThemeType = string.Empty; } + if (page.LayoutType == PageState.Site.DefaultLayoutType) { - page.LayoutType = ""; + page.LayoutType = string.Empty; } - page.IsPersonalizable = (ispersonalizable == null ? false : Boolean.Parse(ispersonalizable)); + page.Icon = (_icon == null ? string.Empty : _icon); + page.Permissions = _permissionGrid.GetPermissions(); + page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable)); page.UserId = null; page = await PageService.AddPageAsync(page); diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index cad64681..8132696d 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -4,248 +4,295 @@ @inject IPageService PageService @inject IThemeService ThemeService -@if (Themes != null) -{ - - - - - - - - - - - - + + + + + + + + + + + + + +
- - - -
- - - -
- - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ + + +
+ + + +
+ + + + @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) { - + } - else - { - - } - } - -
- - - - @if (children != null && children.Count > 0 && (insert == "<" || insert == ">")) - { - - } -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - Cancel -
-
- -} +
+ + + +
+ + + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+
+

+ + } + + + + + + +
+ +
+
+ + +Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private Dictionary _themes; + private Dictionary _panelayouts; + private List _themeList; + private List _pageList; + private int _pageId; + private string _name; + private string _title; + private string _path; + private string _currentparentid; + private string _parentid; + private string _insert = "="; + private List _children; + private int _childid = -1; + private string _isnavigation; + private string _url; + private string _ispersonalizable; + private string _mode; + private string _themetype = "-"; + private string _layouttype = "-"; + private string _icon; + private string _permissions; + private string _createdby; + private DateTime _createdon; + private string _modifiedby; + private DateTime _modifiedon; + private string _deletedby; + private DateTime? _deletedon; - Dictionary themes = new Dictionary(); - Dictionary panelayouts = new Dictionary(); +#pragma warning disable 649 + private PermissionGrid _permissionGrid; +#pragma warning restore 649 - List Themes; - List pages; - int PageId; - string name; - string path; - string currentparentid; - string parentid; - string insert = "="; - List children; - int childid = -1; - string isnavigation; - string ispersonalizable; - string mode; - string themetype; - string layouttype; - string icon; - string permissions; - string createdby; - DateTime createdon; - string modifiedby; - DateTime modifiedon; - string deletedby; - DateTime? deletedon; - - PermissionGrid permissiongrid; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { try { - Themes = await ThemeService.GetThemesAsync(); - pages = PageState.Pages; - children = PageState.Pages.Where(item => item.ParentId == null).ToList(); + _themeList = await ThemeService.GetThemesAsync(); + _pageList = PageState.Pages; + _children = PageState.Pages.Where(item => item.ParentId == null).ToList(); - themes = ThemeService.GetThemeTypes(Themes); + _themes = ThemeService.GetThemeTypes(_themeList); - PageId = Int32.Parse(PageState.QueryString["id"]); - Page page = PageState.Pages.FirstOrDefault(item => item.PageId == PageId); + _pageId = Int32.Parse(PageState.QueryString["id"]); + var page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId); if (page != null) { - name = page.Name; - path = page.Path; - if (path.Contains("/")) + _name = page.Name; + _title = page.Title; + _path = page.Path; + + if (_path.Contains("/")) { - path = path.Substring(path.LastIndexOf("/") + 1); + _path = _path.Substring(_path.LastIndexOf("/") + 1); } + if (page.ParentId == null) { - parentid = ""; + _parentid = string.Empty; } else { - parentid = page.ParentId.ToString(); + _parentid = page.ParentId.ToString(); } - currentparentid = parentid; - isnavigation = page.IsNavigation.ToString(); - ispersonalizable = page.IsPersonalizable.ToString(); - mode = (page.EditMode) ? "edit" : "view"; - themetype = page.ThemeType; - panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); - layouttype = page.LayoutType; - icon = page.Icon; - permissions = page.Permissions; - createdby = page.CreatedBy; - createdon = page.CreatedOn; - modifiedby = page.ModifiedBy; - modifiedon = page.ModifiedOn; - deletedby = page.DeletedBy; - deletedon = page.DeletedOn; + + _currentparentid = _parentid; + _isnavigation = page.IsNavigation.ToString(); + _url = page.Url; + _ispersonalizable = page.IsPersonalizable.ToString(); + _mode = (page.EditMode) ? "edit" : "view"; + _themetype = page.ThemeType; + _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); + _layouttype = page.LayoutType; + if (_themetype == PageState.Site.DefaultThemeType) + { + _themetype = "-"; + } + if (_layouttype == PageState.Site.DefaultLayoutType) + { + _layouttype = "-"; + } + _icon = page.Icon; + _permissions = page.Permissions; + _createdby = page.CreatedBy; + _createdon = page.CreatedOn; + _modifiedby = page.ModifiedBy; + _modifiedon = page.ModifiedOn; + _deletedby = page.DeletedBy; + _deletedon = page.DeletedOn; } } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Page {PageId} {Error}", PageId, ex.Message); + await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message); AddModuleMessage("Error Loading Page", MessageType.Error); } } @@ -254,28 +301,41 @@ { try { - parentid = (string)e.Value; - if (parentid == "-1") + _parentid = (string)e.Value; + _children = new List(); + if (_parentid == "-1") { - children = PageState.Pages.Where(item => item.ParentId == null).ToList(); + foreach(Page p in PageState.Pages.Where(item => item.ParentId == null)) + { + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions)) + { + _children.Add(p); + } + } } else { - children = PageState.Pages.Where(item => item.ParentId == int.Parse(parentid)).ToList(); + foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid))) + { + if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions)) + { + _children.Add(p); + } + } } - if (parentid == currentparentid) + if (_parentid == _currentparentid) { - insert = "="; + _insert = "="; } else { - insert = ">>"; + _insert = ">>"; } StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", parentid, ex.Message); + await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message); AddModuleMessage("Error Loading Child Pages For Parent", MessageType.Error); } } @@ -284,20 +344,20 @@ { try { - themetype = (string)e.Value; - if (themetype != "") + _themetype = (string)e.Value; + if (_themetype != "-") { - panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); + _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); } else { - panelayouts = new Dictionary(); + _panelayouts = new Dictionary(); } StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message); + await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error); } } @@ -307,52 +367,54 @@ Page page = null; try { - if (name != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype))) + if (_name != string.Empty) { - page = PageState.Pages.Where(item => item.PageId == PageId).FirstOrDefault(); + page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId); string currentPath = page.Path; - page.Name = name; - if (path == "" && name.ToLower() != "home") + page.Name = _name; + page.Title = _title; + if (_path == "" && _name.ToLower() != "home") + if (_path == string.Empty && _name.ToLower() != "home") + { + _path = _name; + } + if (_path.Contains("/")) { - path = name; + _path = _path.Substring(_path.LastIndexOf("/") + 1); } - if (path.Contains("/")) - { - path = path.Substring(path.LastIndexOf("/") + 1); - } - if (string.IsNullOrEmpty(parentid)) + if (string.IsNullOrEmpty(_parentid) || _parentid == "-1") { page.ParentId = null; - page.Path = Utilities.GetFriendlyUrl(path); + page.Path = Utilities.GetFriendlyUrl(_path); } else { - page.ParentId = Int32.Parse(parentid); + page.ParentId = Int32.Parse(_parentid); Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId); - if (parent.Path == "") + if (parent.Path == string.Empty) { - page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(path); + page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); } else { - page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(path); + page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); } } - if (insert != "=") + if (_insert != "=") { Page child; - switch (insert) + switch (_insert) { case "<<": page.Order = 0; break; case "<": - child = PageState.Pages.FirstOrDefault(item => item.PageId == childid); + 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); + child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid); if (child != null) page.Order = child.Order + 1; break; case ">>": @@ -360,37 +422,37 @@ break; } } - page.IsNavigation = (isnavigation == null ? true : Boolean.Parse(isnavigation)); - page.EditMode = (mode == "edit" ? true : false); - page.ThemeType = themetype; - page.LayoutType = layouttype ?? ""; - page.Icon = icon ?? ""; - page.Permissions = permissiongrid.GetPermissions(); - + page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); + page.Url = _url; + page.EditMode = (_mode == "edit"); + page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; + page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty; if (page.ThemeType == PageState.Site.DefaultThemeType) { - page.ThemeType = ""; + page.ThemeType = string.Empty; } if (page.LayoutType == PageState.Site.DefaultLayoutType) { - page.LayoutType = ""; + page.LayoutType = string.Empty; } - page.IsPersonalizable = (ispersonalizable != null && Boolean.Parse(ispersonalizable)); + page.Icon = _icon ?? string.Empty; + page.Permissions = _permissionGrid.GetPermissions(); + page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable)); page.UserId = null; page = await PageService.UpdatePageAsync(page); await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId); - if (currentparentid == "") + if (_currentparentid == string.Empty) { await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, null); } else { - await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(currentparentid)); + await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(_currentparentid)); } // update child paths - if (parentid != currentparentid) + if (_parentid != _currentparentid) { foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath))) { @@ -404,7 +466,7 @@ } else { - AddModuleMessage("You Must Provide Page Name And Theme", MessageType.Warning); + AddModuleMessage("You Must Provide Page Name", MessageType.Warning); } } catch (Exception ex) diff --git a/Oqtane.Client/Modules/Admin/Pages/Index.razor b/Oqtane.Client/Modules/Admin/Pages/Index.razor index ce546547..b53f3811 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Index.razor @@ -22,13 +22,14 @@ } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; private async Task DeletePage(Page page) { try { page.IsDeleted = true; + await PageService.UpdatePageAsync(page); await logger.LogInformation("Page Deleted {Page}", page); NavigationManager.NavigateTo(NavigateUrl("admin/pages")); diff --git a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor index bfba2d25..96a65b18 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor @@ -6,66 +6,66 @@ - - - - - - - - - - - - - - } - -
- @if (_modules == null) - { -
-

No Deleted Modules

- } - else - { - -
-
- - - - - - - - - - - - - - - - } - - - - + + + @if (_pages == null) + { +
+

No Deleted Pages

+ } + else + { + +
+
+ + + + + + + + + + + + + + } + + + @if (_modules == null) + { +
+

No Deleted Modules

+ } + else + { + +
+
+ + + + + + + + + + + + + + + + } + + @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private List _pages; + private List _modules; - List _pages; - List _modules; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { @@ -147,7 +129,7 @@ { try { - PageModule pagemodule = await PageModuleService.GetPageModuleAsync(module.PageModuleId); + var pagemodule = await PageModuleService.GetPageModuleAsync(module.PageModuleId); pagemodule.IsDeleted = false; await PageModuleService.UpdatePageModuleAsync(pagemodule); await logger.LogInformation("Module Restored {Module}", module); @@ -168,10 +150,12 @@ await PageModuleService.DeletePageModuleAsync(module.PageModuleId); // check if there are any remaining module instances in the site _modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId); + if (!_modules.Exists(item => item.ModuleId == module.ModuleId)) { await ModuleService.DeleteModuleAsync(module.ModuleId); } + await logger.LogInformation("Module Permanently Deleted {Module}", module); await Load(); StateHasChanged(); diff --git a/Oqtane.Client/Modules/Admin/Register/Index.razor b/Oqtane.Client/Modules/Admin/Register/Index.razor index 46fdca01..2ea64944 100644 --- a/Oqtane.Client/Modules/Admin/Register/Index.razor +++ b/Oqtane.Client/Modules/Admin/Register/Index.razor @@ -3,60 +3,74 @@ @inject NavigationManager NavigationManager @inject IUserService UserService -@if (_message != "") +@if (PageState.Site.AllowRegistration) { - + + + ... + + + + + + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+
+} +else +{ + } -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
- - -
- @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } } + private string _username = string.Empty; + private string _password = string.Empty; + private string _confirm = string.Empty; + private string _email = string.Empty; + private string _displayName = string.Empty; - string _message = "Please Note That Registration Requires A Valid Email Address In Order To Verify Your Identity"; - string _username = ""; - string _password = ""; - string _confirm = ""; - string _email = ""; - string _displayName = ""; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; private async Task Register() { try { - _message = ""; - if (_username != "" && _password != "" && _confirm != "" && _email != "") + bool _isEmailValid = Utilities.IsValidEmail(_email); + + if (_username != "" && _password != "" && _confirm != "" && _isEmailValid) { if (_password == _confirm) { - User user = new User + var user = new User { SiteId = PageState.Site.SiteId, Username = _username, - DisplayName = (_displayName == "" ? _username : _displayName), + DisplayName = (_displayName == string.Empty ? _username : _displayName), Email = _email, Password = _password }; @@ -92,6 +106,6 @@ private void Cancel() { - NavigationManager.NavigateTo(NavigateUrl("")); + NavigationManager.NavigateTo(NavigateUrl(string.Empty)); } -} +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/Reset/Index.razor b/Oqtane.Client/Modules/Admin/Reset/Index.razor index 3fbb1556..b6e4eb66 100644 --- a/Oqtane.Client/Modules/Admin/Reset/Index.razor +++ b/Oqtane.Client/Modules/Admin/Reset/Index.razor @@ -21,11 +21,11 @@ @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } } + private string _username = string.Empty; + private string _password = string.Empty; + private string _confirm = string.Empty; - string _username = ""; - string _password = ""; - string _confirm = ""; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; protected override void OnInitialized() { @@ -35,7 +35,7 @@ } else { - NavigationManager.NavigateTo(NavigateUrl("")); + NavigationManager.NavigateTo(NavigateUrl(string.Empty)); } } @@ -43,11 +43,11 @@ { try { - if (_username != "" && _password != "" && _confirm != "") + if (_username != string.Empty && _password != string.Empty && _confirm != string.Empty) { if (_password == _confirm) { - User user = new User + var user = new User { SiteId = PageState.Site.SiteId, Username = _username, @@ -85,6 +85,6 @@ private void Cancel() { - NavigationManager.NavigateTo(NavigateUrl("")); + NavigationManager.NavigateTo(NavigateUrl(string.Empty)); } } diff --git a/Oqtane.Client/Modules/Admin/Roles/Add.razor b/Oqtane.Client/Modules/Admin/Roles/Add.razor index e908dd1c..34e93e2d 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Add.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Add.razor @@ -6,37 +6,26 @@
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - +
- + - @@ -73,10 +73,10 @@
- + - @@ -87,19 +87,20 @@ Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } - public override string Actions { get { return "Add,Edit"; } } + private int _profileid = -1; + private string _name = string.Empty; + private string _title = string.Empty; + private string _description = string.Empty; + private string _category = string.Empty; + private string _vieworder = "0"; + private string _maxlength = "0"; + private string _defaultvalue = string.Empty; + private string _isrequired = "False"; + private string _isprivate = "False"; - int _profileid = -1; - string _name = ""; - string _title = ""; - string _description = ""; - string _category = ""; - string _vieworder = "0"; - string _maxlength = "0"; - string _defaultvalue = ""; - string _isrequired = "False"; - string _isprivate = "False"; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + + public override string Actions => "Add,Edit"; protected override async Task OnInitializedAsync() { @@ -108,7 +109,7 @@ if (PageState.QueryString.ContainsKey("id")) { _profileid = Int32.Parse(PageState.QueryString["id"]); - Profile profile = await ProfileService.GetProfileAsync(_profileid); + var profile = await ProfileService.GetProfileAsync(_profileid); if (profile != null) { _name = profile.Name; @@ -143,6 +144,7 @@ { profile = new Profile(); } + profile.Name = _name; profile.Title = _title; profile.Description = _description; @@ -152,7 +154,14 @@ profile.DefaultValue = _defaultvalue; profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired)); profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate)); - profile = await ProfileService.UpdateProfileAsync(profile); + if (_profileid != -1) + { + profile = await ProfileService.UpdateProfileAsync(profile); + }else + { + profile = await ProfileService.AddProfileAsync(profile); + } + await logger.LogInformation("Profile Saved {Profile}", profile); NavigationManager.NavigateTo(NavigateUrl()); } diff --git a/Oqtane.Client/Modules/Admin/Profiles/Index.razor b/Oqtane.Client/Modules/Admin/Profiles/Index.razor index 593ccca4..e3cefdaa 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Index.razor @@ -25,9 +25,9 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private List _profiles; - List _profiles; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index 012a5495..d3955307 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -5,86 +5,68 @@ @inject IModuleService ModuleService @inject IPageService PageService -
-
- - - -
-
- @if (_pages == null) - { -
-

No Deleted Pages

- } - else - { - -
-
  NameDeleted ByDeleted On@context.Name@context.DeletedBy@context.DeletedOn  PageModuleDeleted ByDeleted On@PageState.Pages.Find(item => item.PageId == context.PageId).Name@context.Title@context.DeletedBy@context.DeletedOn  NameDeleted ByDeleted On@context.Name@context.DeletedBy@context.DeletedOn  PageModuleDeleted ByDeleted On@PageState.Pages.Find(item => item.PageId == context.PageId).Name@context.Title@context.DeletedBy@context.DeletedOn
- - - - + + + + + + + +

+} + +@code { + private int roleid; + private string name = string.Empty; + private List users; + private int userid = -1; + private string effectivedate = string.Empty; + private string expirydate = string.Empty; + private List userroles; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + + protected override async Task OnInitializedAsync() + { + try + { + roleid = Int32.Parse(PageState.QueryString["id"]); + Role role = await RoleService.GetRoleAsync(roleid); + name = role.Name; + users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId); + users = users.Where(item => item.Role.Name == Constants.RegisteredRole).ToList(); + await GetUserRoles(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Users {Error}", ex.Message); + AddModuleMessage("Error Loading Users", MessageType.Error); + } + } + + private async Task GetUserRoles() + { + try + { + userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId); + userroles = userroles.Where(item => item.RoleId == roleid).ToList(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading User Roles {RoleId} {Error}", roleid, ex.Message); + AddModuleMessage("Error Loading User Roles", MessageType.Error); + } + } + + private async Task SaveUserRole() + { + try + { + if (userid != -1) + { + var userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault(); + if (userrole != null) + { + if (string.IsNullOrEmpty(effectivedate)) + { + userrole.EffectiveDate = null; + } + else + { + userrole.EffectiveDate = DateTime.Parse(effectivedate); + } + + if (string.IsNullOrEmpty(expirydate)) + { + userrole.ExpiryDate = null; + } + else + { + userrole.ExpiryDate = DateTime.Parse(expirydate); + } + await UserRoleService.UpdateUserRoleAsync(userrole); + } + else + { + userrole = new UserRole(); + userrole.UserId = userid; + userrole.RoleId = roleid; + + if (string.IsNullOrEmpty(effectivedate)) + { + userrole.EffectiveDate = null; + } + else + { + userrole.EffectiveDate = DateTime.Parse(effectivedate); + } + + if (string.IsNullOrEmpty(expirydate)) + { + userrole.ExpiryDate = null; + } + else + { + userrole.ExpiryDate = DateTime.Parse(expirydate); + } + + await UserRoleService.AddUserRoleAsync(userrole); + } + + await GetUserRoles(); + await logger.LogInformation("User Assigned To Role {UserRole}", userrole); + AddModuleMessage("User Assigned To Role", MessageType.Success); + } + else + { + AddModuleMessage("You Must Select A User", MessageType.Warning); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving User Roles {RoleId} {Error}", roleid, ex.Message); + AddModuleMessage("Error Saving User Roles", MessageType.Error); + } + } + + private async Task DeleteUserRole(int UserRoleId) + { + try + { + await UserRoleService.DeleteUserRoleAsync(UserRoleId); + await GetUserRoles(); + await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId); + AddModuleMessage("User Removed From Role", MessageType.Success); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message); + AddModuleMessage("Error Removing User From Role", MessageType.Error); + } + } +} diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index b3692a49..e4bae61e 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -7,51 +7,59 @@ @inject IThemeService ThemeService @inject ISettingService SettingService -@if (themes != null) +@if (_themes != null) {
- + - +
- + - +
- + - -
- - - @@ -46,22 +35,21 @@ Cancel -@code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } +@code { + private string _name = string.Empty; + private string _description = string.Empty; + private string _isautoassigned = "False"; - string name = ""; - string description = ""; - string isautoassigned = "False"; - string issystem = "False"; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; private async Task SaveRole() { - Role role = new Role(); + var role = new Role(); role.SiteId = PageState.Page.SiteId; - role.Name = name; - role.Description = description; - role.IsAutoAssigned = (isautoassigned == null ? false : Boolean.Parse(isautoassigned)); - role.IsSystem = (issystem == null ? false : Boolean.Parse(issystem)); + role.Name = _name; + role.Description = _description; + role.IsAutoAssigned = (_isautoassigned == null ? false : Boolean.Parse(_isautoassigned)); + role.IsSystem = false; try { diff --git a/Oqtane.Client/Modules/Admin/Roles/Edit.razor b/Oqtane.Client/Modules/Admin/Roles/Edit.razor index 71bc826a..4b0dd0e0 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Edit.razor @@ -6,37 +6,26 @@ - - - - - - + + + } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private List _roles; - List _roles; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnParametersSetAsync() { diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor new file mode 100644 index 00000000..c292d3d5 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -0,0 +1,201 @@ +@namespace Oqtane.Modules.Admin.Roles +@inherits ModuleBase +@inject IRoleService RoleService +@inject IUserRoleService UserRoleService + +@if (userroles == null) +{ +

Loading...

+} +else +{ +
- + - +
- + - +
- + - -
- - - @@ -47,26 +36,24 @@ Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private int _roleid; + private string _name = string.Empty; + private string _description = string.Empty; + private string _isautoassigned = "False"; - int _roleid; - string _name = ""; - string _description = ""; - string _isautoassigned = "False"; - string _issystem = "False"; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { try { _roleid = Int32.Parse(PageState.QueryString["id"]); - Role role = await RoleService.GetRoleAsync(_roleid); + var role = await RoleService.GetRoleAsync(_roleid); if (role != null) { _name = role.Name; _description = role.Description; _isautoassigned = role.IsAutoAssigned.ToString(); - _issystem = role.IsSystem.ToString(); } } catch (Exception ex) @@ -78,11 +65,11 @@ private async Task SaveRole() { - Role role = await RoleService.GetRoleAsync(_roleid); + var role = await RoleService.GetRoleAsync(_roleid); role.Name = _name; role.Description = _description; role.IsAutoAssigned = (_isautoassigned != null && Boolean.Parse(_isautoassigned)); - role.IsSystem = (_issystem != null && Boolean.Parse(_issystem)); + role.IsSystem = false; try { diff --git a/Oqtane.Client/Modules/Admin/Roles/Index.razor b/Oqtane.Client/Modules/Admin/Roles/Index.razor index 29378752..881a9348 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Index.razor @@ -12,22 +12,24 @@ else
+
      Name @context.Name
+ + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + Cancel + +
+

+ +

+
Users @context.User.DisplayName + +
+ + + + + + + +
- + - +
- + - +
- + - +
- + - +
- + -
+ + +
- + - - @foreach (KeyValuePair panelayout in panelayouts) + @foreach (KeyValuePair panelayout in _panelayouts) { } @@ -79,12 +87,12 @@
- + - - @foreach (KeyValuePair container in containers) + @foreach (KeyValuePair container in _containers) { } @@ -93,10 +101,21 @@
- + - + + + +
+ + + @@ -104,137 +123,200 @@
- -
+
- + - +
- + - +
- + - +
- + - +
- + - +
-
+ +
+ + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
Cancel

- + } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } } + private Dictionary _themes; + private Dictionary _panelayouts; + private Dictionary _containers; + private List _themeList; + private string _name = string.Empty; + private List _tenantList; + private string _tenant = string.Empty; + private List _aliasList; + private string _urls = string.Empty; + private int _logofileid = -1; + private FileManager _logofilemanager; + private int _faviconfileid = -1; + private FileManager _faviconfilemanager; + private string _themetype; + private string _layouttype; + private string _containertype; + private string _allowregistration; + private string _smtphost = string.Empty; + private string _smtpport = string.Empty; + private string _smtpssl = string.Empty; + private string _smtpusername = string.Empty; + private string _smtppassword = string.Empty; + private string _pwaisenabled; + private int _pwaappiconfileid = -1; + private FileManager _pwaappiconfilemanager; + private int _pwasplashiconfileid = -1; + private FileManager _pwasplashiconfilemanager; + private string _createdby; + private DateTime _createdon; + private string _modifiedby; + private DateTime _modifiedon; + private string _deletedby; + private DateTime? _deletedon; + private string _isdeleted; - Dictionary themes; - Dictionary panelayouts; - Dictionary containers; - - List Themes; - string name = ""; - List tenants; - string tenant = ""; - List aliases; - string urls = ""; - int logofileid = -1; - FileManager filemanager; - string themetype; - string layouttype; - string containertype; - - string smtphost = ""; - string smtpport = ""; - string smtpssl = ""; - string smtpusername = ""; - string smtppassword = ""; - - string createdby; - DateTime createdon; - string modifiedby; - DateTime modifiedon; - string deletedby; - DateTime? deletedon; - string isdeleted; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; protected override async Task OnInitializedAsync() { try { - Themes = await ThemeService.GetThemesAsync(); - aliases = await AliasService.GetAliasesAsync(); - Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId, PageState.Alias); + _themeList = await ThemeService.GetThemesAsync(); + _aliasList = await AliasService.GetAliasesAsync(); + Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId); if (site != null) { - name = site.Name; - tenants = await TenantService.GetTenantsAsync(); - tenant = tenants.Find(item => item.TenantId == site.TenantId).Name; - foreach (Alias alias in aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) + _name = site.Name; + _tenantList = await TenantService.GetTenantsAsync(); + _tenant = _tenantList.Find(item => item.TenantId == site.TenantId).Name; + foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) { - urls += alias.Name + "\n"; + _urls += alias.Name + "\n"; } if (site.LogoFileId != null) { - logofileid = site.LogoFileId.Value; + _logofileid = site.LogoFileId.Value; } - themetype = site.DefaultThemeType; - panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); - layouttype = site.DefaultLayoutType; - containertype = site.DefaultContainerType; - Dictionary settings = await SettingService.GetSiteSettingsAsync(site.SiteId); - smtphost = SettingService.GetSetting(settings, "SMTPHost", ""); - smtpport = SettingService.GetSetting(settings, "SMTPPort", ""); - smtpssl = SettingService.GetSetting(settings, "SMTPSSL", ""); - smtpusername = SettingService.GetSetting(settings, "SMTPUsername", ""); - smtppassword = SettingService.GetSetting(settings, "SMTPPassword", ""); + if (site.FaviconFileId != null) + { + _faviconfileid = site.FaviconFileId.Value; + } - createdby = site.CreatedBy; - createdon = site.CreatedOn; - modifiedby = site.ModifiedBy; - modifiedon = site.ModifiedOn; - deletedby = site.DeletedBy; - deletedon = site.DeletedOn; - isdeleted = site.IsDeleted.ToString(); + _themetype = site.DefaultThemeType; + _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); + _layouttype = site.DefaultLayoutType; + _containertype = site.DefaultContainerType; + _allowregistration = site.AllowRegistration.ToString(); + + 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", string.Empty); + _smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty); + _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty); + + _pwaisenabled = site.PwaIsEnabled.ToString(); + + if (site.PwaAppIconFileId != null) + { + _pwaappiconfileid = site.PwaAppIconFileId.Value; + } + + if (site.PwaSplashIconFileId != null) + { + _pwasplashiconfileid = site.PwaSplashIconFileId.Value; + } + + _pwaisenabled = site.PwaIsEnabled.ToString(); + if (site.PwaAppIconFileId != null) + { + _pwaappiconfileid = site.PwaAppIconFileId.Value; + } + if (site.PwaSplashIconFileId != null) + { + _pwasplashiconfileid = site.PwaSplashIconFileId.Value; + } + + _createdby = site.CreatedBy; + _createdon = site.CreatedOn; + _modifiedby = site.ModifiedBy; + _modifiedon = site.ModifiedOn; + _deletedby = site.DeletedBy; + _deletedon = site.DeletedOn; + _isdeleted = site.IsDeleted.ToString(); } - themes = ThemeService.GetThemeTypes(Themes); - containers = ThemeService.GetContainerTypes(Themes); + _themes = ThemeService.GetThemeTypes(_themeList); + _containers = ThemeService.GetContainerTypes(_themeList); } catch (Exception ex) { @@ -247,20 +329,20 @@ { try { - themetype = (string)e.Value; - if (themetype != "") + _themetype = (string)e.Value; + if (_themetype != string.Empty) { - panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype); + _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); } else { - panelayouts = new Dictionary(); + _panelayouts = new Dictionary(); } StateHasChanged(); } catch (Exception ex) { - await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message); + await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error); } } @@ -269,47 +351,65 @@ { try { - if (name != "" && urls != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype)) && !string.IsNullOrEmpty(containertype)) + if (_name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype)) { - bool unique = true; - foreach (string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) + var unique = true; + foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { - if (aliases.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId)) + if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId)) { unique = false; } } + if (unique) { - Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId, PageState.Alias); + var site = await SiteService.GetSiteAsync(PageState.Site.SiteId); if (site != null) { - site.Name = name; + site.Name = _name; site.LogoFileId = null; - int logofileid = filemanager.GetFileId(); + var logofileid = _logofilemanager.GetFileId(); if (logofileid != -1) { site.LogoFileId = logofileid; } - site.DefaultThemeType = themetype; - site.DefaultLayoutType = (layouttype == null ? "" : layouttype); - site.DefaultContainerType = containertype; - site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted)); - site = await SiteService.UpdateSiteAsync(site, PageState.Alias); + site.DefaultThemeType = _themetype; + site.DefaultLayoutType = (_layouttype == null ? string.Empty : _layouttype); + site.DefaultContainerType = _containertype; + site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration)); + site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); - urls = urls.Replace("\n", ","); - string[] names = urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - foreach (Alias alias in aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) + site.PwaIsEnabled = (_pwaisenabled == null ? true : Boolean.Parse(_pwaisenabled)); + + var pwaappiconfileid = _pwaappiconfilemanager.GetFileId(); + if (pwaappiconfileid != -1) + { + site.PwaAppIconFileId = pwaappiconfileid; + } + + var pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId(); + if (pwasplashiconfileid != -1) + { + site.PwaSplashIconFileId = pwasplashiconfileid; + } + + site = await SiteService.UpdateSiteAsync(site); + + _urls = _urls.Replace("\n", ","); + 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); } } + foreach (string name in names) { - if (!aliases.Exists(item => item.Name == name)) + if (!_aliasList.Exists(item => item.Name == name)) { Alias alias = new Alias(); alias.Name = name; @@ -319,12 +419,12 @@ } } - Dictionary 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); + 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); await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); await logger.LogInformation("Site Saved {Site}", site); diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index a692d081..40ac6f39 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -5,7 +5,9 @@ @inject IAliasService AliasService @inject ISiteService SiteService @inject IThemeService ThemeService +@inject ISiteTemplateService SiteTemplateService @inject IUserService UserService +@inject IInstallationService InstallationService @if (_tenants == null) { @@ -16,40 +18,26 @@ else - - - - - @if (!_isinitialized) + + + + + + + + + @if (_tenantid == "+") { - - + + + + + + + + + + + + + + + + + + @if (!_integratedsecurity) + { + + + + + + + + + } + + + + + + + } @@ -111,23 +198,32 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private Dictionary _themes = new Dictionary(); + private Dictionary _panelayouts = new Dictionary(); + private Dictionary _containers = new Dictionary(); + private List _siteTemplates; + private List _themeList; + private List _tenants; + private string _tenantid = "-"; - Dictionary _themes = new Dictionary(); - Dictionary _panelayouts = new Dictionary(); - Dictionary _containers = new Dictionary(); + private string _tenantname = string.Empty; + private string _databasetype = "LocalDB"; + private string _server = "(LocalDb)\\MSSQLLocalDB"; + private string _database = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm"); + private string _username = string.Empty; + private string _password = string.Empty; + private bool _integratedsecurity = true; + private string _hostusername = Constants.HostUser; + private string _hostpassword = string.Empty; - List _themeList; - List _tenants; - string _tenantid = "-1"; - string _name = ""; - string _urls = ""; - string _themetype = ""; - string _layouttype = ""; - string _containertype = ""; - bool _isinitialized = true; - string _username = ""; - string _password = ""; + private string _name = string.Empty; + private string _urls = string.Empty; + private string _themetype = string.Empty; + private string _layouttype = string.Empty; + private string _containertype = string.Empty; + private string _sitetemplatetype = string.Empty; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { @@ -136,29 +232,30 @@ else _urls = PageState.Alias.Name; _themes = ThemeService.GetThemeTypes(_themeList); _containers = ThemeService.GetContainerTypes(_themeList); - _username = Constants.HostUser; + _siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync(); } - private async void TenantChanged(ChangeEventArgs e) + private void TenantChanged(ChangeEventArgs e) { - try + _tenantid = (string)e.Value; + if (string.IsNullOrEmpty(_tenantname)) { - _tenantid = (string)e.Value; - if (_tenantid != "-1") - { - Tenant tenant = _tenants.Where(item => item.TenantId == int.Parse(_tenantid)).FirstOrDefault(); - if (tenant != null) - { - _isinitialized = tenant.IsInitialized; - StateHasChanged(); - } - } + _tenantname = _name; } - catch (Exception ex) + StateHasChanged(); + } + + private void SetIntegratedSecurity(ChangeEventArgs e) + { + if (Convert.ToBoolean((string)e.Value)) { - await logger.LogError(ex, "Error Loading Tenant {TenantId} {Error}", _tenantid, ex.Message); - AddModuleMessage("Error Loading Tenant", MessageType.Error); + _integratedsecurity = true; } + else + { + _integratedsecurity = false; + } + StateHasChanged(); } private async void ThemeChanged(ChangeEventArgs e) @@ -166,7 +263,7 @@ else try { _themetype = (string)e.Value; - if (_themetype != "") + if (_themetype != string.Empty) { _panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype); } @@ -174,6 +271,7 @@ else { _panelayouts = new Dictionary(); } + StateHasChanged(); } catch (Exception ex) @@ -185,99 +283,121 @@ else private async Task SaveSite() { - if (_tenantid != "-1" && _name != "" && _urls != "" && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype)) + if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype) && !string.IsNullOrEmpty(_sitetemplatetype)) { - bool unique = true; - List aliases = await AliasService.GetAliasesAsync(); + var duplicates = new List(); + var aliases = await AliasService.GetAliasesAsync(); foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { if (aliases.Exists(item => item.Name == name)) { - unique = false; + duplicates.Add(name); } } - if (unique) + + if (duplicates.Count == 0) { - bool isvalid = true; + InstallConfig config = new InstallConfig(); - if (!_isinitialized) + if (_tenantid == "+") { - User user = new User(); - user.SiteId = PageState.Site.SiteId; - user.Username = _username; - user.Password = _password; - user = await UserService.LoginUserAsync(user, false, false); - isvalid = user.IsAuthenticated; - } - - if (isvalid) - { - ShowProgressIndicator(); - - aliases = new List(); - _urls = _urls.Replace("\n", ","); - foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) + if (!string.IsNullOrEmpty(_tenantname) && _tenants.FirstOrDefault(item => item.Name == _tenantname) == null) { - Alias alias = new Alias(); - alias.Name = name; - alias.TenantId = int.Parse(_tenantid); - alias.SiteId = -1; - alias = await AliasService.AddAliasAsync(alias); - aliases.Add(alias); - } - - Site site = new Site(); - site.TenantId = int.Parse(_tenantid); - site.Name = _name; - site.LogoFileId = null; - site.DefaultThemeType = _themetype; - site.DefaultLayoutType = (_layouttype == null ? "" : _layouttype); - site.DefaultContainerType = _containertype; - site = await SiteService.AddSiteAsync(site, aliases[0]); - - foreach (Alias alias in aliases) - { - alias.SiteId = site.SiteId; - await AliasService.UpdateAliasAsync(alias); - } - - if (!_isinitialized) - { - User user = new User(); - user.SiteId = site.SiteId; - user.Username = _username; - user.Password = _password; - user.Email = PageState.User.Email; - user.DisplayName = PageState.User.DisplayName; - user = await UserService.AddUserAsync(user, aliases[0]); - - if (user != null) + // validate host credentials + var user = new User(); + user.SiteId = PageState.Site.SiteId; + user.Username = Constants.HostUser; + user.Password = _hostpassword; + user = await UserService.LoginUserAsync(user, false, false); + if (user.IsAuthenticated) { - Tenant tenant = _tenants.FirstOrDefault(item => item.TenantId == int.Parse(_tenantid)); - tenant.IsInitialized = true; - await TenantService.UpdateTenantAsync(tenant); + if (!string.IsNullOrEmpty(_server) && !string.IsNullOrEmpty(_database)) + { + var connectionString = string.Empty; + if (_databasetype == "LocalDB") + { + connectionString = "Data Source=" + _server + ";AttachDbFilename=|DataDirectory|\\" + _database + ".mdf;Initial Catalog=" + _database + ";Integrated Security=SSPI;"; + } + else + { + connectionString = "Data Source=" + _server + ";Initial Catalog=" + _database + ";"; + + if (_integratedsecurity) + { + connectionString += "Integrated Security=SSPI;"; + } + else + { + connectionString += "User ID=" + _username + ";Password=" + _password; + } + } + + config.ConnectionString = connectionString; + config.HostPassword = _hostpassword; + config.HostEmail = user.Email; + config.HostName = user.DisplayName; + config.TenantName = _tenantname; + config.IsNewTenant = true; + } + else + { + AddModuleMessage("You Must Specify A Server And Database", MessageType.Error); + } + } + else + { + AddModuleMessage("Invalid Host Password", MessageType.Error); } } - await Log(aliases[0], LogLevel.Information, "", null, "Site Created {Site}", site); - - Uri uri = new Uri(NavigationManager.Uri); - NavigationManager.NavigateTo(uri.Scheme + "://" + aliases[0].Name, true); + else + { + AddModuleMessage("Tenant Name Is Missing Or Already Exists", MessageType.Error); + } } else { - await logger.LogError("Invalid Password Entered For Host {Username}", _username); - AddModuleMessage("Invalid Host Password", MessageType.Error); + var tenant = _tenants.FirstOrDefault(item => item.TenantId == int.Parse(_tenantid)); + if (tenant != null) + { + config.TenantName = tenant.Name; + config.ConnectionString= tenant.DBConnectionString; + config.IsNewTenant = false; + } + } + + if (!string.IsNullOrEmpty(config.TenantName)) + { + config.SiteName = _name; + config.Aliases = _urls.Replace("\n", ","); + config.DefaultTheme = _themetype; + config.DefaultLayout = _layouttype; + config.DefaultContainer = _containertype; + config.SiteTemplate = _sitetemplatetype; + + ShowProgressIndicator(); + + var installation = await InstallationService.Install(config); + 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); + } + else + { + await logger.LogError("Error Creating Site {Error}", installation.Message); + AddModuleMessage(installation.Message, MessageType.Error); + } } } else { - AddModuleMessage("An Alias Specified Has Already Been Used For Another Site", MessageType.Warning); + AddModuleMessage(string.Join(", ", duplicates.ToArray()) + " Already Used For Another Site", MessageType.Warning); } } else { - AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, And Default Theme/Container", MessageType.Warning); + AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, Default Theme/Container, And Site Template", MessageType.Warning); } - } } diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor index bc3b499c..698892a7 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor @@ -6,43 +6,43 @@ @inject IAliasService AliasService @inject IThemeService ThemeService -@if (themes != null) +@if (_themes != null) {
- + - +
- + - +
- + - -
- - - @foreach (KeyValuePair item in _themes) { @@ -60,10 +48,10 @@ else
- + - @foreach (KeyValuePair panelayout in _panelayouts) { @@ -74,34 +62,133 @@ else
- + - - @foreach (KeyValuePaircontainer in _containers) + @foreach (KeyValuePair container in _containers) { }
+ + + +
+ + + +
- - - + +
- + - + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
+ +
- + - +
- + - +
- + - +
+ +

+ @if (!string.IsNullOrEmpty(_results)) + { + @((MarkupString)_results) + } +} + +@code { + private List _tenants; + private string _tenantid = "-1"; + private string _sql = string.Empty; + private string _results = string.Empty; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + + protected override async Task OnInitializedAsync() + { + _tenants = await TenantService.GetTenantsAsync(); + } + + private async Task Execute() + { + if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql)) + { + var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql }; + sqlquery = await SqlService.ExecuteQueryAsync(sqlquery); + _results = DisplayResults(sqlquery.Results); + } + else + { + AddModuleMessage("You Must Select A Tenant And Provide A SQL Query", MessageType.Warning); + } + } + + private string DisplayResults(List> results) + { + var table = string.Empty; + foreach (Dictionary item in results) + { + if (table == string.Empty) + { + table = "
"; + table += ""; + + foreach (KeyValuePair kvp in item) + { + table += ""; + } + + table += ""; + } + + table += ""; + + foreach (KeyValuePair kvp in item) + { + table += ""; + } + + table += ""; + } + + if (table != string.Empty) + { + table += "
" + kvp.Key + "
" + kvp.Value + "
"; + } + else + { + table = "No Results Returned"; + } + + return table; + } +} diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor new file mode 100644 index 00000000..8e19125f --- /dev/null +++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor @@ -0,0 +1,81 @@ +@namespace Oqtane.Modules.Admin.SystemInfo +@inherits ModuleBase +@inject ISystemService SystemService + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+Access Framework API + +@code { + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + + private string _version = string.Empty; + private string _runtime = string.Empty; + private string _clrversion = string.Empty; + private string _osversion = string.Empty; + private string _serverpath = string.Empty; + private string _servertime = string.Empty; + + protected override async Task OnInitializedAsync() + { + _version = Constants.Version; + _runtime = PageState.Runtime.ToString(); + + Dictionary systeminfo = await SystemService.GetSystemInfoAsync(); + if (systeminfo != null) + { + _clrversion = systeminfo["clrversion"]; + _osversion = systeminfo["osversion"]; + _serverpath = systeminfo["serverpath"]; + _servertime = systeminfo["servertime"]; + } + } +} diff --git a/Oqtane.Client/Modules/Admin/Tenants/Add.razor b/Oqtane.Client/Modules/Admin/Tenants/Add.razor deleted file mode 100644 index baccdfa8..00000000 --- a/Oqtane.Client/Modules/Admin/Tenants/Add.razor +++ /dev/null @@ -1,154 +0,0 @@ -@namespace Oqtane.Modules.Admin.Tenants -@inherits ModuleBase -@inject NavigationManager NavigationManager -@inject ITenantService TenantService -@inject IInstallationService InstallationService - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- -Cancel - -@code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } - - string name = ""; - string type = "LocalDB"; - string server = "(LocalDb)\\MSSQLLocalDB"; - string database = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm"); - string username = ""; - string password = ""; - string schema = ""; - string integratedsecurity = "display: none;"; - - private void SetIntegratedSecurity(ChangeEventArgs e) - { - if (Convert.ToBoolean((string)e.Value)) - { - integratedsecurity = "display: none;"; - } - else - { - integratedsecurity = ""; - } - } - - private async Task SaveTenant() - { - if (!string.IsNullOrEmpty(name)) - { - ShowProgressIndicator(); - - string connectionstring = ""; - if (type == "LocalDB") - { - connectionstring = "Data Source=" + server + ";AttachDbFilename=|DataDirectory|\\" + database + ".mdf;Initial Catalog=" + database + ";Integrated Security=SSPI;"; - } - else - { - connectionstring = "Data Source=" + server + ";Initial Catalog=" + database + ";"; - if (integratedsecurity == "display: none;") - { - connectionstring += "Integrated Security=SSPI;"; - } - else - { - connectionstring += "User ID=" + username + ";Password=" + password; - - } - } - GenericResponse response = await InstallationService.Install(connectionstring); - if (response.Success) - { - Tenant tenant = new Tenant(); - tenant.Name = name; - tenant.DBConnectionString = connectionstring; - tenant.DBSchema = schema; - tenant.IsInitialized = false; - await TenantService.AddTenantAsync(tenant); - await logger.LogInformation("Tenant Created {Tenant}", tenant); - - NavigationManager.NavigateTo(NavigateUrl()); - } - else - { - await logger.LogError("Error Creating Tenant {Error}", response.Message); - AddModuleMessage(response.Message, MessageType.Error); - } - } - else - { - AddModuleMessage("You Must Provide A Name For The Tenant", MessageType.Warning); - } - } -} diff --git a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor index 0224cd1e..94ee91d6 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor @@ -6,51 +6,50 @@ - - - - +
- + - + @if (name == Constants.MasterTenant) + { + + } + else + { + + }
- + - -
- - - +
Cancel @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private int tenantid; + private string name = string.Empty; + private string connectionstring = string.Empty; + private string schema = string.Empty; - int tenantid; - string name = ""; - string connectionstring = ""; - string schema = ""; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { try { tenantid = Int32.Parse(PageState.QueryString["id"]); - Tenant tenant = await TenantService.GetTenantAsync(tenantid); + var tenant = await TenantService.GetTenantAsync(tenantid); if (tenant != null) { name = tenant.Name; connectionstring = tenant.DBConnectionString; - schema = tenant.DBSchema; } } catch (Exception ex) @@ -65,12 +64,12 @@ try { connectionstring = connectionstring.Replace("\\\\", "\\"); - Tenant tenant = await TenantService.GetTenantAsync(tenantid); + var tenant = await TenantService.GetTenantAsync(tenantid); if (tenant != null) { tenant.Name = name; tenant.DBConnectionString = connectionstring; - tenant.DBSchema = schema; + await TenantService.UpdateTenantAsync(tenant); await logger.LogInformation("Tenant Saved {TenantId}", tenantid); diff --git a/Oqtane.Client/Modules/Admin/Tenants/Index.razor b/Oqtane.Client/Modules/Admin/Tenants/Index.razor index 5c22fcbf..ead272dc 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Index.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Index.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Modules.Admin.Tenants @inherits ModuleBase @inject ITenantService TenantService +@inject IAliasService AliasService @if (tenants == null) { @@ -8,8 +9,6 @@ } else { - -
  @@ -18,7 +17,7 @@ else
- + @context.Name
@@ -26,9 +25,9 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private List tenants; - List tenants; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnParametersSetAsync() { @@ -39,9 +38,25 @@ else { try { - await TenantService.DeleteTenantAsync(Tenant.TenantId); - await logger.LogInformation("Tenant Deleted {Tenant}", Tenant); - StateHasChanged(); + string message = string.Empty; + var aliases = await AliasService.GetAliasesAsync(); + foreach (var alias in aliases) + { + if (alias.TenantId == Tenant.TenantId) + { + message += ", " + alias.Name; + } + } + if (string.IsNullOrEmpty(message)) + { + await TenantService.DeleteTenantAsync(Tenant.TenantId); + await logger.LogInformation("Tenant Deleted {Tenant}", Tenant); + StateHasChanged(); + } + else + { + AddModuleMessage("Tenant Cannot Be Deleted Until The Following Sites Are Deleted: " + message.Substring(2), MessageType.Warning); + } } catch (Exception ex) { diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor index a802b838..5ad4f5c6 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Add.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor @@ -5,69 +5,100 @@ @inject IThemeService ThemeService @inject IPackageService PackageService - - - - - -
- - - -
- -@if (packages != null) +@if (_packages != null) { -
-

Available Themes

- - -
- Name - Version - -
- - @context.Name - @context.Version - - - - -
-} + + @if (_packages.Count > 0) + { + + + +
+ Name + Version + +
+ + @context.Name + @context.Version + + + + +
+
+ } + + + + + + +
+ + + +
+
+
Cancel +} @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private List _packages; - List packages; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { - List themes = await ThemeService.GetThemesAsync(); - packages = await PackageService.GetPackagesAsync("theme"); - foreach(Package package in packages.ToArray()) + try { - if (themes.Exists(item => Utilities.GetTypeName(item.ThemeName) == package.PackageId)) + var themes = await ThemeService.GetThemesAsync(); + _packages = await PackageService.GetPackagesAsync("theme"); + + foreach (Package package in _packages.ToArray()) { - packages.Remove(package); + if (themes.Exists(item => Utilities.GetTypeName(item.ThemeName) == package.PackageId)) + { + _packages.Remove(package); + } } } + catch (Exception ex) + { + await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message); + AddModuleMessage("Error Loading Packages", MessageType.Error); + } } private async Task InstallThemes() { - await ThemeService.InstallThemesAsync(); - NavigationManager.NavigateTo(NavigateUrl()); + try + { + await ThemeService.InstallThemesAsync(); + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Installating Theme"); + } } private async Task DownloadTheme(string packageid, string version) { - await PackageService.DownloadPackageAsync(packageid, version, "Themes"); - AddModuleMessage("Theme Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); - StateHasChanged(); + try + { + await PackageService.DownloadPackageAsync(packageid, version, "Themes"); + await logger.LogInformation("Theme {ThemeName} {Version} Downloaded Successfully", packageid, version); + AddModuleMessage("Themes Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Downloading Module {ThemeName} {Version}", packageid, version); + AddModuleMessage("Error Downloading Theme", MessageType.Error); + } + } } -} diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 09ec9823..4a3113b6 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -39,10 +39,10 @@ else } @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private List themes; + private List packages; - List themes; - List packages; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { @@ -52,12 +52,13 @@ else private bool UpgradeAvailable(string themename, string version) { - bool upgradeavailable = false; - Package package = packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault(); + var upgradeavailable = false; + var package = packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault(); if (package != null) { upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0); } + return upgradeavailable; } diff --git a/Oqtane.Client/Modules/Admin/Upgrade/Index.razor b/Oqtane.Client/Modules/Admin/Upgrade/Index.razor index 36dad205..2aa2ce86 100644 --- a/Oqtane.Client/Modules/Admin/Upgrade/Index.razor +++ b/Oqtane.Client/Modules/Admin/Upgrade/Index.razor @@ -5,42 +5,55 @@ @inject IPackageService PackageService @inject IInstallationService InstallationService - - - - - -
- - - -
- - -@if (upgradeavailable) +@if (_package != null) { -
-

Upgrade Available

- - + + + @if (_upgradeavailable) + { + + @("Framework") @_package.Version + } + else + { + + } + + @if (_upgradeavailable) + { + + + + + + +
+ + + +
+
+ } +
} @code { - public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } + private Package _package; + private bool _upgradeavailable = false; - bool upgradeavailable = false; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; protected override async Task OnInitializedAsync() { List packages = await PackageService.GetPackagesAsync("framework"); - Package package = packages.FirstOrDefault(); - if (package != null) + _package = packages.FirstOrDefault(); + if (_package != null) { - upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(Constants.Version)) > 0); + _upgradeavailable = (Version.Parse(_package.Version).CompareTo(Version.Parse(Constants.Version)) > 0); } - if (!upgradeavailable) + else { - AddModuleMessage("Framework Is Up To Date", MessageType.Info); + _package = new Package { Name = Constants.PackageId, Version = Constants.Version }; } } diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor index 5da04ebd..e6ae6b68 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor @@ -9,10 +9,10 @@
- + - @if (userroles != null) { @@ -26,18 +26,18 @@
- + - +
- + -