From e3fc7c0ad1227c4baf568eb323de2a26bddebc43 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 18 Feb 2021 08:38:53 +0100 Subject: [PATCH 01/47] #1120 Fix forUpload SVG throw error --- Oqtane.Server/Controllers/FileController.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index ce36dae2..9e8b3d35 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -538,10 +538,15 @@ namespace Oqtane.Controllers if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) { FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); - using (var image = Image.FromStream(stream)) - { - file.ImageHeight = image.Height; - file.ImageWidth = image.Width; + + //svg has no image and height, the attributes for svg are held in the XML viewport + if(file.Extension != "svg") + { + using (var image = Image.FromStream(stream)) + { + file.ImageHeight = image.Height; + file.ImageWidth = image.Width; + } } stream.Close(); From 45974a9c8038d4ebc96536548db2e6e28b225829 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 18 Feb 2021 08:48:33 +0100 Subject: [PATCH 02/47] Update FileController.cs --- Oqtane.Server/Controllers/FileController.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index 9e8b3d35..07a85f20 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -535,13 +535,12 @@ namespace Oqtane.Controllers file.ImageHeight = 0; file.ImageWidth = 0; - if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) - { - FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); - - //svg has no image and height, the attributes for svg are held in the XML viewport - if(file.Extension != "svg") - { + //svg has no image and height, the attributes for svg are held in the XML viewport + if(file.Extension != "svg") + { + if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + { + FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); using (var image = Image.FromStream(stream)) { file.ImageHeight = image.Height; From 59ba4b2e05e8abf6e9a443047ba3571029ed0cb5 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 18 Feb 2021 08:51:05 +0100 Subject: [PATCH 03/47] doesnt need to open the stream if svg --- Oqtane.Server/Controllers/FileController.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index 9e8b3d35..04ff4f62 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -535,21 +535,20 @@ namespace Oqtane.Controllers file.ImageHeight = 0; file.ImageWidth = 0; - if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + //svg has no image and height, the attributes for svg are held in the XML viewport + if(file.Extension != "svg") { - FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); - - //svg has no image and height, the attributes for svg are held in the XML viewport - if(file.Extension != "svg") - { + if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + { + FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); + using (var image = Image.FromStream(stream)) { file.ImageHeight = image.Height; file.ImageWidth = image.Width; } + stream.Close(); } - - stream.Close(); } return file; From 1aae8a137359b7fdc74f8a6b9c0b667dca4dafc0 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 18 Feb 2021 08:55:13 +0100 Subject: [PATCH 04/47] Update FileController.cs --- Oqtane.Server/Controllers/FileController.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index 07a85f20..b65d4c9e 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -546,9 +546,8 @@ namespace Oqtane.Controllers file.ImageHeight = image.Height; file.ImageWidth = image.Width; } + stream.Close(); } - - stream.Close(); } return file; From 3af095997f80ed8a77c028d7d98bbe72263d0e8a Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 18 Feb 2021 09:27:51 +0100 Subject: [PATCH 05/47] Fixed when file size is less that 1 Kb displays 0. This can be misleading as many svg files are less that 1 kb. File size now displays to 2 deciaml places. --- Oqtane.Client/Modules/Admin/Files/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index 26cd56f9..58990804 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -42,7 +42,7 @@ @context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"] - @(context.Size / 1000) KB + @string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB @if (_files.Count == 0) From 60d685416d6136b0b68c4c8d8e89e6653b9ed78a Mon Sep 17 00:00:00 2001 From: Philip Murray Date: Fri, 19 Feb 2021 13:09:29 +0000 Subject: [PATCH 06/47] Fixed site Favicon not saving The saved function for the favicon was not there --- Oqtane.Client/Modules/Admin/Site/Index.razor | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index acd0105b..bbfd28f7 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -420,6 +420,13 @@ site.LogoFileId = logofileid; } + + var faviconFieldId = _faviconfilemanager.GetFileId(); + if (faviconFieldId != -1) + { + site.FaviconFileId = faviconFieldId; + } + site.DefaultThemeType = _themetype; site.DefaultLayoutType = (_layouttype == "-" ? string.Empty : _layouttype); site.DefaultContainerType = _containertype; From eda2a5637f50d215fef9748b0c27748bfda90c1e Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Wed, 24 Feb 2021 17:26:54 -0500 Subject: [PATCH 07/47] Revert "Fix Upload SVG throw error #1120" --- Oqtane.Client/Modules/Admin/Files/Index.razor | 2 +- Oqtane.Server/Controllers/FileController.cs | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index 58990804..26cd56f9 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -42,7 +42,7 @@ @context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"] - @string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB + @(context.Size / 1000) KB @if (_files.Count == 0) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index b65d4c9e..ce36dae2 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -535,19 +535,16 @@ namespace Oqtane.Controllers file.ImageHeight = 0; file.ImageWidth = 0; - //svg has no image and height, the attributes for svg are held in the XML viewport - if(file.Extension != "svg") - { - if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + { + FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); + using (var image = Image.FromStream(stream)) { - FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); - using (var image = Image.FromStream(stream)) - { - file.ImageHeight = image.Height; - file.ImageWidth = image.Width; - } - stream.Close(); + file.ImageHeight = image.Height; + file.ImageWidth = image.Width; } + + stream.Close(); } return file; From 6c79006dd754e94bc6385d7334510daacd0c8e6d Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 25 Feb 2021 07:44:19 +0100 Subject: [PATCH 08/47] fix for #1134 Files size incorrect when less than 1000 bytes --- Oqtane.Client/Modules/Admin/Files/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index 26cd56f9..58990804 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -42,7 +42,7 @@ @context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"] - @(context.Size / 1000) KB + @string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB @if (_files.Count == 0) From af1eebbf0de2329735cb9c00cbe9860c9cf8aa3d Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 07:45:10 -0500 Subject: [PATCH 09/47] update copyright content --- .../Infrastructure/SiteTemplates/DefaultSiteTemplate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs index 3dd8ab3f..e21629d8 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs @@ -65,7 +65,7 @@ namespace Oqtane.SiteTemplates new Permission(PermissionNames.View, RoleNames.Admin, true), new Permission(PermissionNames.Edit, RoleNames.Admin, true) }.EncodePermissions(), - Content = "

Copyright (c) 2019-2020 .NET Foundation

" + + Content = "

Copyright (c) 2019-2021 .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 in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

" + "

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

" + "

THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

" From 99665800c4d146fd5545fb5dc7807c071ab90ef1 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 07:48:16 -0500 Subject: [PATCH 10/47] remove SVG from allowable upload files --- Oqtane.Shared/Shared/Constants.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 51e71450..613f3f39 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -55,8 +55,8 @@ namespace Oqtane.Shared { [Obsolete(RoleObsoleteMessage)] public const string RegisteredRole = RoleNames.Registered; - public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png,svg,ico"; - public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,svg,ico,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg,csv"; + public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png,ico"; + public const string UploadableFiles = ImageFiles + ",mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg,csv"; public const string ReservedDevices = "CON,NUL,PRN,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$"; public static readonly char[] InvalidFileNameChars = From 8762809a832e9fba7b72e28147413075e7d5861d Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 08:04:39 -0500 Subject: [PATCH 11/47] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d0bb04c..bd6646dd 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ This project is a work in progress and the schedule for implementing enhancement V.2.1.0 ( Q1 2021 ) - [x] Complete Static Localization of Admin UI -- [ ] Cross Platform Database Support ( ie. SQLite ) -- [ ] EF Core Migrations for Database Installation/Upgrade +- [ ] Cross Platform Database Support ( ie. SQLite ) - see #964 +- [ ] EF Core Migrations for Database Installation/Upgrade - see #964 V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 ) - [x] Migration to .NET 5 From ba54076c614cce389022157a94c78b46d389abd2 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 08:04:44 -0500 Subject: [PATCH 12/47] Prepare for 2.0.1 release --- Oqtane.Client/Oqtane.Client.csproj | 4 ++-- Oqtane.Package/Oqtane.Client.nuspec | 4 ++-- Oqtane.Package/Oqtane.Framework.nuspec | 4 ++-- Oqtane.Package/Oqtane.Server.nuspec | 4 ++-- Oqtane.Package/Oqtane.Shared.nuspec | 4 ++-- Oqtane.Package/install.ps1 | 2 +- Oqtane.Package/upgrade.ps1 | 2 +- Oqtane.Server/Oqtane.Server.csproj | 4 ++-- Oqtane.Shared/Oqtane.Shared.csproj | 4 ++-- Oqtane.Shared/Shared/Constants.cs | 4 ++-- Oqtane.Test/Oqtane.Test.csproj | 4 ++-- Oqtane.Upgrade/Oqtane.Upgrade.csproj | 4 ++-- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 72024f75..f6ce11c8 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -5,7 +5,7 @@ Exe 3.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -14,7 +14,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane true true diff --git a/Oqtane.Package/Oqtane.Client.nuspec b/Oqtane.Package/Oqtane.Client.nuspec index 6b01cba1..c669a8a2 100644 --- a/Oqtane.Package/Oqtane.Client.nuspec +++ b/Oqtane.Package/Oqtane.Client.nuspec @@ -2,7 +2,7 @@ Oqtane.Client - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/Oqtane.Framework.nuspec b/Oqtane.Package/Oqtane.Framework.nuspec index 10313bc4..6e68fa19 100644 --- a/Oqtane.Package/Oqtane.Framework.nuspec +++ b/Oqtane.Package/Oqtane.Framework.nuspec @@ -2,7 +2,7 @@ Oqtane.Framework - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane framework - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/Oqtane.Server.nuspec b/Oqtane.Package/Oqtane.Server.nuspec index 36715c37..6adfcb6b 100644 --- a/Oqtane.Package/Oqtane.Server.nuspec +++ b/Oqtane.Package/Oqtane.Server.nuspec @@ -2,7 +2,7 @@ Oqtane.Server - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/Oqtane.Shared.nuspec b/Oqtane.Package/Oqtane.Shared.nuspec index 538e0c8d..59a93473 100644 --- a/Oqtane.Package/Oqtane.Shared.nuspec +++ b/Oqtane.Package/Oqtane.Shared.nuspec @@ -2,7 +2,7 @@ Oqtane.Shared - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/install.ps1 b/Oqtane.Package/install.ps1 index 116d8567..d4b21d97 100644 --- a/Oqtane.Package/install.ps1 +++ b/Oqtane.Package/install.ps1 @@ -1 +1 @@ -Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.0.Install.zip" -Force \ No newline at end of file +Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.1.Install.zip" -Force \ No newline at end of file diff --git a/Oqtane.Package/upgrade.ps1 b/Oqtane.Package/upgrade.ps1 index e41001aa..57e1de1a 100644 --- a/Oqtane.Package/upgrade.ps1 +++ b/Oqtane.Package/upgrade.ps1 @@ -1 +1 @@ -Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.0.Upgrade.zip" -Force \ No newline at end of file +Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.1.Upgrade.zip" -Force \ No newline at end of file diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 474b9335..4a6802f5 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -3,7 +3,7 @@ net5.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane true diff --git a/Oqtane.Shared/Oqtane.Shared.csproj b/Oqtane.Shared/Oqtane.Shared.csproj index 976f255b..65df5df5 100644 --- a/Oqtane.Shared/Oqtane.Shared.csproj +++ b/Oqtane.Shared/Oqtane.Shared.csproj @@ -3,7 +3,7 @@ net5.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane true diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 613f3f39..1b05a7e7 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -5,8 +5,8 @@ namespace Oqtane.Shared { public class Constants { public const string PackageId = "Oqtane.Framework"; - public const string Version = "2.0.0"; - public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0"; + public const string Version = "2.0.1"; + public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1"; public const string PageComponent = "Oqtane.UI.ThemeBuilder, Oqtane.Client"; public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client"; diff --git a/Oqtane.Test/Oqtane.Test.csproj b/Oqtane.Test/Oqtane.Test.csproj index 78c230db..da295fb4 100644 --- a/Oqtane.Test/Oqtane.Test.csproj +++ b/Oqtane.Test/Oqtane.Test.csproj @@ -3,7 +3,7 @@ net5.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane false diff --git a/Oqtane.Upgrade/Oqtane.Upgrade.csproj b/Oqtane.Upgrade/Oqtane.Upgrade.csproj index cd3d0a4c..f67d23d2 100644 --- a/Oqtane.Upgrade/Oqtane.Upgrade.csproj +++ b/Oqtane.Upgrade/Oqtane.Upgrade.csproj @@ -3,7 +3,7 @@ net5.0 Exe - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane false From 5b9196cfd4b030067d4aaa8aa34315e78b60ce56 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 08:05:36 -0500 Subject: [PATCH 13/47] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bd6646dd..5788b1db 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ This project is a work in progress and the schedule for implementing enhancement V.2.1.0 ( Q1 2021 ) - [x] Complete Static Localization of Admin UI -- [ ] Cross Platform Database Support ( ie. SQLite ) - see #964 -- [ ] EF Core Migrations for Database Installation/Upgrade - see #964 +- [ ] Cross Platform Database Support ( ie. SQLite ) - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964) +- [ ] EF Core Migrations for Database Installation/Upgrade - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964) V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 ) - [x] Migration to .NET 5 From 12fd845ed593d920e82b940de2f51ba7383382db Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 09:08:25 -0500 Subject: [PATCH 14/47] Fix issue when creating assets.json and folder does not exist. Improve module/theme uninstall to remove empty folders. --- Oqtane.Server/Controllers/ModuleDefinitionController.cs | 5 +++++ Oqtane.Server/Controllers/ThemeController.cs | 5 +++++ Oqtane.Server/Infrastructure/InstallationManager.cs | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index dc371214..f417ce33 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -135,6 +135,7 @@ namespace Oqtane.Controllers { // use assets.json to clean up file resources List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); + assets.Reverse(); foreach(string asset in assets) { // legacy support for assets that were stored as absolute paths @@ -142,6 +143,10 @@ namespace Oqtane.Controllers if (System.IO.File.Exists(filepath)) { System.IO.File.Delete(filepath); + if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any()) + { + Directory.Delete(Path.GetDirectoryName(filepath)); + } } } _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs index 615080e9..851aeb68 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -63,6 +63,7 @@ namespace Oqtane.Controllers { // use assets.json to clean up file resources List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); + assets.Reverse(); foreach (string asset in assets) { // legacy support for assets that were stored as absolute paths @@ -70,6 +71,10 @@ namespace Oqtane.Controllers if (System.IO.File.Exists(filepath)) { System.IO.File.Delete(filepath); + if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any()) + { + Directory.Delete(Path.GetDirectoryName(filepath)); + } } } _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}", theme.ThemeName); diff --git a/Oqtane.Server/Infrastructure/InstallationManager.cs b/Oqtane.Server/Infrastructure/InstallationManager.cs index f14e8ae1..3b627c70 100644 --- a/Oqtane.Server/Infrastructure/InstallationManager.cs +++ b/Oqtane.Server/Infrastructure/InstallationManager.cs @@ -126,6 +126,10 @@ namespace Oqtane.Infrastructure { File.Delete(manifestpath); } + if (!Directory.Exists(Path.GetDirectoryName(manifestpath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(manifestpath)); + } File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets)); } } From 191a1dea4d26c1c4db0caa5d80c14ccc4457db59 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Sat, 27 Feb 2021 12:50:36 -0500 Subject: [PATCH 15/47] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5788b1db..20559301 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,12 @@ There is a separate [Documentation repository](https://github.com/oqtane/oqtane. This project is a work in progress and the schedule for implementing enhancements is dependent upon the availability of community members who are willing/able to assist. V.2.1.0 ( Q1 2021 ) -- [x] Complete Static Localization of Admin UI - [ ] Cross Platform Database Support ( ie. SQLite ) - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964) - [ ] EF Core Migrations for Database Installation/Upgrade - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964) +V.2.0.1 ( Feb 27, 2021 ) +- [x] Complete Static Localization of Admin UI + V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 ) - [x] Migration to .NET 5 - [x] Static Localization ( ie. labels, help text, etc.. ) From cccb0806e19f0b065101d29df4d12d7e7b2dc0a7 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Tue, 2 Mar 2021 16:17:33 +0100 Subject: [PATCH 16/47] LangVersion Fix #1148 removed the LangVersion property from project --- .../Templates/External/Server/[Owner].[Module].Server.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj index cfce1a60..ec0e8e4a 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj @@ -2,7 +2,6 @@ net5.0 - 7.3 true 1.0.0 [Owner].[Module] From 0d5ecb7427ce44e050f5801a0515ee9814abfe7d Mon Sep 17 00:00:00 2001 From: Charles Nurse Date: Tue, 2 Mar 2021 12:03:26 -0800 Subject: [PATCH 17/47] Include gitignore and README files in Solution Files folder, so they are more accessible for editing --- Oqtane.sln | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Oqtane.sln b/Oqtane.sln index 2755bdb2..70e85123 100644 --- a/Oqtane.sln +++ b/Oqtane.sln @@ -16,6 +16,8 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{77EECA8C-B58E-469E-B8C5-D543AFC9A654}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig + .gitignore = .gitignore + README.md = README.md EndProjectSection EndProject Global From dbc4e3ea66c974a903e053bf5d5866ce8e3c74ec Mon Sep 17 00:00:00 2001 From: Charles Nurse Date: Tue, 2 Mar 2021 12:07:04 -0800 Subject: [PATCH 18/47] Add the Jetbrains Rider "idea" folder to gitignore. --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d47b8dcf..98408e86 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,8 @@ msbuild.binlog *.binlog *.nupkg +*.idea + Oqtane.Server/appsettings.json Oqtane.Server/Data/*.mdf Oqtane.Server/Data/*.ldf From 7205246718c1a93bb875a5cfd0b549dc47b7abb8 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Wed, 3 Mar 2021 13:25:49 +0100 Subject: [PATCH 19/47] Added Delete all pages and modules --- .../Modules/Admin/RecycleBin/Index.razor | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index 2d81476a..c26f852b 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -31,6 +31,9 @@ @context.DeletedOn +
+ +
} @@ -59,6 +62,10 @@ @context.DeletedOn +
+ +
+ }
@@ -69,6 +76,22 @@ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + protected string IsDeleteAllPagesVisible + { + get + { + return _pages.Count == 0 ? "hidden" : "visible"; + } + } + + protected string IsDeleteAllModulesVisible + { + get { + return _modules.Count == 0 ? "hidden" : "visible" ; + } + } + + protected override async Task OnInitializedAsync() { try @@ -126,6 +149,28 @@ } } + private async Task DeleteAllPages() + { + try + { + foreach (Page page in _pages) + { + await PageService.DeletePageAsync(page.PageId); + await logger.LogInformation("Page Permanently Deleted {Page}", page); + } + + await logger.LogInformation("Pages Permanently Deleted"); + await Load(); + StateHasChanged(); + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Permanently Deleting Pages {Error}", ex.Message); + AddModuleMessage(ex.Message, MessageType.Error); + } + } + private async Task RestoreModule(Module module) { try @@ -167,4 +212,31 @@ AddModuleMessage(Localizer["Error Permanently Deleting Module"], MessageType.Error); } } + + private async Task DeleteAllModules() + { + try + { + foreach (Module module in _modules) + { + 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("Modules Permanently Deleted"); + await Load(); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Permanently Deleting Modules {Error}", ex.Message); + AddModuleMessage(Localizer["Error Permanently Deleting Modules"], MessageType.Error); + } + } } From a03434ac413b10ac97080dba1dc8ecd6623c4b25 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Wed, 3 Mar 2021 16:39:32 +0100 Subject: [PATCH 20/47] recycle bin and log paging --- Oqtane.Client/Modules/Admin/Logs/Index.razor | 2 +- .../Modules/Admin/RecycleBin/Index.razor | 34 +++++++------------ 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 3ace61fd..6ccb8bb8 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -48,7 +48,7 @@ else @if (_logs.Any()) { - +
  @Localizer["Date"] diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index c26f852b..7c30c7a1 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -31,9 +31,12 @@ @context.DeletedOn -
- -
+ @if (_pages.Any()) + { +
+ +
+ } } @@ -62,9 +65,12 @@ @context.DeletedOn -
- -
+ @if (_modules.Any()) + { +
+ +
+ } }
@@ -76,22 +82,6 @@ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - protected string IsDeleteAllPagesVisible - { - get - { - return _pages.Count == 0 ? "hidden" : "visible"; - } - } - - protected string IsDeleteAllModulesVisible - { - get { - return _modules.Count == 0 ? "hidden" : "visible" ; - } - } - - protected override async Task OnInitializedAsync() { try From 0fd46d28b5769cae21a9f718bba0b1dc5ba20797 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Wed, 3 Mar 2021 16:55:13 +0100 Subject: [PATCH 21/47] Delete all modules and pages in recycle bin --- .../Modules/Admin/RecycleBin/Index.razor | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index c26f852b..7c30c7a1 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -31,9 +31,12 @@ @context.DeletedOn -
- -
+ @if (_pages.Any()) + { +
+ +
+ } } @@ -62,9 +65,12 @@ @context.DeletedOn -
- -
+ @if (_modules.Any()) + { +
+ +
+ } }
@@ -76,22 +82,6 @@ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - protected string IsDeleteAllPagesVisible - { - get - { - return _pages.Count == 0 ? "hidden" : "visible"; - } - } - - protected string IsDeleteAllModulesVisible - { - get { - return _modules.Count == 0 ? "hidden" : "visible" ; - } - } - - protected override async Task OnInitializedAsync() { try From 63fc1cd04291bf2ea468facf4736af329d0bb6f1 Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Wed, 3 Mar 2021 17:15:00 +0100 Subject: [PATCH 22/47] Update Index.razor --- Oqtane.Client/Modules/Admin/Logs/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 6ccb8bb8..3ace61fd 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -48,7 +48,7 @@ else @if (_logs.Any()) { - +
  @Localizer["Date"] From 745575c1f1671d458034f00a3bc4532032e49321 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 4 Mar 2021 08:30:09 -0500 Subject: [PATCH 23/47] Fix UX issue where the Location field was not being updated when the user selected Create Module --- .../Modules/Admin/ModuleCreator/Index.razor | 79 ++++++++++--------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 66794ad5..d824e595 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -85,28 +85,38 @@ else } @code { - private string _moduledefinitionname = ""; + private string _moduledefinitionname = string.Empty; private string _owner = string.Empty; private string _module = string.Empty; private string _description = string.Empty; private string _template = "-"; public string _reference = Constants.Version; private string _location = string.Empty; + private Dictionary _systeminfo; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { - _moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", ""); - if (string.IsNullOrEmpty(_moduledefinitionname)) + try { - _owner = ModuleState.Title; - _module = ModuleState.Title; - _description = ModuleState.Title; + _moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", ""); + _systeminfo = await SystemService.GetSystemInfoAsync(); + + if (string.IsNullOrEmpty(_moduledefinitionname)) + { + _owner = ModuleState.Title; + _module = ModuleState.Title; + _description = ModuleState.Title; + } + else + { + AddModuleMessage(Localizer["Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below"], MessageType.Info); + } } - else + catch (Exception ex) { - AddModuleMessage(Localizer["Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below"], MessageType.Info); + await logger.LogError(ex, "Error Loading Module Creator"); } } @@ -123,6 +133,8 @@ else SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName); await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + GetLocation(); + AddModuleMessage(Localizer["The Source Code For Your Module Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); } else @@ -161,38 +173,31 @@ else return !string.IsNullOrEmpty(name) && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); } - private async void TemplateChanged(ChangeEventArgs e) + private void TemplateChanged(ChangeEventArgs e) { - try + _template = (string)e.Value; + GetLocation(); + } + + private void GetLocation() + { + _location = string.Empty; + if (_template != "-" && _systeminfo != null && _systeminfo.ContainsKey("serverpath")) { - _location = string.Empty; - _template = (string)e.Value; - if (_template != "-") + string[] path = _systeminfo["serverpath"].Split(Path.DirectorySeparatorChar); + if (_template == "internal") { - Dictionary systeminfo = await SystemService.GetSystemInfoAsync(); - if (systeminfo != null) - { - string[] path = systeminfo["serverpath"].Split(Path.DirectorySeparatorChar); - if (_template == "internal") - { - _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 1) + - Path.DirectorySeparatorChar + "Oqtane.Client" + - Path.DirectorySeparatorChar + "Modules" + - Path.DirectorySeparatorChar + _owner + "." + _module; - } - else - { - _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) + - Path.DirectorySeparatorChar + _owner + "." + _module; - } - } + _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 1) + + Path.DirectorySeparatorChar + "Oqtane.Client" + + Path.DirectorySeparatorChar + "Modules" + + Path.DirectorySeparatorChar + _owner + "." + _module; + } + else + { + _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) + + Path.DirectorySeparatorChar + _owner + "." + _module; } - StateHasChanged(); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Getting System Info {Error}", ex.Message); - AddModuleMessage(Localizer["Error Getting System Info"], MessageType.Error); } + StateHasChanged(); } } From 4c9960b983ecc82d8172b3371215981a749668cc Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 5 Mar 2021 16:41:53 +0300 Subject: [PATCH 24/47] Rows -> Maximum Rows --- Oqtane.Client/Modules/Admin/Logs/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 3ace61fd..ca99da6d 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -36,7 +36,7 @@ else - + - + +

+ - - @@ -36,8 +36,8 @@ else - - @@ -48,7 +48,7 @@ else @if (_logs.Any()) { - +
  @Localizer["Date"] @@ -141,10 +141,6 @@ else private async Task GetLogs() { _logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((_level == "-") ? string.Empty : _level), ((_function == "-") ? string.Empty : _function), int.Parse(_rows)); - await InvokeAsync(() => - { - base.StateHasChanged(); - }); } private string GetClass(string function) diff --git a/Oqtane.Client/Modules/Controls/Pager.razor b/Oqtane.Client/Modules/Controls/Pager.razor index 64f32728..c89b1301 100644 --- a/Oqtane.Client/Modules/Controls/Pager.razor +++ b/Oqtane.Client/Modules/Controls/Pager.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Controls +@namespace Oqtane.Modules.Controls @inherits ModuleControlBase @typeparam TableItem @@ -114,10 +114,10 @@ @code { private int _pages = 0; private int _page = 1; - private int _maxItems; - private int _maxPages; - private int _startPage; - private int _endPage; + private int _maxItems = 10; + private int _maxPages = 5; + private int _startPage = 0; + private int _endPage = 0; [Parameter] public string Format { get; set; } @@ -172,24 +172,20 @@ } } - if (string.IsNullOrEmpty(PageSize)) - { - _maxItems = 10; - } - else + if (!string.IsNullOrEmpty(PageSize)) { _maxItems = int.Parse(PageSize); } - if (string.IsNullOrEmpty(DisplayPages)) - { - _maxPages = 5; - } - else + if (!string.IsNullOrEmpty(DisplayPages)) { _maxPages = int.Parse(DisplayPages); } + _page = 1; + _startPage = 0; + _endPage = 0; + if (Items != null) { ItemList = Items.Skip((_page - 1) * _maxItems).Take(_maxItems); From 86ce8994d9be457c42cd2460a1fa1b6ce8f246dd Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 11 Mar 2021 20:21:15 -0500 Subject: [PATCH 33/47] fix #1156 add defensive coding for scenario where host name does not match any alias --- Oqtane.Server/Pages/_Host.cshtml | 7 ++++++- Oqtane.Server/Pages/_Host.cshtml.cs | 27 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index cf2d69f0..e1cc6c21 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -1,4 +1,4 @@ -@page "/" +@page "/" @namespace Oqtane.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @using Microsoft.Extensions.Configuration @@ -35,6 +35,11 @@ 🗙 + @if (Model.Message != "") + { + @Model.Message + } + @if (Configuration.GetSection("Runtime").Value == "WebAssembly") diff --git a/Oqtane.Server/Pages/_Host.cshtml.cs b/Oqtane.Server/Pages/_Host.cshtml.cs index 4dc9cb7e..156b5fac 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -39,6 +39,7 @@ namespace Oqtane.Pages public string HeadResources = ""; public string BodyResources = ""; + public string Message = ""; public void OnGet() { @@ -54,20 +55,28 @@ namespace Oqtane.Pages if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null && !string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) { var uri = new Uri(Request.GetDisplayUrl()); - var alias = _aliases.GetAlias(uri.Authority + "/" + uri.LocalPath.Substring(1)); - _state.Alias = alias; - - // set default language for site if the culture is not supported - var languages = _languages.GetLanguages(alias.SiteId); - if (languages.Any() && languages.All(l => l.Code != CultureInfo.CurrentUICulture.Name)) + var hostname = uri.Authority + "/" + uri.LocalPath.Substring(1); + var alias = _aliases.GetAlias(hostname); + if (alias != null) { - var defaultLanguage = languages.Where(l => l.IsDefault).SingleOrDefault() ?? languages.First(); + _state.Alias = alias; - SetLocalizationCookie(defaultLanguage.Code); + // set default language for site if the culture is not supported + var languages = _languages.GetLanguages(alias.SiteId); + if (languages.Any() && languages.All(l => l.Code != CultureInfo.CurrentUICulture.Name)) + { + var defaultLanguage = languages.Where(l => l.IsDefault).SingleOrDefault() ?? languages.First(); + + SetLocalizationCookie(defaultLanguage.Code); + } + else + { + SetLocalizationCookie(_localizationManager.GetDefaultCulture()); + } } else { - SetLocalizationCookie(_localizationManager.GetDefaultCulture()); + Message = $"No Matching Alias For Host Name {hostname}"; } } } From c5e3c9b35ee04d41ff6f5de5d899582a21da1846 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 13 Mar 2021 13:02:40 +0300 Subject: [PATCH 34/47] Delete profile should refresh profiles list --- Oqtane.Client/Modules/Admin/Profiles/Index.razor | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Profiles/Index.razor b/Oqtane.Client/Modules/Admin/Profiles/Index.razor index 0bdf8554..f90f367e 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Index.razor @@ -32,7 +32,7 @@ else protected override async Task OnInitializedAsync() { - _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); + await GetProfilesAsync(); } private async Task DeleteProfile(int profileId) @@ -41,7 +41,12 @@ else { await ProfileService.DeleteProfileAsync(profileId); await logger.LogInformation("Profile Deleted {ProfileId}", profileId); + AddModuleMessage(Localizer["Profile Deleted"], MessageType.Success); + + await GetProfilesAsync(); + + StateHasChanged(); } catch (Exception ex) { @@ -49,4 +54,7 @@ else AddModuleMessage(Localizer["Error Deleting Profile"], MessageType.Error); } } + + private async Task GetProfilesAsync() + => _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); } From 801615c981204769f127330d40a0bc5061821901 Mon Sep 17 00:00:00 2001 From: Pieter Kuyck Date: Sat, 13 Mar 2021 12:34:47 +0100 Subject: [PATCH 35/47] fix: user delete --- Oqtane.Server/Controllers/UserController.cs | 1 + Oqtane.Server/Repository/FolderRepository.cs | 10 +++++++++- .../Repository/Interfaces/IFolderRepository.cs | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 9819994b..46189e57 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -271,6 +271,7 @@ namespace Oqtane.Controllers if (result != null) { + _folders.DeleteUserFolder(id); _users.DeleteUser(id); _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", id); } diff --git a/Oqtane.Server/Repository/FolderRepository.cs b/Oqtane.Server/Repository/FolderRepository.cs index dc7125bb..a7acd0b3 100644 --- a/Oqtane.Server/Repository/FolderRepository.cs +++ b/Oqtane.Server/Repository/FolderRepository.cs @@ -90,7 +90,15 @@ namespace Oqtane.Repository _db.Folder.Remove(folder); _db.SaveChanges(); } - + public void DeleteUserFolder(int userId) + { + string userFolderPath = Utilities.PathCombine("Users", userId.ToString(), System.IO.Path.DirectorySeparatorChar.ToString()); + List folderIdsToDelete = new List(_db.Folder.Where(a => a.Path == userFolderPath).Select(a => a.FolderId)); + foreach (int folderId in folderIdsToDelete) + { + DeleteFolder(folderId); + } + } public string GetFolderPath(int folderId) { Folder folder = _db.Folder.Find(folderId); diff --git a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs index 5ce7467f..977d6a28 100644 --- a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Oqtane.Models; namespace Oqtane.Repository @@ -12,6 +12,7 @@ namespace Oqtane.Repository Folder GetFolder(int folderId, bool tracking); Folder GetFolder(int siteId, string path); void DeleteFolder(int folderId); + void DeleteUserFolder(int userId); string GetFolderPath(int folderId); string GetFolderPath(Folder folder); } From c527f28a6d5d9d1ad173f3b1df5073f3d001b53c Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 13 Mar 2021 17:02:24 +0300 Subject: [PATCH 36/47] Address feedback --- Oqtane.Client/Modules/Admin/Profiles/Index.razor | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Profiles/Index.razor b/Oqtane.Client/Modules/Admin/Profiles/Index.razor index f90f367e..141730f9 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Index.razor @@ -30,7 +30,7 @@ else public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - protected override async Task OnInitializedAsync() + protected override async Task OnParametersSetAsync() { await GetProfilesAsync(); } @@ -56,5 +56,7 @@ else } private async Task GetProfilesAsync() - => _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); + { + _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); + } } From 63140bce817cccd43467a59d8c789e2d9fbb89c2 Mon Sep 17 00:00:00 2001 From: Erwin Yulianto Date: Wed, 17 Mar 2021 19:26:50 +0700 Subject: [PATCH 37/47] Remove admin border after edit After finish Edit, there's a class "container" which is conflict with Bootstrap that cause an issue on Full-width pane. --- Oqtane.Client/UI/Pane.razor | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Oqtane.Client/UI/Pane.razor b/Oqtane.Client/UI/Pane.razor index 0c04ff94..139135b9 100644 --- a/Oqtane.Client/UI/Pane.razor +++ b/Oqtane.Client/UI/Pane.razor @@ -18,7 +18,7 @@ else @code { private bool _useadminborder = false; - private string _paneadminborder = "container"; + private string _paneadminborder = "app-pane-admin-border"; private string _panetitle = ""; [CascadingParameter] @@ -34,12 +34,11 @@ else if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && Name != PaneNames.Admin) { _useadminborder = true; - _paneadminborder = "app-pane-admin-border"; _panetitle = "
" + Name + " Pane
"; } else { - _paneadminborder = "container"; + _useadminborder = false; _panetitle = ""; } @@ -130,4 +129,4 @@ else builder.SetKey(module.PageModuleId); builder.CloseComponent(); } -} \ No newline at end of file +} From d8bcc322399eaef73f09f8be7ba7efdf2ede297c Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 29 Mar 2021 12:58:40 -0400 Subject: [PATCH 38/47] refactor user deletion --- Oqtane.Client/Modules/Admin/Users/Index.razor | 2 +- .../Services/Interfaces/IUserService.cs | 4 +- Oqtane.Client/Services/UserService.cs | 6 +-- Oqtane.Server/Controllers/UserController.cs | 52 +++++++++++++++---- Oqtane.Server/Repository/FolderRepository.cs | 10 +--- .../Interfaces/IFolderRepository.cs | 1 - .../Repository/UserRoleRepository.cs | 4 +- 7 files changed, 50 insertions(+), 29 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index 8ac788ee..e648083f 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -85,7 +85,7 @@ else var user = await UserService.GetUserAsync(UserRole.UserId, PageState.Site.SiteId); if (user != null) { - await UserService.DeleteUserAsync(user.UserId); + await UserService.DeleteUserAsync(user.UserId, PageState.Site.SiteId); await logger.LogInformation("User Deleted {User}", UserRole.User); StateHasChanged(); } diff --git a/Oqtane.Client/Services/Interfaces/IUserService.cs b/Oqtane.Client/Services/Interfaces/IUserService.cs index eca072c5..b47b3481 100644 --- a/Oqtane.Client/Services/Interfaces/IUserService.cs +++ b/Oqtane.Client/Services/Interfaces/IUserService.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; using System.Threading.Tasks; namespace Oqtane.Services @@ -13,7 +13,7 @@ namespace Oqtane.Services Task UpdateUserAsync(User user); - Task DeleteUserAsync(int userId); + Task DeleteUserAsync(int userId, int siteId); Task LoginUserAsync(User user, bool setCookie, bool isPersistent); diff --git a/Oqtane.Client/Services/UserService.cs b/Oqtane.Client/Services/UserService.cs index 34aaaebb..3538ecb7 100644 --- a/Oqtane.Client/Services/UserService.cs +++ b/Oqtane.Client/Services/UserService.cs @@ -1,4 +1,4 @@ -using Oqtane.Shared; +using Oqtane.Shared; using Oqtane.Models; using System.Net.Http; using System.Threading.Tasks; @@ -36,9 +36,9 @@ namespace Oqtane.Services return await PutJsonAsync($"{Apiurl}/{user.UserId}", user); } - public async Task DeleteUserAsync(int userId) + public async Task DeleteUserAsync(int userId, int siteId) { - await DeleteAsync($"{Apiurl}/{userId}"); + await DeleteAsync($"{Apiurl}/{userId}?siteid={siteId}"); } public async Task LoginUserAsync(User user, bool setCookie, bool isPersistent) diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 46189e57..4d3f1abc 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -111,7 +111,6 @@ namespace Oqtane.Controllers return null; } - //TODO shoud be moved to another layer private async Task CreateUser(User user) { User newUser = null; @@ -261,19 +260,50 @@ namespace Oqtane.Controllers // DELETE api//5?siteid=x [HttpDelete("{id}")] [Authorize(Roles = RoleNames.Admin)] - public async Task Delete(int id) + public async Task Delete(int id, string siteid) { - IdentityUser identityuser = await _identityUserManager.FindByNameAsync(_users.GetUser(id).Username); - - if (identityuser != null) + User user = _users.GetUser(id); + if (user != null) { - var result = await _identityUserManager.DeleteAsync(identityuser); - - if (result != null) + // remove user roles for site + foreach (UserRole userrole in _userRoles.GetUserRoles(user.UserId, Int32.Parse(siteid)).ToList()) { - _folders.DeleteUserFolder(id); - _users.DeleteUser(id); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", id); + _userRoles.DeleteUserRole(userrole.UserRoleId); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Role Deleted {UserRole}", userrole); + } + + // remove user folder for site + var folder = _folders.GetFolder(Int32.Parse(siteid), Utilities.PathCombine("Users", user.UserId.ToString(), Path.DirectorySeparatorChar.ToString())); + if (folder != null) + { + if (Directory.Exists(_folders.GetFolderPath(folder))) + { + Directory.Delete(_folders.GetFolderPath(folder), true); + } + _folders.DeleteFolder(folder.FolderId); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Folder Deleted {Folder}", folder); + } + + // delete user if they are not a member of any other sites + if (!_userRoles.GetUserRoles(user.UserId, -1).Any()) + { + // get identity user + IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username); + if (identityuser != null) + { + // delete identity user + var result = await _identityUserManager.DeleteAsync(identityuser); + if (result != null) + { + // delete user + _users.DeleteUser(user.UserId); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", user.UserId); + } + else + { + _logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Deleting User {UserId}", user.UserId, result.ToString()); + } + } } } } diff --git a/Oqtane.Server/Repository/FolderRepository.cs b/Oqtane.Server/Repository/FolderRepository.cs index a7acd0b3..dc7125bb 100644 --- a/Oqtane.Server/Repository/FolderRepository.cs +++ b/Oqtane.Server/Repository/FolderRepository.cs @@ -90,15 +90,7 @@ namespace Oqtane.Repository _db.Folder.Remove(folder); _db.SaveChanges(); } - public void DeleteUserFolder(int userId) - { - string userFolderPath = Utilities.PathCombine("Users", userId.ToString(), System.IO.Path.DirectorySeparatorChar.ToString()); - List folderIdsToDelete = new List(_db.Folder.Where(a => a.Path == userFolderPath).Select(a => a.FolderId)); - foreach (int folderId in folderIdsToDelete) - { - DeleteFolder(folderId); - } - } + public string GetFolderPath(int folderId) { Folder folder = _db.Folder.Find(folderId); diff --git a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs index 977d6a28..dba914a7 100644 --- a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs @@ -12,7 +12,6 @@ namespace Oqtane.Repository Folder GetFolder(int folderId, bool tracking); Folder GetFolder(int siteId, string path); void DeleteFolder(int folderId); - void DeleteUserFolder(int userId); string GetFolderPath(int folderId); string GetFolderPath(Folder folder); } diff --git a/Oqtane.Server/Repository/UserRoleRepository.cs b/Oqtane.Server/Repository/UserRoleRepository.cs index 79f8a629..b47bd6f7 100644 --- a/Oqtane.Server/Repository/UserRoleRepository.cs +++ b/Oqtane.Server/Repository/UserRoleRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using Oqtane.Models; @@ -27,7 +27,7 @@ namespace Oqtane.Repository return _db.UserRole.Where(item => item.UserId == userId) .Include(item => item.Role) // eager load roles .Include(item => item.User) // eager load users - .Where(item => item.Role.SiteId == siteId || item.Role.SiteId == null); + .Where(item => item.Role.SiteId == siteId || item.Role.SiteId == null || siteId == -1); } public UserRole AddUserRole(UserRole userRole) From 40f9437ea57732dcaccf18564b56341c5c0ee4ca Mon Sep 17 00:00:00 2001 From: hishamco Date: Mon, 29 Mar 2021 20:15:04 +0300 Subject: [PATCH 39/47] Add Resources folder to Oqtane.Client --- Oqtane.Client/Resources/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Oqtane.Client/Resources/.gitkeep diff --git a/Oqtane.Client/Resources/.gitkeep b/Oqtane.Client/Resources/.gitkeep new file mode 100644 index 00000000..e69de29b From 62362b91940fffb81086baed60ad5507ae782684 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 30 Mar 2021 10:06:25 -0400 Subject: [PATCH 40/47] make module creator templates extensible --- Oqtane.Client/Modules/Admin/Files/Edit.razor | 2 +- .../Modules/Admin/ModuleCreator/Index.razor | 29 +++-- .../Interfaces/IModuleDefinitionService.cs | 1 + .../Services/ModuleDefinitionService.cs | 6 ++ .../Controllers/InstallationController.cs | 18 +++- .../Controllers/ModuleDefinitionController.cs | 54 +++------- .../Infrastructure/UpgradeManager.cs | 14 ++- .../Modules/[Owner].[Module]/Edit.razor | 100 ------------------ .../Modules/[Owner].[Module]/Index.razor | 100 ------------------ .../Modules/[Owner].[Module]/Interop.cs | 15 --- .../Modules/[Owner].[Module]/ModuleInfo.cs | 17 --- .../Services/I[Module]Service.cs | 19 ---- .../Services/[Module]Service.cs | 49 --------- .../Modules/[Owner].[Module]/Settings.razor | 47 -------- .../Controllers/[Module]Controller.cs | 91 ---------------- .../Manager/[Module]Manager.cs | 61 ----------- .../Repository/I[Module]Repository.cs | 14 --- .../Repository/[Module]Context.cs | 18 ---- .../Repository/[Module]Repository.cs | 49 --------- .../Scripts/[Owner].[Module].1.0.0.sql | 26 ----- .../Scripts/[Owner].[Module].Uninstall.sql | 6 -- .../Modules/[Owner].[Module]/Module.css | 1 - .../Modules/[Owner].[Module]/Module.js | 5 - .../[Owner].[Module]/Models/[Module].cs | 19 ---- Oqtane.Shared/Shared/Constants.cs | 4 +- 25 files changed, 67 insertions(+), 698 deletions(-) delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js delete mode 100644 Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs diff --git a/Oqtane.Client/Modules/Admin/Files/Edit.razor b/Oqtane.Client/Modules/Admin/Files/Edit.razor index 892f0559..b2ac3b64 100644 --- a/Oqtane.Client/Modules/Admin/Files/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Files/Edit.razor @@ -36,7 +36,7 @@ - + diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index d824e595..6baa0376 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -9,7 +9,7 @@ @using System.Text.RegularExpressions @using System.IO; -@if (string.IsNullOrEmpty(_moduledefinitionname)) +@if (string.IsNullOrEmpty(_moduledefinitionname) && _systeminfo != null && _templates != null) { @@ -38,13 +38,15 @@ @@ -90,9 +92,11 @@ else private string _module = string.Empty; private string _description = string.Empty; private string _template = "-"; - public string _reference = Constants.Version; + private string _reference = Constants.Version; private string _location = string.Empty; + private Dictionary _systeminfo; + private List _templates; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; @@ -102,6 +106,7 @@ else { _moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", ""); _systeminfo = await SystemService.GetSystemInfoAsync(); + _templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync(); if (string.IsNullOrEmpty(_moduledefinitionname)) { @@ -185,18 +190,8 @@ else if (_template != "-" && _systeminfo != null && _systeminfo.ContainsKey("serverpath")) { string[] path = _systeminfo["serverpath"].Split(Path.DirectorySeparatorChar); - if (_template == "internal") - { - _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 1) + - Path.DirectorySeparatorChar + "Oqtane.Client" + - Path.DirectorySeparatorChar + "Modules" + - Path.DirectorySeparatorChar + _owner + "." + _module; - } - else - { - _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) + - Path.DirectorySeparatorChar + _owner + "." + _module; - } + _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) + + Path.DirectorySeparatorChar + _owner + "." + _module; } StateHasChanged(); } diff --git a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs index e4b8ce64..55f8ad91 100644 --- a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs +++ b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs @@ -13,5 +13,6 @@ namespace Oqtane.Services Task InstallModuleDefinitionsAsync(); Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId); Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition); + Task> GetModuleDefinitionTemplatesAsync(); } } diff --git a/Oqtane.Client/Services/ModuleDefinitionService.cs b/Oqtane.Client/Services/ModuleDefinitionService.cs index 87ae7e09..9f8984c0 100644 --- a/Oqtane.Client/Services/ModuleDefinitionService.cs +++ b/Oqtane.Client/Services/ModuleDefinitionService.cs @@ -53,5 +53,11 @@ namespace Oqtane.Services { return await PostJsonAsync($"{Apiurl}", moduleDefinition); } + + public async Task> GetModuleDefinitionTemplatesAsync() + { + List templates = await GetJsonAsync>($"{Apiurl}/templates"); + return templates; + } } } diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index cac15728..01de103b 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -130,7 +130,14 @@ namespace Oqtane.Controllers var instance = Activator.CreateInstance(type) as IModule; foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { - if (!list.Contains(name)) list.Insert(0, name); + if (System.IO.File.Exists(Path.Combine(binFolder, name + ".dll"))) + { + if (!list.Contains(name)) list.Insert(0, name); + } + else + { + Console.WriteLine("Module " + instance.ModuleDefinition.ModuleDefinitionName + " dependency " + name + ".dll does not exist"); + } } } foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme)))) @@ -138,7 +145,14 @@ namespace Oqtane.Controllers var instance = Activator.CreateInstance(type) as ITheme; foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { - if (!list.Contains(name)) list.Insert(0, name); + if (System.IO.File.Exists(Path.Combine(binFolder, name + ".dll"))) + { + if (!list.Contains(name)) list.Insert(0, name); + } + else + { + Console.WriteLine("Theme " + instance.Theme.ThemeName + " dependency " + name + ".dll does not exist" ); + } } } } diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index f417ce33..8769c120 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -13,8 +13,6 @@ using Oqtane.Repository; using Oqtane.Security; using System; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Configuration; -using System.Xml.Linq; using System.Text.Json; namespace Oqtane.Controllers @@ -174,6 +172,20 @@ namespace Oqtane.Controllers } } + // GET: api//templates + [HttpGet("templates")] + [Authorize(Roles = RoleNames.Host)] + public List Get() + { + var templates = new List(); + string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", Path.DirectorySeparatorChar.ToString()); + foreach (string directory in Directory.GetDirectories(templatePath)) + { + templates.Add(directory.Replace(templatePath, "")); + } + return templates; + } + // POST api/?moduleid=x [HttpPost] [Authorize(Roles = RoleNames.Host)] @@ -185,30 +197,12 @@ namespace Oqtane.Controllers DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath); string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,Path.DirectorySeparatorChar.ToString()); - if (moduleDefinition.Template == "internal") - { - rootPath = Utilities.PathCombine(rootFolder.FullName,Path.DirectorySeparatorChar.ToString()); - moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", Oqtane.Client"; - moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, Oqtane.Server"; - } - else - { - rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name,Path.DirectorySeparatorChar.ToString()); - moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane"; - moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane"; - } + rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name,Path.DirectorySeparatorChar.ToString()); + moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane"; + moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane"; ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition); _logger.Log(LogLevel.Information, this, LogFunction.Create, "Module Definition Created {ModuleDefinition}", moduleDefinition); - - if (moduleDefinition.Template == "internal") - { - // add embedded resources to project file - List resources = new List(); - resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".1.0.0.sql")); - resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".Uninstall.sql")); - EmbedResourceFiles(Utilities.PathCombine(rootPath, "Oqtane.Server", "Oqtane.Server.csproj"), resources); - } } return moduleDefinition; @@ -269,19 +263,5 @@ namespace Oqtane.Controllers } } } - - private void EmbedResourceFiles(string projectfile, List resources) - { - XDocument project = XDocument.Load(projectfile); - var itemGroup = project.Descendants("ItemGroup").Descendants("EmbeddedResource").FirstOrDefault().Parent; - if (itemGroup != null) - { - foreach (var resource in resources) - { - itemGroup.Add(new XElement("EmbeddedResource", new XAttribute("Include", resource))); - } - } - project.Save(projectfile); - } } } diff --git a/Oqtane.Server/Infrastructure/UpgradeManager.cs b/Oqtane.Server/Infrastructure/UpgradeManager.cs index 0344de6e..cbfcc63b 100644 --- a/Oqtane.Server/Infrastructure/UpgradeManager.cs +++ b/Oqtane.Server/Infrastructure/UpgradeManager.cs @@ -1,9 +1,11 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; using Oqtane.Extensions; using Oqtane.Models; using Oqtane.Repository; using Oqtane.Shared; using System.Collections.Generic; +using System.IO; using System.Linq; namespace Oqtane.Infrastructure @@ -12,11 +14,13 @@ namespace Oqtane.Infrastructure { private readonly IAliasRepository _aliases; private readonly IServiceScopeFactory _serviceScopeFactory; + private readonly IWebHostEnvironment _environment; - public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScopeFactory) + public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment) { _aliases = aliases; _serviceScopeFactory = serviceScopeFactory; + _environment = environment; } public void Upgrade(Tenant tenant, string version) @@ -61,6 +65,12 @@ namespace Oqtane.Infrastructure //}); CreateSitePages(tenant, pageTemplates); break; + case "2.0.2": + if (tenant.Name == TenantNames.Master) + { + Directory.Delete(Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString()), true); + } + break; } } diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor deleted file mode 100644 index 339879f8..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor +++ /dev/null @@ -1,100 +0,0 @@ -@using Oqtane.Modules.Controls -@using [Owner].[Module].Services -@using [Owner].[Module].Models - -@namespace [Owner].[Module] -@inherits ModuleBase -@inject I[Module]Service [Module]Service -@inject NavigationManager NavigationManager - -
- +
- - - - -
- - - -
- -Cancel -
-
-@if (PageState.Action == "Edit") -{ - -} - -@code { - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; - - public override string Actions => "Add,Edit"; - - public override string Title => "Manage [Module]"; - - public override List Resources => new List() - { - new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" } - }; - - int _id; - string _name; - string _createdby; - DateTime _createdon; - string _modifiedby; - DateTime _modifiedon; - - protected override async Task OnInitializedAsync() - { - try - { - if (PageState.Action == "Edit") - { - _id = Int32.Parse(PageState.QueryString["id"]); - [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId); - 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, ModuleState.ModuleId); - [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.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor deleted file mode 100644 index 37cfef2a..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor +++ /dev/null @@ -1,100 +0,0 @@ -@using [Owner].[Module].Services -@using [Owner].[Module].Models - -@namespace [Owner].[Module] -@inherits ModuleBase -@inject I[Module]Service [Module]Service -@inject NavigationManager NavigationManager - -@if (_[Module]s == null) -{ -

Loading...

-} -else -{ - -
-
- @if (@_[Module]s.Count != 0) - { - -
-   -   - Name -
- - - - @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]s.1.0.0.sql - database schema definition script
-- Scripts\[Owner].[Module]s.Uninstall.sql - database uninstall script

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

- - - -@code { - public override List Resources => new List() - { - new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }, - new Resource { ResourceType = ResourceType.Script, Url = ModulePath() + "Module.js" } - }; - - List<[Module]> _[Module]s; - - protected override async Task OnInitializedAsync() - { - try - { - _[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, ModuleState.ModuleId); - 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.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs deleted file mode 100644 index 9d6f0a4e..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.JSInterop; -using System.Threading.Tasks; - -namespace [Owner].[Module] -{ - public class Interop - { - private readonly IJSRuntime _jsRuntime; - - public Interop(IJSRuntime jsRuntime) - { - _jsRuntime = jsRuntime; - } - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs deleted file mode 100644 index 6586d51d..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Oqtane.Models; -using Oqtane.Modules; - -namespace [Owner].[Module] -{ - public class ModuleInfo : IModule - { - public ModuleDefinition ModuleDefinition => new ModuleDefinition - { - Name = "[Module]", - Description = "[Module]", - Version = "1.0.0", - ServerManagerType = "[ServerManagerType]", - ReleaseVersions = "1.0.0" - }; - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs deleted file mode 100644 index 601eba6a..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using [Owner].[Module].Models; - -namespace [Owner].[Module].Services -{ - public interface I[Module]Service - { - Task> Get[Module]sAsync(int ModuleId); - - Task Get[Module]Async(int [Module]Id, int ModuleId); - - Task Add[Module]Async(Models.[Module] [Module]); - - Task Update[Module]Async(Models.[Module] [Module]); - - Task Delete[Module]Async(int [Module]Id, int ModuleId); - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs deleted file mode 100644 index 05a85ac7..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs +++ /dev/null @@ -1,49 +0,0 @@ -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].Models; - -namespace [Owner].[Module].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]s = await GetJsonAsync>(CreateAuthorizationPolicyUrl($"{Apiurl}?moduleid={ModuleId}", ModuleId)); - return [Module]s.OrderBy(item => item.Name).ToList(); - } - - public async Task Get[Module]Async(int [Module]Id, int ModuleId) - { - return await GetJsonAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId)); - } - - public async Task Add[Module]Async(Models.[Module] [Module]) - { - return await PostJsonAsync(CreateAuthorizationPolicyUrl($"{Apiurl}", [Module].ModuleId), [Module]); - } - - public async Task Update[Module]Async(Models.[Module] [Module]) - { - return await PutJsonAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{[Module].[Module]Id}", [Module].ModuleId), [Module]); - } - - public async Task Delete[Module]Async(int [Module]Id, int ModuleId) - { - await DeleteAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId)); - } - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor deleted file mode 100644 index 7989d7c9..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor +++ /dev/null @@ -1,47 +0,0 @@ -@namespace [Owner].[Module] -@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.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs deleted file mode 100644 index 3e2fe7b8..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Authorization; -using System.Collections.Generic; -using Microsoft.AspNetCore.Http; -using Oqtane.Shared; -using Oqtane.Enums; -using Oqtane.Infrastructure; -using [Owner].[Module].Models; -using [Owner].[Module].Repository; - -namespace [Owner].[Module].Controllers -{ - [Route(ControllerRoutes.Default)] - public class [Module]Controller : Controller - { - private readonly I[Module]Repository _[Module]Repository; - private readonly ILogManager _logger; - protected int _entityId = -1; - - public [Module]Controller(I[Module]Repository [Module]Repository, ILogManager logger, IHttpContextAccessor accessor) - { - _[Module]Repository = [Module]Repository; - _logger = logger; - - if (accessor.HttpContext.Request.Query.ContainsKey("entityid")) - { - _entityId = int.Parse(accessor.HttpContext.Request.Query["entityid"]); - } - } - - // GET: api/?moduleid=x - [HttpGet] - [Authorize(Policy = PolicyNames.ViewModule)] - public IEnumerable Get(string moduleid) - { - return _[Module]Repository.Get[Module]s(int.Parse(moduleid)); - } - - // GET api//5 - [HttpGet("{id}")] - [Authorize(Policy = PolicyNames.ViewModule)] - public Models.[Module] Get(int id) - { - Models.[Module] [Module] = _[Module]Repository.Get[Module](id); - if ([Module] != null && [Module].ModuleId != _entityId) - { - [Module] = null; - } - return [Module]; - } - - // POST api/ - [HttpPost] - [Authorize(Policy = PolicyNames.EditModule)] - public Models.[Module] Post([FromBody] Models.[Module] [Module]) - { - if (ModelState.IsValid && [Module].ModuleId == _entityId) - { - [Module] = _[Module]Repository.Add[Module]([Module]); - _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]); - } - return [Module]; - } - - // PUT api//5 - [HttpPut("{id}")] - [Authorize(Policy = PolicyNames.EditModule)] - public Models.[Module] Put(int id, [FromBody] Models.[Module] [Module]) - { - if (ModelState.IsValid && [Module].ModuleId == _entityId) - { - [Module] = _[Module]Repository.Update[Module]([Module]); - _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]); - } - return [Module]; - } - - // DELETE api//5 - [HttpDelete("{id}")] - [Authorize(Policy = PolicyNames.EditModule)] - public void Delete(int id) - { - Models.[Module] [Module] = _[Module]Repository.Get[Module](id); - if ([Module] != null && [Module].ModuleId == _entityId) - { - _[Module]Repository.Delete[Module](id); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id); - } - } - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs deleted file mode 100644 index 486c8ddf..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs +++ /dev/null @@ -1,61 +0,0 @@ -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].Models; -using [Owner].[Module].Repository; - -namespace [Owner].[Module].Manager -{ - public class [Module]Manager : IInstallable, IPortable - { - private I[Module]Repository _[Module]Repository; - private ISqlRepository _sql; - - public [Module]Manager(I[Module]Repository [Module]Repository, ISqlRepository sql) - { - _[Module]Repository = [Module]Repository; - _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]s = _[Module]Repository.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]s = null; - if (!string.IsNullOrEmpty(content)) - { - [Module]s = JsonSerializer.Deserialize>(content); - } - if ([Module]s != null) - { - foreach(var [Module] in [Module]s) - { - _[Module]Repository.Add[Module](new Models.[Module] { ModuleId = module.ModuleId, Name = [Module].Name }); - } - } - } - } -} \ No newline at end of file diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs deleted file mode 100644 index 52b7913a..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using [Owner].[Module].Models; - -namespace [Owner].[Module].Repository -{ - public interface I[Module]Repository - { - IEnumerable Get[Module]s(int ModuleId); - Models.[Module] Get[Module](int [Module]Id); - Models.[Module] Add[Module](Models.[Module] [Module]); - Models.[Module] Update[Module](Models.[Module] [Module]); - void Delete[Module](int [Module]Id); - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs deleted file mode 100644 index a10d7219..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.AspNetCore.Http; -using Oqtane.Modules; -using Oqtane.Repository; -using [Owner].[Module].Models; - -namespace [Owner].[Module].Repository -{ - public class [Module]Context : DBContextBase, IService - { - public virtual DbSet [Module] { get; set; } - - public [Module]Context(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor) - { - // ContextBase handles multi-tenant database connections - } - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs deleted file mode 100644 index 9c8c3628..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using System.Linq; -using System.Collections.Generic; -using Oqtane.Modules; -using [Owner].[Module].Models; - -namespace [Owner].[Module].Repository -{ - public class [Module]Repository : I[Module]Repository, IService - { - private readonly [Module]Context _db; - - public [Module]Repository([Module]Context context) - { - _db = context; - } - - public IEnumerable Get[Module]s(int ModuleId) - { - return _db.[Module].Where(item => item.ModuleId == ModuleId); - } - - public Models.[Module] Get[Module](int [Module]Id) - { - return _db.[Module].Find([Module]Id); - } - - public Models.[Module] Add[Module](Models.[Module] [Module]) - { - _db.[Module].Add([Module]); - _db.SaveChanges(); - return [Module]; - } - - public Models.[Module] Update[Module](Models.[Module] [Module]) - { - _db.Entry([Module]).State = EntityState.Modified; - _db.SaveChanges(); - return [Module]; - } - - public void Delete[Module](int [Module]Id) - { - Models.[Module] [Module] = _db.[Module].Find([Module]Id); - _db.[Module].Remove([Module]); - _db.SaveChanges(); - } - } -} diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql deleted file mode 100644 index 7a1b99ea..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql +++ /dev/null @@ -1,26 +0,0 @@ -/* -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.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql deleted file mode 100644 index 47baecc9..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* -Remove [Owner][Module] table -*/ - -DROP TABLE [dbo].[[Owner][Module]] -GO diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css deleted file mode 100644 index 0856a263..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css +++ /dev/null @@ -1 +0,0 @@ -/* Module Custom Styles */ \ No newline at end of file diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js deleted file mode 100644 index 8f072470..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js +++ /dev/null @@ -1,5 +0,0 @@ -/* Module Script */ -var [Owner] = [Owner] || {}; - -[Owner].[Module] = { -}; \ No newline at end of file diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs deleted file mode 100644 index 94f73ffa..00000000 --- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.ComponentModel.DataAnnotations.Schema; -using Oqtane.Models; - -namespace [Owner].[Module].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.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 1b05a7e7..60106dd2 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -5,8 +5,8 @@ namespace Oqtane.Shared { public class Constants { public const string PackageId = "Oqtane.Framework"; - public const string Version = "2.0.1"; - public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1"; + public const string Version = "2.0.2"; + public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2"; public const string PageComponent = "Oqtane.UI.ThemeBuilder, Oqtane.Client"; public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client"; From 367a23171d187a5b69a1789dcb8363fc5805e5a5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 30 Mar 2021 17:26:03 +0300 Subject: [PATCH 41/47] thene -> theme --- Oqtane.Client/Modules/Admin/Themes/View.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Themes/View.razor b/Oqtane.Client/Modules/Admin/Themes/View.razor index 2510759d..d6d4b4de 100644 --- a/Oqtane.Client/Modules/Admin/Themes/View.razor +++ b/Oqtane.Client/Modules/Admin/Themes/View.razor @@ -24,7 +24,7 @@ - + From 09c040128a28a2ff07ab2ccbf39922604397d8b6 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 30 Mar 2021 17:48:49 -0400 Subject: [PATCH 42/47] Ensure Install Wizard will only be displayed if the Master database connection string in appsettings.json is not specified. This addresses a potential security issue where the Install Wizard could be displayed in an existing installation if the Master database connection failed during startup. --- Oqtane.Client/App.razor | 28 ++++++++++------- Oqtane.Client/Modules/Admin/Sites/Index.razor | 2 +- .../Controllers/InstallationController.cs | 3 +- .../Infrastructure/DatabaseManager.cs | 30 +++++++++++++------ .../Interfaces/IDatabaseManager.cs | 4 +-- .../Infrastructure/UpgradeManager.cs | 15 ++++++---- Oqtane.Server/Pages/_Host.cshtml | 4 ++- Oqtane.Server/wwwroot/css/app.css | 9 +++++- 8 files changed, 63 insertions(+), 32 deletions(-) diff --git a/Oqtane.Client/App.razor b/Oqtane.Client/App.razor index 3d13adff..ca4b25bd 100644 --- a/Oqtane.Client/App.razor +++ b/Oqtane.Client/App.razor @@ -1,31 +1,39 @@ -@inject IInstallationService InstallationService +@inject IInstallationService InstallationService @if (_initialized) { - @if (!_installed) + @if (!_installation.Success) { } else { - - - - - + @if (string.IsNullOrEmpty(_installation.Message)) + { + + + + + + } + else + { +
+ @_installation.Message +
+ } } } @code { + private Installation _installation; private bool _initialized; - private bool _installed; private PageState PageState { get; set; } protected override async Task OnParametersSetAsync() { - var installation = await InstallationService.IsInstalled(); - _installed = installation.Success; + _installation = await InstallationService.IsInstalled(); _initialized = true; } diff --git a/Oqtane.Client/Modules/Admin/Sites/Index.razor b/Oqtane.Client/Modules/Admin/Sites/Index.razor index 3a571cd3..9d028e1d 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Index.razor @@ -22,7 +22,7 @@ else - @context.Name + @context.Name } diff --git a/Oqtane.Server/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs index 01de103b..2d8491d6 100644 --- a/Oqtane.Server/Controllers/InstallationController.cs +++ b/Oqtane.Server/Controllers/InstallationController.cs @@ -55,8 +55,7 @@ namespace Oqtane.Controllers [HttpGet("installed")] public Installation IsInstalled() { - bool isInstalled = _databaseManager.IsInstalled(); - return new Installation {Success = isInstalled, Message = string.Empty}; + return _databaseManager.IsInstalled(); } [HttpGet("upgrade")] diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs index 308b5cf0..9ee98e25 100644 --- a/Oqtane.Server/Infrastructure/DatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs @@ -33,27 +33,30 @@ namespace Oqtane.Infrastructure _cache = cache; } - public bool IsInstalled() + public Installation IsInstalled() { - var defaultConnectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey)); - var result = !string.IsNullOrEmpty(defaultConnectionString); - if (result) + var result = new Installation { Success = false, Message = string.Empty }; + if (!string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey))) { + result.Success = true; using (var scope = _serviceScopeFactory.CreateScope()) { var db = scope.ServiceProvider.GetRequiredService(); - result = db.Database.CanConnect(); - if (result) + if (db.Database.CanConnect()) { try { - result = db.Tenant.Any(); + var provisioned = db.Tenant.Any(); } catch { - result = false; + result.Message = "Master Database Not Installed Correctly"; } } + else + { + result.Message = "Cannot Connect To Master Database"; + } } } return result; @@ -74,7 +77,8 @@ namespace Oqtane.Infrastructure // startup or silent installation install = new InstallConfig { ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), TenantName = TenantNames.Master, IsNewTenant = false }; - if (!IsInstalled()) + var installation = IsInstalled(); + if (!installation.Success) { install.Aliases = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty); install.HostPassword = GetInstallationConfig(SettingKeys.HostPasswordKey, string.Empty); @@ -97,6 +101,14 @@ namespace Oqtane.Infrastructure install.ConnectionString = ""; } } + else + { + if (!string.IsNullOrEmpty(installation.Message)) + { + // problem with prior installation + install.ConnectionString = ""; + } + } } else { diff --git a/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs b/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs index ffb0ff9c..6257db16 100644 --- a/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs @@ -1,11 +1,11 @@ -using Oqtane.Models; +using Oqtane.Models; using Oqtane.Shared; namespace Oqtane.Infrastructure { public interface IDatabaseManager { - bool IsInstalled(); + Installation IsInstalled(); Installation Install(); Installation Install(InstallConfig install); } diff --git a/Oqtane.Server/Infrastructure/UpgradeManager.cs b/Oqtane.Server/Infrastructure/UpgradeManager.cs index cbfcc63b..b2385b2b 100644 --- a/Oqtane.Server/Infrastructure/UpgradeManager.cs +++ b/Oqtane.Server/Infrastructure/UpgradeManager.cs @@ -25,14 +25,12 @@ namespace Oqtane.Infrastructure public void Upgrade(Tenant tenant, string version) { - // core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute logic once - var pageTemplates = new List(); - + // core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute the logic once switch (version) { case "0.9.0": - // add a page to all existing sites on upgrade - + // this code is commented out on purpose - it provides an example of how to programmatically add a page to all existing sites on upgrade + var pageTemplates = new List(); //pageTemplates.Add(new PageTemplate //{ // Name = "Test", @@ -68,7 +66,12 @@ namespace Oqtane.Infrastructure case "2.0.2": if (tenant.Name == TenantNames.Master) { - Directory.Delete(Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString()), true); + // remove Internal module template files as they are no longer supported + var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString()); + if (Directory.Exists(internalTemplatePath)) + { + Directory.Delete(internalTemplatePath, true); + } } break; } diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index e1cc6c21..1678969c 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -37,7 +37,9 @@ @if (Model.Message != "") { - @Model.Message +
+ @Model.Message +
} diff --git a/Oqtane.Server/wwwroot/css/app.css b/Oqtane.Server/wwwroot/css/app.css index ce87887d..eebf63a6 100644 --- a/Oqtane.Server/wwwroot/css/app.css +++ b/Oqtane.Server/wwwroot/css/app.css @@ -1,4 +1,4 @@ -@import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); +@import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); html, body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; @@ -125,6 +125,13 @@ app { vertical-align: inherit; } +.app-alert { + padding: 20px; + background-color: #f44336; /* red */ + color: white; + margin-bottom: 15px; +} + /* Tooltips */ .app-tooltip { cursor: help; From ec0b317f80589b2afbf2157c12cd015145aed390 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 31 Mar 2021 00:50:19 +0300 Subject: [PATCH 43/47] Fix localizer in Admin pages --- Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor | 2 +- Oqtane.Client/Modules/Admin/Pages/Index.razor | 2 +- Oqtane.Client/Modules/Admin/Profiles/Index.razor | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index 538bf700..3ebfed0b 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -26,7 +26,7 @@ else @if (context.AssemblyName != "Oqtane.Client") { - + } @context.Name diff --git a/Oqtane.Client/Modules/Admin/Pages/Index.razor b/Oqtane.Client/Modules/Admin/Pages/Index.razor index 4ff925fc..fef67427 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Index.razor @@ -16,7 +16,7 @@
- + @(new string('-', context.Level * 2))@(context.Name)
diff --git a/Oqtane.Client/Modules/Admin/Profiles/Index.razor b/Oqtane.Client/Modules/Admin/Profiles/Index.razor index 141730f9..4705b290 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Index.razor @@ -19,7 +19,7 @@ else
- + @context.Name
From c92a81fcb6f1f644b0110bdb9558fc64092a3468 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 31 Mar 2021 14:15:36 +0300 Subject: [PATCH 44/47] Remove unnecessary localizer from RecycleBin page --- Oqtane.Client/Modules/Admin/RecycleBin/Index.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index 7c30c7a1..47e2a47a 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -34,7 +34,7 @@ @if (_pages.Any()) {
- +
} } @@ -68,7 +68,7 @@ @if (_modules.Any()) {
- +
} From bd48e1d8f1d37c7285ea4f4e228a89f3b1efe2ef Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Wed, 31 Mar 2021 15:39:01 -0400 Subject: [PATCH 45/47] if running on WebAssembly reload the client application if the server application is restarted --- Oqtane.Client/UI/SiteRouter.razor | 9 +++++++-- Oqtane.Server/Infrastructure/SyncManager.cs | 4 ++-- Oqtane.Server/Startup.cs | 5 ++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 6b42f15b..ea3148dc 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -80,7 +80,7 @@ var urlparameters = string.Empty; var editmode = false; var reload = Reload.None; - var lastsyncdate = DateTime.UtcNow; + var lastsyncdate = DateTime.UtcNow.AddHours(-1); var runtime = GetRuntime(); Uri uri = new Uri(_absoluteUri); @@ -107,9 +107,14 @@ SiteState.Alias = alias; // set state for services lastsyncdate = alias.SyncDate; - // process any sync events for site + // process any sync events if (reload != Reload.Site && alias.SyncEvents.Any()) { + // if running on WebAssembly reload the client application if the server application was restarted + if (runtime == Shared.Runtime.WebAssembly && PageState != null && alias.SyncEvents.Exists(item => item.TenantId == -1)) + { + NavigationManager.NavigateTo(uri.Scheme + "://" + uri.Authority + "?reload", true); + } if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == alias.SiteId)) { reload = Reload.Site; diff --git a/Oqtane.Server/Infrastructure/SyncManager.cs b/Oqtane.Server/Infrastructure/SyncManager.cs index f41c01b0..d70cc456 100644 --- a/Oqtane.Server/Infrastructure/SyncManager.cs +++ b/Oqtane.Server/Infrastructure/SyncManager.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; using System; using System.Collections.Generic; using System.Linq; @@ -17,7 +17,7 @@ namespace Oqtane.Infrastructure public List GetSyncEvents(int tenantId, DateTime lastSyncDate) { - return SyncEvents.Where(item => item.TenantId == tenantId && item.ModifiedOn >= lastSyncDate).ToList(); + return SyncEvents.Where(item => (item.TenantId == tenantId || item.TenantId == -1) && item.ModifiedOn >= lastSyncDate).ToList(); } public void AddSyncEvent(int tenantId, string entityName, int entityId) diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index ba2a7d89..1e744c01 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -226,7 +226,7 @@ namespace Oqtane } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncManager sync) { ServiceActivator.Configure(app.ApplicationServices); @@ -264,6 +264,9 @@ namespace Oqtane endpoints.MapControllers(); endpoints.MapFallbackToPage("/_Host"); }); + + // create a sync event to identify server application startup + sync.AddSyncEvent(-1, "Application", -1); } } } From 58c84da9c990f62bce927109a7476a1fdb66147a Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 1 Apr 2021 09:44:07 -0400 Subject: [PATCH 46/47] add ability to test SMTP connection in Site Settings --- Oqtane.Client/Modules/Admin/Site/Index.razor | 287 ++++++++++-------- .../Modules/Admin/UserProfile/Add.razor | 2 +- .../Modules/Admin/UserProfile/View.razor | 2 +- Oqtane.Client/UI/SiteRouter.razor | 2 +- .../Controllers/NotificationController.cs | 6 +- 5 files changed, 168 insertions(+), 131 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index bbfd28f7..62de4921 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -7,146 +7,150 @@ @inject IThemeService ThemeService @inject ISettingService SettingService @inject IStringLocalizer Localizer +@inject INotificationService NotificationService @if (_initialized) { - - - - - - - - - - - - - - - - - - - - - - - - - - @if (_layouts.Count > 0) - { +
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
+ + + + + + + + + + + + + + + + + +
- + - +
+ + + +
+ + + +
+ + + +
+ + + +
+
+ + + + + + + + + + + + - } - - - - - - - - - - - - - - - - -
+ + + +
+ + + +
+ + +
- - - -
- - - -
- - - -
- - - -
- + @if (_layouts.Count > 0) + { + + + + + + + + + } + + + + + + + + + + + + + + + + + +
@@ -201,6 +205,8 @@
- @Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In the Scheduled Jobs"] + @Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In Scheduled Jobs"]
+ +

@@ -482,7 +488,6 @@ await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); await logger.LogInformation("Site Settings Saved {Site}", site); - AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success); } } @@ -502,4 +507,36 @@ AddModuleMessage(Localizer["Error Saving Site"], MessageType.Error); } } + + private async Task SendEmail() + { + if (_smtphost != "" && _smtpport != "" && _smtpsender != "") + { + try + { + var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); + SettingService.SetSetting(settings, "SMTPHost", _smtphost); + SettingService.SetSetting(settings, "SMTPPort", _smtpport); + SettingService.SetSetting(settings, "SMTPSSL", _smtpssl); + SettingService.SetSetting(settings, "SMTPUsername", _smtpusername); + SettingService.SetSetting(settings, "SMTPPassword", _smtppassword); + SettingService.SetSetting(settings, "SMTPSender", _smtpsender); + await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); + await logger.LogInformation("Site SMTP Settings Saved"); + + await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User.DisplayName, PageState.User.Email, PageState.User.DisplayName, PageState.User.Email, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly.")); + AddModuleMessage(Localizer["SMTP Settings Saved And A Message Has Been Sent To The Email Address Associated To Your User Account... Please Wait A Few Minutes For Delivery. If You Do Not Receive The Email Please Review The Notification Job In Scheduled Jobs For Any Log Details."], MessageType.Info); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Testing SMTP Configuration"); + AddModuleMessage(Localizer["Error Testing SMTP Configuration"], MessageType.Error); + } + } + else + { + AddModuleMessage(Localizer["You Must Specify The SMTP Host, Port, And Sender"], MessageType.Warning); + } + + } } diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor index dcc96ff4..48959e80 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor @@ -55,7 +55,7 @@ { var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, null); notification = await NotificationService.AddNotificationAsync(notification); - await logger.LogInformation("Notification Created {Notification}", notification); + await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId); NavigationManager.NavigateTo(NavigateUrl()); } else diff --git a/Oqtane.Client/Modules/Admin/UserProfile/View.razor b/Oqtane.Client/Modules/Admin/UserProfile/View.razor index ff9f3937..263a0345 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/View.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/View.razor @@ -183,7 +183,7 @@ { var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid); notification = await NotificationService.AddNotificationAsync(notification); - await logger.LogInformation("Notification Created {Notification}", notification); + await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId); NavigationManager.NavigateTo(NavigateUrl()); } else diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index ea3148dc..70bda7df 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -113,7 +113,7 @@ // if running on WebAssembly reload the client application if the server application was restarted if (runtime == Shared.Runtime.WebAssembly && PageState != null && alias.SyncEvents.Exists(item => item.TenantId == -1)) { - NavigationManager.NavigateTo(uri.Scheme + "://" + uri.Authority + "?reload", true); + NavigationManager.NavigateTo(_absoluteUri + (!_absoluteUri.Contains("?") ? "?" : "&") + "reload", true); } if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == alias.SiteId)) { diff --git a/Oqtane.Server/Controllers/NotificationController.cs b/Oqtane.Server/Controllers/NotificationController.cs index 5c73eb78..8fbb4872 100644 --- a/Oqtane.Server/Controllers/NotificationController.cs +++ b/Oqtane.Server/Controllers/NotificationController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Oqtane.Enums; @@ -65,7 +65,7 @@ namespace Oqtane.Controllers if (IsAuthorized(notification.FromUserId)) { notification = _notifications.AddNotification(notification); - _logger.Log(LogLevel.Information, this, LogFunction.Create, "Notification Added {Notification}", notification); + _logger.Log(LogLevel.Information, this, LogFunction.Create, "Notification Added {NotificationId}", notification.NotificationId); } return notification; } @@ -78,7 +78,7 @@ namespace Oqtane.Controllers if (IsAuthorized(notification.FromUserId)) { notification = _notifications.UpdateNotification(notification); - _logger.Log(LogLevel.Information, this, LogFunction.Update, "Notification Updated {Folder}", notification); + _logger.Log(LogLevel.Information, this, LogFunction.Update, "Notification Updated {NotificationId}", notification.NotificationId); } return notification; } From af5f79d343ed18e308775fe401551b3424e26863 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 1 Apr 2021 17:58:59 -0400 Subject: [PATCH 47/47] fix dropdown list UX behavior where there is a default option --- Oqtane.Client/Modules/Admin/Pages/Add.razor | 11 ++------- Oqtane.Client/Modules/Admin/Pages/Edit.razor | 24 ++++--------------- Oqtane.Client/Modules/Admin/Site/Index.razor | 11 ++------- Oqtane.Client/Modules/Admin/Sites/Edit.razor | 11 ++------- .../Modules/Controls/FileManager.razor | 22 ++++------------- 5 files changed, 15 insertions(+), 64 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index 171ab885..b0234619 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -101,18 +101,11 @@ diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 5efdd992..e1229e43 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -23,18 +23,11 @@ @@ -112,18 +105,11 @@ diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index 62de4921..4fcb5dd3 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -82,18 +82,11 @@ diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor index b1afc85c..6d28aee6 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor @@ -31,18 +31,11 @@ diff --git a/Oqtane.Client/Modules/Controls/FileManager.razor b/Oqtane.Client/Modules/Controls/FileManager.razor index f4650202..90bc48c5 100644 --- a/Oqtane.Client/Modules/Controls/FileManager.razor +++ b/Oqtane.Client/Modules/Controls/FileManager.razor @@ -12,21 +12,14 @@ @if (ShowFolders || FolderId <= 0) {
- @if (string.IsNullOrEmpty(Folder)) { } @foreach (Folder folder in _folders) { - if (folder.FolderId == FolderId) - { - - } - else - { - - } + }
@@ -34,18 +27,11 @@ @if (ShowFiles) {
- @foreach (File file in _files) { - if (file.FileId == FileId) - { - - } - else - { - - } + }
- @foreach (var theme in _themes) { - if (theme.TypeName == _themetype) - { - - } - else - { - - } + } - @foreach (Page page in _pageList) { - if (page.PageId.ToString() == _parentid) - { - - } - else - { - - } + } - + @foreach (var theme in _themes) { - if (theme.TypeName == _themetype) - { - - } - else - { - - } + } - @foreach (var theme in _themes) { - if (theme.TypeName == _themetype) - { - - } - else - { - - } + } - @foreach (var theme in _themes) { - if (theme.TypeName == _themetype) - { - - } - else - { - - } + }