From d8d1412a8f28d9813fcebdb8625a3d8809fa9003 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 22:28:17 +0300 Subject: [PATCH 001/177] Fallback to English as default culture --- .../Modules/Controls/ActionDialog.razor | 4 ++-- Oqtane.Client/Modules/Controls/Label.razor | 10 ++++++++-- .../Modules/Controls/LocalizableComponent.cs | 17 ++++++++++++++++- Oqtane.Client/Modules/Controls/Section.razor | 4 ++-- Oqtane.Client/Modules/Controls/TabPanel.razor | 4 ++-- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/ActionDialog.razor b/Oqtane.Client/Modules/Controls/ActionDialog.razor index fa992e979..ac7e4690b 100644 --- a/Oqtane.Client/Modules/Controls/ActionDialog.razor +++ b/Oqtane.Client/Modules/Controls/ActionDialog.razor @@ -99,8 +99,8 @@ if (IsLocalizable) { - Header = Localize(nameof(Header)); - Message = Localize(nameof(Message)); + Header = Localize(nameof(Header), Header); + Message = Localize(nameof(Message), Message); } _authorized = IsAuthorized(); diff --git a/Oqtane.Client/Modules/Controls/Label.razor b/Oqtane.Client/Modules/Controls/Label.razor index 3869d8b47..85e65d14e 100644 --- a/Oqtane.Client/Modules/Controls/Label.razor +++ b/Oqtane.Client/Modules/Controls/Label.razor @@ -45,8 +45,14 @@ else if (IsLocalizable) { - ChildContent =@@Localize("Text"); - HelpText = Localize(nameof(HelpText)); + var value = Localize("Text"); + var key = $"{ResourceKey}.Text"; + if (!value.Equals(key)) + { + ChildContent =@@Localize("Text"); + } + + HelpText = Localize(nameof(HelpText), HelpText); } } } diff --git a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs index 80222e66c..657494d77 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -24,10 +24,25 @@ protected string Localize(string name) { return name; } - + return _localizer?[key] ?? name; } + protected string Localize(string name, string defaultValue) + { + var key = $"{ResourceKey}.{name}"; + var value = Localize(name); + + if (value == key) + { + return defaultValue; + } + else + { + return value; + } + } + protected override void OnParametersSet() { if (!String.IsNullOrEmpty(ResourceKey)) diff --git a/Oqtane.Client/Modules/Controls/Section.razor b/Oqtane.Client/Modules/Controls/Section.razor index 573a536ba..fd8b9a521 100644 --- a/Oqtane.Client/Modules/Controls/Section.razor +++ b/Oqtane.Client/Modules/Controls/Section.razor @@ -49,8 +49,8 @@ if (IsLocalizable) { _heading = !string.IsNullOrEmpty(Heading) - ? Localize(nameof(Heading)) - : Localize(nameof(Name)); + ? Localize(nameof(Heading), Heading) + : Localize(nameof(Name), Name); } } } diff --git a/Oqtane.Client/Modules/Controls/TabPanel.razor b/Oqtane.Client/Modules/Controls/TabPanel.razor index 9472bab34..7c2eaa243 100644 --- a/Oqtane.Client/Modules/Controls/TabPanel.razor +++ b/Oqtane.Client/Modules/Controls/TabPanel.razor @@ -44,11 +44,11 @@ else { if (string.IsNullOrEmpty(Heading)) { - Name = Localize(nameof(Name)); + Name = Localize(nameof(Name), Name); } else { - Heading = Localize(nameof(Heading)); + Heading = Localize(nameof(Heading), Heading); } } } From 16b5dd99cc80cfbddf4b26198eaae5b2a378c660 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 22:39:38 +0300 Subject: [PATCH 002/177] Localize components for the roles pages --- Oqtane.Client/Modules/Admin/Roles/Add.razor | 6 +++--- Oqtane.Client/Modules/Admin/Roles/Edit.razor | 6 +++--- Oqtane.Client/Modules/Admin/Roles/Index.razor | 8 ++++---- Oqtane.Client/Modules/Admin/Roles/Users.razor | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Roles/Add.razor b/Oqtane.Client/Modules/Admin/Roles/Add.razor index 34e93e2d6..1f6c520f7 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Add.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Add.razor @@ -6,7 +6,7 @@ - +
- + @@ -14,7 +14,7 @@
- + @@ -22,7 +22,7 @@
- + - - - + + + diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor index a583aedc8..e7ccd726d 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Users.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -12,7 +12,7 @@ else
- + @@ -14,7 +14,7 @@
- + @@ -22,7 +22,7 @@
- + Name @context.Name
+ diff --git a/Oqtane.Client/_Imports.razor b/Oqtane.Client/_Imports.razor index 3a920652f..7afebdf12 100644 --- a/Oqtane.Client/_Imports.razor +++ b/Oqtane.Client/_Imports.razor @@ -7,6 +7,7 @@ @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web +@using Microsoft.Extensions.Localization @using Microsoft.JSInterop @using Oqtane.Models From 261f48e842e52bcda9f9c219063dce43563d6a21 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 22:56:41 +0300 Subject: [PATCH 005/177] Localize components for the users pages --- Oqtane.Client/Modules/Admin/Users/Add.razor | 6 +++--- Oqtane.Client/Modules/Admin/Users/Edit.razor | 6 +++--- Oqtane.Client/Modules/Admin/Users/Index.razor | 10 +++++----- Oqtane.Client/Modules/Admin/Users/Roles.razor | 10 +++++----- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Users/Add.razor b/Oqtane.Client/Modules/Admin/Users/Add.razor index 4b15ce82c..3df788942 100644 --- a/Oqtane.Client/Modules/Admin/Users/Add.razor +++ b/Oqtane.Client/Modules/Admin/Users/Add.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Users +@namespace Oqtane.Modules.Admin.Users @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -6,7 +6,7 @@ @inject ISettingService SettingService - + @if (profiles != null) {
- + @@ -20,7 +20,7 @@ else
- +
- + @@ -42,7 +42,7 @@ else
- + From c70f37d33c33bc6ef929588135060ac59bb01bd4 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 22:43:53 +0300 Subject: [PATCH 003/177] Fix resource keys --- Oqtane.Client/Modules/Admin/Roles/Users.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor index e7ccd726d..17028d435 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Users.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -12,7 +12,7 @@ else - + diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor index 17028d435..ecd7cb911 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Users.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -1,11 +1,12 @@ -@namespace Oqtane.Modules.Admin.Roles +@namespace Oqtane.Modules.Admin.Roles @inherits ModuleBase @inject IRoleService RoleService @inject IUserRoleService UserRoleService +@inject IStringLocalizer Localizer @if (userroles == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -49,20 +50,20 @@ else
- + @@ -20,7 +20,7 @@ else
- + @@ -26,16 +27,16 @@
- -Cancel + +@Localizer["Cancel"] -@code { +@code { private string _name = string.Empty; private string _description = string.Empty; private string _isautoassigned = "False"; diff --git a/Oqtane.Client/Modules/Admin/Roles/Edit.razor b/Oqtane.Client/Modules/Admin/Roles/Edit.razor index e8af37fe5..2598c810a 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Edit.razor @@ -1,7 +1,8 @@ -@namespace Oqtane.Modules.Admin.Roles +@namespace Oqtane.Modules.Admin.Roles @inherits ModuleBase @inject NavigationManager NavigationManager @inject IRoleService RoleService +@inject IStringLocalizer Localizer @@ -26,14 +27,14 @@
- -Cancel + +@Localizer["Cancel"] @code { private int _roleid; diff --git a/Oqtane.Client/Modules/Admin/Roles/Index.razor b/Oqtane.Client/Modules/Admin/Roles/Index.razor index 727dc184e..6344925db 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Index.razor @@ -1,10 +1,11 @@ -@namespace Oqtane.Modules.Admin.Roles +@namespace Oqtane.Modules.Admin.Roles @inherits ModuleBase @inject IRoleService RoleService +@inject IStringLocalizer Localizer @if (_roles == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -15,7 +16,7 @@ else
     Name@Localizer["Name"]
- - Cancel + + @Localizer["Cancel"]

-
Users@Localizer["Users"]   @context.User.DisplayName - +
@@ -53,7 +53,7 @@
} - + @if (profiles != null) { diff --git a/Oqtane.Client/Modules/Admin/Users/Edit.razor b/Oqtane.Client/Modules/Admin/Users/Edit.razor index 87a6a3878..ed24d3cc6 100644 --- a/Oqtane.Client/Modules/Admin/Users/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Users/Edit.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Users +@namespace Oqtane.Modules.Admin.Users @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -14,7 +14,7 @@ else
} - + @if (profiles != null) {
@@ -80,7 +80,7 @@ else
}
- + @if (profiles != null) { diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index efcd89a28..d0d0d76d9 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Users +@namespace Oqtane.Modules.Admin.Users @inherits ModuleBase @inject IUserRoleService UserRoleService @inject IUserService UserService @@ -12,7 +12,7 @@ } else { - +
@@ -27,13 +27,13 @@ else
diff --git a/Oqtane.Client/Modules/Admin/Users/Roles.razor b/Oqtane.Client/Modules/Admin/Users/Roles.razor index 9a056a431..322fb9393 100644 --- a/Oqtane.Client/Modules/Admin/Users/Roles.razor +++ b/Oqtane.Client/Modules/Admin/Users/Roles.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Users +@namespace Oqtane.Modules.Admin.Users @inherits ModuleBase @inject IRoleService RoleService @inject IUserService UserService @@ -13,7 +13,7 @@ else
- + - + - + @context.User.DisplayName
- + @@ -21,7 +21,7 @@ else
- +
- + @@ -43,7 +43,7 @@ else
- + From 086e3623c37b621de30f780b7d7f4e2f60331e76 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:04:16 +0300 Subject: [PATCH 006/177] Localize non components in users pages --- Oqtane.Client/Modules/Admin/Users/Add.razor | 71 ++++++++-------- Oqtane.Client/Modules/Admin/Users/Edit.razor | 80 ++++++++++--------- Oqtane.Client/Modules/Admin/Users/Index.razor | 9 ++- Oqtane.Client/Modules/Admin/Users/Roles.razor | 15 ++-- 4 files changed, 90 insertions(+), 85 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Users/Add.razor b/Oqtane.Client/Modules/Admin/Users/Add.razor index 3df788942..d669f678b 100644 --- a/Oqtane.Client/Modules/Admin/Users/Add.razor +++ b/Oqtane.Client/Modules/Admin/Users/Add.razor @@ -4,6 +4,7 @@ @inject IUserService UserService @inject IProfileService ProfileService @inject ISettingService SettingService +@inject IStringLocalizer Localizer @@ -12,15 +13,15 @@ + +
- -
- + @@ -28,7 +29,7 @@
- + @@ -36,7 +37,7 @@
- + @@ -44,7 +45,7 @@
- + @@ -56,42 +57,42 @@ @if (profiles != null) { - - @foreach (Profile profile in profiles) - { - var p = profile; - if (p.Category != category) +
+ @foreach (Profile profile in profiles) { + var p = profile; + if (p.Category != category) + { + + + + category = p.Category; + } - + + - category = p.Category; } - - - - - } -
+ @p.Category +
- @p.Category - + + + @if (p.IsRequired) + { + + } + else + { + + } +
- - - @if (p.IsRequired) - { - - } - else - { - - } -
+
}
- -Cancel + +@Localizer["Cancel"] @code { private string username = string.Empty; @@ -185,7 +186,7 @@ } return valid; } - + private void ProfileChanged(ChangeEventArgs e, string SettingName) { var value = (string)e.Value; diff --git a/Oqtane.Client/Modules/Admin/Users/Edit.razor b/Oqtane.Client/Modules/Admin/Users/Edit.razor index ed24d3cc6..edabc73d7 100644 --- a/Oqtane.Client/Modules/Admin/Users/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Users/Edit.razor @@ -4,6 +4,7 @@ @inject IUserService UserService @inject IProfileService ProfileService @inject ISettingService SettingService +@inject IStringLocalizer Localizer @if (PageState.User != null && photofileid != -1) { @@ -20,7 +21,7 @@ else @@ -83,43 +84,44 @@ else @if (profiles != null) { -
- + @@ -28,7 +29,7 @@ else
- + @@ -36,7 +37,7 @@ else
- + @@ -44,7 +45,7 @@ else
- + @@ -52,7 +53,7 @@ else
- + @@ -60,7 +61,7 @@ else
- + @@ -68,12 +69,12 @@ else
- +
- @foreach (Profile profile in profiles) - { - var p = profile; - if (p.Category != category) +
+ @foreach (Profile profile in profiles) { + var p = profile; + if (p.Category != category) + { + + + + category = p.Category; + } - + + - category = p.Category; } - - - - - } -
+ @p.Category +
- @p.Category - + + + @if (p.IsRequired) + { + + } + else + { + + } +
- - - @if (p.IsRequired) - { - - } - else - { - - } -
+
}
- -Cancel -

+ +@Localizer["Cancel"] +
+
@code { @@ -246,7 +248,7 @@ else } return valid; } - + private void ProfileChanged(ChangeEventArgs e, string SettingName) { var value = (string)e.Value; diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index d0d0d76d9..8087f2bf8 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -3,11 +3,12 @@ @inject IUserRoleService UserRoleService @inject IUserService UserService @inject ISettingService SettingService +@inject IStringLocalizer Localizer @if (userroles == null) {

- Loading... + @Localizer["Loading..."]

} else @@ -15,7 +16,7 @@ else
- +
@@ -23,11 +24,11 @@ else
     Name@Localizer["Name"] - + diff --git a/Oqtane.Client/Modules/Admin/Users/Roles.razor b/Oqtane.Client/Modules/Admin/Users/Roles.razor index 322fb9393..922298298 100644 --- a/Oqtane.Client/Modules/Admin/Users/Roles.razor +++ b/Oqtane.Client/Modules/Admin/Users/Roles.razor @@ -3,10 +3,11 @@ @inject IRoleService RoleService @inject IUserService UserService @inject IUserRoleService UserRoleService +@inject IStringLocalizer Localizer @if (userroles == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -50,23 +51,23 @@ else
- - Cancel + + @Localizer["Cancel"]

- Roles + @Localizer["Roles"]  
@context.Role.Name @if (context.Role.Name != RoleNames.Registered) - { - - } + { + + } From 5c3e22ab34b88aa825ebe11cda115e319200fdc8 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:13:13 +0300 Subject: [PATCH 007/177] Localize components of the user profile pages --- .../Modules/Admin/UserProfile/Add.razor | 8 ++++---- .../Modules/Admin/UserProfile/Index.razor | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor index b19bae1dc..af3782afa 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.UserProfile +@namespace Oqtane.Modules.Admin.UserProfile @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -9,7 +9,7 @@ - + + @@ -42,8 +43,8 @@ - - Cancel + + @Localizer["Cancel"] } @code { diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index c017db003..758dddb4c 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -1,9 +1,10 @@ -@namespace Oqtane.Modules.Admin.Themes +@namespace Oqtane.Modules.Admin.Themes @using System.Net @inherits ModuleBase @inject NavigationManager NavigationManager @inject IThemeService ThemeService @inject IPackageService PackageService +@inject IStringLocalizer Localizer @if (_themes == null) { @@ -17,8 +18,8 @@ else
- - + + @@ -34,7 +35,7 @@ else diff --git a/Oqtane.Client/Modules/Admin/Themes/View.razor b/Oqtane.Client/Modules/Admin/Themes/View.razor index 195b01800..eb9871c95 100644 --- a/Oqtane.Client/Modules/Admin/Themes/View.razor +++ b/Oqtane.Client/Modules/Admin/Themes/View.razor @@ -1,8 +1,9 @@ -@namespace Oqtane.Modules.Admin.Themes +@namespace Oqtane.Modules.Admin.Themes @using System.Net @inherits ModuleBase @inject IThemeService ThemeService @inject NavigationManager NavigationManager +@inject IStringLocalizer Localizer
- + @@ -17,7 +17,7 @@
- + @@ -25,7 +25,7 @@
- + From c1fa6589af51a5f70f8ce19978412e266c635034 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:42:27 +0300 Subject: [PATCH 011/177] Localize non components for themes pages --- Oqtane.Client/Modules/Admin/Themes/Add.razor | 13 +++++++------ Oqtane.Client/Modules/Admin/Themes/Index.razor | 9 +++++---- Oqtane.Client/Modules/Admin/Themes/View.razor | 5 +++-- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor index f320edef2..6ab6fde3c 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Add.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor @@ -1,9 +1,10 @@ -@namespace Oqtane.Modules.Admin.Themes +@namespace Oqtane.Modules.Admin.Themes @inherits ModuleBase @inject NavigationManager NavigationManager @inject IFileService FileService @inject IThemeService ThemeService @inject IPackageService PackageService +@inject IStringLocalizer Localizer @if (_packages != null) { @@ -14,15 +15,15 @@
-
NameVersion@Localizer["Name"]@Localizer["Version"] @context.Name @context.Version - +    NameVersion@Localizer["Name"]@Localizer["Version"]   @if (UpgradeAvailable(context.ThemeName, context.Version)) { - + }
@@ -62,7 +63,7 @@
-Cancel +@Localizer["Cancel"] @code { private string _themeName = ""; From bbda3009522f590acb77f73cd5a54939273fc57c Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:46:14 +0300 Subject: [PATCH 012/177] Localize components for the tenants pages --- Oqtane.Client/Modules/Admin/Tenants/Edit.razor | 6 +++--- Oqtane.Client/Modules/Admin/Tenants/Index.razor | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor index 245ce1cba..cc0c1d77f 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Tenants +@namespace Oqtane.Modules.Admin.Tenants @inherits ModuleBase @inject NavigationManager NavigationManager @inject ITenantService TenantService @@ -6,7 +6,7 @@ - - + + From 2672f47cdfd1c11f422ac10ee92dde499d0632ea Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:47:38 +0300 Subject: [PATCH 013/177] Localize non components of the tenants pages --- Oqtane.Client/Modules/Admin/Tenants/Edit.razor | 7 ++++--- Oqtane.Client/Modules/Admin/Tenants/Index.razor | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor index cc0c1d77f..34f58934b 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject ITenantService TenantService +@inject IStringLocalizer Localizer
- + @if (name == TenantNames.Master) @@ -21,7 +21,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Tenants/Index.razor b/Oqtane.Client/Modules/Admin/Tenants/Index.razor index 5858a059e..9ecefb698 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Index.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Tenants +@namespace Oqtane.Modules.Admin.Tenants @inherits ModuleBase @inject ITenantService TenantService @inject IAliasService AliasService @@ -16,8 +16,8 @@ else Name @context.Name
@@ -29,8 +30,8 @@
- -Cancel + +@Localizer["Cancel"] @code { private int tenantid; @@ -69,7 +70,7 @@ { tenant.Name = name; tenant.DBConnectionString = connectionstring; - + await TenantService.UpdateTenantAsync(tenant); await logger.LogInformation("Tenant Saved {TenantId}", tenantid); diff --git a/Oqtane.Client/Modules/Admin/Tenants/Index.razor b/Oqtane.Client/Modules/Admin/Tenants/Index.razor index 9ecefb698..fda4c3a47 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Index.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Index.razor @@ -2,10 +2,11 @@ @inherits ModuleBase @inject ITenantService TenantService @inject IAliasService AliasService +@inject IStringLocalizer Localizer @if (tenants == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -13,7 +14,7 @@ else
    - Name + @Localizer["Name"]
From a14616a7c1a5bea39bcb5eb9643cba27ffd151d8 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:54:59 +0300 Subject: [PATCH 014/177] Localize system info page --- .../Modules/Admin/SystemInfo/Index.razor | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor index ca7c7f2c6..98c95892a 100644 --- a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor +++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor @@ -1,11 +1,12 @@ -@namespace Oqtane.Modules.Admin.SystemInfo +@namespace Oqtane.Modules.Admin.SystemInfo @inherits ModuleBase @inject ISystemService SystemService +@inject IStringLocalizer Localizer
- + @@ -13,7 +14,7 @@
- + @@ -21,7 +22,7 @@
- + @@ -29,7 +30,7 @@
- + @@ -37,7 +38,7 @@
- + @@ -45,14 +46,14 @@
- +
-Access Framework API +@Localizer["Access Framework API"] @code { public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; From 1518afbd938e5bcfad8fd9ab67fee5293e471461 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 17 Nov 2020 23:57:58 +0300 Subject: [PATCH 015/177] Localize SQL page --- Oqtane.Client/Modules/Admin/Sql/Index.razor | 28 +++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Sql/Index.razor b/Oqtane.Client/Modules/Admin/Sql/Index.razor index e27350f87..69191bab5 100644 --- a/Oqtane.Client/Modules/Admin/Sql/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sql/Index.razor @@ -1,8 +1,9 @@ -@namespace Oqtane.Modules.Admin.Sql +@namespace Oqtane.Modules.Admin.Sql @inherits ModuleBase @inject NavigationManager NavigationManager @inject ITenantService TenantService @inject ISqlService SqlService +@inject IStringLocalizer Localizer @if (_tenants == null) { @@ -13,11 +14,11 @@ else
- +
- +
- -

+ +
+
@if (!string.IsNullOrEmpty(_results)) { @((MarkupString)_results) @@ -78,25 +80,25 @@ else { table = "
"; table += ""; - + foreach (KeyValuePair kvp in item) { table += ""; } - + table += ""; } - + table += ""; - + foreach (KeyValuePair kvp in item) { table += ""; } - + table += ""; } - + if (table != string.Empty) { table += "
" + kvp.Key + "
" + kvp.Value + "
"; @@ -105,7 +107,7 @@ else { table = "No Results Returned"; } - + return table; } } From 236a4bd3d93796bb384eb0bbb61d30e765fd4dbb Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 18 Nov 2020 00:09:51 +0300 Subject: [PATCH 016/177] Localize components of sites page --- Oqtane.Client/Modules/Admin/Sites/Add.razor | 34 +++++++++---------- Oqtane.Client/Modules/Admin/Sites/Edit.razor | 16 ++++----- Oqtane.Client/Modules/Admin/Sites/Index.razor | 8 ++--- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index 7ee36435d..2c9ca3211 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Sites +@namespace Oqtane.Modules.Admin.Sites @inherits ModuleBase @inject NavigationManager NavigationManager @inject ITenantService TenantService @@ -18,7 +18,7 @@ else - + From 917caab7a10bd948eec734646ed32096dea24c7f Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:44:44 +0300 Subject: [PATCH 024/177] Localize components of the pages --- Oqtane.Client/Modules/Admin/Pages/Add.razor | 32 +++++++++---------- Oqtane.Client/Modules/Admin/Pages/Edit.razor | 32 +++++++++---------- Oqtane.Client/Modules/Admin/Pages/Index.razor | 8 ++--- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index f666441b3..cd243df0a 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -1,17 +1,17 @@ -@namespace Oqtane.Modules.Admin.Pages +@namespace Oqtane.Modules.Admin.Pages @inherits ModuleBase @inject NavigationManager NavigationManager @inject IPageService PageService @inject IThemeService ThemeService - + @if (_themeList != null) {
- + @@ -26,7 +26,7 @@ else
- + @@ -34,7 +34,7 @@ else
- +
- +
- +
- +
- +
- + @@ -123,7 +123,7 @@ else
- +
- + @@ -142,7 +142,7 @@ else
- + @@ -150,7 +150,7 @@ else
- +
- + @@ -171,7 +171,7 @@ else
- + @@ -180,7 +180,7 @@ else }
- + @@ -188,7 +188,7 @@ else
- + diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor index 43599e981..d27a1392e 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Sites +@namespace Oqtane.Modules.Admin.Sites @inherits ModuleBase @inject NavigationManager NavigationManager @inject ISiteService SiteService @@ -11,7 +11,7 @@
- + @@ -19,7 +19,7 @@
- + @@ -27,7 +27,7 @@
- + @@ -36,7 +37,7 @@
- + @@ -44,7 +45,7 @@
- + @@ -52,11 +53,11 @@
- +
- +
- +
- +
- +
-
+
- + @@ -138,7 +139,7 @@
- + @@ -146,7 +147,7 @@
- + @@ -154,7 +155,7 @@
- + @@ -162,7 +163,7 @@
- + @@ -170,22 +171,22 @@
-
+
- - + + - + @@ -32,11 +33,11 @@ } - + @if (_modules == null) {
-

No Deleted Modules

+

@Localizer["No Deleted Modules"]

} else { @@ -44,14 +45,14 @@
- - - - + + + + - - + + @@ -150,12 +151,12 @@ await PageModuleService.DeletePageModuleAsync(module.PageModuleId); // check if there are any remaining module instances in the site _modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId); - + if (!_modules.Exists(item => item.ModuleId == module.ModuleId)) { await ModuleService.DeleteModuleAsync(module.ModuleId); } - + await logger.LogInformation("Module Permanently Deleted {Module}", module); await Load(); StateHasChanged(); From 387c1aa57f0f523945e7d3fc69a6c7f690129ed2 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:34:39 +0300 Subject: [PATCH 022/177] Localize component for the profiles pages --- .../Modules/Admin/Profiles/Edit.razor | 20 +++++++++---------- .../Modules/Admin/Profiles/Index.razor | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor index 44843e8e1..9a27c2a93 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor @@ -6,7 +6,7 @@
- +
- + @@ -193,7 +194,7 @@
- + @@ -203,8 +204,8 @@
- - Cancel + + @Localizer["Cancel"]

From 322d45dd12a74989b5e14d98aaae29970863eeaa Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 19 Nov 2020 17:33:49 +0300 Subject: [PATCH 019/177] Runtime enum should be in Oqtane,Shared --- Oqtane.Client/Modules/Admin/Login/Index.razor | 2 +- Oqtane.Client/Themes/Controls/LoginBase.cs | 4 ++-- Oqtane.Client/UI/PageState.cs | 6 +++--- Oqtane.Client/UI/Runtime.cs | 5 ++++- Oqtane.Client/UI/SiteRouter.razor | 6 +++--- .../Extensions/OqtaneServiceCollectionExtensions.cs | 1 - Oqtane.Server/Startup.cs | 1 - Oqtane.Shared/Enums/Runtime.cs | 8 ++++++++ 8 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 Oqtane.Shared/Enums/Runtime.cs diff --git a/Oqtane.Client/Modules/Admin/Login/Index.razor b/Oqtane.Client/Modules/Admin/Login/Index.razor index 498151877..2a1b4793b 100644 --- a/Oqtane.Client/Modules/Admin/Login/Index.razor +++ b/Oqtane.Client/Modules/Admin/Login/Index.razor @@ -87,7 +87,7 @@ private async Task Login() { - if (PageState.Runtime == Runtime.Server) + if (PageState.Runtime == Oqtane.Shared.Runtime.Server) { // server-side Blazor var user = new User(); diff --git a/Oqtane.Client/Themes/Controls/LoginBase.cs b/Oqtane.Client/Themes/Controls/LoginBase.cs index 60bbb7814..d923b0129 100644 --- a/Oqtane.Client/Themes/Controls/LoginBase.cs +++ b/Oqtane.Client/Themes/Controls/LoginBase.cs @@ -1,10 +1,10 @@ -using System; +using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using Oqtane.Providers; using Oqtane.Services; -using Oqtane.UI; +using Oqtane.Shared; namespace Oqtane.Themes.Controls { diff --git a/Oqtane.Client/UI/PageState.cs b/Oqtane.Client/UI/PageState.cs index cde1779b6..325f15d21 100644 --- a/Oqtane.Client/UI/PageState.cs +++ b/Oqtane.Client/UI/PageState.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Oqtane.Models; @@ -19,6 +19,6 @@ public class PageState public string Action { get; set; } public bool EditMode { get; set; } public DateTime LastSyncDate { get; set; } - public Runtime Runtime { get; set; } + public Oqtane.Shared.Runtime Runtime { get; set; } } -} \ No newline at end of file +} diff --git a/Oqtane.Client/UI/Runtime.cs b/Oqtane.Client/UI/Runtime.cs index dcc886b14..2d7e6b005 100644 --- a/Oqtane.Client/UI/Runtime.cs +++ b/Oqtane.Client/UI/Runtime.cs @@ -1,5 +1,8 @@ -namespace Oqtane.UI +using System; + +namespace Oqtane.UI { + [Obsolete("This enum is deprecated and will be removed in the upcoming major release, please use Oqtane.Shared.Runtime instead.")] public enum Runtime { Server, diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index f95f8607e..56360ca98 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -560,8 +560,8 @@ return pageresources; } - private Runtime GetRuntime() + private Oqtane.Shared.Runtime GetRuntime() => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) - ? Runtime.WebAssembly - : Runtime.Server; + ? Oqtane.Shared.Runtime.WebAssembly + : Oqtane.Shared.Runtime.Server; } \ No newline at end of file diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs index 3afb023bb..bcfdf9a85 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -8,7 +8,6 @@ using Oqtane.Modules; using Oqtane.Services; using Oqtane.Shared; -using Oqtane.UI; // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index 8671e0f7d..b008ee308 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -21,7 +21,6 @@ using Oqtane.Security; using Oqtane.Services; using Oqtane.Shared; -using Oqtane.UI; namespace Oqtane { diff --git a/Oqtane.Shared/Enums/Runtime.cs b/Oqtane.Shared/Enums/Runtime.cs new file mode 100644 index 000000000..4cca8235b --- /dev/null +++ b/Oqtane.Shared/Enums/Runtime.cs @@ -0,0 +1,8 @@ +namespace Oqtane.Shared +{ + public enum Runtime + { + Server, + WebAssembly + } +} From 80dd3cae92e6869866c1a3768dc57e3134bf16cb Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 19 Nov 2020 14:20:44 -0500 Subject: [PATCH 020/177] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 728641cf7..2800b3426 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Please note that this project is owned by the .NET Foundation and is governed by - Install the latest edition (v16.8 or higher) of [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) (Community, Professional, or Enterprise Editions) with the **ASP.NET and web development** workload enabled. Oqtane works with ALL editions of Visual Studio from Community to Enterprise. If you do not have a SQL Server installation available already and you wish to use LocalDB for development, you must also install the **.NET desktop development workload**. -- Download a release or Clone the Oqtane source code to your local system. Open the **Oqtane.sln** solution file and Build the solution. +- Download a release or Clone the Oqtane source code to your local system. Open the **Oqtane.sln** solution file and Build the solution. Make sure you specify Oqtane.Server as the Startup Project and then Run the application. **Using Version 1:** @@ -26,7 +26,7 @@ Please note that this project is owned by the .NET Foundation and is governed by - Install [Visual Studio 2019](https://visualstudio.microsoft.com/vs) (Community, Professional, or Enterprise Editions) with the **ASP.NET and web development** workload enabled. Oqtane works with ALL editions of Visual Studio from Community to Enterprise. If you do not have a SQL Server installation available already and you wish to use LocalDB for development, you must also install the **.NET desktop development workload**. -- Download a release or Clone the Oqtane source code from a v1.x Tag to your local system. Open the **Oqtane.sln** solution file and Build the solution. +- Download a release or Clone the Oqtane source code from a v1.x Tag to your local system. Open the **Oqtane.sln** solution file and Build the solution. Make sure you specify Oqtane.Server as the Startup Project and then Run the application. **Installing an official release:** From 09d84bc12a4027546d598247a52abc9a699dce94 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:30:07 +0300 Subject: [PATCH 021/177] Localize Recylce Bin --- .../Modules/Admin/RecycleBin/Index.razor | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index 220f5ffe4..beaa74c14 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -1,16 +1,17 @@ -@namespace Oqtane.Modules.Admin.RecycleBin +@namespace Oqtane.Modules.Admin.RecycleBin @inherits ModuleBase @inject NavigationManager NavigationManager @inject IPageModuleService PageModuleService @inject IModuleService ModuleService @inject IPageService PageService +@inject IStringLocalizer Localizer - + @if (_pages == null) {
-

No Deleted Pages

+

@Localizer["No Deleted Pages"]

} else { @@ -19,12 +20,12 @@
    NameDeleted ByDeleted On@Localizer["Deleted By"]@Localizer["Deleted On"] @context.Name @context.DeletedBy @context.DeletedOn   PageModuleDeleted ByDeleted On@Localizer["Page"]@Localizer["Module"]@Localizer["Deleted By"]@Localizer["Deleted On"] @PageState.Pages.Find(item => item.PageId == context.PageId).Name @context.Title @context.DeletedBy
- - + + From fcfcd46d8ee4ac9e3487e7d1c4b0413dd6391a1f Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:37:10 +0300 Subject: [PATCH 023/177] Localize non components for the profiles pages --- .../Modules/Admin/Profiles/Edit.razor | 184 +++++++++--------- .../Modules/Admin/Profiles/Index.razor | 5 +- 2 files changed, 96 insertions(+), 93 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor index 9a27c2a93..4eab45b98 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Edit.razor @@ -2,97 +2,98 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject IProfileService ProfileService +@inject IStringLocalizer Localizer -
- + @@ -14,7 +14,7 @@
- + @@ -22,7 +22,7 @@
- + @@ -30,7 +30,7 @@
- + @@ -38,7 +38,7 @@
- + @@ -46,7 +46,7 @@
- + @@ -54,7 +54,7 @@
- + @@ -62,7 +62,7 @@
- + @@ -70,7 +70,7 @@
- +
- + Name @context.Name
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- -Cancel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ +@Localizer["Cancel"] @code { private int _profileid = -1; @@ -169,7 +170,8 @@ if (_profileid != -1) { profile = await ProfileService.UpdateProfileAsync(profile); - }else + } + else { profile = await ProfileService.AddProfileAsync(profile); } diff --git a/Oqtane.Client/Modules/Admin/Profiles/Index.razor b/Oqtane.Client/Modules/Admin/Profiles/Index.razor index 80c7f5a23..e7985f519 100644 --- a/Oqtane.Client/Modules/Admin/Profiles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Profiles/Index.razor @@ -1,10 +1,11 @@ @namespace Oqtane.Modules.Admin.Profiles @inherits ModuleBase @inject IProfileService ProfileService +@inject IStringLocalizer Localizer @if (_profiles == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -14,7 +15,7 @@ else
   Name@Localizer["Name"]
- + @@ -19,7 +19,7 @@
- +
- +
- +
- + @@ -78,18 +78,18 @@
- +
-
+
- + @@ -97,7 +97,7 @@
- +
- +
- +
- + @@ -164,7 +164,7 @@
- + + + + + + + + +
diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index ee191dd83..2ae692d7f 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -1,17 +1,17 @@ -@namespace Oqtane.Modules.Admin.Pages +@namespace Oqtane.Modules.Admin.Pages @inherits ModuleBase @inject NavigationManager NavigationManager @inject IPageService PageService @inject IThemeService ThemeService - + @if (_themeList != null) {
- + @@ -19,7 +19,7 @@
- +
- +
- +
- + @@ -89,18 +89,18 @@
- +
-
+
@@ -135,7 +136,7 @@ @@ -203,8 +204,8 @@ } - -Cancel + +@Localizer["Cancel"] @code { private List _themeList; diff --git a/Oqtane.Client/Modules/Admin/Pages/Index.razor b/Oqtane.Client/Modules/Admin/Pages/Index.razor index 7c54bfa22..4e3966f98 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Index.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject IPageService PageService +@inject IStringLocalizer Localizer @if (PageState.Pages != null) { @@ -11,7 +12,7 @@
- + From e1b02ee405f57d88c1a65a53e7514fe44e0c81d5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:53:55 +0300 Subject: [PATCH 026/177] Localize components for the logs pages --- Oqtane.Client/Modules/Admin/Logs/Detail.razor | 30 +++++++++---------- Oqtane.Client/Modules/Admin/Logs/Index.razor | 4 +-- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Logs/Detail.razor b/Oqtane.Client/Modules/Admin/Logs/Detail.razor index 1baac265c..03c0d629a 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Detail.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Detail.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Logs +@namespace Oqtane.Modules.Admin.Logs @using System.Globalization @inherits ModuleBase @inject NavigationManager NavigationManager @@ -10,7 +10,7 @@
- + @@ -108,7 +108,7 @@
- +
- +
- +
- + @@ -175,7 +175,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Pages/Index.razor b/Oqtane.Client/Modules/Admin/Pages/Index.razor index 02d1d14ca..7c54bfa22 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Index.razor @@ -1,11 +1,11 @@ -@namespace Oqtane.Modules.Admin.Pages +@namespace Oqtane.Modules.Admin.Pages @inherits ModuleBase @inject NavigationManager NavigationManager @inject IPageService PageService @if (PageState.Pages != null) { - +
@@ -14,8 +14,8 @@
- - + + From 9a3fd94c11b44570a3f8c2b18e4a0365fcf42d75 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:50:14 +0300 Subject: [PATCH 025/177] Localize non components for the pages --- Oqtane.Client/Modules/Admin/Pages/Add.razor | 31 ++++++++++--------- Oqtane.Client/Modules/Admin/Pages/Edit.razor | 31 ++++++++++--------- Oqtane.Client/Modules/Admin/Pages/Index.razor | 3 +- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index cd243df0a..1d205ba5a 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -3,6 +3,7 @@ @inject NavigationManager NavigationManager @inject IPageService PageService @inject IThemeService ThemeService +@inject IStringLocalizer Localizer @@ -23,7 +24,7 @@ @@ -101,7 +102,7 @@ @@ -187,8 +188,8 @@
Name @(new string('-', context.Level * 2))@(context.Name) @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) {
- -Cancel + +@Localizer["Cancel"] @code { private List _themeList; diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 2ae692d7f..19f58753f 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -3,6 +3,7 @@ @inject NavigationManager NavigationManager @inject IPageService PageService @inject IThemeService ThemeService +@inject IStringLocalizer Localizer @@ -23,7 +24,7 @@
@if (_parentid == _currentparentid) { - + } - + @if (_children != null && _children.Count > 0) { - - + + } - + @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) {
   Name@Localizer["Name"]
- + From db6e550c86cddbc701e77a644ddfc93a14eb5495 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 00:56:37 +0300 Subject: [PATCH 027/177] Localize non components for the logs pages --- Oqtane.Client/Modules/Admin/Logs/Detail.razor | 215 +++++++++--------- Oqtane.Client/Modules/Admin/Logs/Index.razor | 33 +-- 2 files changed, 125 insertions(+), 123 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Logs/Detail.razor b/Oqtane.Client/Modules/Admin/Logs/Detail.razor index 03c0d629a..7c2c13037 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Detail.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Detail.razor @@ -6,134 +6,135 @@ @inject IPageService PageService @inject IPageModuleService PageModuleService @inject IUserService UserService +@inject IStringLocalizer Localizer -
- + @@ -18,7 +18,7 @@
- + @@ -26,7 +26,7 @@
- + @@ -34,7 +34,7 @@
- + @@ -42,7 +42,7 @@
- + @@ -52,7 +52,7 @@ {
- + @@ -63,7 +63,7 @@ {
- + @@ -74,7 +74,7 @@ {
- + @@ -83,7 +83,7 @@ }
- + @@ -91,7 +91,7 @@
- + @@ -99,7 +99,7 @@
- + @@ -109,7 +109,7 @@ {
- + @@ -118,7 +118,7 @@ }
- + @@ -126,7 +126,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 3fcb0fb5c..f4ae994ee 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Logs +@namespace Oqtane.Modules.Admin.Logs @inherits ModuleBase @inject ILogService LogService @@ -56,7 +56,7 @@ else Function @context.LogDate @context.Level @context.Feature
- - - - - - - - - - - - - - - - - - - - - @if (_pageName != string.Empty) - { - - - - - } - @if (_moduleTitle != string.Empty) - { - - - - - } - @if (_username != string.Empty) - { - - - - - } - - - - +
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - - -
+ + + + + + + + + + + + + + + + + + + + + @if (_pageName != string.Empty) + { + } + @if (_moduleTitle != string.Empty) + { - @if (!string.IsNullOrEmpty(_exception)) - { - - - - - } + } + @if (_username != string.Empty) + { + } + + + + + + + + + + + + + @if (!string.IsNullOrEmpty(_exception)) + { -
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
- + - +
- + - +
- - - -
- + - +
+ + + +
+ + + +
+ + + +
- + - +
-Cancel + } +
+ + + +
+ + + +
+@Localizer["Cancel"] @code { private int _logId; @@ -167,7 +168,7 @@ _feature = log.Feature; _function = log.Function; _category = log.Category; - + if (log.PageId != null) { var page = await PageService.GetPageAsync(log.PageId.Value); @@ -176,7 +177,7 @@ _pageName = page.Name; } } - + if (log.PageId != null && log.ModuleId != null) { var pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value); @@ -185,7 +186,7 @@ _moduleTitle = pagemodule.Title; } } - + if (log.UserId != null) { var user = await UserService.GetUserAsync(log.UserId.Value, PageState.Site.SiteId); @@ -194,7 +195,7 @@ _username = user.Username; } } - + _url = log.Url; _template = log.MessageTemplate; _message = log.Message; diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index f4ae994ee..59830a0d4 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -1,17 +1,18 @@ @namespace Oqtane.Modules.Admin.Logs @inherits ModuleBase @inject ILogService LogService +@inject IStringLocalizer Localizer @if (_logs == null) { -

Loading...

+

@Localizer["Loading..."]

} else { - - - - + + + + @@ -66,7 +67,7 @@ else } else { -

No Logs Match The Criteria Specified

+

@Localizer["No Logs Match The Criteria Specified"]

} } From be1237f748e521767b64ea1dde1038d598154219 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:00:50 +0300 Subject: [PATCH 028/177] Localize login page --- Oqtane.Client/Modules/Admin/Login/Index.razor | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Login/Index.razor b/Oqtane.Client/Modules/Admin/Login/Index.razor index 2a1b4793b..25d5b2aea 100644 --- a/Oqtane.Client/Modules/Admin/Login/Index.razor +++ b/Oqtane.Client/Modules/Admin/Login/Index.razor @@ -3,6 +3,7 @@ @inject NavigationManager NavigationManager @inject IUserService UserService @inject IServiceProvider ServiceProvider +@inject IStringLocalizer Localizer @if (_message != string.Empty) { @@ -18,23 +19,23 @@ From bc570de9e6fea86684c04d62b5244d6fa2934be3 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:06:57 +0300 Subject: [PATCH 029/177] Localize components for jobs pages --- Oqtane.Client/Modules/Admin/Jobs/Add.razor | 16 ++++++++-------- Oqtane.Client/Modules/Admin/Jobs/Edit.razor | 18 +++++++++--------- Oqtane.Client/Modules/Admin/Jobs/Index.razor | 12 ++++++------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Jobs/Add.razor b/Oqtane.Client/Modules/Admin/Jobs/Add.razor index 65361e419..c216d83d6 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Add.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Add.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Jobs +@namespace Oqtane.Modules.Admin.Jobs @inherits ModuleBase @inject NavigationManager NavigationManager @inject IJobService JobService @@ -6,7 +6,7 @@
- + - + - +  DateLevelFeatureFunction@Localizer["Date"]@Localizer["Level"]@Localizer["Feature"]@Localizer["Function"]
- - - - + + + + @@ -35,11 +35,11 @@ else diff --git a/Oqtane.Client/Modules/Admin/Jobs/Log.razor b/Oqtane.Client/Modules/Admin/Jobs/Log.razor index 2d4ef7060..f5d8a391c 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Log.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Log.razor @@ -1,19 +1,20 @@ -@namespace Oqtane.Modules.Admin.Jobs +@namespace Oqtane.Modules.Admin.Jobs @inherits ModuleBase @inject IJobLogService JobLogService +@inject IStringLocalizer Localizer @if (_jobLogs == null) { -

Loading...

+

@Localizer["Loading..."]

} else {
-
- - - + + + + From fb3bd51227b3e2d9215ed7ffb3c54c15c7d40dac Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:17:36 +0300 Subject: [PATCH 031/177] Localize components for the files pages --- Oqtane.Client/Modules/Admin/Files/Add.razor | 12 ++++++------ Oqtane.Client/Modules/Admin/Files/Details.razor | 8 ++++---- Oqtane.Client/Modules/Admin/Files/Edit.razor | 10 +++++----- Oqtane.Client/Modules/Admin/Files/Index.razor | 12 ++++++------ 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Add.razor b/Oqtane.Client/Modules/Admin/Files/Add.razor index 9f19370d3..4822b3af8 100644 --- a/Oqtane.Client/Modules/Admin/Files/Add.razor +++ b/Oqtane.Client/Modules/Admin/Files/Add.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Files +@namespace Oqtane.Modules.Admin.Files @using System.IO @inherits ModuleBase @inject NavigationManager NavigationManager @@ -6,11 +6,11 @@ @inject IFolderService FolderService - +
- + @@ -14,7 +14,7 @@
- + @@ -22,7 +22,7 @@
- +
- + @@ -47,7 +47,7 @@
- + @@ -55,7 +55,7 @@
- + @@ -63,7 +63,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor index 25d8e4fba..8fbed6323 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Jobs +@namespace Oqtane.Modules.Admin.Jobs @inherits ModuleBase @inject NavigationManager NavigationManager @inject IJobService JobService @@ -6,7 +6,7 @@ - - - + + + From 177dcad5a10abe2e5bc9c5c06d6f9036e046f5bf Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:12:15 +0300 Subject: [PATCH 030/177] Localize non components for the jobs pages --- Oqtane.Client/Modules/Admin/Jobs/Add.razor | 17 +++++++++-------- Oqtane.Client/Modules/Admin/Jobs/Edit.razor | 19 ++++++++++--------- Oqtane.Client/Modules/Admin/Jobs/Index.razor | 14 +++++++------- Oqtane.Client/Modules/Admin/Jobs/Log.razor | 13 +++++++------ 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Jobs/Add.razor b/Oqtane.Client/Modules/Admin/Jobs/Add.razor index c216d83d6..fde389bff 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Add.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Add.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject IJobService JobService +@inject IStringLocalizer Localizer
- + @@ -14,7 +14,7 @@
- + @@ -22,7 +22,7 @@
- +
- + @@ -47,7 +47,7 @@
- + @@ -55,7 +55,7 @@
- + @@ -63,7 +63,7 @@
- + @@ -71,7 +71,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index 6ba8c69b5..e99a09b0e 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Jobs +@namespace Oqtane.Modules.Admin.Jobs @inherits ModuleBase @inject IJobService JobService @@ -8,8 +8,8 @@ } else { - - + +

@@ -25,9 +25,9 @@ else
  @context.Name @DisplayStatus(context.IsEnabled, context.IsExecuting) @DisplayFrequency(context.Interval, context.Frequency)
@@ -26,8 +27,8 @@ @@ -38,10 +39,10 @@ @@ -70,8 +71,8 @@
- -Cancel + +@Localizer["Cancel"] @code { private string _name = string.Empty; diff --git a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor index 8fbed6323..62929440a 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject IJobService JobService +@inject IStringLocalizer Localizer @@ -26,8 +27,8 @@ @@ -38,10 +39,10 @@ @@ -78,8 +79,8 @@
- -Cancel + +@Localizer["Cancel"] @code { private int _jobId; @@ -158,7 +159,7 @@ { job.NextExecution = DateTime.Parse(_nextExecution); } - + job.RetentionHistory = int.Parse(_retentionHistory); try diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index e99a09b0e..cbc137f7e 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -4,7 +4,7 @@ @if (_jobs == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -18,10 +18,10 @@ else
     NameStatusFrequencyNext Execution@Localizer["Name"]@Localizer["Status"]@Localizer["Frequency"]@Localizer["Next Execution"]   @if (context.IsStarted) { - + } else { - + } NameStatusStartedFinished@Localizer["Name"]@Localizer["Status"]@Localizer["Started"]@Localizer["Finished"] @context.Job.Name
- + @@ -19,13 +19,13 @@
Cancel - + @if (_folders != null) {
- + @@ -33,7 +33,7 @@
- + - - + + From 6b617132051071b298a9f7b4a45c5bcc27a28e4e Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:20:59 +0300 Subject: [PATCH 032/177] Localize non components for the files pages --- Oqtane.Client/Modules/Admin/Files/Add.razor | 15 ++++++++------- Oqtane.Client/Modules/Admin/Files/Details.razor | 5 +++-- Oqtane.Client/Modules/Admin/Files/Edit.razor | 3 ++- Oqtane.Client/Modules/Admin/Files/Index.razor | 15 ++++++++------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Add.razor b/Oqtane.Client/Modules/Admin/Files/Add.razor index 4822b3af8..df16cac80 100644 --- a/Oqtane.Client/Modules/Admin/Files/Add.razor +++ b/Oqtane.Client/Modules/Admin/Files/Add.razor @@ -4,6 +4,7 @@ @inject NavigationManager NavigationManager @inject IFileService FileService @inject IFolderService FolderService +@inject IStringLocalizer Localizer @@ -17,7 +18,7 @@
- + @@ -17,7 +17,7 @@
- +
- + diff --git a/Oqtane.Client/Modules/Admin/Files/Edit.razor b/Oqtane.Client/Modules/Admin/Files/Edit.razor index 73cac84d3..bde883c3b 100644 --- a/Oqtane.Client/Modules/Admin/Files/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Files/Edit.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Files +@namespace Oqtane.Modules.Admin.Files @inherits ModuleBase @inject IFolderService FolderService @inject IFileService FileService @@ -9,7 +9,7 @@ @@ -46,7 +46,7 @@ Cancel @if (!_isSystem && PageState.QueryString.ContainsKey("id")) { - + }

diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index ccb8a135b..f1897de8f 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Files +@namespace Oqtane.Modules.Admin.Files @inherits ModuleBase @inject NavigationManager NavigationManager @inject IFolderService FolderService @@ -20,9 +20,9 @@
- +
- + @@ -34,7 +34,7 @@
- +
-   -   - +   +   +
@@ -36,8 +36,8 @@
Size @context.Name @context.ModifiedOn @context.Extension.ToUpper() File
- Cancel + @Localizer["Cancel"] @if (_folders != null) @@ -46,8 +47,8 @@
- - Cancel + + @Localizer["Cancel"] }
@@ -81,10 +82,10 @@ if (!Constants.UploadableFiles.Split(',') .Contains(Path.GetExtension(filename).ToLower().Replace(".", ""))) - { - AddModuleMessage("File Could Not Be Downloaded From Url Due To Its File Extension", MessageType.Warning); - return ; - } + { + AddModuleMessage("File Could Not Be Downloaded From Url Due To Its File Extension", MessageType.Warning); + return; + } if (!filename.IsPathOrFileValid()) { diff --git a/Oqtane.Client/Modules/Admin/Files/Details.razor b/Oqtane.Client/Modules/Admin/Files/Details.razor index 379e9d7fe..1ec0107dc 100644 --- a/Oqtane.Client/Modules/Admin/Files/Details.razor +++ b/Oqtane.Client/Modules/Admin/Files/Details.razor @@ -3,6 +3,7 @@ @inject IFileService FileService @inject IFolderService FolderService @inject NavigationManager NavigationManager +@inject IStringLocalizer
Localizer @if (_folders != null) { @@ -37,8 +38,8 @@
- - Cancel + + @Localizer["Cancel"]

diff --git a/Oqtane.Client/Modules/Admin/Files/Edit.razor b/Oqtane.Client/Modules/Admin/Files/Edit.razor index bde883c3b..81829d3a3 100644 --- a/Oqtane.Client/Modules/Admin/Files/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Files/Edit.razor @@ -3,6 +3,7 @@ @inject IFolderService FolderService @inject IFileService FileService @inject NavigationManager NavigationManager +@inject IStringLocalizer Localizer @if (_folders != null) { @@ -41,7 +42,7 @@ @if (!_isSystem) { - + } Cancel @if (!_isSystem && PageState.QueryString.ContainsKey("id")) diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index f1897de8f..bff903881 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -3,13 +3,14 @@ @inject NavigationManager NavigationManager @inject IFolderService FolderService @inject IFileService FileService +@inject IStringLocalizer Localizer @if (_files != null) { - - - - + + + + - + @if (_files.Count == 0) { -
No Files Exist In Selected Folder
+
@Localizer["No Files Exist In Selected Folder"]
} } From d5d13c6def7dc090137f3874f72e32f22e878932 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:26:01 +0300 Subject: [PATCH 033/177] Localizer register page --- .../Modules/Admin/Register/Index.razor | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Register/Index.razor b/Oqtane.Client/Modules/Admin/Register/Index.razor index 2ea649449..dfff44e04 100644 --- a/Oqtane.Client/Modules/Admin/Register/Index.razor +++ b/Oqtane.Client/Modules/Admin/Register/Index.razor @@ -1,7 +1,8 @@ -@namespace Oqtane.Modules.Admin.Register +@namespace Oqtane.Modules.Admin.Register @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService +@inject IStringLocalizer Localizer @if (PageState.Site.AllowRegistration) { @@ -17,27 +18,27 @@
- +
- +
- +
- +
- +
- - + +
From d45035ce56eefe78c295e69139b1d237d211fb45 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:27:30 +0300 Subject: [PATCH 034/177] Localize reset page --- Oqtane.Client/Modules/Admin/Reset/Index.razor | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Reset/Index.razor b/Oqtane.Client/Modules/Admin/Reset/Index.razor index b6e4eb666..1a04eb46d 100644 --- a/Oqtane.Client/Modules/Admin/Reset/Index.razor +++ b/Oqtane.Client/Modules/Admin/Reset/Index.razor @@ -1,23 +1,24 @@ -@namespace Oqtane.Modules.Admin.Reset +@namespace Oqtane.Modules.Admin.Reset @inherits ModuleBase @inject NavigationManager NavigationManager @inject IUserService UserService +@inject IStringLocalizer Localizer
- +
- +
- +
- - + +
@code { From 46bf6828198cf3c7b92e0d4113a4b950054287bc Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:32:15 +0300 Subject: [PATCH 035/177] Localize module creator page --- .../Modules/Admin/ModuleCreator/Index.razor | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index cafecf3bc..2ad8f8ed4 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -4,11 +4,12 @@ @inject IModuleDefinitionService ModuleDefinitionService @inject IModuleService ModuleService @inject ISystemService SystemService +@inject IStringLocalizer Localizer
- +    NameModifiedTypeSize@Localizer["Name"]@Localizer["Modified"]@Localizer["Type"]@Localizer["Size"] @context.Name @context.ModifiedOn@context.Extension.ToUpper() File@context.Extension.ToUpper() @Localizer["File"] @(context.Size / 1000) KB
@@ -63,7 +64,7 @@ {
- + @@ -16,7 +17,7 @@
- + @@ -24,7 +25,7 @@
- + @@ -32,19 +33,19 @@
- +
- +
- + @@ -72,7 +73,7 @@ }
- + @code { private string _owner = string.Empty; From a77a86a43976673c944393a4aba363ff594e81da Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:37:18 +0300 Subject: [PATCH 036/177] Localize components for the module definitions pages --- .../Modules/Admin/ModuleDefinitions/Add.razor | 8 +++--- .../Admin/ModuleDefinitions/Edit.razor | 28 +++++++++---------- .../Admin/ModuleDefinitions/Index.razor | 12 ++++---- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor index 526f1af4f..32233f6c4 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.ModuleDefinitions +@namespace Oqtane.Modules.Admin.ModuleDefinitions @inherits ModuleBase @inject NavigationManager NavigationManager @inject IFileService FileService @@ -10,7 +10,7 @@ @if (_packages.Count > 0) { - +
@@ -28,11 +28,11 @@ } - + - - + + From 867c8f84ad030c2764b8b3af935dbc55bfc062b1 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:43:02 +0300 Subject: [PATCH 038/177] Localize components for the modules pages --- Oqtane.Client/Modules/Admin/Modules/Export.razor | 4 ++-- Oqtane.Client/Modules/Admin/Modules/Import.razor | 4 ++-- .../Modules/Admin/Modules/Settings.razor | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Modules/Export.razor b/Oqtane.Client/Modules/Admin/Modules/Export.razor index eaa0bc92f..6a7942b6d 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Export.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Export.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Modules +@namespace Oqtane.Modules.Admin.Modules @inherits ModuleBase @inject NavigationManager NavigationManager @inject IModuleService ModuleService @@ -7,7 +7,7 @@ @@ -81,8 +82,8 @@ } - -Cancel + +@Localizer["Cancel"] @code { private List _containers = new List(); From c7cb3ad53a684fd5e7555ea4696c82d9498af969 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:53:24 +0300 Subject: [PATCH 040/177] Localize HtmlText --- Oqtane.Client/Modules/HtmlText/Edit.razor | 7 ++++--- Oqtane.Client/Modules/HtmlText/Index.razor | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/Modules/HtmlText/Edit.razor b/Oqtane.Client/Modules/HtmlText/Edit.razor index 0e15706ff..25ef9b634 100644 --- a/Oqtane.Client/Modules/HtmlText/Edit.razor +++ b/Oqtane.Client/Modules/HtmlText/Edit.razor @@ -1,16 +1,17 @@ -@using Oqtane.Modules.HtmlText.Services +@using Oqtane.Modules.HtmlText.Services @using Oqtane.Modules.HtmlText.Models @using Oqtane.Modules.Controls @namespace Oqtane.Modules.HtmlText @inherits ModuleBase @inject IHtmlTextService HtmlTextService @inject NavigationManager NavigationManager +@inject IStringLocalizer Localizer @if (_content != null) { - - Cancel + + @Localizer["Cancel"] @if (!string.IsNullOrEmpty(_content)) {
diff --git a/Oqtane.Client/Modules/HtmlText/Index.razor b/Oqtane.Client/Modules/HtmlText/Index.razor index 36e7c35cd..c38009c58 100644 --- a/Oqtane.Client/Modules/HtmlText/Index.razor +++ b/Oqtane.Client/Modules/HtmlText/Index.razor @@ -1,4 +1,4 @@ -@using Oqtane.Modules.HtmlText.Services +@using Oqtane.Modules.HtmlText.Services @namespace Oqtane.Modules.HtmlText @inherits ModuleBase @inject IHtmlTextService HtmlTextService @@ -7,7 +7,7 @@ @if (PageState.EditMode) { -


+


} @code { From f9a0ecca61dcce99ff3d10f474bdd1a3e15eb8d6 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:56:25 +0300 Subject: [PATCH 041/177] Localizer installer page --- Oqtane.Client/UI/Installer.razor | 39 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/Oqtane.Client/UI/Installer.razor b/Oqtane.Client/UI/Installer.razor index 6ee0bba4b..8c1fc95a8 100644 --- a/Oqtane.Client/UI/Installer.razor +++ b/Oqtane.Client/UI/Installer.razor @@ -1,37 +1,38 @@ -@namespace Oqtane.UI +@namespace Oqtane.UI @inject NavigationManager NavigationManager @inject IInstallationService InstallationService @inject ISiteService SiteService @inject IUserService UserService @inject IJSRuntime JSRuntime +@inject IStringLocalizer Localizer
-
Version: @Constants.Version
+
@Localizer["Version:"] @Constants.Version

-

Database Configuration


+

@Localizer["Database Configuration"]


- + diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index 51ed89924..71e5d1706 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -1,14 +1,14 @@ -@namespace Oqtane.Modules.Admin.ModuleDefinitions +@namespace Oqtane.Modules.Admin.ModuleDefinitions @inherits ModuleBase @inject IModuleDefinitionService ModuleDefinitionService @inject NavigationManager NavigationManager - +
- + @@ -16,7 +16,7 @@
- + @@ -24,18 +24,18 @@
- +
-
+
- + @@ -43,7 +43,7 @@
- + @@ -51,7 +51,7 @@
- + @@ -59,7 +59,7 @@
- + @@ -67,7 +67,7 @@
- + @@ -75,7 +75,7 @@
- + @@ -83,7 +83,7 @@
- + @@ -92,7 +92,7 @@
- + - + From 4599e9a0fc8e2514af4c7d0e1ffdc6c560ff210e Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:39:56 +0300 Subject: [PATCH 037/177] Localize non components for the module definitions pages --- .../Modules/Admin/ModuleDefinitions/Add.razor | 11 ++++++----- .../Modules/Admin/ModuleDefinitions/Edit.razor | 10 ++++++---- .../Modules/Admin/ModuleDefinitions/Index.razor | 13 +++++++------ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor index 32233f6c4..23bc7a101 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor @@ -4,6 +4,7 @@ @inject IFileService FileService @inject IModuleDefinitionService ModuleDefinitionService @inject IPackageService PackageService +@inject IStringLocalizer Localizer @if (_packages != null) { @@ -14,15 +15,15 @@
-
- + + @@ -42,8 +43,8 @@ - - Cancel + + @Localizer["Cancel"] } @code { diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor index 71e5d1706..b47700ebd 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Edit.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject IModuleDefinitionService ModuleDefinitionService @inject NavigationManager NavigationManager +@inject IStringLocalizer Localizer @@ -83,7 +84,7 @@
diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index fabf69736..3d0fe338c 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.ModuleDefinitions +@namespace Oqtane.Modules.Admin.ModuleDefinitions @inherits ModuleBase @inject NavigationManager NavigationManager @inject IModuleDefinitionService ModuleDefinitionService @@ -10,7 +10,7 @@ } else { - +
@@ -21,20 +21,20 @@ else
  @if (context.AssemblyName != "Oqtane.Client") { - + } @context.Name @context.Version @if (UpgradeAvailable(context.ModuleDefinitionName, context.Version)) - { + { - } + } NameVersion@Localizer["Name"]@Localizer["Version"] @context.Name @context.Version - +
- + @@ -102,9 +103,10 @@
- -Cancel -

+ +@Localizer["Cancel"] +
+
@code { diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index 3d0fe338c..7d5cbd906 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -3,10 +3,11 @@ @inject NavigationManager NavigationManager @inject IModuleDefinitionService ModuleDefinitionService @inject IPackageService PackageService +@inject IStringLocalizer Localizer @if (_moduleDefinitions == null) { -

Loading...

+

@Localizer["Loading..."]

} else { @@ -16,24 +17,24 @@ else
   NameVersion@Localizer["Name"]@Localizer["Version"]   @if (context.AssemblyName != "Oqtane.Client") - { + { - } + } @context.Name @context.Version @if (UpgradeAvailable(context.ModuleDefinitionName, context.Version)) { - + }
- + diff --git a/Oqtane.Client/Modules/Admin/Modules/Import.razor b/Oqtane.Client/Modules/Admin/Modules/Import.razor index 1d99bcb9a..632486d20 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Import.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Import.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Modules +@namespace Oqtane.Modules.Admin.Modules @inherits ModuleBase @inject NavigationManager NavigationManager @inject IModuleService ModuleService @@ -7,7 +7,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index 31cedb010..acf15177f 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Modules +@namespace Oqtane.Modules.Admin.Modules @inherits ModuleBase @inject NavigationManager NavigationManager @inject IThemeService ThemeService @@ -6,13 +6,13 @@ @inject IPageModuleService PageModuleService - + @if (_containers != null) {
- + @@ -20,7 +20,7 @@
- +
- +
- +
}
- + @if (_permissions != null) { @@ -76,7 +76,7 @@ @if (_settingsModuleType != null) { - + @DynamicComponent } From d108cc399082d8baa9286378e33f315d735afbdb Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 01:45:09 +0300 Subject: [PATCH 039/177] Localize non components for the modules pages --- Oqtane.Client/Modules/Admin/Modules/Export.razor | 5 +++-- Oqtane.Client/Modules/Admin/Modules/Import.razor | 5 +++-- Oqtane.Client/Modules/Admin/Modules/Settings.razor | 11 ++++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Modules/Export.razor b/Oqtane.Client/Modules/Admin/Modules/Export.razor index 6a7942b6d..80010036c 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Export.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Export.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject IModuleService ModuleService +@inject IStringLocalizer Localizer
@@ -15,8 +16,8 @@
- -Cancel + +@Localizer["Cancel"] @code { diff --git a/Oqtane.Client/Modules/Admin/Modules/Import.razor b/Oqtane.Client/Modules/Admin/Modules/Import.razor index 632486d20..b3ace3328 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Import.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Import.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @inject NavigationManager NavigationManager @inject IModuleService ModuleService +@inject IStringLocalizer Localizer @@ -15,8 +16,8 @@
- -Cancel + +@Localizer["Cancel"] @code { diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index acf15177f..95bb5cec9 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -4,6 +4,7 @@ @inject IThemeService ThemeService @inject IModuleService ModuleService @inject IPageModuleService PageModuleService +@inject IStringLocalizer Localizer @@ -24,7 +25,7 @@
- +
- + @@ -39,7 +40,7 @@
- + @@ -47,18 +48,18 @@
- +
- + @@ -66,7 +67,7 @@
- + @@ -76,12 +77,12 @@
-

Application Administrator


+

@Localizer["Application Administrator"]


- + @@ -89,7 +90,7 @@
- + @@ -97,7 +98,7 @@
- + @@ -105,7 +106,7 @@
- + @@ -118,7 +119,7 @@
-

+

From f8e1c8c53d578eadfa3c85f000233d8243b79d00 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 02:05:48 +0300 Subject: [PATCH 042/177] Localize Login & UserProfile components --- Oqtane.Client/Themes/Controls/Login.razor | 9 +++++---- Oqtane.Client/Themes/Controls/UserProfile.razor | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/Login.razor b/Oqtane.Client/Themes/Controls/Login.razor index 84ef808e7..f4c415c9b 100644 --- a/Oqtane.Client/Themes/Controls/Login.razor +++ b/Oqtane.Client/Themes/Controls/Login.razor @@ -1,5 +1,6 @@ -@namespace Oqtane.Themes.Controls -@inherits LoginBase +@namespace Oqtane.Themes.Controls +@inherits LoginBase +@inject IStringLocalizer Localizer \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/UserProfile.razor b/Oqtane.Client/Themes/Controls/UserProfile.razor index a5d95aebf..e939d633c 100644 --- a/Oqtane.Client/Themes/Controls/UserProfile.razor +++ b/Oqtane.Client/Themes/Controls/UserProfile.razor @@ -1,5 +1,6 @@ -@namespace Oqtane.Themes.Controls -@inherits ThemeControlBase +@namespace Oqtane.Themes.Controls +@inherits ThemeControlBase +@inject IStringLocalizer Localizer @inject NavigationManager NavigationManager @@ -14,7 +15,7 @@ @if (PageState.Site.AllowRegistration) { - + } From 5cee11accbdeadbd143570172d3f61c9858627a0 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 02:11:16 +0300 Subject: [PATCH 043/177] Localize ControlPanel component --- .../Themes/Controls/ControlPanel.razor | 51 ++++++++++--------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 7629066bb..02ae862ca 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Themes.Controls +@namespace Oqtane.Themes.Controls @inherits ThemeControlBase @inject NavigationManager NavigationManager @inject IUserService UserService @@ -9,6 +9,7 @@ @inject IPageModuleService PageModuleService @inject ILogService logger @inject ISettingService SettingService +@inject IStringLocalizer Localizer @if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) { @@ -16,7 +17,7 @@
- Control Panel + @Localizer["Control Panel"] @@ -27,7 +28,7 @@ {
- +
@@ -35,18 +36,18 @@
- +
- +
- +
- +

@@ -54,13 +55,13 @@ @if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone)) {
- +
} else {
- +
}
@@ -73,15 +74,15 @@ @@ -92,10 +93,10 @@
- + @if (ModuleType == "new") { @@ -106,22 +107,22 @@ { if (category == Category) { - + } else { - + } } - + @foreach (Page p in _pages) { }
@@ -166,7 +167,7 @@ {
- + @foreach (var container in _containers) { @@ -190,7 +191,7 @@
- + @((MarkupString) Message)
From 33c8fe6e33ec635422e6a20a7407a0688042316d Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 02:22:21 +0300 Subject: [PATCH 044/177] Localize PermissionGrid component --- Oqtane.Client/Modules/Controls/PermissionGrid.razor | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/PermissionGrid.razor b/Oqtane.Client/Modules/Controls/PermissionGrid.razor index 204aa21f4..000f54be6 100644 --- a/Oqtane.Client/Modules/Controls/PermissionGrid.razor +++ b/Oqtane.Client/Modules/Controls/PermissionGrid.razor @@ -1,7 +1,8 @@ -@namespace Oqtane.Modules.Controls +@namespace Oqtane.Modules.Controls @inherits ModuleControlBase @inject IRoleService RoleService @inject IUserService UserService +@inject IStringLocalizer Localizer @if (_permissions != null) { @@ -9,7 +10,7 @@ - + @foreach (PermissionString permission in _permissions) { @@ -35,7 +36,7 @@
Role@Localizer["Role"]@permission.PermissionName
- + @foreach (PermissionString permission in _permissions) { @@ -65,7 +66,7 @@ From 26f610e43b1e65578bc23b16e23e416f4b3169ba Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 20 Nov 2020 02:25:45 +0300 Subject: [PATCH 045/177] Localize RichTextEditor component --- Oqtane.Client/Modules/Controls/RichTextEditor.razor | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor index 3d7d2327d..40af94979 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditor.razor +++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor @@ -1,5 +1,6 @@ -@namespace Oqtane.Modules.Controls +@namespace Oqtane.Modules.Controls @inherits ModuleControlBase +@inject IStringLocalizer Localizer
@@ -12,12 +13,12 @@
}
-    - +    + @if (_filemanagervisible) { @((MarkupString)"  ") - + }
@@ -61,9 +62,9 @@
- +
- +
@if (ReadOnly) { From d64f06eb714ecae2c78e551d417158f0046f7ec6 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 20 Nov 2020 10:20:29 -0500 Subject: [PATCH 046/177] missing using statement causing compilation error --- Oqtane.Client/Themes/Controls/LoginBase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/LoginBase.cs b/Oqtane.Client/Themes/Controls/LoginBase.cs index d923b0129..ed9eb2890 100644 --- a/Oqtane.Client/Themes/Controls/LoginBase.cs +++ b/Oqtane.Client/Themes/Controls/LoginBase.cs @@ -4,7 +4,7 @@ using Microsoft.JSInterop; using Oqtane.Providers; using Oqtane.Services; -using Oqtane.Shared; +using Oqtane.UI; namespace Oqtane.Themes.Controls { @@ -29,7 +29,7 @@ protected async Task LogoutUser() { await UserService.LogoutUserAsync(PageState.User); - if (PageState.Runtime == Runtime.Server) + if (PageState.Runtime == Oqtane.Shared.Runtime.Server) { // server-side Blazor var interop = new Interop(jsRuntime); From 710aab9b93e74986041676c20b73260679ed921b Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 20 Nov 2020 10:30:07 -0500 Subject: [PATCH 047/177] missing IStringLocalizer causing compilation error --- Oqtane.Client/Modules/Admin/Jobs/Index.razor | 22 +++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index cbc137f7e..ffd32c17e 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Modules.Admin.Jobs @inherits ModuleBase @inject IJobService JobService +@inject IStringLocalizer Localizer @if (_jobs == null) { @@ -11,7 +12,8 @@ else -

+
+
@@ -34,13 +36,13 @@ else
@@ -48,7 +50,7 @@ else @code { private List _jobs; - + public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } } protected override async Task OnParametersSetAsync() @@ -81,7 +83,7 @@ else private string DisplayFrequency(int interval, string frequency) { - var result = "Every " + interval.ToString() + " "; + var result = "Every " + interval.ToString() + " "; switch (frequency) { case "m": @@ -97,12 +99,12 @@ else result += "Month"; break; } - + if (interval > 1) { result += "s"; } - + return result; } From 19f924c3d3e229dd5fd66c42393db439c3f32d5d Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 20 Nov 2020 16:40:25 -0500 Subject: [PATCH 048/177] fix ModuleCreator Invalid character use in naming fields #889 --- .../Modules/Admin/ModuleCreator/Index.razor | 135 +++++++++--------- 1 file changed, 71 insertions(+), 64 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 2ad8f8ed4..9da0deec0 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -4,74 +4,75 @@ @inject IModuleDefinitionService ModuleDefinitionService @inject IModuleService ModuleService @inject ISystemService SystemService -@inject IStringLocalizer Localizer +@inject IStringLocalizer Localizer +@using System.Text.RegularExpressions -
User@Localizer["User"]@permission.PermissionName
- +
@context.NextExecution @if (context.IsStarted) - { + { - } - else - { + } + else + { - } + }
- - - - - - - - - - - - - - - - +
- - - -
- - - -
- - - -
- - - -
+ + + + + + + + + + + + + + + + + + + + + @if (!string.IsNullOrEmpty(_location)) + { - @if (!string.IsNullOrEmpty(_location)) - { - - - - - } -
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
- + - +
- - - -
+ } +
@@ -94,18 +95,18 @@ { try { - if (!string.IsNullOrEmpty(_owner) && !string.IsNullOrEmpty(_module) && _template != "-") + if (IsValid(_owner) && IsValid(_module) && _template != "-") { ShowProgressIndicator(); var interop = new Interop(JSRuntime); await interop.RedirectBrowser(NavigateUrl(), 5); - var moduleDefinition = new ModuleDefinition { Owner = _owner.Replace(" ", ""), Name = _module.Replace(" ", ""), Description = _description, Template = _template, Version = _reference }; + var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference }; await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition, ModuleState.ModuleId); } else { - AddModuleMessage("You Must Provide An Owner, Module Name, And Template", MessageType.Warning); + AddModuleMessage("You Must Provide A Valid Owner Name, Module Name, And Template", MessageType.Warning); } } catch (Exception ex) @@ -114,6 +115,12 @@ } } + private bool IsValid(string name) + { + // must contain letters, underscores and digits and first character must be letter or underscore + return !string.IsNullOrEmpty(name) && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$"); + } + private async void TemplateChanged(ChangeEventArgs e) { try From 1e1a2aa145126c8c3239a6feb1acf56a4f9a2dfd Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 24 Nov 2020 10:48:30 -0500 Subject: [PATCH 049/177] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2800b3426..356567ac6 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,11 @@ There is a separate [Documentation repository](https://github.com/oqtane/oqtane. # Roadmap 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 ) +- [ ] Complete Static Localization of Admin UI +- [ ] EF Core Migrations for Database Installation/Upgrade +- [ ] Support for Multiple Relational Databases ( ie. SQLite ) + 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.. ) @@ -77,8 +82,6 @@ V.1.0.0 ( released in conjunction with .NET Core 3.2 on May 19, 2020 ) - [x] Dynamic CSS/Lazy Loading Future Consideration -- [ ] DB Migrations for Database Installation/Upgrade -- [ ] Support for other Databases ( ie. SQLite ) - [ ] OAuth Support - [ ] Site Configuration Migrations - [ ] Pub/Sub Event Framework From 5e42ab8ccaf8ff52de22e0e11c7f25f6ca728f76 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 24 Nov 2020 16:22:53 -0500 Subject: [PATCH 050/177] improve user experience by delegating application restart responsibility to the host user --- .../Modules/Admin/ModuleCreator/Index.razor | 10 +-------- .../Modules/Admin/ModuleDefinitions/Add.razor | 6 ++---- .../Admin/ModuleDefinitions/Index.razor | 8 ++----- .../Modules/Admin/SystemInfo/Index.razor | 21 +++++++++++++++++-- Oqtane.Client/Modules/Admin/Themes/Add.razor | 6 ++---- .../Modules/Admin/Themes/Index.razor | 8 ++----- .../Modules/Controls/ModuleMessage.razor | 2 +- Oqtane.Client/Services/InstallationService.cs | 7 ++++++- .../Interfaces/IInstallationService.cs | 3 ++- .../Controllers/InstallationController.cs | 8 +++++++ .../Controllers/ModuleDefinitionController.cs | 7 +------ Oqtane.Server/Controllers/ThemeController.cs | 6 ++---- .../Infrastructure/InstallationManager.cs | 10 +++------ .../Interfaces/IInstallationManager.cs | 4 ++-- 14 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 9da0deec0..28b1c6e05 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -86,23 +86,15 @@ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override void OnInitialized() - { - AddModuleMessage("Please Note That Once You Select The Create Module Button The Application Must Restart In Order To Complete The Process. If You Create An External Module You Will Need To Compile The Source Code And Then Relaunch Your Site In Order To Make It Functional.", MessageType.Info); - } - private async Task CreateModule() { try { if (IsValid(_owner) && IsValid(_module) && _template != "-") { - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 5); - var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference }; await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition, ModuleState.ModuleId); + AddModuleMessage("The Source Code For Your Module Has Been Created And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application.", MessageType.Success); } else { diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor index 23bc7a101..22d08ac2e 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Add.razor @@ -78,14 +78,12 @@ { try { - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 10); await ModuleDefinitionService.InstallModuleDefinitionsAsync(); + AddModuleMessage("Module Installed Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); } catch (Exception ex) { - await logger.LogError(ex, "Error Installating Module"); + await logger.LogError(ex, "Error Installing Module"); } } diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index 7d5cbd906..da1f58a89 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -85,10 +85,8 @@ else { await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules"); await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version); - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 10); await ModuleDefinitionService.InstallModuleDefinitionsAsync(); + AddModuleMessage("Module Installed Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); } catch (Exception ex) { @@ -101,10 +99,8 @@ else { try { - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 10); await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId); + AddModuleMessage("Module Deleted Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); } catch (Exception ex) { diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor index 98c95892a..5a1e485a3 100644 --- a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor +++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Modules.Admin.SystemInfo @inherits ModuleBase @inject ISystemService SystemService +@inject IInstallationService InstallationService @inject IStringLocalizer Localizer @@ -53,7 +54,8 @@
-@Localizer["Access Framework API"] +@Localizer["Access Framework API"]  + @code { public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; @@ -79,4 +81,19 @@ _servertime = systeminfo["servertime"]; } } -} + + private async Task RestartApplication() + { + try + { + ShowProgressIndicator(); + var interop = new Interop(JSRuntime); + await interop.RedirectBrowser(NavigateUrl(""), 10); + await InstallationService.RestartAsync(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Restarting Application"); + } + } +} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor index 6ab6fde3c..fa896dd42 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Add.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor @@ -78,14 +78,12 @@ { try { - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 10); await ThemeService.InstallThemesAsync(); + AddModuleMessage("Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); } catch (Exception ex) { - await logger.LogError(ex, "Error Installating Theme"); + await logger.LogError(ex, "Error Installing Theme"); } } diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 758dddb4c..8b64bff86 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -86,10 +86,8 @@ else { await PackageService.DownloadPackageAsync(themename, version, "Themes"); await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version); - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 10); await ThemeService.InstallThemesAsync(); + AddModuleMessage("Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); } catch (Exception ex) { @@ -102,10 +100,8 @@ else { try { - ShowProgressIndicator(); - var interop = new Interop(JSRuntime); - await interop.RedirectBrowser(NavigateUrl(), 10); await ThemeService.DeleteThemeAsync(Theme.ThemeName); + AddModuleMessage("Theme Deleted Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); } catch (Exception ex) { diff --git a/Oqtane.Client/Modules/Controls/ModuleMessage.razor b/Oqtane.Client/Modules/Controls/ModuleMessage.razor index ee846b13f..04a1056e9 100644 --- a/Oqtane.Client/Modules/Controls/ModuleMessage.razor +++ b/Oqtane.Client/Modules/Controls/ModuleMessage.razor @@ -5,7 +5,7 @@ @if (!string.IsNullOrEmpty(_message)) { } + + @if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null)) { if (PageState.EditMode) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor new file mode 100644 index 000000000..3b630a7a0 --- /dev/null +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -0,0 +1,30 @@ +@namespace Oqtane.Themes.Controls +@inherits ThemeControlBase +@using System.Globalization +@inject ILocalizationService LocalizationService + +@if (_supportedCultures != null) +{ +
+ + +
+} + +@code{ + private string _selectedCulture; + private string[] _supportedCultures; + + protected override async Task OnParametersSetAsync() + { + _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); + _supportedCultures = await LocalizationService.GetSupportedCultures(); + } +} diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index 2aa0dd9dd..92dea6bc0 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -48,6 +48,12 @@ @if (Configuration.GetSection("Runtime").Value == "WebAssembly") { + } else { diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index b008ee308..b134a19e5 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -127,6 +127,7 @@ public void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSingleton(); From 75556070d6138e65e3982de1a5a36f8ef0954a96 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:04:34 +0300 Subject: [PATCH 061/177] Ability to change culture --- Oqtane.Client/Oqtane.Client.csproj | 1 + Oqtane.Client/Program.cs | 10 ++++++++++ Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 12 ++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index 3ce834394..da11a4722 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -17,6 +17,7 @@ https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 Oqtane true + true diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 7fdfa6bd5..6689db41a 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; @@ -10,6 +11,7 @@ using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; +using Microsoft.JSInterop; using Oqtane.Modules; using Oqtane.Providers; using Oqtane.Services; @@ -89,6 +91,14 @@ public static async Task Main(string[] args) } var host = builder.Build(); + var jsRuntime = host.Services.GetRequiredService(); + var culture = await jsRuntime.InvokeAsync("oqtaneCulture.get"); + if (culture != null) + { + var cultureInfo = CultureInfo.GetCultureInfo(culture); + CultureInfo.DefaultThreadCurrentCulture = cultureInfo; + CultureInfo.DefaultThreadCurrentUICulture = cultureInfo; + } ServiceActivator.Configure(host.Services); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 3b630a7a0..8ce1c52d4 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -2,6 +2,7 @@ @inherits ThemeControlBase @using System.Globalization @inject ILocalizationService LocalizationService +@inject NavigationManager NavigationManager @if (_supportedCultures != null) { @@ -12,7 +13,7 @@
@@ -24,7 +25,14 @@ protected override async Task OnParametersSetAsync() { - _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); + _selectedCulture = _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); _supportedCultures = await LocalizationService.GetSupportedCultures(); } + + private async Task SetCultureAsync(string culture) + { + await JSRuntime.InvokeVoidAsync("oqtaneCulture.set", culture); + + NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + } } From 330499dda5c86c219783fc68a8778d605d238370 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:10:01 +0300 Subject: [PATCH 062/177] Use Interop --- Oqtane.Client/Program.cs | 4 ++- .../Themes/Controls/LanguageSwitcher.razor | 6 ++-- Oqtane.Client/UI/Interop.cs | 29 ++++++++++++++++++- Oqtane.Server/Pages/_Host.cshtml | 8 +---- Oqtane.Server/wwwroot/js/interop.js | 6 ++++ 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 6689db41a..43dc617ad 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -16,6 +16,7 @@ using Oqtane.Providers; using Oqtane.Services; using Oqtane.Shared; +using Oqtane.UI; namespace Oqtane.Client { @@ -92,7 +93,8 @@ public static async Task Main(string[] args) var host = builder.Build(); var jsRuntime = host.Services.GetRequiredService(); - var culture = await jsRuntime.InvokeAsync("oqtaneCulture.get"); + var interop = new Interop(jsRuntime); + var culture = await interop.getCulture(); if (culture != null) { var cultureInfo = CultureInfo.GetCultureInfo(culture); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 8ce1c52d4..ddde387b4 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -25,13 +25,15 @@ protected override async Task OnParametersSetAsync() { - _selectedCulture = _selectedCulture = await JSRuntime.InvokeAsync("oqtaneCulture.get"); + var interop = new Interop(JSRuntime); + _selectedCulture = await interop.getCulture(); _supportedCultures = await LocalizationService.GetSupportedCultures(); } private async Task SetCultureAsync(string culture) { - await JSRuntime.InvokeVoidAsync("oqtaneCulture.set", culture); + var interop = new Interop(JSRuntime); + await interop.setCulture(culture); NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 53b8df4f6..83a88ad5f 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -1,4 +1,4 @@ -using Microsoft.JSInterop; +using Microsoft.JSInterop; using Oqtane.Models; using System.Threading.Tasks; @@ -234,5 +234,32 @@ public Task RedirectBrowser(string url, int wait) } } + public async Task getCulture() + { + try + { + var culture = await _jsRuntime.InvokeAsync("Oqtane.Interop.getCulture"); + + return culture; + } + catch + { + return null; + } + } + + public Task setCulture(string culture) + { + try + { + _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setCulture", culture); + + return Task.CompletedTask; + } + catch + { + return Task.CompletedTask; + } + } } } diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index 92dea6bc0..ecf906e4e 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 System.Globalization @@ -48,12 +48,6 @@ @if (Configuration.GetSection("Runtime").Value == "WebAssembly") { - } else { diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index 2e4092e45..dc3f03941 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -362,5 +362,11 @@ Oqtane.Interop = { setInterval(function () { window.location.href = url; }, wait * 1000); + }, + getCulture: function () { + return window.localStorage['OqtaneCulture']; + }, + setCulture: function (culture) { + window.localStorage['OqtaneCulture'] = culture; } }; From d4dd80ff3252fc432036b7b2098353ddf27bd79d Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:15:52 +0300 Subject: [PATCH 063/177] Add missing event args --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index ddde387b4..9c67f24cc 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -13,7 +13,7 @@ From fa3cc48fd0a5fc782102a6978acc0934a04610e8 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 02:19:47 +0300 Subject: [PATCH 064/177] Avoid to select the current selected culture --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 9c67f24cc..e14e8a8ec 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -32,9 +32,12 @@ private async Task SetCultureAsync(string culture) { - var interop = new Interop(JSRuntime); - await interop.setCulture(culture); + if (culture != CultureInfo.CurrentUICulture.Name) + { + var interop = new Interop(JSRuntime); + await interop.setCulture(culture); - NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + } } } From fd60b40c535c8001b950eb4c162175b59c8e1737 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 1 Dec 2020 19:36:02 -0500 Subject: [PATCH 065/177] Fixes to make site alias, page path, and module action Url resolutions case insensitive. Optimized logic for Settings component which fixed localization rendering issue. --- .../Modules/Admin/Modules/Export.razor | 2 +- .../Modules/Admin/Modules/Import.razor | 2 +- .../Modules/Admin/Modules/Settings.razor | 2 +- .../Themes/Controls/ModuleTitle.razor | 14 +++-------- Oqtane.Client/UI/ModuleInstance.razor | 17 ++++--------- Oqtane.Client/UI/Pane.razor | 11 ++------ Oqtane.Client/UI/SiteRouter.razor | 25 ++++++++++--------- Oqtane.Server/Controllers/AliasController.cs | 4 +-- 8 files changed, 29 insertions(+), 48 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Modules/Export.razor b/Oqtane.Client/Modules/Admin/Modules/Export.razor index 80010036c..fd1aa71c7 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Export.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Export.razor @@ -24,7 +24,7 @@ private string _content = string.Empty; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - public override string Title => "Export Module"; + public override string Title => "Export Content"; private async Task ExportModule() diff --git a/Oqtane.Client/Modules/Admin/Modules/Import.razor b/Oqtane.Client/Modules/Admin/Modules/Import.razor index b3ace3328..585aeeda0 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Import.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Import.razor @@ -24,7 +24,7 @@ private string _content = string.Empty; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - public override string Title => "Import Module"; + public override string Title => "Import Content"; private async Task ImportModule() { diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index 95bb5cec9..a4bd4188f 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -121,7 +121,7 @@ _permissionNames = ModuleState.ModuleDefinition.PermissionNames; _pageId = ModuleState.PageId.ToString(); - _settingsModuleType = Type.GetType(ModuleState.ModuleType); + _settingsModuleType = Type.GetType(ModuleState.ModuleDefinition.ControlTypeTemplate.Replace(Constants.ActionToken, PageState.Action), false, true); if (_settingsModuleType != null) { var moduleobject = Activator.CreateInstance(_settingsModuleType) as IModuleControl; diff --git a/Oqtane.Client/Themes/Controls/ModuleTitle.razor b/Oqtane.Client/Themes/Controls/ModuleTitle.razor index 0dd706eeb..24a5da861 100644 --- a/Oqtane.Client/Themes/Controls/ModuleTitle.razor +++ b/Oqtane.Client/Themes/Controls/ModuleTitle.razor @@ -9,21 +9,15 @@ @code { private string title = ""; - protected override Task OnParametersSetAsync() + protected override void OnParametersSet() { - title = ModuleState.Title; - // check for core module actions component - if (Constants.DefaultModuleActions.Contains(PageState.Action)) + if (!string.IsNullOrEmpty(ModuleState.ControlTitle)) { - title = PageState.Action; + title = ModuleState.ControlTitle; } else { - if (!string.IsNullOrEmpty(ModuleState.ControlTitle)) - { - title = ModuleState.ControlTitle; - } + title = ModuleState.Title; } - return Task.CompletedTask; } } diff --git a/Oqtane.Client/UI/ModuleInstance.razor b/Oqtane.Client/UI/ModuleInstance.razor index 80af124da..c619f2689 100644 --- a/Oqtane.Client/UI/ModuleInstance.razor +++ b/Oqtane.Client/UI/ModuleInstance.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.UI +@namespace Oqtane.UI @@ -28,17 +28,10 @@ { DynamicComponent = builder => { - string typename = ModuleState.ModuleType; - // check for core module actions component - if (Constants.DefaultModuleActions.Contains(PageState.Action)) - { - typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, PageState.Action); - } - Type moduleType = null; - if (typename != null) + if (!string.IsNullOrEmpty(ModuleState.ModuleType)) { - moduleType = Type.GetType(typename); + moduleType = Type.GetType(ModuleState.ModuleType); if (moduleType != null) { @@ -48,13 +41,13 @@ else { // module does not exist with typename specified - _message = "Module Does Not Have A Component Named " + Utilities.GetTypeNameLastSegment(typename, 0) + ".razor"; + _message = "Module Does Not Have A Component Named " + Utilities.GetTypeNameLastSegment(ModuleState.ModuleType, 0) + ".razor"; _messagetype = MessageType.Error; } } else { - _message = "Something is wrong with moduletype"; + _message = "Module Type Is Invalid For " + ModuleState.ModuleDefinitionName; _messagetype = MessageType.Error; } diff --git a/Oqtane.Client/UI/Pane.razor b/Oqtane.Client/UI/Pane.razor index 028fca3f2..0c04ff947 100644 --- a/Oqtane.Client/UI/Pane.razor +++ b/Oqtane.Client/UI/Pane.razor @@ -52,14 +52,7 @@ else Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId); if (module != null && !module.IsDeleted) { - var typename = module.ModuleType; - // check for core module actions component - if (Constants.DefaultModuleActions.Contains(PageState.Action)) - { - typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, PageState.Action); - } - - var moduleType = Type.GetType(typename); + var moduleType = Type.GetType(module.ModuleType); if (moduleType != null) { bool authorized = false; @@ -96,7 +89,7 @@ else } else { - // module control does not exist with name specified + // module type does not exist } } } diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index f8406a13f..082e04ee1 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -230,7 +230,7 @@ if (PageState == null || reload == Reload.Site) { - page = pages.Where(item => item.Path == path).FirstOrDefault(); + page = pages.FirstOrDefault(item => item.Path.Equals(path, StringComparison.OrdinalIgnoreCase)); } else { @@ -465,22 +465,23 @@ } } - module.ModuleType = typename.Replace(Constants.ActionToken, action); - - // get additional metadata from IModuleControl interface - typename = module.ModuleType; - if (Constants.DefaultModuleActions.Contains(action)) + // ensure component exists and implements IModuleControl + module.ModuleType = ""; + if (Constants.DefaultModuleActions.Contains(action, StringComparer.OrdinalIgnoreCase)) { - // core framework module action components typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, action); } - Type moduletype = Type.GetType(typename); - - // ensure component implements IModuleControl - if (moduletype != null && !moduletype.GetInterfaces().Contains(typeof(IModuleControl))) + else { - module.ModuleType = ""; + typename = typename.Replace(Constants.ActionToken, action); } + Type moduletype = Type.GetType(typename, false, true); // case insensitive + if (moduletype != null && moduletype.GetInterfaces().Contains(typeof(IModuleControl))) + { + module.ModuleType = Utilities.GetFullTypeName(moduletype.AssemblyQualifiedName); // get actual type name + } + + // get additional metadata from IModuleControl interface if (moduletype != null && module.ModuleType != "") { var moduleobject = Activator.CreateInstance(moduletype) as IModuleControl; diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index 188160a01..8956bac7e 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using Oqtane.Models; @@ -62,7 +62,7 @@ public Alias Get(string name, string sync) for (int i = segments.Length; i > 0; i--) { name = string.Join("/", segments, 0, i); - alias = aliases.Find(item => item.Name == name); + alias = aliases.Find(item => item.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); if (alias != null) { break; // found a matching alias From 1b3cc2c44e04414d75158d007841f806e0d0760e Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 13:37:18 +0300 Subject: [PATCH 066/177] Interop local storage APIs should be generic --- Oqtane.Client/Program.cs | 2 +- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 4 ++-- Oqtane.Client/UI/Interop.cs | 10 +++++----- Oqtane.Server/wwwroot/js/interop.js | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 43dc617ad..fcc030998 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -94,7 +94,7 @@ public static async Task Main(string[] args) var host = builder.Build(); var jsRuntime = host.Services.GetRequiredService(); var interop = new Interop(jsRuntime); - var culture = await interop.getCulture(); + var culture = await interop.GetLocalStorage("OqtaneCulture"); if (culture != null) { var cultureInfo = CultureInfo.GetCultureInfo(culture); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index e14e8a8ec..4b0a3acd6 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -26,7 +26,7 @@ protected override async Task OnParametersSetAsync() { var interop = new Interop(JSRuntime); - _selectedCulture = await interop.getCulture(); + _selectedCulture = await interop.GetLocalStorage("OqtaneCulture"); _supportedCultures = await LocalizationService.GetSupportedCultures(); } @@ -35,7 +35,7 @@ if (culture != CultureInfo.CurrentUICulture.Name) { var interop = new Interop(JSRuntime); - await interop.setCulture(culture); + await interop.SetLocalStorage("OqtaneCulture", culture); NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 83a88ad5f..10c37d44e 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -234,13 +234,13 @@ public Task RedirectBrowser(string url, int wait) } } - public async Task getCulture() + public async Task GetLocalStorage(string name) { try { - var culture = await _jsRuntime.InvokeAsync("Oqtane.Interop.getCulture"); + var value = await _jsRuntime.InvokeAsync("Oqtane.Interop.getLocalStorage", name); - return culture; + return value; } catch { @@ -248,11 +248,11 @@ public async Task getCulture() } } - public Task setCulture(string culture) + public Task SetLocalStorage(string name, string value) { try { - _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setCulture", culture); + _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setLocalStorage", name, value); return Task.CompletedTask; } diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index dc3f03941..e71f4b81f 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -363,10 +363,10 @@ Oqtane.Interop = { window.location.href = url; }, wait * 1000); }, - getCulture: function () { - return window.localStorage['OqtaneCulture']; + getLocalStorage: function (name) { + return window.localStorage[name]; }, - setCulture: function (culture) { - window.localStorage['OqtaneCulture'] = culture; + setLocalStorage: function (name, value) { + window.localStorage[name] = value; } }; From a37eb8a44a68147b7f77e77c0cf3f1c755238c61 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 14:05:49 +0300 Subject: [PATCH 067/177] Introduce Culture model to avoid CultureInfo.DisplayName issue --- .../Interfaces/ILocalizationService.cs | 6 ++++-- Oqtane.Client/Services/LocalizationService.cs | 7 +++++-- .../Themes/Controls/LanguageSwitcher.razor | 7 ++++--- .../Controllers/LocalizationController.cs | 20 +++++++++++++++++-- Oqtane.Shared/Models/Culture.cs | 9 +++++++++ 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 Oqtane.Shared/Models/Culture.cs diff --git a/Oqtane.Client/Services/Interfaces/ILocalizationService.cs b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs index c025ee452..8a580cc65 100644 --- a/Oqtane.Client/Services/Interfaces/ILocalizationService.cs +++ b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs @@ -1,11 +1,13 @@ +using System.Collections.Generic; using System.Threading.Tasks; +using Oqtane.Models; namespace Oqtane.Services { public interface ILocalizationService { - Task GetDefaultCulture(); + Task GetDefaultCulture(); - Task GetSupportedCultures(); + Task> GetSupportedCultures(); } } diff --git a/Oqtane.Client/Services/LocalizationService.cs b/Oqtane.Client/Services/LocalizationService.cs index 4c658c502..ea6e5fd88 100644 --- a/Oqtane.Client/Services/LocalizationService.cs +++ b/Oqtane.Client/Services/LocalizationService.cs @@ -1,5 +1,7 @@ +using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; +using Oqtane.Models; using Oqtane.Shared; namespace Oqtane.Services @@ -15,8 +17,9 @@ public LocalizationService(HttpClient http, SiteState siteState) : base(http) private string Apiurl => CreateApiUrl(_siteState.Alias, "Localization"); - public async Task GetDefaultCulture() => await GetJsonAsync($"{Apiurl}/getDefaultCulture"); + public async Task GetDefaultCulture() => await GetJsonAsync($"{Apiurl}/getDefaultCulture"); - public async Task GetSupportedCultures() => await GetJsonAsync($"{Apiurl}/getSupportedCultures"); + public async Task> GetSupportedCultures() + => await GetJsonAsync>($"{Apiurl}/getSupportedCultures"); } } diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 4b0a3acd6..7c3ca1d23 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Themes.Controls @inherits ThemeControlBase -@using System.Globalization +@using System.Globalization +@using Oqtane.Models @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager @@ -13,7 +14,7 @@ @@ -21,7 +22,7 @@ @code{ private string _selectedCulture; - private string[] _supportedCultures; + private IEnumerable _supportedCultures; protected override async Task OnParametersSetAsync() { diff --git a/Oqtane.Server/Controllers/LocalizationController.cs b/Oqtane.Server/Controllers/LocalizationController.cs index f8b7433ac..46e475ef6 100644 --- a/Oqtane.Server/Controllers/LocalizationController.cs +++ b/Oqtane.Server/Controllers/LocalizationController.cs @@ -1,6 +1,9 @@ using System.Collections.Generic; +using System.Globalization; +using System.Linq; using Microsoft.AspNetCore.Mvc; using Oqtane.Infrastructure; +using Oqtane.Models; using Oqtane.Shared; namespace Oqtane.Controllers @@ -17,10 +20,23 @@ public LocalizationController(ILocalizationManager localizationManager) // GET: api/localization/getSupportedCultures [HttpGet("getSupportedCultures")] - public IEnumerable GetSupportedCultures() => _localizationManager.GetSupportedCultures(); + public IEnumerable GetSupportedCultures() + => _localizationManager.GetSupportedCultures().Select(c => new Culture { + Name = CultureInfo.GetCultureInfo(c).Name, + DisplayName = CultureInfo.GetCultureInfo(c).DisplayName + }); // GET api/localization/getDefaultCulture [HttpGet("getDefaultCulture")] - public string GetDefaultCulture() => _localizationManager.GetDefaultCulture(); + public Culture GetDefaultCulture() + { + var culture = _localizationManager.GetDefaultCulture(); + + return new Culture + { + Name = CultureInfo.GetCultureInfo(culture).Name, + DisplayName = CultureInfo.GetCultureInfo(culture).DisplayName + }; + } } } diff --git a/Oqtane.Shared/Models/Culture.cs b/Oqtane.Shared/Models/Culture.cs new file mode 100644 index 000000000..78d249d6b --- /dev/null +++ b/Oqtane.Shared/Models/Culture.cs @@ -0,0 +1,9 @@ +namespace Oqtane.Models +{ + public class Culture + { + public string Name { get; set; } + + public string DisplayName { get; set; } + } +} From 5ee38e4ae753f10f8c146f7aded7174014e315d7 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 14:13:01 +0300 Subject: [PATCH 068/177] Add Visible property to control the visibility --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 7c3ca1d23..c8e7bfb98 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -5,7 +5,7 @@ @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager -@if (_supportedCultures != null) +@if (_supportedCultures != null && Visible) {
} @code{ - private string _selectedCulture; private IEnumerable _supportedCultures; [Parameter] @@ -29,8 +28,6 @@ protected override async Task OnParametersSetAsync() { - var interop = new Interop(JSRuntime); - _selectedCulture = await interop.GetLocalStorage("OqtaneCulture"); _supportedCultures = await LocalizationService.GetCulturesAsync(); } From 20f1a6175fae476760d71df709020e73345411d5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 17:15:08 +0300 Subject: [PATCH 071/177] Use cookie everywhere --- Oqtane.Client/Oqtane.Client.csproj | 1 + Oqtane.Client/Program.cs | 4 ++- .../Themes/Controls/LanguageSwitcher.razor | 6 ++-- Oqtane.Client/UI/Interop.cs | 29 ------------------- .../ApplicationBuilderExtensions.cs | 5 +--- Oqtane.Server/Pages/_Host.cshtml | 8 ----- Oqtane.Server/wwwroot/js/interop.js | 6 ---- 7 files changed, 9 insertions(+), 50 deletions(-) diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj index da11a4722..72024f758 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -31,6 +31,7 @@ + diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index cc85b9b99..4c2d12016 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -10,6 +10,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.DependencyInjection; using Microsoft.JSInterop; using Oqtane.Modules; @@ -94,7 +95,8 @@ public static async Task Main(string[] args) var host = builder.Build(); var jsRuntime = host.Services.GetRequiredService(); var interop = new Interop(jsRuntime); - var culture = await interop.GetLocalStorage("OqtaneCulture"); + var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName); + var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie).UICultures[0].Value; var localizationService = host.Services.GetRequiredService(); var cultures = await localizationService.GetCulturesAsync(); diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index e1d160025..6f748e885 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Themes.Controls @inherits ThemeControlBase -@using System.Globalization +@using System.Globalization +@using Microsoft.AspNetCore.Localization; @using Oqtane.Models @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager @@ -36,7 +37,8 @@ if (culture != CultureInfo.CurrentUICulture.Name) { var interop = new Interop(JSRuntime); - await interop.SetLocalStorage("OqtaneCulture", culture); + var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)); + await interop.SetCookie(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue, 360); NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); } diff --git a/Oqtane.Client/UI/Interop.cs b/Oqtane.Client/UI/Interop.cs index 10c37d44e..3964b070a 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -1,5 +1,4 @@ using Microsoft.JSInterop; -using Oqtane.Models; using System.Threading.Tasks; namespace Oqtane.UI @@ -233,33 +232,5 @@ public Task RedirectBrowser(string url, int wait) return Task.CompletedTask; } } - - public async Task GetLocalStorage(string name) - { - try - { - var value = await _jsRuntime.InvokeAsync("Oqtane.Interop.getLocalStorage", name); - - return value; - } - catch - { - return null; - } - } - - public Task SetLocalStorage(string name, string value) - { - try - { - _jsRuntime.InvokeVoidAsync("Oqtane.Interop.setLocalStorage", name, value); - - return Task.CompletedTask; - } - catch - { - return Task.CompletedTask; - } - } } } diff --git a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs index 67676d160..81ca19ac1 100644 --- a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs @@ -1,5 +1,4 @@ -using System; -using System.Globalization; +using System; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Builder; @@ -31,8 +30,6 @@ public static IApplicationBuilder UseOqtaneLocalization(this IApplicationBuilder var defaultCulture = localizationManager.GetDefaultCulture(); var supportedCultures = localizationManager.GetSupportedCultures(); - CultureInfo.CurrentUICulture = new CultureInfo(defaultCulture); - app.UseRequestLocalization(options => { options.SetDefaultCulture(defaultCulture) .AddSupportedUICultures(supportedCultures) diff --git a/Oqtane.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml index ecf906e4e..cf2d69f08 100644 --- a/Oqtane.Server/Pages/_Host.cshtml +++ b/Oqtane.Server/Pages/_Host.cshtml @@ -1,17 +1,9 @@ @page "/" @namespace Oqtane.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@using System.Globalization -@using Microsoft.AspNetCore.Localization @using Microsoft.Extensions.Configuration @inject IConfiguration Configuration @model Oqtane.Pages.HostModel - -@{ - // Set localization cookie - var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture)); - HttpContext.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue); -} diff --git a/Oqtane.Server/wwwroot/js/interop.js b/Oqtane.Server/wwwroot/js/interop.js index e71f4b81f..2e4092e45 100644 --- a/Oqtane.Server/wwwroot/js/interop.js +++ b/Oqtane.Server/wwwroot/js/interop.js @@ -362,11 +362,5 @@ Oqtane.Interop = { setInterval(function () { window.location.href = url; }, wait * 1000); - }, - getLocalStorage: function (name) { - return window.localStorage[name]; - }, - setLocalStorage: function (name, value) { - window.localStorage[name] = value; } }; From 5e293ee2988fd70cb9d87585cda0f6ce657b62c5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 3 Dec 2020 17:25:01 +0300 Subject: [PATCH 072/177] Fix SupportedCultures bug --- Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs index 81ca19ac1..4f43068e1 100644 --- a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs @@ -32,7 +32,7 @@ public static IApplicationBuilder UseOqtaneLocalization(this IApplicationBuilder app.UseRequestLocalization(options => { options.SetDefaultCulture(defaultCulture) - .AddSupportedUICultures(supportedCultures) + .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); }); From 9f590b32f78fb8f3f84a27720627b1b319bed20b Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 3 Dec 2020 15:19:23 -0500 Subject: [PATCH 073/177] fix #957 related to loading resources within a Settings component --- Oqtane.Client/UI/SiteRouter.razor | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 082e04ee1..667816ab2 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -484,8 +484,19 @@ // get additional metadata from IModuleControl interface if (moduletype != null && module.ModuleType != "") { + // retrieve module component resources var moduleobject = Activator.CreateInstance(moduletype) as IModuleControl; page.Resources = ManagePageResources(page.Resources, moduleobject.Resources); + if (action.ToLower() == "settings" && module.ModuleDefinition != null) + { + // settings components are embedded within a framework settings module + moduletype = Type.GetType(module.ModuleDefinition.ControlTypeTemplate.Replace(Constants.ActionToken, action), false, true); + if (moduletype != null) + { + moduleobject = Activator.CreateInstance(moduletype) as IModuleControl; + page.Resources = ManagePageResources(page.Resources, moduleobject.Resources); + } + } // additional metadata needed for admin components if (module.ModuleId == moduleid && action != "") From 14f8155df63ad2b0616bd556414350081ead6b5f Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Sun, 6 Dec 2020 16:09:46 +0100 Subject: [PATCH 074/177] FileController fix - using PhysicalFile framework method (current implementation causes file locks and 500 error at heavy load) - Add correct mimetype to header based on file extension --- Oqtane.Server/Controllers/FileController.cs | 33 +++++++------------- Oqtane.Server/Extensions/StringExtensions.cs | 14 +++++++++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index fb43a7cb7..5389b423a 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -17,6 +17,7 @@ using Oqtane.Infrastructure; using Oqtane.Repository; using Microsoft.AspNetCore.Routing.Constraints; +using Oqtane.Extensions; // ReSharper disable StringIndexOfIsCultureSpecific.1 @@ -314,9 +315,9 @@ private async Task MergeFile(string folder, string filename) { string merged = ""; - // parse the filename which is in the format of filename.ext.part_x_y + // parse the filename which is in the format of filename.ext.part_x_y string token = ".part_"; - string parts = Path.GetExtension(filename)?.Replace(token, ""); // returns "x_y" + string parts = Path.GetExtension(filename)?.Replace(token, ""); // returns "x_y" int totalparts = int.Parse(parts?.Substring(parts.IndexOf("_") + 1)); filename = Path.GetFileNameWithoutExtension(filename); // base filename @@ -435,45 +436,33 @@ private bool CanAccessFiles(string[] files) [HttpGet("download/{id}")] public IActionResult Download(int id) { - string errorpath = Path.Combine(GetFolderPath("images"), "error.png"); - Models.File file = _files.GetFile(id); + var file = _files.GetFile(id); if (file != null) { if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions)) { - string filepath = Path.Combine(GetFolderPath(file.Folder), file.Name); + var filepath = Path.Combine(GetFolderPath(file.Folder), file.Name); if (System.IO.File.Exists(filepath)) { - var stream = new FileStream(filepath, FileMode.Open); - return File(stream, "application/octet-stream", file.Name); - } - else - { - _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath); - HttpContext.Response.StatusCode = 404; - if (System.IO.File.Exists(errorpath)) - { - var stream = new FileStream(errorpath, FileMode.Open); - return File(stream, "application/octet-stream", file.Name); - } + return PhysicalFile(filepath, file.Name.GetMimeType(), file.Name); } + + _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath); + HttpContext.Response.StatusCode = 404; } else { _logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access File {FileId}", id); HttpContext.Response.StatusCode = 401; - var stream = new FileStream(errorpath, FileMode.Open); - return File(stream, "application/octet-stream", file.Name); } } else { _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id); HttpContext.Response.StatusCode = 404; - var stream = new FileStream(errorpath, FileMode.Open); - return File(stream, "application/octet-stream", file.Name); } - return null; + string errorPath = Path.Combine(GetFolderPath("images"), "error.png"); + return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, errorPath.GetMimeType()) : null; } private string GetFolderPath(Folder folder) diff --git a/Oqtane.Server/Extensions/StringExtensions.cs b/Oqtane.Server/Extensions/StringExtensions.cs index 49b3b2cd7..a2c7c88b7 100644 --- a/Oqtane.Server/Extensions/StringExtensions.cs +++ b/Oqtane.Server/Extensions/StringExtensions.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.StaticFiles; namespace Oqtane.Extensions { @@ -11,7 +12,20 @@ public static bool StartWithAnyOf(this string s, IEnumerable list) { return false; } + return list.Any(f => s.StartsWith(f)); } + + public static string GetMimeType(this string fileName) + { + var provider = new FileExtensionContentTypeProvider(); + + if (!provider.TryGetContentType(fileName, out var contentType)) + { + contentType = "application/octet-stream"; + } + + return contentType; + } } } From 8c9fc952d8eb309e8fcfd01099eaf40f1da890e2 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 6 Dec 2020 19:28:12 +0300 Subject: [PATCH 075/177] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a7477a61..c8cfec4ea 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ 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 ) -- [ ] Complete Static Localization of Admin UI +- [x] Complete Static Localization of Admin UI - [ ] Cross Platform Database Support ( ie. SQLite ) - [ ] EF Core Migrations for Database Installation/Upgrade From b878b3ee2f462607952e5fe4e1d3b272e0d0c940 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 6 Dec 2020 19:51:25 +0300 Subject: [PATCH 076/177] Localize ActionDialog.Text --- Oqtane.Client/Modules/Controls/ActionDialog.razor | 1 + 1 file changed, 1 insertion(+) diff --git a/Oqtane.Client/Modules/Controls/ActionDialog.razor b/Oqtane.Client/Modules/Controls/ActionDialog.razor index ac7e4690b..4770729b2 100644 --- a/Oqtane.Client/Modules/Controls/ActionDialog.razor +++ b/Oqtane.Client/Modules/Controls/ActionDialog.razor @@ -99,6 +99,7 @@ if (IsLocalizable) { + Text = Localize(nameof(Text), Text); Header = Localize(nameof(Header), Header); Message = Localize(nameof(Message), Message); } From 5678a1796a38bd88bb74bb306667eb6f70ff3240 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 6 Dec 2020 21:45:33 +0300 Subject: [PATCH 077/177] Add missing Files localization strings --- Oqtane.Client/Modules/Admin/Files/Add.razor | 4 ++-- Oqtane.Client/Modules/Admin/Files/Edit.razor | 6 +++--- Oqtane.Client/Modules/Admin/Files/Index.razor | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Files/Add.razor b/Oqtane.Client/Modules/Admin/Files/Add.razor index df16cac80..33633fe03 100644 --- a/Oqtane.Client/Modules/Admin/Files/Add.razor +++ b/Oqtane.Client/Modules/Admin/Files/Add.razor @@ -7,7 +7,7 @@ @inject IStringLocalizer Localizer - + - + @@ -47,7 +47,7 @@ @if (_files.Count == 0) { -
@Localizer["No Files Exist In Selected Folder"]
+
@Localizer["No Files Exist In Selected Folder"]
} } From 5e49206828d17fdb76a54b1106a30ffa4d9582a6 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 6 Dec 2020 21:46:03 +0300 Subject: [PATCH 078/177] Add FileManager localization strings --- Oqtane.Client/Modules/Controls/FileManager.razor | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/FileManager.razor b/Oqtane.Client/Modules/Controls/FileManager.razor index 291b2acb5..e1c4b3f9c 100644 --- a/Oqtane.Client/Modules/Controls/FileManager.razor +++ b/Oqtane.Client/Modules/Controls/FileManager.razor @@ -1,7 +1,8 @@ -@namespace Oqtane.Modules.Controls +@namespace Oqtane.Modules.Controls @inherits ModuleControlBase @inject IFolderService FolderService @inject IFileService FileService +@inject IStringLocalizer Localizer @if (_folders != null) { @@ -14,7 +15,7 @@ - + @foreach (File file in _files) { if (file.FileId == FileId) @@ -62,10 +63,10 @@ } - + @if (ShowFiles && GetFileId() != -1) { - + } From f0f30558699f387a1224f60a6d05069cd24755d5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 6 Dec 2020 21:46:19 +0300 Subject: [PATCH 079/177] Add PermissionGrid localization strings --- Oqtane.Client/Modules/Controls/PermissionGrid.razor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/PermissionGrid.razor b/Oqtane.Client/Modules/Controls/PermissionGrid.razor index 000f54be6..d11b07950 100644 --- a/Oqtane.Client/Modules/Controls/PermissionGrid.razor +++ b/Oqtane.Client/Modules/Controls/PermissionGrid.razor @@ -13,7 +13,7 @@ @foreach (PermissionString permission in _permissions) { - + } @foreach (Role role in _roles) @@ -39,7 +39,7 @@ @foreach (PermissionString permission in _permissions) { - + } @@ -65,7 +65,7 @@ From 35e776b15020f1158fe694f999fbef19db7d015d Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Mon, 7 Dec 2020 21:27:00 +0100 Subject: [PATCH 080/177] Fix - return to url during login fail when returnurl contains "/" --- Oqtane.Client/Themes/Controls/LoginBase.cs | 2 +- Oqtane.Client/UI/SiteRouter.razor | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/LoginBase.cs b/Oqtane.Client/Themes/Controls/LoginBase.cs index ed9eb2890..27f434974 100644 --- a/Oqtane.Client/Themes/Controls/LoginBase.cs +++ b/Oqtane.Client/Themes/Controls/LoginBase.cs @@ -22,7 +22,7 @@ protected void LoginUser() { returnurl += "/" + PageState.Page.Path; } - NavigationManager.NavigateTo(NavigateUrl("login", "returnurl=" + returnurl)); + NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + returnurl)); } protected async Task LogoutUser() diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 667816ab2..469a0a7b9 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -300,7 +300,7 @@ if (user == null) { // redirect to login page - NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "login", "returnurl=" + path)); + NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "login", "?returnurl=" + path)); } else { @@ -565,4 +565,4 @@ => RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")) ? Oqtane.Shared.Runtime.WebAssembly : Oqtane.Shared.Runtime.Server; -} \ No newline at end of file +} From 87ba77fdba3fa8ab3edafd537708de21c30fc1ea Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 13:43:05 +0300 Subject: [PATCH 081/177] Localize AuditInfo --- .../Modules/Controls/AuditInfo.razor | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/AuditInfo.razor b/Oqtane.Client/Modules/Controls/AuditInfo.razor index 026a29869..aa2cf7904 100644 --- a/Oqtane.Client/Modules/Controls/AuditInfo.razor +++ b/Oqtane.Client/Modules/Controls/AuditInfo.razor @@ -1,5 +1,6 @@ @namespace Oqtane.Modules.Controls @inherits ModuleControlBase +@inject IStringLocalizer Localizer @if (_text != string.Empty) { @@ -39,16 +40,16 @@ _text = string.Empty; if (!String.IsNullOrEmpty(CreatedBy) || CreatedOn.HasValue) { - _text += "

Created "; + _text += $"

{Localizer["Created"]} "; if (!String.IsNullOrEmpty(CreatedBy)) { - _text += " by " + CreatedBy + ""; + _text += $" {Localizer["by"]} {CreatedBy}"; } if (CreatedOn != null) { - _text += " on " + CreatedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + ""; + _text += $" {Localizer["on"]} {CreatedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}"; } _text += "

"; @@ -56,16 +57,16 @@ if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn.HasValue) { - _text += "

Last modified "; + _text += $"

{Localizer["Last modified"]} "; if (!String.IsNullOrEmpty(ModifiedBy)) { - _text += " by " + ModifiedBy + ""; + _text += $" {Localizer["by"]} {ModifiedBy}"; } if (ModifiedOn != null) { - _text += " on " + ModifiedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + ""; + _text += $" {Localizer["on"]} {ModifiedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}"; } _text += "

"; @@ -73,16 +74,16 @@ if (!String.IsNullOrEmpty(DeletedBy) || DeletedOn.HasValue) { - _text += "

Deleted "; + _text += $"

{Localizer["Deleted"]} "; if (!String.IsNullOrEmpty(DeletedBy)) { - _text += " by " + DeletedBy + ""; + _text += $" {Localizer["by"]} {DeletedBy}"; } if (DeletedOn != null) { - _text += " on " + DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + ""; + _text += $" {Localizer["on"]} {DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}"; } _text += "

"; From e0087c1dbba79c3729e5d85d4f1fb111ac59b7d5 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 14:37:54 +0300 Subject: [PATCH 082/177] Add missing Jobs localization strings --- Oqtane.Client/Modules/Admin/Jobs/Index.razor | 20 ++++++++++---------- Oqtane.Client/Modules/Admin/Jobs/Log.razor | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index ffd32c17e..f2a02c75c 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -28,7 +28,7 @@ else
- + @@ -63,17 +63,17 @@ else var status = string.Empty; if (!isEnabled) { - status = "Disabled"; + status = Localizer["Disabled"]; } else { if (isExecuting) { - status = "Executing"; + status = Localizer["Executing"]; } else { - status = "Idle"; + status = Localizer["Idle"]; } } @@ -83,26 +83,26 @@ else private string DisplayFrequency(int interval, string frequency) { - var result = "Every " + interval.ToString() + " "; + var result = $"{Localizer["Every"]} {interval.ToString()} "; switch (frequency) { case "m": - result += "Minute"; + result += Localizer["Minute"]; break; case "H": - result += "Hour"; + result += Localizer["Hour"]; break; case "d": - result += "Day"; + result += Localizer["Day"]; break; case "M": - result += "Month"; + result += Localizer["Month"]; break; } if (interval > 1) { - result += "s"; + result += Localizer["s"]; } return result; diff --git a/Oqtane.Client/Modules/Admin/Jobs/Log.razor b/Oqtane.Client/Modules/Admin/Jobs/Log.razor index f5d8a391c..b0049db77 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Log.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Log.razor @@ -50,17 +50,17 @@ else var status = string.Empty; if (isExecuting) { - status = "Executing"; + status = Localizer["Executing"]; } else { if (succeeded != null && succeeded.Value) { - status = "Succeeded"; + status = Localizer["Succeeded"]; } else { - status = "Failed"; + status = Localizer["Failed"]; } } From 055ae26bc16e27bfd4a9a54f2a973a519c422034 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 14:41:03 +0300 Subject: [PATCH 083/177] Add missing Logs localization strings --- Oqtane.Client/Modules/Admin/Logs/Index.razor | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index 59830a0d4..a0ea8b04c 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -14,13 +14,13 @@ else - + - + @@ -52,7 +52,7 @@ - + From df1d64608368d350f4748e31321246eebb4fea41 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 16:37:55 +0300 Subject: [PATCH 085/177] Refactor LocalizableComponent --- .../Modules/Controls/ActionDialog.razor | 9 ++-- .../Modules/Controls/ActionLink.razor | 6 +-- Oqtane.Client/Modules/Controls/Label.razor | 4 +- .../Modules/Controls/LocalizableComponent.cs | 46 ++++++++----------- Oqtane.Client/Modules/Controls/Section.razor | 9 ++-- Oqtane.Client/Modules/Controls/TabPanel.razor | 15 +++--- 6 files changed, 33 insertions(+), 56 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/ActionDialog.razor b/Oqtane.Client/Modules/Controls/ActionDialog.razor index 4770729b2..73723fa56 100644 --- a/Oqtane.Client/Modules/Controls/ActionDialog.razor +++ b/Oqtane.Client/Modules/Controls/ActionDialog.razor @@ -97,12 +97,9 @@ _iconSpan = $" "; } - if (IsLocalizable) - { - Text = Localize(nameof(Text), Text); - Header = Localize(nameof(Header), Header); - Message = Localize(nameof(Message), Message); - } + Text = Localize(nameof(Text), Text); + Header = Localize(nameof(Header), Header); + Message = Localize(nameof(Message), Message); _authorized = IsAuthorized(); } diff --git a/Oqtane.Client/Modules/Controls/ActionLink.razor b/Oqtane.Client/Modules/Controls/ActionLink.razor index eacc98133..1ba9ef12b 100644 --- a/Oqtane.Client/Modules/Controls/ActionLink.razor +++ b/Oqtane.Client/Modules/Controls/ActionLink.razor @@ -95,11 +95,7 @@ } - if (IsLocalizable) - { - _text = Localize(nameof(Text), _text); - } - + _text = Localize(nameof(Text), _text); _url = EditUrl(Action, _parameters); _authorized = IsAuthorized(); } diff --git a/Oqtane.Client/Modules/Controls/Label.razor b/Oqtane.Client/Modules/Controls/Label.razor index 85e65d14e..05f2b7901 100644 --- a/Oqtane.Client/Modules/Controls/Label.razor +++ b/Oqtane.Client/Modules/Controls/Label.razor @@ -45,11 +45,11 @@ else if (IsLocalizable) { - var value = Localize("Text"); var key = $"{ResourceKey}.Text"; + var value = Localize(key); if (!value.Equals(key)) { - ChildContent =@@Localize("Text"); + ChildContent =@@value; } HelpText = Localize(nameof(HelpText), HelpText); diff --git a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs index 657494d77..40f2eda55 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -15,27 +15,22 @@ public class LocalizableComponent : ModuleControlBase protected bool IsLocalizable { get; private set; } - protected string Localize(string name) - { - var key = $"{ResourceKey}.{name}"; + protected string Localize(string name) => _localizer?[name] ?? name; - // TODO: we should have a ShowMissingResourceKeys option which developers/translators can enable to find missing translations which would display the key rather than the name + protected string Localize(string propertyName, string propertyValue) + { if (!IsLocalizable) { - return name; + return propertyValue; } - return _localizer?[key] ?? name; - } - - protected string Localize(string name, string defaultValue) - { - var key = $"{ResourceKey}.{name}"; - var value = Localize(name); + var key = $"{ResourceKey}.{propertyName}"; + var value = Localize(key); if (value == key) { - return defaultValue; + // Returns default property value (English version) instead of ResourceKey.PropertyName + return propertyValue; } else { @@ -45,26 +40,21 @@ protected string Localize(string name, string defaultValue) protected override void OnParametersSet() { - if (!String.IsNullOrEmpty(ResourceKey)) + IsLocalizable = false; + + if (!String.IsNullOrEmpty(ResourceKey) && ModuleState?.ModuleType != null) { - if (ModuleState?.ModuleType != null) + var moduleType = Type.GetType(ModuleState.ModuleType); + if (moduleType != null) { - var moduleType = Type.GetType(ModuleState.ModuleType); - if (moduleType != null) + using (var scope = ServiceActivator.GetScope()) { - using (var scope = ServiceActivator.GetScope()) - { - var localizerFactory = scope.ServiceProvider.GetService(); - _localizer = localizerFactory.Create(moduleType); - } + var localizerFactory = scope.ServiceProvider.GetService(); + _localizer = localizerFactory.Create(moduleType); + + IsLocalizable = true; } } - - IsLocalizable = true; - } - else - { - IsLocalizable = false; } } } diff --git a/Oqtane.Client/Modules/Controls/Section.razor b/Oqtane.Client/Modules/Controls/Section.razor index fd8b9a521..027b0e854 100644 --- a/Oqtane.Client/Modules/Controls/Section.razor +++ b/Oqtane.Client/Modules/Controls/Section.razor @@ -46,11 +46,8 @@ { base.OnParametersSet(); - if (IsLocalizable) - { - _heading = !string.IsNullOrEmpty(Heading) - ? Localize(nameof(Heading), Heading) - : Localize(nameof(Name), Name); - } + _heading = !string.IsNullOrEmpty(Heading) + ? Localize(nameof(Heading), Heading) + : Localize(nameof(Name), Name); } } diff --git a/Oqtane.Client/Modules/Controls/TabPanel.razor b/Oqtane.Client/Modules/Controls/TabPanel.razor index 7c2eaa243..e618c8965 100644 --- a/Oqtane.Client/Modules/Controls/TabPanel.razor +++ b/Oqtane.Client/Modules/Controls/TabPanel.razor @@ -40,16 +40,13 @@ else { base.OnParametersSet(); - if (IsLocalizable) + if (string.IsNullOrEmpty(Heading)) { - if (string.IsNullOrEmpty(Heading)) - { - Name = Localize(nameof(Name), Name); - } - else - { - Heading = Localize(nameof(Heading), Heading); - } + Name = Localize(nameof(Name), Name); + } + else + { + Heading = Localize(nameof(Heading), Heading); } } From 5ce7284a6b1c06d6806af98f669c6562e8dd7bf8 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 16:45:53 +0300 Subject: [PATCH 086/177] Returns English version if the value is empty --- Oqtane.Client/Modules/Controls/LocalizableComponent.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs index 40f2eda55..773df857e 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -34,7 +34,15 @@ protected string Localize(string propertyName, string propertyValue) } else { - return value; + if (value == String.Empty) + { + // Returns default property value (English version) + return propertyValue; + } + else + { + return value; + } } } From 299e28abc46b7e6f19ff919b1bb687188a352fdc Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 20:40:54 +0300 Subject: [PATCH 087/177] Avoid Label.Text to be empty --- Oqtane.Client/Modules/Controls/Label.razor | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/Label.razor b/Oqtane.Client/Modules/Controls/Label.razor index 05f2b7901..b67143cb4 100644 --- a/Oqtane.Client/Modules/Controls/Label.razor +++ b/Oqtane.Client/Modules/Controls/Label.razor @@ -43,16 +43,12 @@ else _openLabel += ">"; - if (IsLocalizable) + var text = Localize("Text", String.Empty); + if (text != String.Empty) { - var key = $"{ResourceKey}.Text"; - var value = Localize(key); - if (!value.Equals(key)) - { - ChildContent =@@value; - } - - HelpText = Localize(nameof(HelpText), HelpText); + ChildContent =@@text; } + + HelpText = Localize(nameof(HelpText), HelpText); } } From 29c37575f1d3e5467bb83c1138ffafcadbecfede Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 20:45:54 +0300 Subject: [PATCH 088/177] Add missing Roles localization strings --- Oqtane.Client/Modules/Admin/Roles/Index.razor | 2 +- Oqtane.Client/Modules/Admin/Roles/Users.razor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Roles/Index.razor b/Oqtane.Client/Modules/Admin/Roles/Index.razor index 6344925db..b221904d7 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Index.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Index.razor @@ -20,7 +20,7 @@ else - + diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor index ecd7cb911..a4b409216 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Users.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -25,7 +25,7 @@ else - + From 0e95e94cab868a3855df9a618dd7e37d47a1a2a8 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 20:50:14 +0300 Subject: [PATCH 090/177] Add missing Sql localization strings --- Oqtane.Client/Modules/Admin/Sql/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Sql/Index.razor b/Oqtane.Client/Modules/Admin/Sql/Index.razor index 69191bab5..c003d1b4a 100644 --- a/Oqtane.Client/Modules/Admin/Sql/Index.razor +++ b/Oqtane.Client/Modules/Admin/Sql/Index.razor @@ -105,7 +105,7 @@ else } else { - table = "No Results Returned"; + table = Localizer["No Results Returned"]; } return table; From 836ba5eeb951aa044941c609a4213f707b394267 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 20:55:28 +0300 Subject: [PATCH 091/177] Add missing Tenanat localization strings --- Oqtane.Client/Modules/Admin/Tenants/Index.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Tenants/Index.razor b/Oqtane.Client/Modules/Admin/Tenants/Index.razor index fda4c3a47..bf27d99f7 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Index.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Index.razor @@ -18,7 +18,7 @@ else - + From 2d15f5d185a8cab2f122dd8364e28d63869ea6dc Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 20:55:38 +0300 Subject: [PATCH 092/177] Add missing Themes localization strings --- Oqtane.Client/Modules/Admin/Themes/Index.razor | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 8b64bff86..8d27b057d 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -26,17 +26,17 @@ else From c27e8b55dfd088f3c97fc9bec86e98e64d883bde Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 21:16:37 +0300 Subject: [PATCH 093/177] Add missing Users localization strings --- Oqtane.Client/Modules/Admin/Users/Add.razor | 2 +- Oqtane.Client/Modules/Admin/Users/Index.razor | 2 +- Oqtane.Client/Modules/Admin/Users/Roles.razor | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Users/Add.razor b/Oqtane.Client/Modules/Admin/Users/Add.razor index d669f678b..15c14bce6 100644 --- a/Oqtane.Client/Modules/Admin/Users/Add.razor +++ b/Oqtane.Client/Modules/Admin/Users/Add.razor @@ -14,7 +14,7 @@ + diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor index 8087f2bf8..8ac788eea 100644 --- a/Oqtane.Client/Modules/Admin/Users/Index.razor +++ b/Oqtane.Client/Modules/Admin/Users/Index.razor @@ -31,7 +31,7 @@ else + + + + + + + + + +} + +@code { + private List _languages; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + + protected override async Task OnParametersSetAsync() + { + _languages = await LanguageService.GetLanguagesAsync(PageState.Site.SiteId); + } + + private async Task DeleteLanguage(Language language) + { + try + { + await LanguageService.DeleteLanguageAsync(language.LanguageId); + await logger.LogInformation("Language Deleted {Language}", language); + + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Deleting Language {Language} {Error}", language, ex.Message); + + AddModuleMessage(Localizer["Error Deleting Language"], MessageType.Error); + } + } +} diff --git a/Oqtane.Server/Repository/SiteRepository.cs b/Oqtane.Server/Repository/SiteRepository.cs index d8df82b63..647914422 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -502,6 +502,33 @@ private List CreateAdminPages(List pageTemplates = n } }); pageTemplates.Add(new PageTemplate + { + Name = "Language Management", + Parent = "Admin", + Path = "admin/languages", + Icon = Icons.Text, + IsNavigation = false, + IsPersonalizable = false, + PagePermissions = new List + { + new Permission(PermissionNames.View, RoleNames.Host, true), + new Permission(PermissionNames.Edit, RoleNames.Host, true) + }.EncodePermissions(), + PageTemplateModules = new List + { + new PageTemplateModule + { + ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Languages.Index).ToModuleDefinitionName(), Title = "Language Management", Pane = "Content", + ModulePermissions = new List + { + new Permission(PermissionNames.View, RoleNames.Host, true), + new Permission(PermissionNames.Edit, RoleNames.Host, true) + }.EncodePermissions(), + Content = "" + } + } + }); + pageTemplates.Add(new PageTemplate { Name = "Scheduled Jobs", Parent = "Admin", Path = "admin/jobs", Icon = Icons.Timer, IsNavigation = false, IsPersonalizable = false, PagePermissions = new List diff --git a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql index 8eb6eef3e..a52e80229 100644 --- a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql +++ b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql @@ -8,6 +8,7 @@ CREATE TABLE [dbo].[Language]( [LanguageId] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](100) NOT NULL, [Code] [nvarchar](10) NOT NULL, + [IsCurrent] [bit] NOT NULL, [TenantId] [int], [CreatedBy] [nvarchar](256) NOT NULL, [CreatedOn] [datetime] NOT NULL, From 8ab511fda773aad2ed4958485798ae891a7355ae Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 23:17:35 +0300 Subject: [PATCH 125/177] Return empty list if languages list are null --- Oqtane.Client/Services/LanguageService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Services/LanguageService.cs b/Oqtane.Client/Services/LanguageService.cs index da1e0342b..5f5d29cb4 100644 --- a/Oqtane.Client/Services/LanguageService.cs +++ b/Oqtane.Client/Services/LanguageService.cs @@ -23,7 +23,7 @@ public async Task> GetLanguagesAsync(int siteId) { var languages = await GetJsonAsync>($"{Apiurl}?siteid={siteId}"); - return languages.OrderBy(l => l.Name).ToList(); + return languages?.OrderBy(l => l.Name).ToList() ?? Enumerable.Empty().ToList(); } public async Task GetLanguageAsync(int languageId) From 70595eb90ab04a77789045cc00b8a455bf80df12 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 23:50:21 +0300 Subject: [PATCH 126/177] Fix Language table --- Oqtane.Server/Repository/Context/TenantDBContext.cs | 2 +- Oqtane.Server/Repository/LanguageRepository.cs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Oqtane.Server/Repository/Context/TenantDBContext.cs b/Oqtane.Server/Repository/Context/TenantDBContext.cs index 79270ffb1..d6fd06c4e 100644 --- a/Oqtane.Server/Repository/Context/TenantDBContext.cs +++ b/Oqtane.Server/Repository/Context/TenantDBContext.cs @@ -21,7 +21,7 @@ public class TenantDBContext : DBContextBase public virtual DbSet Folder { get; set; } public virtual DbSet File { get; set; } - public virtual DbSet Languages { get; set; } + public virtual DbSet Language { get; set; } public TenantDBContext(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor) { diff --git a/Oqtane.Server/Repository/LanguageRepository.cs b/Oqtane.Server/Repository/LanguageRepository.cs index 2f59a0471..bdfd1b3eb 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -13,22 +13,22 @@ public LanguageRepository(TenantDBContext context) _db = context; } - public IEnumerable GetLanguages(int siteId) => _db.Languages.Where(l => l.SiteId == siteId); + public IEnumerable GetLanguages(int siteId) => _db.Language.Where(l => l.SiteId == siteId); public Language AddLanguage(Language language) { - _db.Languages.Add(language); + _db.Language.Add(language); _db.SaveChanges(); return language; } - public Language GetLanguage(int languageId) => _db.Languages.Find(languageId); + public Language GetLanguage(int languageId) => _db.Language.Find(languageId); public void DeleteLanguage(int languageId) { - var language = _db.Languages.Find(languageId); - _db.Languages.Remove(language); + var language = _db.Language.Find(languageId); + _db.Language.Remove(language); _db.SaveChanges(); } } From 128729d4a09d3f0f048ff93d30a75a0cd8206cfb Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 23:50:34 +0300 Subject: [PATCH 127/177] TenantId -> SiteId --- Oqtane.Server/Scripts/Tenant.02.00.02.00.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql index a52e80229..8eb547142 100644 --- a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql +++ b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql @@ -9,7 +9,7 @@ CREATE TABLE [dbo].[Language]( [Name] [nvarchar](100) NOT NULL, [Code] [nvarchar](10) NOT NULL, [IsCurrent] [bit] NOT NULL, - [TenantId] [int], + [SiteId] [int], [CreatedBy] [nvarchar](256) NOT NULL, [CreatedOn] [datetime] NOT NULL, [ModifiedBy] [nvarchar](256) NOT NULL, @@ -21,7 +21,7 @@ CREATE TABLE [dbo].[Language]( ) GO -ALTER TABLE [dbo].[Language] WITH CHECK ADD CONSTRAINT [FK_Language_Tenant] FOREIGN KEY([TenantId]) +ALTER TABLE [dbo].[Language] WITH CHECK ADD CONSTRAINT [FK_Language_Tenant] FOREIGN KEY([SiteId]) REFERENCES [dbo].[Tenant] ([TenantId]) ON DELETE CASCADE GO \ No newline at end of file From 7d090e51a12d00f9b6573ba0adf9b754ecaa6b78 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 23:51:15 +0300 Subject: [PATCH 128/177] Add language page --- .../Modules/Admin/Languages/Add.razor | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 Oqtane.Client/Modules/Admin/Languages/Add.razor diff --git a/Oqtane.Client/Modules/Admin/Languages/Add.razor b/Oqtane.Client/Modules/Admin/Languages/Add.razor new file mode 100644 index 000000000..baa287e53 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Languages/Add.razor @@ -0,0 +1,72 @@ +@namespace Oqtane.Modules.Admin.Languages +@inherits ModuleBase +@using System.Globalization +@inject NavigationManager NavigationManager +@inject ILanguageService LanguageService +@inject IStringLocalizer Localizer + +
@@ -38,7 +38,7 @@ @if (PageState.QueryString.ContainsKey("id")) { - + } @foreach (Folder folder in _folders) { @@ -44,10 +44,10 @@ { } - Cancel + @Localizer["Cancel"] @if (!_isSystem && PageState.QueryString.ContainsKey("id")) { - + }

diff --git a/Oqtane.Client/Modules/Admin/Files/Index.razor b/Oqtane.Client/Modules/Admin/Files/Index.razor index bff903881..82da2bb75 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -38,7 +38,7 @@
@context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"]@Localizer["Role"]@permission.PermissionName@Localizer[permission.PermissionName]
@Localizer["User"]@permission.PermissionName@Localizer[permission.PermissionName]
- +
@context.Name @DisplayStatus(context.IsEnabled, context.IsExecuting) From f123ac89ef68c352f03e15c7a716d4a686252a82 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 15:08:21 +0300 Subject: [PATCH 084/177] Add missing RecylceBin localization strings --- Oqtane.Client/Modules/Admin/RecycleBin/Index.razor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor index beaa74c14..15725daa5 100644 --- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor +++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor @@ -19,13 +19,13 @@
   Name@Localizer["Name"] @Localizer["Deleted By"] @Localizer["Deleted On"] @context.Name @context.DeletedBy @context.DeletedOn @PageState.Pages.Find(item => item.PageId == context.PageId).Name @context.Title @context.DeletedBy @context.Name @context.Name @context.Name @if (context.AssemblyName != "Oqtane.Client") - { - - } + { + + } @context.Name @context.Version @if (UpgradeAvailable(context.ThemeName, context.Version)) - { - - } + { + + }
- - + diff --git a/Oqtane.Client/Modules/Admin/Users/Roles.razor b/Oqtane.Client/Modules/Admin/Users/Roles.razor index 922298298..b59883158 100644 --- a/Oqtane.Client/Modules/Admin/Users/Roles.razor +++ b/Oqtane.Client/Modules/Admin/Users/Roles.razor @@ -14,7 +14,7 @@ else - + @@ -181,7 +181,7 @@ else - + diff --git a/Oqtane.Client/Modules/Admin/UserProfile/View.razor b/Oqtane.Client/Modules/Admin/UserProfile/View.razor index 316b17ea1..c9ec1c61b 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/View.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/View.razor @@ -10,7 +10,7 @@
- + @@ -26,7 +26,7 @@ else
- + From 62f60825255c8d130cad638f220b8c6ba5730094 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 21:23:03 +0300 Subject: [PATCH 094/177] Localize TriStateCheckBox control --- Oqtane.Client/Modules/Controls/TriStateCheckBox.razor | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor b/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor index 845db70be..26991f37b 100644 --- a/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor +++ b/Oqtane.Client/Modules/Controls/TriStateCheckBox.razor @@ -1,5 +1,6 @@ -@namespace Oqtane.Modules.Controls +@namespace Oqtane.Modules.Controls @inherits ModuleControlBase +@inject IStringLocalizer Localizer @@ -51,11 +52,11 @@ { case true: _src = "images/checked.png"; - _title = "Permission Granted"; + _title = Localizer["Permission Granted"]; break; case false: _src = "images/unchecked.png"; - _title = "Permission Denied"; + _title = Localizer["Permission Denied"]; break; case null: _src = "images/null.png"; From 169a4b00a449fabfb8c23295f4255b36d60f5208 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 22:45:20 +0300 Subject: [PATCH 095/177] Add missing FileManager localization strings --- Oqtane.Client/Modules/Controls/FileManager.razor | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/FileManager.razor b/Oqtane.Client/Modules/Controls/FileManager.razor index e1c4b3f9c..f46502027 100644 --- a/Oqtane.Client/Modules/Controls/FileManager.razor +++ b/Oqtane.Client/Modules/Controls/FileManager.razor @@ -220,7 +220,7 @@ { await logger.LogError(ex, "Error Loading Files {Error}", ex.Message); - _message = "Error Loading Files"; + _message = Localizer["Error Loading Files"]; _messagetype = MessageType.Error; } } @@ -279,7 +279,7 @@ { await logger.LogInformation("File Upload Succeeded {Files}", upload); - _message = "File Upload Succeeded"; + _message = Localizer["File Upload Succeeded"]; _messagetype = MessageType.Success; await GetFiles(); @@ -299,7 +299,7 @@ { await logger.LogError("File Upload Failed For {Files}", result.Replace(",", ", ")); - _message = "File Upload Failed"; + _message = Localizer["File Upload Failed"]; _messagetype = MessageType.Error; } } @@ -307,13 +307,13 @@ { await logger.LogError(ex, "File Upload Failed {Error}", ex.Message); - _message = "File Upload Failed"; + _message = Localizer["File Upload Failed"]; _messagetype = MessageType.Error; } } else { - _message = "You Have Not Selected A File To Upload"; + _message = Localizer["You Have Not Selected A File To Upload"]; _messagetype = MessageType.Warning; } } @@ -326,7 +326,7 @@ await FileService.DeleteFileAsync(FileId); await logger.LogInformation("File Deleted {File}", FileId); - _message = "File Deleted"; + _message = Localizer["File Deleted"]; _messagetype = MessageType.Success; await GetFiles(); @@ -338,7 +338,7 @@ { await logger.LogError(ex, "Error Deleting File {File} {Error}", FileId, ex.Message); - _message = "Error Deleting File"; + _message = Localizer["Error Deleting File"]; _messagetype = MessageType.Error; } } From c35b5d861adb192ff6d342e4b64a17f4b4420b51 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 22:46:28 +0300 Subject: [PATCH 096/177] Add missing User Profile localization strings --- Oqtane.Client/Modules/Admin/UserProfile/Index.razor | 4 ++-- Oqtane.Client/Modules/Admin/UserProfile/View.razor | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor index 0435b2b1f..a5ca73276 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor @@ -149,7 +149,7 @@ else @context.FromDisplayName @context.Subject @context.CreatedOn @context.ToDisplayName @context.Subject @context.CreatedOn
@if (title == "From") { From 3caf06d8ffe38247c8ff0703dfe1300793e2bccf Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 22:50:36 +0300 Subject: [PATCH 097/177] Add Content folder to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8f8f91bac..d47b8dcfb 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ Oqtane.Server/Data/*.mdf Oqtane.Server/Data/*.ldf /Oqtane.Server/Properties/PublishProfiles/FolderProfile.pubxml +Oqtane.Server/Content From 941d08f0a2b3d872689c2ae59bc9a56d0fa9e663 Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 8 Dec 2020 22:57:58 +0300 Subject: [PATCH 098/177] Add missing Control Panel localization strings --- Oqtane.Client/Themes/Controls/ControlPanel.razor | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 0ea20a8ac..c1ba3e542 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -398,17 +398,17 @@ await PageModuleService.AddPageModuleAsync(pageModule); await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane); - Message = "
Module Added To Page
"; + Message = $"
{Localizer["Module Added To Page"]}
"; NavigationManager.NavigateTo(NavigateUrl()); } else { - Message = "
You Must Select A Module
"; + Message = $"
{Localizer["You Must Select A Module"]}
"; } } else { - Message = "
Not Authorized
"; + Message = $"
{Localizer["Not Authorized"]}
"; } } From dd89296713396b0a2c7ea2284cc593a77e93b5b1 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 9 Dec 2020 17:47:49 +0300 Subject: [PATCH 099/177] Replace Visible with ShowLanguageSwitcher property --- Oqtane.Client/Themes/Controls/ControlPanel.razor | 16 +++++++++++----- .../Themes/Controls/LanguageSwitcher.razor | 5 +---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 0ea20a8ac..d38db7de2 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -9,7 +9,7 @@ @inject IPageModuleService PageModuleService @inject ILogService logger @inject ISettingService SettingService -@inject IStringLocalizer Localizer +@inject IStringLocalizer Localizer @if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) { @@ -198,7 +198,10 @@ } - +@if (ShowLanguageSwitcher) +{ + +} @if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null)) { @@ -289,6 +292,9 @@ [Parameter] public string BodyClass { get; set; } = "card-body"; + [Parameter] + public bool ShowLanguageSwitcher { get; set; } = true; + protected override async Task OnInitializedAsync() { @@ -316,12 +322,12 @@ private void CategoryChanged(ChangeEventArgs e) { - Category = (string) e.Value; + Category = (string)e.Value; } private void ModuleChanged(ChangeEventArgs e) { - ModuleDefinitionName = (string) e.Value; + ModuleDefinitionName = (string)e.Value; if (ModuleDefinitionName != "-") { var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName); @@ -337,7 +343,7 @@ private void PageChanged(ChangeEventArgs e) { - PageId = (string) e.Value; + PageId = (string)e.Value; if (PageId != "-") { _modules = PageState.Modules diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 6f748e885..4dca37bc0 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -6,7 +6,7 @@ @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager -@if (_supportedCultures != null && Visible) +@if (_supportedCultures != null) {
- +
@Localizer["Access Framework API"]  - + @code { public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; diff --git a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor index 34f58934b..247b338ab 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor @@ -56,7 +56,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Loading Tenant {TenantId} {Error}", tenantid, ex.Message); - AddModuleMessage("Error Loading Tenant", MessageType.Error); + AddModuleMessage(Localizer["Error Loading Tenant"], MessageType.Error); } } @@ -80,7 +80,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Saving Tenant {TenantId} {Error}", tenantid, ex.Message); - AddModuleMessage("Error Saving Tenant", MessageType.Error); + AddModuleMessage(Localizer["Error Saving Tenant"], MessageType.Error); } } } diff --git a/Oqtane.Client/Modules/Admin/Tenants/Index.razor b/Oqtane.Client/Modules/Admin/Tenants/Index.razor index bf27d99f7..2aa70ecb6 100644 --- a/Oqtane.Client/Modules/Admin/Tenants/Index.razor +++ b/Oqtane.Client/Modules/Admin/Tenants/Index.razor @@ -56,13 +56,13 @@ else } else { - AddModuleMessage("Tenant Cannot Be Deleted Until The Following Sites Are Deleted: " + message.Substring(2), MessageType.Warning); + AddModuleMessage(Localizer["Tenant Cannot Be Deleted Until The Following Sites Are Deleted: {0}", message.Substring(2)], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Deleting Tenant {Tenant} {Error}", Tenant, ex.Message); - AddModuleMessage("Error Deleting Tenant", MessageType.Error); + AddModuleMessage(Localizer["Error Deleting Tenant"], MessageType.Error); } } } \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/Themes/Add.razor b/Oqtane.Client/Modules/Admin/Themes/Add.razor index fa896dd42..ab042ed5c 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Add.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Add.razor @@ -70,7 +70,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message); - AddModuleMessage("Error Loading Packages", MessageType.Error); + AddModuleMessage(Localizer["Error Loading Packages"], MessageType.Error); } } @@ -79,7 +79,7 @@ try { await ThemeService.InstallThemesAsync(); - AddModuleMessage("Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); + AddModuleMessage(Localizer["Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); } catch (Exception ex) { @@ -93,13 +93,13 @@ { await PackageService.DownloadPackageAsync(packageid, version, "Themes"); await logger.LogInformation("Theme {ThemeName} {Version} Downloaded Successfully", packageid, version); - AddModuleMessage("Themes Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success); + AddModuleMessage(Localizer["Themes Downloaded Successfully. Click Install To Complete Installation."], MessageType.Success); StateHasChanged(); } catch (Exception ex) { await logger.LogError(ex, "Error Downloading Module {ThemeName} {Version}", packageid, version); - AddModuleMessage("Error Downloading Theme", MessageType.Error); + AddModuleMessage(Localizer["Error Downloading Theme"], MessageType.Error); } } } diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 8d27b057d..816bd06f8 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -61,7 +61,7 @@ else if (_themes == null) { await logger.LogError(ex, "Error Loading Themes {Error}", ex.Message); - AddModuleMessage("Error Loading Themes", MessageType.Error); + AddModuleMessage(Localizer["Error Loading Themes"], MessageType.Error); } } } @@ -87,12 +87,12 @@ else await PackageService.DownloadPackageAsync(themename, version, "Themes"); await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version); await ThemeService.InstallThemesAsync(); - AddModuleMessage("Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); + AddModuleMessage(Localizer["Theme Installed Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); } catch (Exception ex) { await logger.LogError(ex, "Error Downloading Theme {ThemeName} {Version} {Error}", themename, version, ex.Message); - AddModuleMessage("Error Downloading Theme", MessageType.Error); + AddModuleMessage(Localizer["Error Downloading Theme"], MessageType.Error); } } @@ -101,12 +101,12 @@ else try { await ThemeService.DeleteThemeAsync(Theme.ThemeName); - AddModuleMessage("Theme Deleted Successfully. You Must Restart Your Application To Apply These Changes.", MessageType.Success); + AddModuleMessage(Localizer["Theme Deleted Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); } catch (Exception ex) { await logger.LogError(ex, "Error Deleting Theme {Theme} {Error}", Theme, ex.Message); - AddModuleMessage("Error Deleting Theme", MessageType.Error); + AddModuleMessage(Localizer["Error Deleting Theme"], MessageType.Error); } } } \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/Themes/View.razor b/Oqtane.Client/Modules/Admin/Themes/View.razor index eb9871c95..2510759df 100644 --- a/Oqtane.Client/Modules/Admin/Themes/View.razor +++ b/Oqtane.Client/Modules/Admin/Themes/View.razor @@ -96,7 +96,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message); - AddModuleMessage("Error Loading Theme", MessageType.Error); + AddModuleMessage(Localizer["Error Loading Theme"], MessageType.Error); } } } diff --git a/Oqtane.Client/Modules/Admin/Upgrade/Index.razor b/Oqtane.Client/Modules/Admin/Upgrade/Index.razor index 9642a090e..c0475d595 100644 --- a/Oqtane.Client/Modules/Admin/Upgrade/Index.razor +++ b/Oqtane.Client/Modules/Admin/Upgrade/Index.razor @@ -78,7 +78,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Executing Upgrade {Error}", ex.Message); - AddModuleMessage("Error Executing Upgrade", MessageType.Error); + AddModuleMessage(Localizer["Error Executing Upgrade"], MessageType.Error); } } @@ -95,7 +95,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Downloading Framework {Error}", ex.Message); - AddModuleMessage("Error Downloading Framework", MessageType.Error); + AddModuleMessage(Localizer["Error Downloading Framework"], MessageType.Error); } } } diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor index 7803a769b..d32127268 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor @@ -74,13 +74,13 @@ } else { - AddModuleMessage("User Does Not Exist. Please Verify That The Username Provided Is Correct.", MessageType.Warning); + AddModuleMessage(Localizer["User Does Not Exist. Please Verify That The Username Provided Is Correct."], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message); - AddModuleMessage("Error Adding Notification", MessageType.Error); + AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor index a5ca73276..4b2874b6a 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Index.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Index.razor @@ -248,13 +248,13 @@ else } else { - AddModuleMessage("Current User Is Not Logged In", MessageType.Warning); + AddModuleMessage(Localizer["Current User Is Not Logged In"], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); - AddModuleMessage("Error Loading User Profile", MessageType.Error); + AddModuleMessage(Localizer["Error Loading User Profile"], MessageType.Error); } } @@ -291,22 +291,22 @@ else await UserService.UpdateUserAsync(user); await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId); await logger.LogInformation("User Profile Saved"); - AddModuleMessage("User Profile Updated Successfully", MessageType.Success); + AddModuleMessage(Localizer["User Profile Updated Successfully"], MessageType.Success); } else { - AddModuleMessage("Passwords Entered Do Not Match", MessageType.Warning); + AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); } } else { - AddModuleMessage("You Must Provide A Username and Email Address As Well As All Required Profile Information", MessageType.Warning); + AddModuleMessage(Localizer["You Must Provide A Username and Email Address As Well As All Required Profile Information"], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Saving User Profile {Error}", ex.Message); - AddModuleMessage("Error Saving User Profile", MessageType.Error); + AddModuleMessage(Localizer["Error Saving User Profile"], MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/UserProfile/View.razor b/Oqtane.Client/Modules/Admin/UserProfile/View.razor index c9ec1c61b..fcd7340c0 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/View.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/View.razor @@ -158,7 +158,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Loading Users {Error}", ex.Message); - AddModuleMessage("Error Loading Users", MessageType.Error); + AddModuleMessage(Localizer["Error Loading Users"], MessageType.Error); } } @@ -202,13 +202,13 @@ } else { - AddModuleMessage("User Does Not Exist. Please Verify That The Username Provided Is Correct.", MessageType.Warning); + AddModuleMessage(Localizer["User Does Not Exist. Please Verify That The Username Provided Is Correct."], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message); - AddModuleMessage("Error Adding Notification", MessageType.Error); + AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error); } } } diff --git a/Oqtane.Client/Modules/Admin/Users/Add.razor b/Oqtane.Client/Modules/Admin/Users/Add.razor index 15c14bce6..89b1e7759 100644 --- a/Oqtane.Client/Modules/Admin/Users/Add.razor +++ b/Oqtane.Client/Modules/Admin/Users/Add.razor @@ -116,7 +116,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); - AddModuleMessage("Error Loading User Profile", MessageType.Error); + AddModuleMessage(Localizer["Error Loading User Profile"], MessageType.Error); } } @@ -150,23 +150,23 @@ else { await logger.LogError("Error Adding User {Username} {Email}", username, email); - AddModuleMessage("Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.", MessageType.Error); + AddModuleMessage(Localizer["Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use."], MessageType.Error); } } else { - AddModuleMessage("Passwords Entered Do Not Match", MessageType.Warning); + AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); } } else { - AddModuleMessage("You Must Provide A Username, Password, Email Address And All Required Profile Information", MessageType.Warning); + AddModuleMessage(Localizer["You Must Provide A Username, Password, Email Address And All Required Profile Information"], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", username, email, ex.Message); - AddModuleMessage("Error Adding User", MessageType.Error); + AddModuleMessage(Localizer["Error Adding User"], MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/Users/Edit.razor b/Oqtane.Client/Modules/Admin/Users/Edit.razor index edabc73d7..be68ff7d7 100644 --- a/Oqtane.Client/Modules/Admin/Users/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Users/Edit.razor @@ -178,7 +178,7 @@ else catch (Exception ex) { await logger.LogError(ex, "Error Loading User {UserId} {Error}", userid, ex.Message); - AddModuleMessage("Error Loading User", MessageType.Error); + AddModuleMessage(Localizer["Error Loading User"], MessageType.Error); } } @@ -217,18 +217,18 @@ else } else { - AddModuleMessage("Passwords Entered Do Not Match", MessageType.Warning); + AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); } } else { - AddModuleMessage("You Must Provide A Username, Password, Email Address, And All Required Profile Information", MessageType.Warning); + AddModuleMessage(Localizer["You Must Provide A Username, Password, Email Address, And All Required Profile Information"], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Saving User {Username} {Email} {Error}", username, email, ex.Message); - AddModuleMessage("Error Saving User", MessageType.Error); + AddModuleMessage(Localizer["Error Saving User"], MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/Users/Roles.razor b/Oqtane.Client/Modules/Admin/Users/Roles.razor index b59883158..037daabb6 100644 --- a/Oqtane.Client/Modules/Admin/Users/Roles.razor +++ b/Oqtane.Client/Modules/Admin/Users/Roles.razor @@ -98,7 +98,7 @@ else catch (Exception ex) { await logger.LogError(ex, "Error Loading Roles {Error}", ex.Message); - AddModuleMessage("Error Loading Roles", MessageType.Error); + AddModuleMessage(Localizer["Error Loading Roles"], MessageType.Error); } } @@ -112,7 +112,7 @@ else catch (Exception ex) { await logger.LogError(ex, "Error Loading User Roles {UserId} {Error}", userid, ex.Message); - AddModuleMessage("Error Loading User Roles", MessageType.Error); + AddModuleMessage(Localizer["Error Loading User Roles"], MessageType.Error); } } @@ -173,17 +173,17 @@ else await GetUserRoles(); await logger.LogInformation("User Assigned To Role {UserRole}", userrole); - AddModuleMessage("User Assigned To Role", MessageType.Success); + AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success); } else { - AddModuleMessage("You Must Select A Role", MessageType.Warning); + AddModuleMessage(Localizer["You Must Select A Role"], MessageType.Warning); } } catch (Exception ex) { await logger.LogError(ex, "Error Saving User Roles {UserId} {Error}", userid, ex.Message); - AddModuleMessage("Error Saving User Roles", MessageType.Error); + AddModuleMessage(Localizer["Error Saving User Roles"], MessageType.Error); } } @@ -194,12 +194,12 @@ else await UserRoleService.DeleteUserRoleAsync(UserRoleId); await GetUserRoles(); await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId); - AddModuleMessage("User Removed From Role", MessageType.Success); + AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success); } catch (Exception ex) { await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message); - AddModuleMessage("Error Removing User From Role", MessageType.Error); + AddModuleMessage(Localizer["Error Removing User From Role"], MessageType.Error); } } } From cf68d7320f3391f89641f0d89498fde37a3faad1 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 9 Dec 2020 21:15:35 +0300 Subject: [PATCH 101/177] Localize alert messages in controls --- Oqtane.Client/Modules/Controls/PermissionGrid.razor | 2 +- Oqtane.Client/Modules/Controls/RichTextEditor.razor | 2 +- Oqtane.Client/Modules/HtmlText/Edit.razor | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/PermissionGrid.razor b/Oqtane.Client/Modules/Controls/PermissionGrid.razor index d11b07950..a35a52090 100644 --- a/Oqtane.Client/Modules/Controls/PermissionGrid.razor +++ b/Oqtane.Client/Modules/Controls/PermissionGrid.razor @@ -180,7 +180,7 @@ } catch { - _message = "Username Does Not Exist"; + _message = Localizer["Username Does Not Exist"]; } } diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor index 40af94979..3a33cc331 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditor.razor +++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor @@ -194,7 +194,7 @@ } else { - _message = "You Must Select An Image To Insert"; + _message = Localizer["You Must Select An Image To Insert"]; } } else diff --git a/Oqtane.Client/Modules/HtmlText/Edit.razor b/Oqtane.Client/Modules/HtmlText/Edit.razor index 25ef9b634..311c4cd7b 100644 --- a/Oqtane.Client/Modules/HtmlText/Edit.razor +++ b/Oqtane.Client/Modules/HtmlText/Edit.razor @@ -92,7 +92,7 @@ catch (Exception ex) { await logger.LogError(ex, "Error Saving Content {Error}", ex.Message); - AddModuleMessage("Error Saving Content", MessageType.Error); + AddModuleMessage(Localizer["Error Saving Content"], MessageType.Error); } } } From e94069e8a5e9c2f74d329528f4d98283779482f4 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 9 Dec 2020 21:17:33 +0300 Subject: [PATCH 102/177] Localize alert messages in UI --- Oqtane.Client/UI/Installer.razor | 2 +- Oqtane.Client/UI/ModuleInstance.razor | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/UI/Installer.razor b/Oqtane.Client/UI/Installer.razor index 8c1fc95a8..9231e092e 100644 --- a/Oqtane.Client/UI/Installer.razor +++ b/Oqtane.Client/UI/Installer.razor @@ -208,7 +208,7 @@ } else { - _message = "Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length"; + _message = Localizer["Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length"]; } } diff --git a/Oqtane.Client/UI/ModuleInstance.razor b/Oqtane.Client/UI/ModuleInstance.razor index c619f2689..273404e98 100644 --- a/Oqtane.Client/UI/ModuleInstance.razor +++ b/Oqtane.Client/UI/ModuleInstance.razor @@ -1,4 +1,5 @@ @namespace Oqtane.UI +@inject IStringLocalizer Localizer @@ -41,13 +42,13 @@ else { // module does not exist with typename specified - _message = "Module Does Not Have A Component Named " + Utilities.GetTypeNameLastSegment(ModuleState.ModuleType, 0) + ".razor"; + _message = Localizer["Module Does Not Have A Component Named {0}.razor", Utilities.GetTypeNameLastSegment(ModuleState.ModuleType, 0)]; _messagetype = MessageType.Error; } } else { - _message = "Module Type Is Invalid For " + ModuleState.ModuleDefinitionName; + _message = Localizer["Module Type Is Invalid For {0}", ModuleState.ModuleDefinitionName]; _messagetype = MessageType.Error; } From 144c33bcaba34ab1d6ecf1b492a4bace3e693f13 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Sat, 12 Dec 2020 15:58:58 -0500 Subject: [PATCH 103/177] make QueryString parameter keys case insensitive - resolves #992 --- Oqtane.Client/UI/SiteRouter.razor | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor index 469a0a7b9..6b42f15bd 100644 --- a/Oqtane.Client/UI/SiteRouter.razor +++ b/Oqtane.Client/UI/SiteRouter.razor @@ -338,10 +338,13 @@ private Dictionary ParseQueryString(string query) { - Dictionary querystring = new Dictionary(); + Dictionary querystring = new Dictionary(StringComparer.OrdinalIgnoreCase); // case insensistive keys if (!string.IsNullOrEmpty(query)) { - query = query.Substring(1); // ignore "?" + if (query.StartsWith("?")) + { + query = query.Substring(1); // ignore "?" + } foreach (string kvp in query.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)) { if (kvp != "") From deaaa74fc80640c9ac8d226e55147b7c731a6370 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 14 Dec 2020 08:52:01 -0500 Subject: [PATCH 104/177] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a7477a61..c2462077b 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ V.1.0.0 ( released in conjunction with .NET Core 3.2 on May 19, 2020 ) - [x] Dynamic CSS/Lazy Loading Future Consideration -- [ ] OAuth Support +- [ ] Support For Additional Authentication Providers (ie. OAuth) - [ ] Site Configuration Migrations - [ ] Pub/Sub Event Framework - [ ] Admin UI Markup Optimization ( ie. replace tables with divs in forms ) From eec680a151ac1d190077667d986e155d0f37e43c Mon Sep 17 00:00:00 2001 From: hishamco Date: Tue, 15 Dec 2020 00:22:33 +0300 Subject: [PATCH 105/177] Revert LogManager localization changes --- Oqtane.Server/Infrastructure/LogManager.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Oqtane.Server/Infrastructure/LogManager.cs b/Oqtane.Server/Infrastructure/LogManager.cs index 19f579ee0..648f873fb 100644 --- a/Oqtane.Server/Infrastructure/LogManager.cs +++ b/Oqtane.Server/Infrastructure/LogManager.cs @@ -3,7 +3,6 @@ using System.Text.Json; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Localization; using Oqtane.Enums; using Oqtane.Models; using Oqtane.Repository; @@ -19,16 +18,14 @@ public class LogManager : ILogManager private readonly IConfigurationRoot _config; private readonly IUserPermissions _userPermissions; private readonly IHttpContextAccessor _accessor; - private readonly IStringLocalizer _localizer; - public LogManager(ILogRepository logs, ITenantResolver tenantResolver, IConfigurationRoot config, IUserPermissions userPermissions, IHttpContextAccessor accessor, IStringLocalizer localizer) + public LogManager(ILogRepository logs, ITenantResolver tenantResolver, IConfigurationRoot config, IUserPermissions userPermissions, IHttpContextAccessor accessor) { _logs = logs; _tenantResolver = tenantResolver; _config = config; _userPermissions = userPermissions; _accessor = accessor; - _localizer = localizer; } public void Log(LogLevel level, object @class, LogFunction function, string message, params object[] args) @@ -124,7 +121,6 @@ public void Log(Log log) log.LogDate = DateTime.UtcNow; log.Server = Environment.MachineName; log.MessageTemplate = log.Message; - log.Message = _localizer[log.Message]; log = ProcessStructuredLog(log); try { From 07711c082ee4f01e307211c75543753b1df1ca8f Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Tue, 15 Dec 2020 10:49:48 +0100 Subject: [PATCH 106/177] FileController - content disposition --- Oqtane.Client/Modules/ModuleBase.cs | 7 ++- Oqtane.Server/Controllers/FileController.cs | 53 ++++++++++++++++---- Oqtane.Server/Extensions/MimeUtilities.cs | 31 ++++++++++++ Oqtane.Server/Extensions/StringExtensions.cs | 13 +---- Oqtane.Shared/Shared/Utilities.cs | 16 ++++-- 5 files changed, 93 insertions(+), 27 deletions(-) create mode 100644 Oqtane.Server/Extensions/MimeUtilities.cs diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index bfd9d395d..3fd548ac0 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -116,7 +116,12 @@ public string EditUrl(string path, int moduleid, string action, string parameter public string ContentUrl(int fileid) { - return Utilities.ContentUrl(PageState.Alias, fileid); + return ContentUrl(fileid, false); + } + + public string ContentUrl(int fileid, bool asAttachment) + { + return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment); } public virtual Dictionary GetUrlParameters(string parametersTemplate = "") diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index 5389b423a..a5f0ffdd2 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -66,7 +66,7 @@ public FileController(IWebHostEnvironment environment, IFileRepository files, IF { foreach (string file in Directory.GetFiles(folder)) { - files.Add(new Models.File { Name = Path.GetFileName(file), Extension = Path.GetExtension(file)?.Replace(".", "") }); + files.Add(new Models.File {Name = Path.GetFileName(file), Extension = Path.GetExtension(file)?.Replace(".", "")}); } } } @@ -147,8 +147,10 @@ public Models.File Put(int id, [FromBody] Models.File file) { Directory.CreateDirectory(folderpath); } + System.IO.File.Move(Path.Combine(GetFolderPath(_file.Folder), _file.Name), Path.Combine(folderpath, file.Name)); } + file.Extension = Path.GetExtension(file.Name).ToLower().Replace(".", ""); file = _files.UpdateFile(file); _logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", file); @@ -221,7 +223,7 @@ public Models.File UploadFile(string url, string folderid) { _logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url Due To Its File Extension {Url}", url); - HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict; + HttpContext.Response.StatusCode = (int) HttpStatusCode.Conflict; return file; } @@ -229,7 +231,7 @@ public Models.File UploadFile(string url, string folderid) { _logger.Log(LogLevel.Error, this, LogFunction.Create, $"File Could Not Be Downloaded From Url Due To Its File Name Not Allowed {url}"); - HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict; + HttpContext.Response.StatusCode = (int) HttpStatusCode.Conflict; return file; } @@ -266,7 +268,7 @@ public async Task UploadFile(string folder, IFormFile file) if (!file.FileName.IsPathOrFileValid()) { - HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict; + HttpContext.Response.StatusCode = (int) HttpStatusCode.Conflict; return; } @@ -432,9 +434,38 @@ private bool CanAccessFiles(string[] files) return canaccess; } + + /// + /// Get file with header + /// Content-Disposition: inline + /// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + /// + /// File Id from Oqtane filesystem + /// file content + // GET api//download/5 [HttpGet("download/{id}")] - public IActionResult Download(int id) + public IActionResult DownloadInline(int id) + { + return Download(id, false); + } + /// + /// Get file with header + /// Content-Disposition: attachment; filename="filename.jpg" + /// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition + /// + /// + /// File Id from Oqtane filesystem + /// + + // GET api//download/5/attach + [HttpGet("download/{id}/attach")] + public IActionResult DownloadAttachment(int id) + { + return Download(id, true); + } + + private IActionResult Download(int id, bool asAttachment) { var file = _files.GetFile(id); if (file != null) @@ -444,7 +475,10 @@ public IActionResult Download(int id) var filepath = Path.Combine(GetFolderPath(file.Folder), file.Name); if (System.IO.File.Exists(filepath)) { - return PhysicalFile(filepath, file.Name.GetMimeType(), file.Name); + var result = asAttachment + ? PhysicalFile(filepath, file.GetMimeType(), file.Name) + : PhysicalFile(filepath, file.GetMimeType()); + return result; } _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Does Not Exist {FileId} {FilePath}", id, filepath); @@ -461,8 +495,9 @@ public IActionResult Download(int id) _logger.Log(LogLevel.Error, this, LogFunction.Read, "File Not Found {FileId}", id); HttpContext.Response.StatusCode = 404; } + string errorPath = Path.Combine(GetFolderPath("images"), "error.png"); - return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, errorPath.GetMimeType()) : null; + return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null; } private string GetFolderPath(Folder folder) @@ -480,7 +515,7 @@ private void CreateDirectory(string folderpath) if (!Directory.Exists(folderpath)) { string path = ""; - var separators = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }; + var separators = new char[] {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar}; string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries); foreach (string folder in folders) { @@ -501,7 +536,7 @@ private Models.File CreateFile(string filename, int folderid, string filepath) FileInfo fileinfo = new FileInfo(filepath); file.Extension = fileinfo.Extension.ToLower().Replace(".", ""); - file.Size = (int)fileinfo.Length; + file.Size = (int) fileinfo.Length; file.ImageHeight = 0; file.ImageWidth = 0; diff --git a/Oqtane.Server/Extensions/MimeUtilities.cs b/Oqtane.Server/Extensions/MimeUtilities.cs new file mode 100644 index 000000000..f5983da68 --- /dev/null +++ b/Oqtane.Server/Extensions/MimeUtilities.cs @@ -0,0 +1,31 @@ +using Microsoft.AspNetCore.StaticFiles; +using Oqtane.Models; + +namespace Oqtane.Extensions +{ + public static class MimeUtilities + { + /// + /// Return Mime content type based on file extension + /// + /// File name + public static string GetMimeType(string fileName) + { + var provider = new FileExtensionContentTypeProvider(); + + if (!provider.TryGetContentType(fileName, out var contentType)) + contentType = "application/octet-stream"; + // we can add additional mappings here + + return contentType; + } + + /// + /// Return Mime content type based on file extension + /// + public static string GetMimeType(this File file) + { + return GetMimeType(file?.Name); + } + } +} diff --git a/Oqtane.Server/Extensions/StringExtensions.cs b/Oqtane.Server/Extensions/StringExtensions.cs index a2c7c88b7..ede3bce91 100644 --- a/Oqtane.Server/Extensions/StringExtensions.cs +++ b/Oqtane.Server/Extensions/StringExtensions.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.StaticFiles; +using Oqtane.Models; namespace Oqtane.Extensions { @@ -15,17 +16,5 @@ public static bool StartWithAnyOf(this string s, IEnumerable list) return list.Any(f => s.StartsWith(f)); } - - public static string GetMimeType(this string fileName) - { - var provider = new FileExtensionContentTypeProvider(); - - if (!provider.TryGetContentType(fileName, out var contentType)) - { - contentType = "application/octet-stream"; - } - - return contentType; - } } } diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs index c2cfc90fa..3de29f594 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -95,11 +95,17 @@ public static string EditUrl(string alias, string path, int moduleid, string act return NavigateUrl(alias, path, parameters); } - public static string ContentUrl(Alias alias, int fileid) + public static string ContentUrl(Alias alias, int fileId) { - string url = (alias == null) ? "/~" : "/" + alias.AliasId; - url += Constants.ContentUrl + fileid.ToString(); - return url; + return ContentUrl(alias, fileId, false); + } + + public static string ContentUrl(Alias alias, int fileId, bool asAttachment) + { + var aliasUrl = (alias == null) ? "/~" : "/" + alias.AliasId; + var method = asAttachment ? "/attach":""; + + return $"{aliasUrl}{Constants.ContentUrl}{fileId}{method}"; } public static string GetTypeName(string fullyqualifiedtypename) @@ -380,4 +386,4 @@ public static Dictionary ParseQueryString(string query) return dictionary; } } -} \ No newline at end of file +} From df382ce7a35d1ac6a94d4b9b632805f51dca890a Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 22 Dec 2020 08:37:33 -0500 Subject: [PATCH 107/177] allow developers to use custom icon libraries (Open Iconic is the default) --- Oqtane.Client/Modules/Admin/Dashboard/Index.razor | 4 ++-- Oqtane.Client/Modules/Admin/Pages/Add.razor | 2 +- Oqtane.Client/Modules/Admin/Pages/Edit.razor | 2 +- Oqtane.Client/Modules/Controls/ActionDialog.razor | 6 +++++- Oqtane.Client/Modules/Controls/ActionLink.razor | 6 +++++- Oqtane.Client/Themes/Controls/MenuHorizontal.razor | 6 +++--- Oqtane.Client/Themes/Controls/MenuVertical.razor | 4 ++-- Oqtane.Client/Themes/Controls/ModuleActions.razor | 4 ++-- .../Infrastructure/SiteTemplates/DefaultSiteTemplate.cs | 6 +++--- .../Infrastructure/SiteTemplates/EmptySiteTemplate.cs | 4 ++-- Oqtane.Server/Oqtane.Server.csproj | 4 ++++ Oqtane.Server/Scripts/Tenant.02.00.01.01.sql | 9 +++++++++ Oqtane.Shared/Shared/Icons.cs | 4 ++-- 13 files changed, 41 insertions(+), 20 deletions(-) create mode 100644 Oqtane.Server/Scripts/Tenant.02.00.01.01.sql diff --git a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor index 7e3004fb3..650eaee6e 100644 --- a/Oqtane.Client/Modules/Admin/Dashboard/Index.razor +++ b/Oqtane.Client/Modules/Admin/Dashboard/Index.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Modules.Admin.Dashboard +@namespace Oqtane.Modules.Admin.Dashboard @inherits ModuleBase @inject IPageService PageService @inject IUserService UserService @@ -11,7 +11,7 @@ string url = NavigateUrl(p.Path);
-

@p.Name +

@p.Name
} diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index 72bc3c6f6..2a253ed1a 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -157,7 +157,7 @@
- + diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 7cd500a65..4a99881c6 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -168,7 +168,7 @@
- + diff --git a/Oqtane.Client/Modules/Controls/ActionDialog.razor b/Oqtane.Client/Modules/Controls/ActionDialog.razor index 73723fa56..43d6e0af2 100644 --- a/Oqtane.Client/Modules/Controls/ActionDialog.razor +++ b/Oqtane.Client/Modules/Controls/ActionDialog.razor @@ -94,7 +94,11 @@ if (!string.IsNullOrEmpty(IconName)) { - _iconSpan = $" "; + if (!IconName.Contains(" ")) + { + IconName = "oi oi-" + IconName; + } + _iconSpan = $" "; } Text = Localize(nameof(Text), Text); diff --git a/Oqtane.Client/Modules/Controls/ActionLink.razor b/Oqtane.Client/Modules/Controls/ActionLink.razor index 1ba9ef12b..cf2cd1df0 100644 --- a/Oqtane.Client/Modules/Controls/ActionLink.razor +++ b/Oqtane.Client/Modules/Controls/ActionLink.razor @@ -91,7 +91,11 @@ if (!string.IsNullOrEmpty(IconName)) { - _iconSpan = $"{(IconOnly ? "" : " ")}"; + if (!IconName.Contains(" ")) + { + IconName = "oi oi-" + IconName; + } + _iconSpan = $"{(IconOnly ? "" : " ")}"; } diff --git a/Oqtane.Client/Themes/Controls/MenuHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuHorizontal.razor index 4400ad714..575a513ba 100644 --- a/Oqtane.Client/Themes/Controls/MenuHorizontal.razor +++ b/Oqtane.Client/Themes/Controls/MenuHorizontal.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Themes.Controls +@namespace Oqtane.Themes.Controls @inherits MenuBase @if (MenuPages.Any()) @@ -19,7 +19,7 @@ @if (p.Icon != string.Empty) { - + } @p.Name(current) @@ -31,7 +31,7 @@ @if (p.Icon != string.Empty) { - + } @p.Name diff --git a/Oqtane.Client/Themes/Controls/MenuVertical.razor b/Oqtane.Client/Themes/Controls/MenuVertical.razor index a269df153..79b205897 100644 --- a/Oqtane.Client/Themes/Controls/MenuVertical.razor +++ b/Oqtane.Client/Themes/Controls/MenuVertical.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Themes.Controls +@namespace Oqtane.Themes.Controls @inherits MenuBase @if (MenuPages.Any()) @@ -22,7 +22,7 @@ } @if (p.Icon != string.Empty) { - + } @p.Name diff --git a/Oqtane.Client/Themes/Controls/ModuleActions.razor b/Oqtane.Client/Themes/Controls/ModuleActions.razor index 6373a11d9..dbc8c15ba 100644 --- a/Oqtane.Client/Themes/Controls/ModuleActions.razor +++ b/Oqtane.Client/Themes/Controls/ModuleActions.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.Themes.Controls +@namespace Oqtane.Themes.Controls @inherits ModuleActionsBase @attribute [OqtaneIgnore] @@ -22,7 +22,7 @@ } else { - + }   @action.Name diff --git a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs index 688a1b256..3dd8ab3fa 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs @@ -39,7 +39,7 @@ public List CreateSite(Site site) Name = "Home", Parent = "", Path = "", - Icon = "home", + Icon = "oi oi-home", IsNavigation = true, IsPersonalizable = false, PagePermissions = new List { @@ -85,7 +85,7 @@ public List CreateSite(Site site) Name = "Private", Parent = "", Path = "private", - Icon = "lock-locked", + Icon = "oi oi-lock-locked", IsNavigation = true, IsPersonalizable = false, PagePermissions = new List { @@ -109,7 +109,7 @@ public List CreateSite(Site site) Name = "My Page", Parent = "", Path = "mypage", - Icon = "target", + Icon = "oi oi-target", IsNavigation = true, IsPersonalizable = true, PagePermissions = new List { diff --git a/Oqtane.Server/Infrastructure/SiteTemplates/EmptySiteTemplate.cs b/Oqtane.Server/Infrastructure/SiteTemplates/EmptySiteTemplate.cs index 408fa3fe4..e37cbbcb0 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/EmptySiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/EmptySiteTemplate.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; using Oqtane.Infrastructure; using System.Collections.Generic; using Oqtane.Extensions; @@ -27,7 +27,7 @@ public List CreateSite(Site site) Name = "Home", Parent = "", Path = "", - Icon = "home", + Icon = "oi oi-home", IsNavigation = true, IsPersonalizable = false, PagePermissions = new List { diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 9053bea78..699eccf8b 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -26,6 +26,7 @@ + @@ -60,6 +61,9 @@ + + + diff --git a/Oqtane.Server/Scripts/Tenant.02.00.01.01.sql b/Oqtane.Server/Scripts/Tenant.02.00.01.01.sql new file mode 100644 index 000000000..149728bea --- /dev/null +++ b/Oqtane.Server/Scripts/Tenant.02.00.01.01.sql @@ -0,0 +1,9 @@ +/* + +Version 2.0.1 Tenant migration script + +*/ + +UPDATE [dbo].[Page] SET Icon = IIF(Icon <> '', 'oi oi-' + Icon, ''); +GO + diff --git a/Oqtane.Shared/Shared/Icons.cs b/Oqtane.Shared/Shared/Icons.cs index 586d0baef..521c3c123 100644 --- a/Oqtane.Shared/Shared/Icons.cs +++ b/Oqtane.Shared/Shared/Icons.cs @@ -1,9 +1,9 @@ -namespace Oqtane.Shared +namespace Oqtane.Shared { //Open Iconic icons set public static class Icons { - private const string Prefix = ""; //oi- + private const string Prefix = "oi oi-"; public const string AccountLogin = Prefix + "account-login"; public const string AccountLogout = Prefix + "account-logout"; public const string ActionRedo = Prefix + "action-redo"; From f05b955c340476eff01ced1af7e1d6befc4c0614 Mon Sep 17 00:00:00 2001 From: hishamco Date: Mon, 28 Dec 2020 18:15:28 +0300 Subject: [PATCH 108/177] Show LanguageSwitcher if more than one culture --- Oqtane.Client/Themes/Controls/ControlPanel.razor | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 931f3ff32..8018be30d 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -10,6 +10,7 @@ @inject ILogService logger @inject ISettingService SettingService @inject IStringLocalizer Localizer +@inject ILocalizationService LocalizationService @if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) { @@ -317,6 +318,12 @@ _allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId); _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList(); _categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList(); + + var cultures = await LocalizationService.GetCulturesAsync(); + if (cultures.Count() < 2) + { + ShowLanguageSwitcher = false; + } } } From 56e86edf9f71162113724b15bc36cf6f8192e376 Mon Sep 17 00:00:00 2001 From: hishamco Date: Mon, 28 Dec 2020 19:59:58 +0300 Subject: [PATCH 109/177] Address feedback --- Oqtane.Client/Themes/Controls/ControlPanel.razor | 7 ------- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 8018be30d..931f3ff32 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -10,7 +10,6 @@ @inject ILogService logger @inject ISettingService SettingService @inject IStringLocalizer Localizer -@inject ILocalizationService LocalizationService @if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) { @@ -318,12 +317,6 @@ _allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId); _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList(); _categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList(); - - var cultures = await LocalizationService.GetCulturesAsync(); - if (cultures.Count() < 2) - { - ShowLanguageSwitcher = false; - } } } diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 4dca37bc0..16391513d 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -6,7 +6,7 @@ @inject ILocalizationService LocalizationService @inject NavigationManager NavigationManager -@if (_supportedCultures != null) +@if (_supportedCultures?.Count() > 1) {
- + From a61a2f748cc98d1da5a878a18586dd851fe472a3 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 5 Jan 2021 09:00:42 -0500 Subject: [PATCH 114/177] fixed issue with Sql Management and System Info missing icons after new installation --- Oqtane.Server/Repository/SiteRepository.cs | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/Oqtane.Server/Repository/SiteRepository.cs b/Oqtane.Server/Repository/SiteRepository.cs index 0130e5e3a..d8df82b63 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -525,12 +525,7 @@ private List CreateAdminPages(List pageTemplates = n }); pageTemplates.Add(new PageTemplate { - Name = "Sql Management", - Parent = "Admin", - Path = "admin/sql", - Icon = "spreadsheet", - IsNavigation = false, - IsPersonalizable = false, + Name = "Sql Management", Parent = "Admin", Path = "admin/sql", Icon = Icons.Spreadsheet, IsNavigation = false, IsPersonalizable = false, PagePermissions = new List { new Permission(PermissionNames.View, RoleNames.Host, true), @@ -552,12 +547,7 @@ private List CreateAdminPages(List pageTemplates = n }); pageTemplates.Add(new PageTemplate { - Name = "System Info", - Parent = "Admin", - Path = "admin/system", - Icon = "medical-cross", - IsNavigation = false, - IsPersonalizable = false, + Name = "System Info", Parent = "Admin", Path = "admin/system", Icon = Icons.MedicalCross, IsNavigation = false, IsPersonalizable = false, PagePermissions = new List { new Permission(PermissionNames.View, RoleNames.Host, true), From 91c5ff7b007c73889918035faf0a46041bc3b3f2 Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Tue, 5 Jan 2021 19:52:14 +0100 Subject: [PATCH 115/177] UpdateSettings bugfix ISettingControl introduction --- .../Modules/Admin/Modules/Settings.razor | 18 ++++++++++-------- Oqtane.Shared/Interfaces/ISettingsControl.cs | 9 +++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 Oqtane.Shared/Interfaces/ISettingsControl.cs diff --git a/Oqtane.Client/Modules/Admin/Modules/Settings.razor b/Oqtane.Client/Modules/Admin/Modules/Settings.razor index a4bd4188f..c6ebe5c32 100644 --- a/Oqtane.Client/Modules/Admin/Modules/Settings.razor +++ b/Oqtane.Client/Modules/Admin/Modules/Settings.razor @@ -1,4 +1,5 @@ @namespace Oqtane.Modules.Admin.Modules +@using Oqtane.Interfaces @inherits ModuleBase @inject NavigationManager NavigationManager @inject IThemeService ThemeService @@ -137,7 +138,7 @@ builder.AddComponentReferenceCapture(1, inst => { _settings = Convert.ChangeType(inst, _settingsModuleType); }); builder.CloseComponent(); }; - } + } } private async Task SaveModule() @@ -162,15 +163,16 @@ module.Permissions = _permissionGrid.GetPermissions(); await ModuleService.UpdateModuleAsync(module); - if (_settingsModuleType != null) + + if (_settings is ISettingsControl control) { - var moduleType = Type.GetType(ModuleState.ModuleType); - if (moduleType != null) - { - moduleType.GetMethod("UpdateSettings")?.Invoke(_settings, null); // method must be public in settings component - } + await control.UpdateSettings(); + } + else + { + // Compatibility 2.0 fallback + _settings?.GetType().GetMethod("UpdateSettings")?.Invoke(_settings, null); // method must be public in settings component } - NavigationManager.NavigateTo(NavigateUrl()); } diff --git a/Oqtane.Shared/Interfaces/ISettingsControl.cs b/Oqtane.Shared/Interfaces/ISettingsControl.cs new file mode 100644 index 000000000..c57530995 --- /dev/null +++ b/Oqtane.Shared/Interfaces/ISettingsControl.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Oqtane.Interfaces +{ + public interface ISettingsControl + { + Task UpdateSettings(); + } +} From de25e3fbf1ed31f2e6d3fe28ce79c69fd0ceca14 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 5 Jan 2021 14:47:09 -0500 Subject: [PATCH 116/177] fix navigation usability issue for shared add/edit page UI invoked by Control Panel and Page Management --- Oqtane.Client/Modules/Admin/Pages/Add.razor | 23 +++++++++++++++++-- Oqtane.Client/Modules/Admin/Pages/Edit.razor | 23 +++++++++++++++++-- .../Themes/Controls/ControlPanel.razor | 4 ++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index 2a253ed1a..171ab885c 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -189,7 +189,7 @@ -@Localizer["Cancel"] + @code { private List _themeList; @@ -386,7 +386,14 @@ await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId); await logger.LogInformation("Page Added {Page}", page); - NavigationManager.NavigateTo(NavigateUrl(page.Path)); + if (PageState.QueryString.ContainsKey("cp")) + { + NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + } + else + { + NavigationManager.NavigateTo(NavigateUrl(page.Path)); + } } else { @@ -401,6 +408,18 @@ } } + private void Cancel() + { + if (PageState.QueryString.ContainsKey("cp")) + { + NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + } + else + { + NavigationManager.NavigateTo(NavigateUrl()); + } + } + private static bool PagePathIsUnique(string pagePath, int siteId, List existingPages) { return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath); diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 4a99881c6..5efdd992b 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -205,7 +205,7 @@ -@Localizer["Cancel"] + @code { private List _themeList; @@ -493,7 +493,14 @@ } await logger.LogInformation("Page Saved {Page}", page); - NavigationManager.NavigateTo(NavigateUrl(page.Path)); + if (PageState.QueryString.ContainsKey("cp")) + { + NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + } + else + { + NavigationManager.NavigateTo(NavigateUrl(page.Path)); + } } else { @@ -507,6 +514,18 @@ } } + private void Cancel() + { + if (PageState.QueryString.ContainsKey("cp")) + { + NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path)); + } + else + { + NavigationManager.NavigateTo(NavigateUrl()); + } + } + private static bool PagePathIsUnique(string pagePath, int siteId, int pageId, List existingPages) { return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath && page.PageId != pageId); diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 931f3ff32..eee041214 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -485,10 +485,10 @@ switch (location) { case "Add": - url = EditUrl(PageState.Page.Path, module.ModuleId, location, ""); + url = EditUrl(PageState.Page.Path, module.ModuleId, location, "cp=" + PageState.Page.PageId); break; case "Edit": - url = EditUrl(PageState.Page.Path, module.ModuleId, location, "id=" + PageState.Page.PageId.ToString()); + url = EditUrl(PageState.Page.Path, module.ModuleId, location, "id=" + PageState.Page.PageId.ToString() + "&cp=" + PageState.Page.PageId); break; } } From 778f9cb356d7c3df7bb974fcf321956b3b9db9af Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 5 Jan 2021 16:57:36 -0500 Subject: [PATCH 117/177] added better validaton and user feedback related to SMTP configuration --- Oqtane.Client/Modules/Admin/Site/Index.razor | 29 ++++++++++++------- .../Infrastructure/Jobs/NotificationJob.cs | 9 ++++-- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index 3910ab9be..ddf174508 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -129,9 +129,14 @@
+ + +
+ @Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In the Scheduled Jobs"] +
- + @@ -139,7 +144,7 @@
- + @@ -147,15 +152,18 @@
- + - +
- + @@ -163,7 +171,7 @@
- + @@ -205,7 +213,6 @@
- @Localizer["Cancel"]

@@ -232,7 +239,7 @@ private string _allowregistration; private string _smtphost = string.Empty; private string _smtpport = string.Empty; - private string _smtpssl = string.Empty; + private string _smtpssl = "False"; private string _smtpusername = string.Empty; private string _smtppassword = string.Empty; private string _pwaisenabled; @@ -287,7 +294,7 @@ var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); _smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty); _smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty); - _smtpssl = SettingService.GetSetting(settings, "SMTPSSL", string.Empty); + _smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "False"); _smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty); _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty); @@ -437,9 +444,9 @@ SettingService.SetSetting(settings, "SMTPPassword", _smtppassword); await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); - await logger.LogInformation("Site Saved {Site}", site); + await logger.LogInformation("Site Settings Saved {Site}", site); - NavigationManager.NavigateTo(NavigateUrl()); + AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success); } } else diff --git a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs index 2e18950f2..404829d79 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Net; @@ -47,7 +47,10 @@ public override string ExecuteJob(IServiceProvider provider) // get site settings List sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList(); Dictionary settings = GetSettings(sitesettings); - if (settings.ContainsKey("SMTPHost") && settings["SMTPHost"] != "") + if (settings.ContainsKey("SMTPHost") && settings["SMTPHost"] != "" && + settings.ContainsKey("SMTPPort") && settings["SMTPPort"] != "" && + settings.ContainsKey("SMTPSSL") && settings["SMTPSSL"] != "" && + settings.ContainsKey("SMTPUsername") && settings["SMTPUsername"] != "") { // construct SMTP Client var client = new SmtpClient() @@ -112,7 +115,7 @@ public override string ExecuteJob(IServiceProvider provider) } else { - log += "SMTP Not Configured" + "
"; + log += "SMTP Not Configured Properly In Site Settings - Host, Port, SSL, And Username Are All Required" + "
"; } } } From e3e5f782aaae890aa7011e91d4038eb7ea1e1222 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Tue, 5 Jan 2021 17:11:45 -0500 Subject: [PATCH 118/177] support for shared razor class library static resources in external module template --- .../Modules/Templates/External/Package/debug.cmd | 2 +- .../External/Server/[Owner].[Module].Server.csproj | 5 +++++ .../External/Server/wwwroot/_content/Placeholder.txt | 11 +++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 Oqtane.Server/wwwroot/Modules/Templates/External/Server/wwwroot/_content/Placeholder.txt diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd index c19712236..2137d929f 100644 --- a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/debug.cmd @@ -4,4 +4,4 @@ XCOPY "..\Server\bin\Debug\net5.0\[Owner].[Module].Server.Oqtane.dll" "..\..\[Ro XCOPY "..\Server\bin\Debug\net5.0\[Owner].[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y XCOPY "..\Shared\bin\Debug\net5.0\[Owner].[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y XCOPY "..\Shared\bin\Debug\net5.0\[Owner].[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net5.0\" /Y -XCOPY "..\Server\wwwroot\Modules\[Owner].[Module]\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Modules\[Owner].[Module]\" /Y /S /I +XCOPY "..\Server\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I 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 2a2a8a2f1..cfce1a600 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 @@ -19,6 +19,11 @@ + + + + + diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/wwwroot/_content/Placeholder.txt b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/wwwroot/_content/Placeholder.txt new file mode 100644 index 000000000..5a324d79d --- /dev/null +++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/wwwroot/_content/Placeholder.txt @@ -0,0 +1,11 @@ +The _content folder should only contain static resources from shared razor component libraries (RCLs). Static resources can be extracted from shared RCL Nuget packages by executing a Publish task on the module's Server project to a local folder and copying the files from the _content folder which is created. Each shared RCL would have its own appropriately named subfolder within the module's _content folder. + +ie. + +/_content + /Radzen.Blazor + /css + /fonts + /syncfusion.blazor + /scripts + /styles From 1276c0269e303ec3ef2d904fc2d6b4448855bd3f Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 7 Jan 2021 15:06:48 -0500 Subject: [PATCH 119/177] add SMTP sender email --- Oqtane.Client/Modules/Admin/Site/Index.razor | 15 +++++++++++++-- .../Infrastructure/Jobs/NotificationJob.cs | 6 +++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index ddf174508..63e588894 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -127,7 +127,7 @@
-
+
+ + + +
@@ -163,7 +163,7 @@
- + @@ -177,6 +177,14 @@
+ + + +
@@ -242,6 +250,7 @@ private string _smtpssl = "False"; private string _smtpusername = string.Empty; private string _smtppassword = string.Empty; + private string _smtpsender = string.Empty; private string _pwaisenabled; private int _pwaappiconfileid = -1; private FileManager _pwaappiconfilemanager; @@ -297,6 +306,7 @@ _smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "False"); _smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty); _smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty); + _smtpsender = SettingService.GetSetting(settings, "SMTPSender", string.Empty); _pwaisenabled = site.PwaIsEnabled.ToString(); @@ -442,6 +452,7 @@ SettingService.SetSetting(settings, "SMTPSSL", _smtpssl); SettingService.SetSetting(settings, "SMTPUsername", _smtpusername); SettingService.SetSetting(settings, "SMTPPassword", _smtppassword); + SettingService.SetSetting(settings, "SMTPSender", _smtpsender); await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId); await logger.LogInformation("Site Settings Saved {Site}", site); diff --git a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs index 404829d79..deafe30ac 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -50,7 +50,7 @@ public override string ExecuteJob(IServiceProvider provider) if (settings.ContainsKey("SMTPHost") && settings["SMTPHost"] != "" && settings.ContainsKey("SMTPPort") && settings["SMTPPort"] != "" && settings.ContainsKey("SMTPSSL") && settings["SMTPSSL"] != "" && - settings.ContainsKey("SMTPUsername") && settings["SMTPUsername"] != "") + settings.ContainsKey("SMTPSender") && settings["SMTPSender"] != "") { // construct SMTP Client var client = new SmtpClient() @@ -72,7 +72,7 @@ public override string ExecuteJob(IServiceProvider provider) foreach (Notification notification in notifications) { MailMessage mailMessage = new MailMessage(); - mailMessage.From = new MailAddress(settings["SMTPUsername"], site.Name); + mailMessage.From = new MailAddress(settings["SMTPSender"], site.Name); mailMessage.Subject = notification.Subject; if (notification.FromUserId != null) { @@ -115,7 +115,7 @@ public override string ExecuteJob(IServiceProvider provider) } else { - log += "SMTP Not Configured Properly In Site Settings - Host, Port, SSL, And Username Are All Required" + "
"; + log += "SMTP Not Configured Properly In Site Settings - Host, Port, SSL, And Sender Are All Required" + "
"; } } } From aa19a3583430ba6814ec89bbade07810b69157ec Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 20:09:04 +0300 Subject: [PATCH 120/177] Add language repository & controller --- .../Controllers/LanguageController.cs | 52 +++++++++++++++++++ .../Repository/Context/TenantDBContext.cs | 4 +- .../Interfaces/ILanguageRepository.cs | 16 ++++++ .../Repository/LanguageRepository.cs | 35 +++++++++++++ Oqtane.Server/Startup.cs | 1 + Oqtane.Shared/Models/Language.cs | 25 +++++++++ 6 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 Oqtane.Server/Controllers/LanguageController.cs create mode 100644 Oqtane.Server/Repository/Interfaces/ILanguageRepository.cs create mode 100644 Oqtane.Server/Repository/LanguageRepository.cs create mode 100644 Oqtane.Shared/Models/Language.cs diff --git a/Oqtane.Server/Controllers/LanguageController.cs b/Oqtane.Server/Controllers/LanguageController.cs new file mode 100644 index 000000000..b2a38ee5e --- /dev/null +++ b/Oqtane.Server/Controllers/LanguageController.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Oqtane.Enums; +using Oqtane.Infrastructure; +using Oqtane.Models; +using Oqtane.Repository; +using Oqtane.Shared; + +namespace Oqtane.Controllers +{ + [Route(ControllerRoutes.Default)] + public class LanguageController : Controller + { + private readonly ILanguageRepository _languages; + private readonly ILogManager _logger; + + public LanguageController(ILanguageRepository language, ILogManager logger) + { + _languages = roles; + _logger = language; + } + + [HttpGet] + [Authorize(Roles = RoleNames.Registered)] + public IEnumerable Get(string siteid) => _languages.GetLanguages(int.Parse(siteid)); + + [HttpGet("{id}")] + [Authorize(Roles = RoleNames.Registered)] + public Language Get(int id) => _languages.GetLanguage(id); + + [HttpPost] + [Authorize(Roles = RoleNames.Admin)] + public Language Post([FromBody] Language language) + { + if (ModelState.IsValid) + { + language = _languages.AddLanguage(language); + _logger.Log(LogLevel.Information, this, LogFunction.Create, "Language Added {Language}", role); + } + return role; + } + + [HttpDelete("{id}")] + [Authorize(Roles = RoleNames.Admin)] + public void Delete(int id) + { + _languages.DeleteLanguage(id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Language Deleted {LanguageId}", id); + } + } +} diff --git a/Oqtane.Server/Repository/Context/TenantDBContext.cs b/Oqtane.Server/Repository/Context/TenantDBContext.cs index be085b206..79270ffb1 100644 --- a/Oqtane.Server/Repository/Context/TenantDBContext.cs +++ b/Oqtane.Server/Repository/Context/TenantDBContext.cs @@ -1,4 +1,4 @@ -using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Oqtane.Models; @@ -21,6 +21,8 @@ public class TenantDBContext : DBContextBase public virtual DbSet Folder { get; set; } public virtual DbSet File { get; set; } + public virtual DbSet Languages { get; set; } + public TenantDBContext(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor) { // DBContextBase handles multi-tenant database connections diff --git a/Oqtane.Server/Repository/Interfaces/ILanguageRepository.cs b/Oqtane.Server/Repository/Interfaces/ILanguageRepository.cs new file mode 100644 index 000000000..0ec10442e --- /dev/null +++ b/Oqtane.Server/Repository/Interfaces/ILanguageRepository.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using Oqtane.Models; + +namespace Oqtane.Repository +{ + public interface ILanguageRepository + { + IEnumerable GetLanguages(int siteId); + + Language AddLanguage(Language language); + + Language GetLanguage(int languageId); + + void DeleteLanguage(int languageId); + } +} diff --git a/Oqtane.Server/Repository/LanguageRepository.cs b/Oqtane.Server/Repository/LanguageRepository.cs new file mode 100644 index 000000000..2f59a0471 --- /dev/null +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Linq; +using Oqtane.Models; + +namespace Oqtane.Repository +{ + public class LanguageRepository : ILanguageRepository + { + private TenantDBContext _db; + + public LanguageRepository(TenantDBContext context) + { + _db = context; + } + + public IEnumerable GetLanguages(int siteId) => _db.Languages.Where(l => l.SiteId == siteId); + + public Language AddLanguage(Language language) + { + _db.Languages.Add(language); + _db.SaveChanges(); + + return language; + } + + public Language GetLanguage(int languageId) => _db.Languages.Find(languageId); + + public void DeleteLanguage(int languageId) + { + var language = _db.Languages.Find(languageId); + _db.Languages.Remove(language); + _db.SaveChanges(); + } + } +} diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index b134a19e5..b4e9569dc 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -213,6 +213,7 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); // load the external assemblies into the app domain, install services services.AddOqtane(_runtime, _supportedCultures); diff --git a/Oqtane.Shared/Models/Language.cs b/Oqtane.Shared/Models/Language.cs new file mode 100644 index 000000000..2433d0d0b --- /dev/null +++ b/Oqtane.Shared/Models/Language.cs @@ -0,0 +1,25 @@ +using System; + +namespace Oqtane.Models +{ + public class Language : IAuditable + { + public int LanguageId { get; set; } + + public int? SiteId { get; set; } + + public string Name { get; set; } + + public string Code { get; set; } + + public bool IsCurrent { get; set; } + + public string CreatedBy { get; set; } + + public DateTime CreatedOn { get; set; } + + public string ModifiedBy { get; set; } + + public DateTime ModifiedOn { get; set; } + } +} From 3059e8c763d87740f38262cf5f3896e0afffdb50 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 20:17:35 +0300 Subject: [PATCH 121/177] Add language service --- Oqtane.Client/Program.cs | 1 + .../Services/Interfaces/ILanguageService.cs | 17 +++++++++ Oqtane.Client/Services/LanguageService.cs | 38 +++++++++++++++++++ Oqtane.Server/Startup.cs | 1 + 4 files changed, 57 insertions(+) create mode 100644 Oqtane.Client/Services/Interfaces/ILanguageService.cs create mode 100644 Oqtane.Client/Services/LanguageService.cs diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index 4c2d12016..558b8290a 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -67,6 +67,7 @@ public static async Task Main(string[] args) builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); await LoadClientAssemblies(httpClient); diff --git a/Oqtane.Client/Services/Interfaces/ILanguageService.cs b/Oqtane.Client/Services/Interfaces/ILanguageService.cs new file mode 100644 index 000000000..82fbcc782 --- /dev/null +++ b/Oqtane.Client/Services/Interfaces/ILanguageService.cs @@ -0,0 +1,17 @@ +using Oqtane.Models; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Oqtane.Services +{ + public interface ILanguageService + { + Task> GetLanguagesAsync(int siteId); + + Task GetLanguageAsync(int languageId); + + Task AddLanguageAsync(Language language); + + Task DeleteLanguageAsync(int languageId); + } +} diff --git a/Oqtane.Client/Services/LanguageService.cs b/Oqtane.Client/Services/LanguageService.cs new file mode 100644 index 000000000..432a23127 --- /dev/null +++ b/Oqtane.Client/Services/LanguageService.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using Oqtane.Models; +using Oqtane.Shared; + +namespace Oqtane.Services +{ + public class LanguageService : ServiceBase, ILanguageService + { + + private readonly SiteState _siteState; + + public LanguageService(HttpClient http, SiteState siteState) : base(http) + { + _siteState = siteState; + } + + private string Apiurl => CreateApiUrl(_siteState.Alias, "Language"); + + public async Task> GetLanguagesAsync(int siteId) + { + var languages = await GetJsonAsync>($"{Apiurl}?siteid={siteId}"); + + return languages.OrderBy(l => l.Name).ToList(); + } + + public async Task GetLanguageAsync(int languageId) + => await GetJsonAsync($"{Apiurl}/{languageId}"); + + public async Task AddRoleAsync(Language language) + => await PostJsonAsync(Apiurl, language); + + public async Task DeleteLanguageAsync(int languageId) + => await DeleteAsync($"{Apiurl}/{languageId}"); + } +} diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index b4e9569dc..0353bc03e 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -128,6 +128,7 @@ public void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddSingleton(); From 9b4316d6cd66d7b09e66f23b3afabab7d716acfd Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 21:32:11 +0300 Subject: [PATCH 122/177] Fix errors --- Oqtane.Client/Services/LanguageService.cs | 2 +- Oqtane.Server/Controllers/LanguageController.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Oqtane.Client/Services/LanguageService.cs b/Oqtane.Client/Services/LanguageService.cs index 432a23127..da1e0342b 100644 --- a/Oqtane.Client/Services/LanguageService.cs +++ b/Oqtane.Client/Services/LanguageService.cs @@ -29,7 +29,7 @@ public async Task> GetLanguagesAsync(int siteId) public async Task GetLanguageAsync(int languageId) => await GetJsonAsync($"{Apiurl}/{languageId}"); - public async Task AddRoleAsync(Language language) + public async Task AddLanguageAsync(Language language) => await PostJsonAsync(Apiurl, language); public async Task DeleteLanguageAsync(int languageId) diff --git a/Oqtane.Server/Controllers/LanguageController.cs b/Oqtane.Server/Controllers/LanguageController.cs index b2a38ee5e..2b8f7cf01 100644 --- a/Oqtane.Server/Controllers/LanguageController.cs +++ b/Oqtane.Server/Controllers/LanguageController.cs @@ -17,8 +17,8 @@ public class LanguageController : Controller public LanguageController(ILanguageRepository language, ILogManager logger) { - _languages = roles; - _logger = language; + _languages = language; + _logger = logger; } [HttpGet] @@ -36,9 +36,9 @@ public Language Post([FromBody] Language language) if (ModelState.IsValid) { language = _languages.AddLanguage(language); - _logger.Log(LogLevel.Information, this, LogFunction.Create, "Language Added {Language}", role); + _logger.Log(LogLevel.Information, this, LogFunction.Create, "Language Added {Language}", language); } - return role; + return language; } [HttpDelete("{id}")] From 21e09d95da17aaaf297b52e68179bf3451b4cd32 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 21:32:25 +0300 Subject: [PATCH 123/177] Add migration script --- Oqtane.Server/Scripts/Tenant.02.00.02.00.sql | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Oqtane.Server/Scripts/Tenant.02.00.02.00.sql diff --git a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql new file mode 100644 index 000000000..8eb6eef3e --- /dev/null +++ b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql @@ -0,0 +1,26 @@ +/* + +Version 2.0.0 Tenant migration script + +*/ + +CREATE TABLE [dbo].[Language]( + [LanguageId] [int] IDENTITY(1,1) NOT NULL, + [Name] [nvarchar](100) NOT NULL, + [Code] [nvarchar](10) NOT NULL, + [TenantId] [int], + [CreatedBy] [nvarchar](256) NOT NULL, + [CreatedOn] [datetime] NOT NULL, + [ModifiedBy] [nvarchar](256) NOT NULL, + [ModifiedOn] [datetime] NOT NULL, + CONSTRAINT [PK_Language] PRIMARY KEY CLUSTERED + ( + [LanguageId] ASC + ) +) +GO + +ALTER TABLE [dbo].[Language] WITH CHECK ADD CONSTRAINT [FK_Language_Tenant] FOREIGN KEY([TenantId]) +REFERENCES [dbo].[Tenant] ([TenantId]) +ON DELETE CASCADE +GO \ No newline at end of file From 91a844c9101b726a9bb73b75ea64fe6067417948 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 10 Jan 2021 23:17:03 +0300 Subject: [PATCH 124/177] Add language management page template --- .../Modules/Admin/Languages/Index.razor | 54 +++++++++++++++++++ Oqtane.Server/Repository/SiteRepository.cs | 27 ++++++++++ Oqtane.Server/Scripts/Tenant.02.00.02.00.sql | 1 + 3 files changed, 82 insertions(+) create mode 100644 Oqtane.Client/Modules/Admin/Languages/Index.razor diff --git a/Oqtane.Client/Modules/Admin/Languages/Index.razor b/Oqtane.Client/Modules/Admin/Languages/Index.razor new file mode 100644 index 000000000..c45a8bc22 --- /dev/null +++ b/Oqtane.Client/Modules/Admin/Languages/Index.razor @@ -0,0 +1,54 @@ +@namespace Oqtane.Modules.Admin.Languages +@inherits ModuleBase +@inject ILanguageService LanguageService +@inject IStringLocalizer Localizer + +@if (_languages == null) +{ +

@Localizer["Loading..."]

+} +else +{ + + + +
+
 @Localizer["Name"]@Localizer["Code"]@context.Name@context.Code
+ + + + + + + + +
+ + + +
+ + + +
+ +@Localizer["Cancel"] + +@code { + private string _code = string.Empty; + private string _isCurrent = "False"; + + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; + + private static IEnumerable GetCultures() + => CultureInfo.GetCultures(CultureTypes.AllCultures) + .Select(c => new Culture { Name = c.Name, DisplayName = c.DisplayName }); + + private async Task SaveLanguage() + { + var language = new Language + { + SiteId = PageState.Page.SiteId, + Name = CultureInfo.GetCultureInfo(_code).DisplayName, + Code = _code, + IsCurrent = (_isCurrent == null ? false : Boolean.Parse(_isCurrent)) + }; + + try + { + language = await LanguageService.AddLanguageAsync(language); + + await logger.LogInformation("Language Added {Language}", language); + + NavigationManager.NavigateTo(NavigateUrl()); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Adding Language {Language} {Error}", language, ex.Message); + + AddModuleMessage(Localizer["Error Adding Language"], MessageType.Error); + } + } +} From 3a8fc428a6e3a719f13aa66ee5e36ed62ae9da5b Mon Sep 17 00:00:00 2001 From: hishamco Date: Mon, 11 Jan 2021 00:04:43 +0300 Subject: [PATCH 129/177] Use TriaStateCheckBox for language IsCurrent --- Oqtane.Client/Modules/Admin/Languages/Index.razor | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Oqtane.Client/Modules/Admin/Languages/Index.razor b/Oqtane.Client/Modules/Admin/Languages/Index.razor index c45a8bc22..933903ccd 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Index.razor @@ -16,11 +16,13 @@ else   @Localizer["Name"] @Localizer["Code"] + @Localizer["Is Current"]
@context.Name @context.Code +
} From 932c5590afee063eb1cded3c312335afe5b8ce2e Mon Sep 17 00:00:00 2001 From: hishamco Date: Mon, 11 Jan 2021 00:11:30 +0300 Subject: [PATCH 130/177] Make sure one language is set to current --- Oqtane.Server/Repository/LanguageRepository.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Oqtane.Server/Repository/LanguageRepository.cs b/Oqtane.Server/Repository/LanguageRepository.cs index bdfd1b3eb..ade74f2df 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -17,6 +17,12 @@ public LanguageRepository(TenantDBContext context) public Language AddLanguage(Language language) { + if (language.IsCurrent) + { + // Ensure all other languages are not set to current + _db.Language.ToList().ForEach(l => l.IsCurrent = false); + } + _db.Language.Add(language); _db.SaveChanges(); From 1dcb14811ddfe54034fe911246665f5781922782 Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Mon, 11 Jan 2021 13:11:55 +0100 Subject: [PATCH 131/177] Add missing ContentUrl method --- Oqtane.Client/Themes/ThemeBase.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Oqtane.Client/Themes/ThemeBase.cs b/Oqtane.Client/Themes/ThemeBase.cs index 7f57ec70c..a2ca3c86b 100644 --- a/Oqtane.Client/Themes/ThemeBase.cs +++ b/Oqtane.Client/Themes/ThemeBase.cs @@ -88,5 +88,10 @@ public string ContentUrl(int fileid) { return Utilities.ContentUrl(PageState.Alias, fileid); } + + public string ContentUrl(int fileid, bool asAttachment) + { + return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment); + } } } From f1a1a21d74777757c1beed754f8d5001057c17d8 Mon Sep 17 00:00:00 2001 From: Pavel Vesely Date: Mon, 11 Jan 2021 13:13:25 +0100 Subject: [PATCH 132/177] Introduce GetFolderPath and GetFilePath repository methods --- Oqtane.Server/Controllers/FileController.cs | 19 +++++++----------- Oqtane.Server/Repository/FileRepository.cs | 20 ++++++++++++++++++- Oqtane.Server/Repository/FolderRepository.cs | 19 +++++++++++++++++- .../Repository/Interfaces/IFileRepository.cs | 2 ++ .../Interfaces/IFolderRepository.cs | 2 ++ 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index a5f0ffdd2..ce36dae29 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -142,13 +142,13 @@ public Models.File Put(int id, [FromBody] Models.File file) Models.File _file = _files.GetFile(id, false); if (_file.Name != file.Name || _file.FolderId != file.FolderId) { - string folderpath = GetFolderPath(file.Folder); + string folderpath = _folders.GetFolderPath(file.Folder); if (!Directory.Exists(folderpath)) { Directory.CreateDirectory(folderpath); } - System.IO.File.Move(Path.Combine(GetFolderPath(_file.Folder), _file.Name), Path.Combine(folderpath, file.Name)); + System.IO.File.Move(_files.GetFilePath(_file), Path.Combine(folderpath, file.Name)); } file.Extension = Path.GetExtension(file.Name).ToLower().Replace(".", ""); @@ -177,7 +177,7 @@ public void Delete(int id) { _files.DeleteFile(id); - string filepath = Path.Combine(GetFolderPath(file.Folder), file.Name); + string filepath = _files.GetFilePath(file); if (System.IO.File.Exists(filepath)) { System.IO.File.Delete(filepath); @@ -213,7 +213,7 @@ public Models.File UploadFile(string url, string folderid) return file; } - string folderPath = GetFolderPath(folder); + string folderPath = _folders.GetFolderPath(folder); CreateDirectory(folderPath); string filename = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1); @@ -280,7 +280,7 @@ public async Task UploadFile(string folder, IFormFile file) if (virtualFolder != null && _userPermissions.IsAuthorized(User, PermissionNames.Edit, virtualFolder.Permissions)) { - folderPath = GetFolderPath(virtualFolder); + folderPath = _folders.GetFolderPath(virtualFolder); } } else @@ -291,7 +291,7 @@ public async Task UploadFile(string folder, IFormFile file) } } - if (folderPath != "") + if (!String.IsNullOrEmpty(folderPath)) { CreateDirectory(folderPath); using (var stream = new FileStream(Path.Combine(folderPath, file.FileName), FileMode.Create)) @@ -472,7 +472,7 @@ private IActionResult Download(int id, bool asAttachment) { if (_userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions)) { - var filepath = Path.Combine(GetFolderPath(file.Folder), file.Name); + var filepath = _files.GetFilePath(file); if (System.IO.File.Exists(filepath)) { var result = asAttachment @@ -500,11 +500,6 @@ private IActionResult Download(int id, bool asAttachment) return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null; } - private string GetFolderPath(Folder folder) - { - return Utilities.PathCombine(_environment.ContentRootPath, "Content", "Tenants", _tenants.GetTenant().TenantId.ToString(), "Sites", folder.SiteId.ToString(), folder.Path); - } - private string GetFolderPath(string folder) { return Utilities.PathCombine(_environment.WebRootPath, folder); diff --git a/Oqtane.Server/Repository/FileRepository.cs b/Oqtane.Server/Repository/FileRepository.cs index 0e5fa7981..078668105 100644 --- a/Oqtane.Server/Repository/FileRepository.cs +++ b/Oqtane.Server/Repository/FileRepository.cs @@ -1,9 +1,11 @@ using System.Collections.Generic; +using System.IO; using System.Linq; using Microsoft.EntityFrameworkCore; using Oqtane.Extensions; using Oqtane.Models; using Oqtane.Shared; +using File = Oqtane.Models.File; namespace Oqtane.Repository { @@ -11,11 +13,13 @@ public class FileRepository : IFileRepository { private TenantDBContext _db; private readonly IPermissionRepository _permissions; + private readonly IFolderRepository _folderRepository; - public FileRepository(TenantDBContext context, IPermissionRepository permissions) + public FileRepository(TenantDBContext context, IPermissionRepository permissions, IFolderRepository folderRepository) { _db = context; _permissions = permissions; + _folderRepository = folderRepository; } public IEnumerable GetFiles(int folderId) @@ -74,5 +78,19 @@ public void DeleteFile(int fileId) _db.File.Remove(file); _db.SaveChanges(); } + + public string GetFilePath(int fileId) + { + var file = _db.File.Find(fileId); + return GetFilePath(file); + } + + public string GetFilePath(File file) + { + if (file == null) return null; + var folder = file.Folder ?? _db.Folder.Find(file.FolderId); + var filepath = Path.Combine(_folderRepository.GetFolderPath(folder), file.Name); + return filepath; + } } } diff --git a/Oqtane.Server/Repository/FolderRepository.cs b/Oqtane.Server/Repository/FolderRepository.cs index dbaed6c1a..dc7125bbb 100644 --- a/Oqtane.Server/Repository/FolderRepository.cs +++ b/Oqtane.Server/Repository/FolderRepository.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Hosting; using Microsoft.EntityFrameworkCore; using Oqtane.Extensions; using Oqtane.Models; @@ -11,11 +12,15 @@ public class FolderRepository : IFolderRepository { private TenantDBContext _db; private readonly IPermissionRepository _permissions; + private readonly IWebHostEnvironment _environment; + private readonly ITenantResolver _tenants; - public FolderRepository(TenantDBContext context, IPermissionRepository permissions) + public FolderRepository(TenantDBContext context, IPermissionRepository permissions,IWebHostEnvironment environment, ITenantResolver tenants) { _db = context; _permissions = permissions; + _environment = environment; + _tenants = tenants; } public IEnumerable GetFolders(int siteId) @@ -85,5 +90,17 @@ public void DeleteFolder(int folderId) _db.Folder.Remove(folder); _db.SaveChanges(); } + + public string GetFolderPath(int folderId) + { + Folder folder = _db.Folder.Find(folderId); + return GetFolderPath(folder); + } + + public string GetFolderPath(Folder folder) + { + return Utilities.PathCombine(_environment.ContentRootPath, "Content", "Tenants", _tenants.GetTenant().TenantId.ToString(), "Sites", folder.SiteId.ToString(), folder.Path); + } + } } diff --git a/Oqtane.Server/Repository/Interfaces/IFileRepository.cs b/Oqtane.Server/Repository/Interfaces/IFileRepository.cs index 7ef99025a..adfe8f89d 100644 --- a/Oqtane.Server/Repository/Interfaces/IFileRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IFileRepository.cs @@ -11,5 +11,7 @@ public interface IFileRepository File GetFile(int fileId); File GetFile(int fileId, bool tracking); void DeleteFile(int fileId); + string GetFilePath(int fileId); + string GetFilePath(File file); } } diff --git a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs index 52b67e5b7..5ce7467fb 100644 --- a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs @@ -12,5 +12,7 @@ public interface IFolderRepository Folder GetFolder(int folderId, bool tracking); Folder GetFolder(int siteId, string path); void DeleteFolder(int folderId); + string GetFolderPath(int folderId); + string GetFolderPath(Folder folder); } } From c5ae8c979b74efdee4c7ee90d215efc7e39becf3 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 13 Jan 2021 18:19:56 +0300 Subject: [PATCH 133/177] Cultures should come from supported cultures --- .../Modules/Admin/Languages/Add.razor | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Languages/Add.razor b/Oqtane.Client/Modules/Admin/Languages/Add.razor index baa287e53..efd5f22b3 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Add.razor @@ -2,6 +2,7 @@ @inherits ModuleBase @using System.Globalization @inject NavigationManager NavigationManager +@inject ILocalizationService LocalizationService @inject ILanguageService LanguageService @inject IStringLocalizer Localizer @@ -11,12 +12,15 @@ - + @if (_supportedCultures?.Count() > 1) + { + + } @@ -31,7 +35,7 @@ - + @Localizer["Cancel"] @code { @@ -40,9 +44,12 @@ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; - private static IEnumerable GetCultures() - => CultureInfo.GetCultures(CultureTypes.AllCultures) - .Select(c => new Culture { Name = c.Name, DisplayName = c.DisplayName }); + private IEnumerable _supportedCultures; + + protected override async Task OnParametersSetAsync() + { + _supportedCultures = await LocalizationService.GetCulturesAsync(); + } private async Task SaveLanguage() { From b3152ee3e5c162cfa0b511062532bf6d5afab438 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 13 Jan 2021 18:26:36 +0300 Subject: [PATCH 134/177] LanguageSwitcher should have the cultures from language management --- Oqtane.Client/Themes/Controls/LanguageSwitcher.razor | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index 16391513d..dd92bf159 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -1,9 +1,9 @@ @namespace Oqtane.Themes.Controls @inherits ThemeControlBase @using System.Globalization -@using Microsoft.AspNetCore.Localization; +@using Microsoft.AspNetCore.Localization; @using Oqtane.Models -@inject ILocalizationService LocalizationService +@inject ILanguageService LanguageService @inject NavigationManager NavigationManager @if (_supportedCultures?.Count() > 1) @@ -26,7 +26,8 @@ protected override async Task OnParametersSetAsync() { - _supportedCultures = await LocalizationService.GetCulturesAsync(); + var languages = await LanguageService.GetLanguagesAsync(PageState.Site.SiteId); + _supportedCultures = languages.Select(l => new Culture { Name = l.Code, DisplayName = l.Name }); } private async Task SetCultureAsync(string culture) From a2943d083beae73cf45156459d5b483346262cf1 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 13 Jan 2021 18:43:26 +0300 Subject: [PATCH 135/177] Set culture when added language set to current --- .../Modules/Admin/Languages/Add.razor | 18 ++++++++++++++++++ .../Themes/Controls/LanguageSwitcher.razor | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/Languages/Add.razor b/Oqtane.Client/Modules/Admin/Languages/Add.razor index efd5f22b3..02b8e0c25 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Add.razor @@ -1,6 +1,7 @@ @namespace Oqtane.Modules.Admin.Languages @inherits ModuleBase @using System.Globalization +@using Microsoft.AspNetCore.Localization @inject NavigationManager NavigationManager @inject ILocalizationService LocalizationService @inject ILanguageService LanguageService @@ -65,6 +66,11 @@ { language = await LanguageService.AddLanguageAsync(language); + if (language.IsCurrent) + { + await SetCultureAsync(language.Code); + } + await logger.LogInformation("Language Added {Language}", language); NavigationManager.NavigateTo(NavigateUrl()); @@ -76,4 +82,16 @@ AddModuleMessage(Localizer["Error Adding Language"], MessageType.Error); } } + + private async Task SetCultureAsync(string culture) + { + if (culture != CultureInfo.CurrentUICulture.Name) + { + var interop = new Interop(JSRuntime); + var localizationCookieValue = CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)); + await interop.SetCookie(CookieRequestCultureProvider.DefaultCookieName, localizationCookieValue, 360); + + NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true); + } + } } diff --git a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor index dd92bf159..bd4ac6fc9 100644 --- a/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor +++ b/Oqtane.Client/Themes/Controls/LanguageSwitcher.razor @@ -1,7 +1,7 @@ @namespace Oqtane.Themes.Controls @inherits ThemeControlBase @using System.Globalization -@using Microsoft.AspNetCore.Localization; +@using Microsoft.AspNetCore.Localization @using Oqtane.Models @inject ILanguageService LanguageService @inject NavigationManager NavigationManager From 54ff8eced16cd2e641b6db32c3f8ce365a536706 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 13 Jan 2021 23:41:08 +0300 Subject: [PATCH 136/177] Fix the relationship --- Oqtane.Server/Scripts/Tenant.02.00.02.00.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql index 8eb547142..0e6d04ab1 100644 --- a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql +++ b/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql @@ -21,7 +21,7 @@ CREATE TABLE [dbo].[Language]( ) GO -ALTER TABLE [dbo].[Language] WITH CHECK ADD CONSTRAINT [FK_Language_Tenant] FOREIGN KEY([SiteId]) -REFERENCES [dbo].[Tenant] ([TenantId]) +ALTER TABLE [dbo].[Language] WITH CHECK ADD CONSTRAINT [FK_Language_Site] FOREIGN KEY([SiteId]) +REFERENCES [dbo].[Site] ([SiteId]) ON DELETE CASCADE GO \ No newline at end of file From e938d4f8015a2aa039a67b1df1263fd86732b3c2 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 15 Jan 2021 00:28:59 +0300 Subject: [PATCH 137/177] Add Admins role --- Oqtane.Server/Controllers/LanguageController.cs | 6 ++++-- Oqtane.Server/Repository/SiteRepository.cs | 8 ++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Oqtane.Server/Controllers/LanguageController.cs b/Oqtane.Server/Controllers/LanguageController.cs index 2b8f7cf01..c63988bb6 100644 --- a/Oqtane.Server/Controllers/LanguageController.cs +++ b/Oqtane.Server/Controllers/LanguageController.cs @@ -12,6 +12,8 @@ namespace Oqtane.Controllers [Route(ControllerRoutes.Default)] public class LanguageController : Controller { + private const string HostAdminRoles = RoleNames.Host + "," + RoleNames.Admin; + private readonly ILanguageRepository _languages; private readonly ILogManager _logger; @@ -30,7 +32,7 @@ public LanguageController(ILanguageRepository language, ILogManager logger) public Language Get(int id) => _languages.GetLanguage(id); [HttpPost] - [Authorize(Roles = RoleNames.Admin)] + [Authorize(Roles = HostAdminRoles)] public Language Post([FromBody] Language language) { if (ModelState.IsValid) @@ -42,7 +44,7 @@ public Language Post([FromBody] Language language) } [HttpDelete("{id}")] - [Authorize(Roles = RoleNames.Admin)] + [Authorize(Roles = HostAdminRoles)] public void Delete(int id) { _languages.DeleteLanguage(id); diff --git a/Oqtane.Server/Repository/SiteRepository.cs b/Oqtane.Server/Repository/SiteRepository.cs index 647914422..774d03308 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -512,7 +512,9 @@ private List CreateAdminPages(List pageTemplates = n PagePermissions = new List { new Permission(PermissionNames.View, RoleNames.Host, true), - new Permission(PermissionNames.Edit, RoleNames.Host, true) + new Permission(PermissionNames.Edit, RoleNames.Host, true), + new Permission(PermissionNames.View, RoleNames.Admin, true), + new Permission(PermissionNames.Edit, RoleNames.Admin, true) }.EncodePermissions(), PageTemplateModules = new List { @@ -522,7 +524,9 @@ private List CreateAdminPages(List pageTemplates = n ModulePermissions = new List { new Permission(PermissionNames.View, RoleNames.Host, true), - new Permission(PermissionNames.Edit, RoleNames.Host, true) + new Permission(PermissionNames.Edit, RoleNames.Host, true), + new Permission(PermissionNames.View, RoleNames.Admin, true), + new Permission(PermissionNames.Edit, RoleNames.Admin, true) }.EncodePermissions(), Content = "" } From bc0ba9230397e3f092455480e7d2e4a80a680df4 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 15 Jan 2021 01:35:53 +0300 Subject: [PATCH 138/177] Revert the changes in the LanguageController --- Oqtane.Server/Controllers/LanguageController.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Oqtane.Server/Controllers/LanguageController.cs b/Oqtane.Server/Controllers/LanguageController.cs index c63988bb6..2b8f7cf01 100644 --- a/Oqtane.Server/Controllers/LanguageController.cs +++ b/Oqtane.Server/Controllers/LanguageController.cs @@ -12,8 +12,6 @@ namespace Oqtane.Controllers [Route(ControllerRoutes.Default)] public class LanguageController : Controller { - private const string HostAdminRoles = RoleNames.Host + "," + RoleNames.Admin; - private readonly ILanguageRepository _languages; private readonly ILogManager _logger; @@ -32,7 +30,7 @@ public LanguageController(ILanguageRepository language, ILogManager logger) public Language Get(int id) => _languages.GetLanguage(id); [HttpPost] - [Authorize(Roles = HostAdminRoles)] + [Authorize(Roles = RoleNames.Admin)] public Language Post([FromBody] Language language) { if (ModelState.IsValid) @@ -44,7 +42,7 @@ public Language Post([FromBody] Language language) } [HttpDelete("{id}")] - [Authorize(Roles = HostAdminRoles)] + [Authorize(Roles = RoleNames.Admin)] public void Delete(int id) { _languages.DeleteLanguage(id); From a2029a3ca3ac498bc9e3cf011dc69ef5f1639297 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Sun, 17 Jan 2021 11:46:09 -0500 Subject: [PATCH 139/177] auto registration of scheduled jobs --- .../Infrastructure/DatabaseManager.cs | 10 +--- .../Infrastructure/Jobs/HostedServiceBase.cs | 56 +++++++++++++++---- .../Infrastructure/Jobs/NotificationJob.cs | 8 ++- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs index 4f5983225..35f933537 100644 --- a/Oqtane.Server/Infrastructure/DatabaseManager.cs +++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Data; using System.IO; @@ -244,14 +244,6 @@ private Installation CreateTenant(InstallConfig install) db.Tenant.Add(tenant); db.SaveChanges(); _cache.Remove("tenants"); - - if (install.TenantName == TenantNames.Master) - { - var job = new Job { Name = "Notification Job", JobType = "Oqtane.Infrastructure.NotificationJob, Oqtane.Server", Frequency = "m", Interval = 1, StartDate = null, EndDate = null, IsEnabled = false, IsStarted = false, IsExecuting = false, NextExecution = null, RetentionHistory = 10, CreatedBy = "", CreatedOn = DateTime.UtcNow, ModifiedBy = "", ModifiedOn = DateTime.UtcNow }; - db.Job.Add(job); - db.SaveChanges(); - _cache.Remove("jobs"); - } } else { diff --git a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs index 5fb499345..96ab55a08 100644 --- a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs +++ b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -25,6 +25,15 @@ public HostedServiceBase(IServiceScopeFactory serviceScopeFactory) // abstract method must be overridden public abstract string ExecuteJob(IServiceProvider provider); + // public properties which can be overridden and are used during auto registration of job + public string Name { get; set; } = ""; + public string Frequency { get; set; } = "d"; // day + public int Interval { get; set; } = 1; + public DateTime? StartDate { get; set; } = null; + public DateTime? EndDate { get; set; } = null; + public int RetentionHistory { get; set; } = 10; + public bool IsEnabled { get; set; } = false; + protected async Task ExecuteAsync(CancellationToken stoppingToken) { await Task.Yield(); // required so that this method does not block startup @@ -153,27 +162,52 @@ public Task StartAsync(CancellationToken cancellationToken) // set IsExecuting to false in case this job was forcefully terminated previously using (var scope = _serviceScopeFactory.CreateScope()) { - string jobType = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName); + string jobTypeName = Utilities.GetFullTypeName(GetType().AssemblyQualifiedName); IJobRepository jobs = scope.ServiceProvider.GetRequiredService(); - Job job = jobs.GetJobs().Where(item => item.JobType == jobType).FirstOrDefault(); + Job job = jobs.GetJobs().Where(item => item.JobType == jobTypeName).FirstOrDefault(); if (job != null) { job.IsStarted = true; job.IsExecuting = false; jobs.UpdateJob(job); } + else + { + // auto registration + job = new Job { JobType = jobTypeName }; + // optional properties + var jobType = Type.GetType(jobTypeName); + var jobObject = ActivatorUtilities.CreateInstance(scope.ServiceProvider, jobType) as HostedServiceBase; + if (jobObject.Name != "") + { + job.Name = jobObject.Name; + } + else + { + job.Name = Utilities.GetTypeName(job.JobType); + } + job.Frequency = jobObject.Frequency; + job.Interval = jobObject.Interval; + job.StartDate = jobObject.StartDate; + job.EndDate = jobObject.EndDate; + job.RetentionHistory = jobObject.RetentionHistory; + job.IsEnabled = jobObject.IsEnabled; + job.IsStarted = true; + job.IsExecuting = false; + jobs.AddJob(job); + } } - } - catch - { - // can occur during the initial installation as there is no DBContext - } - _executingTask = ExecuteAsync(_cancellationTokenSource.Token); + _executingTask = ExecuteAsync(_cancellationTokenSource.Token); - if (_executingTask.IsCompleted) + if (_executingTask.IsCompleted) + { + return _executingTask; + } + } + catch { - return _executingTask; + // can occur during the initial installation because this method is called during startup and the database has not yet been created } return Task.CompletedTask; diff --git a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs index deafe30ac..bc1a2d318 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -14,7 +14,13 @@ public class NotificationJob : HostedServiceBase { // JobType = "Oqtane.Infrastructure.NotificationJob, Oqtane.Server" - public NotificationJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory) {} + public NotificationJob(IServiceScopeFactory serviceScopeFactory) : base(serviceScopeFactory) + { + Name = "Notification Job"; + Frequency = "m"; // minute + Interval = 1; + IsEnabled = false; + } public override string ExecuteJob(IServiceProvider provider) { From 8be9fd6eb2ae9d7dc0d1d436043983934c995636 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 18 Jan 2021 08:59:07 -0500 Subject: [PATCH 140/177] set SiteState in HostedServiceBase for scheduled jobs --- .../Infrastructure/Jobs/HostedServiceBase.cs | 10 +- .../Infrastructure/Jobs/NotificationJob.cs | 156 ++++++++---------- 2 files changed, 80 insertions(+), 86 deletions(-) diff --git a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs index 96ab55a08..36fbefb6e 100644 --- a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs +++ b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs @@ -91,7 +91,15 @@ protected async Task ExecuteAsync(CancellationToken stoppingToken) // execute the job try { - log.Notes = ExecuteJob(scope.ServiceProvider); + var notes = ""; + var tenants = scope.ServiceProvider.GetRequiredService(); + var siteState = scope.ServiceProvider.GetRequiredService(); + foreach (var tenant in tenants.GetTenants()) + { + siteState.Alias = new Alias { TenantId = tenant.TenantId }; + notes += ExecuteJob(scope.ServiceProvider); + } + log.Notes = notes; log.Succeeded = true; } catch (Exception ex) diff --git a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs index bc1a2d318..92d1d3366 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -26,103 +26,89 @@ public override string ExecuteJob(IServiceProvider provider) { string log = ""; - // iterate through tenants in this installation - List tenants = new List(); - var aliasRepository = provider.GetRequiredService(); - List aliases = aliasRepository.GetAliases().ToList(); - foreach (Alias alias in aliases) - { - if (tenants.Contains(alias.TenantId)) continue; - tenants.Add(alias.TenantId); - - // use the SiteState to set the Alias explicitly so the tenant can be resolved - var siteState = provider.GetRequiredService(); - siteState.Alias = alias; + // get services + var siteRepository = provider.GetRequiredService(); + var settingRepository = provider.GetRequiredService(); + var notificationRepository = provider.GetRequiredService(); - // get services which require tenant resolution - var siteRepository = provider.GetRequiredService(); - var settingRepository = provider.GetRequiredService(); - var notificationRepository = provider.GetRequiredService(); + // iterate through sites for this tenant + List sites = siteRepository.GetSites().ToList(); + foreach (Site site in sites) + { + log += "Processing Notifications For Site: " + site.Name + "
"; - // iterate through sites for this tenant - List sites = siteRepository.GetSites().ToList(); - foreach (Site site in sites) + // get site settings + List sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList(); + Dictionary settings = GetSettings(sitesettings); + if (settings.ContainsKey("SMTPHost") && settings["SMTPHost"] != "" && + settings.ContainsKey("SMTPPort") && settings["SMTPPort"] != "" && + settings.ContainsKey("SMTPSSL") && settings["SMTPSSL"] != "" && + settings.ContainsKey("SMTPSender") && settings["SMTPSender"] != "") { - log += "Processing Notifications For Site: " + site.Name + "
"; + // construct SMTP Client + var client = new SmtpClient() + { + DeliveryMethod = SmtpDeliveryMethod.Network, + UseDefaultCredentials = false, + Host = settings["SMTPHost"], + Port = int.Parse(settings["SMTPPort"]), + EnableSsl = bool.Parse(settings["SMTPSSL"]) + }; + if (settings["SMTPUsername"] != "" && settings["SMTPPassword"] != "") + { + client.Credentials = new NetworkCredential(settings["SMTPUsername"], settings["SMTPPassword"]); + } - // get site settings - List sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList(); - Dictionary settings = GetSettings(sitesettings); - if (settings.ContainsKey("SMTPHost") && settings["SMTPHost"] != "" && - settings.ContainsKey("SMTPPort") && settings["SMTPPort"] != "" && - settings.ContainsKey("SMTPSSL") && settings["SMTPSSL"] != "" && - settings.ContainsKey("SMTPSender") && settings["SMTPSender"] != "") + // iterate through notifications + int sent = 0; + List notifications = notificationRepository.GetNotifications(site.SiteId, -1, -1).ToList(); + foreach (Notification notification in notifications) { - // construct SMTP Client - var client = new SmtpClient() + MailMessage mailMessage = new MailMessage(); + mailMessage.From = new MailAddress(settings["SMTPSender"], site.Name); + mailMessage.Subject = notification.Subject; + if (notification.FromUserId != null) { - DeliveryMethod = SmtpDeliveryMethod.Network, - UseDefaultCredentials = false, - Host = settings["SMTPHost"], - Port = int.Parse(settings["SMTPPort"]), - EnableSsl = bool.Parse(settings["SMTPSSL"]) - }; - if (settings["SMTPUsername"] != "" && settings["SMTPPassword"] != "") + mailMessage.Body = "From: " + notification.FromDisplayName + "<" + notification.FromEmail + ">" + "\n"; + } + else { - client.Credentials = new NetworkCredential(settings["SMTPUsername"], settings["SMTPPassword"]); + mailMessage.Body = "From: " + site.Name + "\n"; } - - // iterate through notifications - int sent = 0; - List notifications = notificationRepository.GetNotifications(site.SiteId, -1, -1).ToList(); - foreach (Notification notification in notifications) + mailMessage.Body += "Sent: " + notification.CreatedOn + "\n"; + if (notification.ToUserId != null) + { + mailMessage.To.Add(new MailAddress(notification.ToEmail, notification.ToDisplayName)); + mailMessage.Body += "To: " + notification.ToDisplayName + "<" + notification.ToEmail + ">" + "\n"; + } + else { - MailMessage mailMessage = new MailMessage(); - mailMessage.From = new MailAddress(settings["SMTPSender"], site.Name); - mailMessage.Subject = notification.Subject; - if (notification.FromUserId != null) - { - mailMessage.Body = "From: " + notification.FromDisplayName + "<" + notification.FromEmail + ">" + "\n"; - } - else - { - mailMessage.Body = "From: " + site.Name + "\n"; - } - mailMessage.Body += "Sent: " + notification.CreatedOn + "\n"; - if (notification.ToUserId != null) - { - mailMessage.To.Add(new MailAddress(notification.ToEmail, notification.ToDisplayName)); - mailMessage.Body += "To: " + notification.ToDisplayName + "<" + notification.ToEmail + ">" + "\n"; - } - else - { - mailMessage.To.Add(new MailAddress(notification.ToEmail)); - mailMessage.Body += "To: " + notification.ToEmail + "\n"; - } - mailMessage.Body += "Subject: " + notification.Subject + "\n\n"; - mailMessage.Body += notification.Body; + mailMessage.To.Add(new MailAddress(notification.ToEmail)); + mailMessage.Body += "To: " + notification.ToEmail + "\n"; + } + mailMessage.Body += "Subject: " + notification.Subject + "\n\n"; + mailMessage.Body += notification.Body; - // send mail - try - { - client.Send(mailMessage); - sent = sent++; - notification.IsDelivered = true; - notification.DeliveredOn = DateTime.UtcNow; - notificationRepository.UpdateNotification(notification); - } - catch (Exception ex) - { - // error - log += ex.Message + "
"; - } + // send mail + try + { + client.Send(mailMessage); + sent = sent++; + notification.IsDelivered = true; + notification.DeliveredOn = DateTime.UtcNow; + notificationRepository.UpdateNotification(notification); + } + catch (Exception ex) + { + // error + log += ex.Message + "
"; } - log += "Notifications Delivered: " + sent + "
"; - } - else - { - log += "SMTP Not Configured Properly In Site Settings - Host, Port, SSL, And Sender Are All Required" + "
"; } + log += "Notifications Delivered: " + sent + "
"; + } + else + { + log += "SMTP Not Configured Properly In Site Settings - Host, Port, SSL, And Sender Are All Required" + "
"; } } From b664bc2dbb18a2ab0db365ea8c5a9ad70c28d0e5 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 18 Jan 2021 10:19:42 -0500 Subject: [PATCH 141/177] remove Add Job component and make Type read-only in Edit --- Oqtane.Client/Modules/Admin/Jobs/Add.razor | 141 ------------------- Oqtane.Client/Modules/Admin/Jobs/Edit.razor | 4 +- Oqtane.Client/Modules/Admin/Jobs/Index.razor | 1 - 3 files changed, 2 insertions(+), 144 deletions(-) delete mode 100644 Oqtane.Client/Modules/Admin/Jobs/Add.razor diff --git a/Oqtane.Client/Modules/Admin/Jobs/Add.razor b/Oqtane.Client/Modules/Admin/Jobs/Add.razor deleted file mode 100644 index 8535d2c0f..000000000 --- a/Oqtane.Client/Modules/Admin/Jobs/Add.razor +++ /dev/null @@ -1,141 +0,0 @@ -@namespace Oqtane.Modules.Admin.Jobs -@inherits ModuleBase -@inject NavigationManager NavigationManager -@inject IJobService JobService -@inject IStringLocalizer Localizer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -
- - - -
- - - - -
- - - -
- - - -
- - - -
- -@Localizer["Cancel"] - -@code { - private string _name = string.Empty; - private string _jobType = string.Empty; - private string _isEnabled = "True"; - private string _interval = string.Empty; - private string _frequency = string.Empty; - private string _startDate = string.Empty; - private string _endDate = string.Empty; - private string _retentionHistory = "10"; - - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - - private async Task SaveJob() - { - if (_name != string.Empty && !string.IsNullOrEmpty(_jobType) && _frequency != string.Empty && _interval != string.Empty && _retentionHistory != string.Empty) - { - var job = new Job(); - job.Name = _name; - job.JobType = _jobType; - job.IsEnabled = Boolean.Parse(_isEnabled); - job.Frequency = _frequency; - job.Interval = int.Parse(_interval); - - if (_startDate == string.Empty) - { - job.StartDate = null; - } - else - { - job.StartDate = DateTime.Parse(_startDate); - } - - if (_endDate == string.Empty) - { - job.EndDate = null; - } - else - { - job.EndDate = DateTime.Parse(_endDate); - } - - job.RetentionHistory = int.Parse(_retentionHistory); - job.IsStarted = false; - job.IsExecuting = false; - job.NextExecution = null; - - try - { - job = await JobService.AddJobAsync(job); - await logger.LogInformation("Job Added {Job}", job); - NavigationManager.NavigateTo(NavigateUrl()); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Adding Job {Job} {Error}", job, ex.Message); - AddModuleMessage(Localizer["Error Adding Job"], MessageType.Error); - } - } - else - { - AddModuleMessage(Localizer["You Must Provide The Job Name, Type, Frequency, and Retention"], MessageType.Warning); - } - } - -} diff --git a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor index 65043de8d..9a436b6db 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Edit.razor @@ -15,10 +15,10 @@ - + - + diff --git a/Oqtane.Client/Modules/Admin/Jobs/Index.razor b/Oqtane.Client/Modules/Admin/Jobs/Index.razor index 7a435f776..5aefdcbe2 100644 --- a/Oqtane.Client/Modules/Admin/Jobs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Jobs/Index.razor @@ -9,7 +9,6 @@ } else { -
From 82a118b603fe1b9394be0cf2b253cc7987b358fe Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 18 Jan 2021 14:39:56 -0500 Subject: [PATCH 142/177] notification improvements --- .../Modules/Admin/UserProfile/Add.razor | 20 +--- .../Modules/Admin/UserProfile/View.razor | 20 +--- Oqtane.Server/Controllers/UserController.cs | 30 +----- .../Infrastructure/Jobs/NotificationJob.cs | 96 ++++++++++++------- .../Repository/NotificationRepository.cs | 4 +- Oqtane.Shared/Models/Notification.cs | 46 ++++++++- 6 files changed, 122 insertions(+), 94 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor index d32127268..dcc96ff43 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor @@ -48,26 +48,12 @@ private async Task Send() { - var notification = new Notification(); try { var user = await UserService.GetUserAsync(username, PageState.Site.SiteId); if (user != null) - { - notification.SiteId = PageState.Site.SiteId; - notification.FromUserId = PageState.User.UserId; - notification.FromDisplayName = PageState.User.DisplayName; - notification.FromEmail = PageState.User.Email; - notification.ToUserId = user.UserId; - notification.ToDisplayName = user.DisplayName; - notification.ToEmail = user.Email; - notification.Subject = subject; - notification.Body = body; - notification.ParentId = null; - notification.CreatedOn = DateTime.UtcNow; - notification.IsDelivered = false; - notification.DeliveredOn = null; - notification.SendOn = DateTime.UtcNow; + { + 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); NavigationManager.NavigateTo(NavigateUrl()); @@ -79,7 +65,7 @@ } catch (Exception ex) { - await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message); + await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message); AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/UserProfile/View.razor b/Oqtane.Client/Modules/Admin/UserProfile/View.razor index fcd7340c0..ff9f39373 100644 --- a/Oqtane.Client/Modules/Admin/UserProfile/View.razor +++ b/Oqtane.Client/Modules/Admin/UserProfile/View.razor @@ -176,26 +176,12 @@ private async Task Send() { - var notification = new Notification(); try { var user = await UserService.GetUserAsync(username, PageState.Site.SiteId); if (user != null) - { - notification.SiteId = PageState.Site.SiteId; - notification.FromUserId = PageState.User.UserId; - notification.FromDisplayName = PageState.User.DisplayName; - notification.FromEmail = PageState.User.Email; - notification.ToUserId = user.UserId; - notification.ToDisplayName = user.DisplayName; - notification.ToEmail = user.Email; - notification.Subject = subject; - notification.Body = body; - notification.ParentId = notificationid; - notification.CreatedOn = DateTime.UtcNow; - notification.IsDelivered = false; - notification.DeliveredOn = null; - notification.SendOn = DateTime.UtcNow; + { + 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); NavigationManager.NavigateTo(NavigateUrl()); @@ -207,7 +193,7 @@ } catch (Exception ex) { - await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message); + await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message); AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error); } } diff --git a/Oqtane.Server/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs index 5a97087af..9819994b6 100644 --- a/Oqtane.Server/Controllers/UserController.cs +++ b/Oqtane.Server/Controllers/UserController.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; @@ -146,20 +146,10 @@ private async Task CreateUser(User user) newUser = _users.AddUser(user); if (!verified) { - Notification notification = new Notification(); - notification.SiteId = user.SiteId; - notification.FromUserId = null; - notification.ToUserId = newUser.UserId; - notification.ToEmail = newUser.Email; - notification.Subject = "User Account Verification"; string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser); string url = HttpContext.Request.Scheme + "://" + _tenants.GetAlias().Name + "/login?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token); - notification.Body = "Dear " + user.DisplayName + ",\n\nIn Order To Complete The Registration Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!"; - notification.ParentId = null; - notification.CreatedOn = DateTime.UtcNow; - notification.IsDelivered = false; - notification.DeliveredOn = null; - notification.SendOn = DateTime.UtcNow; + string body = "Dear " + user.DisplayName + ",\n\nIn Order To Complete The Registration Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!"; + var notification = new Notification(user.SiteId, null, newUser, "User Account Verification", body, null); _notifications.AddNotification(notification); } @@ -379,20 +369,10 @@ public async Task Forgot([FromBody] User user) IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username); if (identityuser != null) { - Notification notification = new Notification(); - notification.SiteId = user.SiteId; - notification.FromUserId = null; - notification.ToUserId = user.UserId; - notification.ToEmail = ""; - notification.Subject = "User Password Reset"; string token = await _identityUserManager.GeneratePasswordResetTokenAsync(identityuser); string url = HttpContext.Request.Scheme + "://" + _tenants.GetAlias().Name + "/reset?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token); - notification.Body = "Dear " + user.DisplayName + ",\n\nPlease Click The Link Displayed Below To Reset Your Password:\n\n" + url + "\n\nThank You!"; - notification.ParentId = null; - notification.CreatedOn = DateTime.UtcNow; - notification.IsDelivered = false; - notification.DeliveredOn = null; - notification.SendOn = DateTime.UtcNow; + string body = "Dear " + user.DisplayName + ",\n\nPlease Click The Link Displayed Below To Reset Your Password:\n\n" + url + "\n\nThank You!"; + var notification = new Notification(user.SiteId, null, user, "User Password Reset", body, null); _notifications.AddNotification(notification); _logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset Notification Sent For {Username}", user.Username); } diff --git a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs index 92d1d3366..7818d9d3b 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -22,16 +22,18 @@ public NotificationJob(IServiceScopeFactory serviceScopeFactory) : base(serviceS IsEnabled = false; } + // job is executed for each tenant in installation public override string ExecuteJob(IServiceProvider provider) { string log = ""; // get services var siteRepository = provider.GetRequiredService(); + var userRepository = provider.GetRequiredService(); var settingRepository = provider.GetRequiredService(); var notificationRepository = provider.GetRequiredService(); - // iterate through sites for this tenant + // iterate through sites for current tenant List sites = siteRepository.GetSites().ToList(); foreach (Site site in sites) { @@ -59,49 +61,79 @@ public override string ExecuteJob(IServiceProvider provider) client.Credentials = new NetworkCredential(settings["SMTPUsername"], settings["SMTPPassword"]); } - // iterate through notifications + // iterate through undelivered notifications int sent = 0; List notifications = notificationRepository.GetNotifications(site.SiteId, -1, -1).ToList(); foreach (Notification notification in notifications) { - MailMessage mailMessage = new MailMessage(); - mailMessage.From = new MailAddress(settings["SMTPSender"], site.Name); - mailMessage.Subject = notification.Subject; - if (notification.FromUserId != null) + // get sender and receiver information if not provided + if ((string.IsNullOrEmpty(notification.FromEmail) || string.IsNullOrEmpty(notification.FromDisplayName)) && notification.FromUserId != null) { - mailMessage.Body = "From: " + notification.FromDisplayName + "<" + notification.FromEmail + ">" + "\n"; + var user = userRepository.GetUser(notification.FromUserId.Value); + if (user != null) + { + notification.FromEmail = (string.IsNullOrEmpty(notification.FromEmail)) ? user.Email : notification.FromEmail; + notification.FromDisplayName = (string.IsNullOrEmpty(notification.FromDisplayName)) ? user.DisplayName : notification.FromDisplayName; + } } - else - { - mailMessage.Body = "From: " + site.Name + "\n"; - } - mailMessage.Body += "Sent: " + notification.CreatedOn + "\n"; - if (notification.ToUserId != null) + if ((string.IsNullOrEmpty(notification.ToEmail) || string.IsNullOrEmpty(notification.ToDisplayName)) && notification.ToUserId != null) { - mailMessage.To.Add(new MailAddress(notification.ToEmail, notification.ToDisplayName)); - mailMessage.Body += "To: " + notification.ToDisplayName + "<" + notification.ToEmail + ">" + "\n"; + var user = userRepository.GetUser(notification.ToUserId.Value); + if (user != null) + { + notification.ToEmail = (string.IsNullOrEmpty(notification.ToEmail)) ? user.Email : notification.ToEmail; + notification.ToDisplayName = (string.IsNullOrEmpty(notification.ToDisplayName)) ? user.DisplayName : notification.ToDisplayName; + } } - else - { - mailMessage.To.Add(new MailAddress(notification.ToEmail)); - mailMessage.Body += "To: " + notification.ToEmail + "\n"; - } - mailMessage.Body += "Subject: " + notification.Subject + "\n\n"; - mailMessage.Body += notification.Body; - - // send mail - try + + // validate recipient + if (string.IsNullOrEmpty(notification.ToEmail)) { - client.Send(mailMessage); - sent = sent++; - notification.IsDelivered = true; - notification.DeliveredOn = DateTime.UtcNow; + log += "Recipient Missing For NotificationId: " + notification.NotificationId + "
"; + notification.IsDeleted = true; notificationRepository.UpdateNotification(notification); } - catch (Exception ex) + else { - // error - log += ex.Message + "
"; + MailMessage mailMessage = new MailMessage(); + mailMessage.From = new MailAddress(settings["SMTPSender"], site.Name); + mailMessage.Subject = notification.Subject; + if (!string.IsNullOrEmpty(notification.FromEmail) && !string.IsNullOrEmpty(notification.FromDisplayName)) + { + mailMessage.Body = "From: " + notification.FromDisplayName + "<" + notification.FromEmail + ">" + "\n"; + } + else + { + mailMessage.Body = "From: " + site.Name + "\n"; + } + mailMessage.Body += "Sent: " + notification.CreatedOn + "\n"; + if (!string.IsNullOrEmpty(notification.ToEmail) && !string.IsNullOrEmpty(notification.ToDisplayName)) + { + mailMessage.To.Add(new MailAddress(notification.ToEmail, notification.ToDisplayName)); + mailMessage.Body += "To: " + notification.ToDisplayName + "<" + notification.ToEmail + ">" + "\n"; + } + else + { + mailMessage.To.Add(new MailAddress(notification.ToEmail)); + mailMessage.Body += "To: " + notification.ToEmail + "\n"; + } + mailMessage.Body += "Subject: " + notification.Subject + "\n\n"; + mailMessage.Body += notification.Body; + + // send mail + try + { + client.Send(mailMessage); + sent = sent++; + notification.IsDelivered = true; + notification.DeliveredOn = DateTime.UtcNow; + notificationRepository.UpdateNotification(notification); + } + catch (Exception ex) + { + // error + log += ex.Message + "
"; + } } } log += "Notifications Delivered: " + sent + "
"; diff --git a/Oqtane.Server/Repository/NotificationRepository.cs b/Oqtane.Server/Repository/NotificationRepository.cs index 43025c3a2..38ec8559c 100644 --- a/Oqtane.Server/Repository/NotificationRepository.cs +++ b/Oqtane.Server/Repository/NotificationRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using Oqtane.Models; @@ -20,7 +20,7 @@ public IEnumerable GetNotifications(int siteId, int fromUserId, in { return _db.Notification .Where(item => item.SiteId == siteId) - .Where(item => item.IsDelivered == false) + .Where(item => item.IsDelivered == false && item.IsDeleted == false) .Where(item => item.SendOn == null || item.SendOn < System.DateTime.UtcNow) .ToList(); } diff --git a/Oqtane.Shared/Models/Notification.cs b/Oqtane.Shared/Models/Notification.cs index 7ccdbd9d4..6795c9544 100644 --- a/Oqtane.Shared/Models/Notification.cs +++ b/Oqtane.Shared/Models/Notification.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel.DataAnnotations.Schema; namespace Oqtane.Models @@ -23,6 +23,50 @@ public class Notification : IDeletable public DateTime? DeletedOn { get; set; } public bool IsDeleted { get; set; } public DateTime? SendOn { get; set; } + + public Notification() {} + + public Notification(int siteId, User from, User to, string subject, string body, int? parentId) + { + SiteId = siteId; + if (from != null) + { + FromUserId = from.UserId; + FromDisplayName = from.DisplayName; + FromEmail = from.Email; + } + if (to != null) + { + ToUserId = to.UserId; + ToDisplayName = to.DisplayName; + ToEmail = to.Email; + } + Subject = subject; + Body = body; + ParentId = parentId; + CreatedOn = DateTime.UtcNow; + IsDelivered = false; + DeliveredOn = null; + SendOn = DateTime.UtcNow; + } + + public Notification(int siteId, string fromDisplayName, string fromEmail, string toDisplayName, string toEmail, string subject, string body) + { + SiteId = siteId; + FromUserId = null; + FromDisplayName = fromDisplayName; + FromEmail = fromEmail; + ToUserId = null; + ToDisplayName = toDisplayName; + ToEmail = toEmail; + Subject = subject; + Body = body; + ParentId = null; + CreatedOn = DateTime.UtcNow; + IsDelivered = false; + DeliveredOn = null; + SendOn = DateTime.UtcNow; + } } } From c0ed7c79345443f004c46ea0940704ac20f63e55 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 21 Jan 2021 17:09:34 -0500 Subject: [PATCH 143/177] Localization fixes - table definition, SQL script naming, SQL script not marked as Embedded Resource, changed column name from IsCurrrent to IsDefault to reflect intent, set default language for site in _Host --- .../Modules/Admin/Languages/Add.razor | 80 +++++++++++-------- .../Modules/Admin/Languages/Index.razor | 6 +- Oqtane.Server/Controllers/AliasController.cs | 21 +---- Oqtane.Server/Oqtane.Server.csproj | 1 + Oqtane.Server/Pages/_Host.cshtml.cs | 35 ++++++++ Oqtane.Server/Repository/AliasRepository.cs | 23 +++++- .../Repository/Context/DBContextBase.cs | 16 ++-- .../Repository/Context/MasterDBContext.cs | 18 ++++- .../Repository/Interfaces/IAliasRepository.cs | 3 +- .../Repository/LanguageRepository.cs | 4 +- Oqtane.Server/Repository/TenantResolver.cs | 54 ++++++++----- ...02.00.02.00.sql => Tenant.02.00.01.02.sql} | 4 +- Oqtane.Server/Startup.cs | 5 +- Oqtane.Shared/Models/Language.cs | 2 +- 14 files changed, 178 insertions(+), 94 deletions(-) rename Oqtane.Server/Scripts/{Tenant.02.00.02.00.sql => Tenant.02.00.01.02.sql} (90%) diff --git a/Oqtane.Client/Modules/Admin/Languages/Add.razor b/Oqtane.Client/Modules/Admin/Languages/Add.razor index 02b8e0c25..7efbcf858 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Add.razor @@ -7,41 +7,48 @@ @inject ILanguageService LanguageService @inject IStringLocalizer Localizer - - - - - - - - - -
- - - @if (_supportedCultures?.Count() > 1) - { - - } -
- - - -
- -@Localizer["Cancel"] +@if (_supportedCultures == null) +{ +

@Localizer["Loading..."]

+} +else +{ + @if (_supportedCultures?.Count() > 1) + { + + + + + + + + + +
+ + + +
+ + + +
+ + } + @Localizer["Cancel"] +} @code { private string _code = string.Empty; - private string _isCurrent = "False"; + private string _isDefault = "False"; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; @@ -50,6 +57,10 @@ protected override async Task OnParametersSetAsync() { _supportedCultures = await LocalizationService.GetCulturesAsync(); + if (_supportedCultures.Count() <= 1) + { + AddModuleMessage(Localizer["The Only Supported Culture That Has Been Defined Is English"], MessageType.Warning); + } } private async Task SaveLanguage() @@ -59,14 +70,14 @@ SiteId = PageState.Page.SiteId, Name = CultureInfo.GetCultureInfo(_code).DisplayName, Code = _code, - IsCurrent = (_isCurrent == null ? false : Boolean.Parse(_isCurrent)) + IsDefault = (_isDefault == null ? false : Boolean.Parse(_isDefault)) }; try { language = await LanguageService.AddLanguageAsync(language); - if (language.IsCurrent) + if (language.IsDefault) { await SetCultureAsync(language.Code); } @@ -78,7 +89,6 @@ catch (Exception ex) { await logger.LogError(ex, "Error Adding Language {Language} {Error}", language, ex.Message); - AddModuleMessage(Localizer["Error Adding Language"], MessageType.Error); } } diff --git a/Oqtane.Client/Modules/Admin/Languages/Index.razor b/Oqtane.Client/Modules/Admin/Languages/Index.razor index 933903ccd..748c875b6 100644 --- a/Oqtane.Client/Modules/Admin/Languages/Index.razor +++ b/Oqtane.Client/Modules/Admin/Languages/Index.razor @@ -16,13 +16,13 @@ else   @Localizer["Name"] @Localizer["Code"] - @Localizer["Is Current"] + @Localizer["Default?"] - + @context.Name @context.Code - + } diff --git a/Oqtane.Server/Controllers/AliasController.cs b/Oqtane.Server/Controllers/AliasController.cs index 8956bac7e..4d8dac8d8 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -50,29 +50,13 @@ public Alias Get(int id) [HttpGet("name/{**name}")] public Alias Get(string name, string sync) { - List aliases = _aliases.GetAliases().ToList(); // cached Alias alias = null; + if (_accessor.HttpContext != null) { name = (name == "~") ? "" : name; name = _accessor.HttpContext.Request.Host.Value + "/" + WebUtility.UrlDecode(name); - var segments = name.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); - - // iterate segments in reverse order - for (int i = segments.Length; i > 0; i--) - { - name = string.Join("/", segments, 0, i); - alias = aliases.Find(item => item.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); - if (alias != null) - { - break; // found a matching alias - } - } - } - if (alias == null && aliases.Any()) - { - // use first alias if name does not exist - alias = aliases.FirstOrDefault(); + alias = _aliases.GetAlias(name); } // get sync events @@ -81,6 +65,7 @@ public Alias Get(string name, string sync) alias.SyncDate = DateTime.UtcNow; alias.SyncEvents = _syncManager.GetSyncEvents(alias.TenantId, DateTime.ParseExact(sync, "yyyyMMddHHmmssfff", CultureInfo.InvariantCulture)); } + return alias; } diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 8176804d2..1ac18c292 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -35,6 +35,7 @@ + diff --git a/Oqtane.Server/Pages/_Host.cshtml.cs b/Oqtane.Server/Pages/_Host.cshtml.cs index c50e5b1f1..662beb18f 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -7,11 +7,28 @@ using System; using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Http.Extensions; +using Oqtane.Repository; +using Microsoft.AspNetCore.Localization; +using Microsoft.Extensions.Configuration; namespace Oqtane.Pages { public class HostModel : PageModel { + private IConfiguration _configuration; + private readonly SiteState _state; + private readonly IAliasRepository _aliases; + private readonly ILanguageRepository _languages; + + public HostModel(IConfiguration configuration, SiteState state, IAliasRepository aliases, ILanguageRepository languages) + { + _configuration = configuration; + _state = state; + _aliases = aliases; + _languages = languages; + } + public string HeadResources = ""; public string BodyResources = ""; @@ -24,6 +41,24 @@ public void OnGet() ProcessModuleControls(assembly); ProcessThemeControls(assembly); } + + // if framework is installed + if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) + { + Uri uri = new Uri(Request.GetDisplayUrl()); + var alias = _aliases.GetAlias(uri.Authority + "/" + uri.LocalPath.Substring(1)); + _state.Alias = alias; + + // set default language for site + var language = _languages.GetLanguages(alias.SiteId).Where(item => item.IsDefault).FirstOrDefault(); + if (language != null) + { + HttpContext.Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue( + new RequestCulture(language.Code))); + } + } } private void ProcessHostResources(Assembly assembly) diff --git a/Oqtane.Server/Repository/AliasRepository.cs b/Oqtane.Server/Repository/AliasRepository.cs index ccb266813..f25c4c035 100644 --- a/Oqtane.Server/Repository/AliasRepository.cs +++ b/Oqtane.Server/Repository/AliasRepository.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; @@ -48,6 +48,27 @@ public Alias GetAlias(int aliasId) return _db.Alias.Find(aliasId); } + public Alias GetAlias(string name) + { + Alias alias = null; + + List aliases = GetAliases().ToList(); + var segments = name.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + + // iterate segments in reverse order + for (int i = segments.Length; i > 0; i--) + { + name = string.Join("/", segments, 0, i); + alias = aliases.Find(item => item.Name.Equals(name, StringComparison.OrdinalIgnoreCase)); + if (alias != null) + { + break; // found a matching alias + } + } + + return alias; + } + public void DeleteAlias(int aliasId) { Alias alias = _db.Alias.Find(aliasId); diff --git a/Oqtane.Server/Repository/Context/DBContextBase.cs b/Oqtane.Server/Repository/Context/DBContextBase.cs index 247006bd9..522bf0d9e 100644 --- a/Oqtane.Server/Repository/Context/DBContextBase.cs +++ b/Oqtane.Server/Repository/Context/DBContextBase.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; @@ -10,20 +10,24 @@ namespace Oqtane.Repository { public class DBContextBase : IdentityUserContext { - private Tenant _tenant; + private ITenantResolver _tenantResolver; private IHttpContextAccessor _accessor; public DBContextBase(ITenantResolver tenantResolver, IHttpContextAccessor accessor) { - _tenant = tenantResolver.GetTenant(); + _tenantResolver = tenantResolver; _accessor = accessor; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { - optionsBuilder.UseSqlServer(_tenant.DBConnectionString - .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()) - ); + var tenant = _tenantResolver.GetTenant(); + if (tenant != null) + { + optionsBuilder.UseSqlServer(tenant.DBConnectionString + .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()) + ); + } base.OnConfiguring(optionsBuilder); } diff --git a/Oqtane.Server/Repository/Context/MasterDBContext.cs b/Oqtane.Server/Repository/Context/MasterDBContext.cs index 65312819d..976874cf9 100644 --- a/Oqtane.Server/Repository/Context/MasterDBContext.cs +++ b/Oqtane.Server/Repository/Context/MasterDBContext.cs @@ -1,18 +1,32 @@ -using System; +using System; using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Oqtane.Models; +using Microsoft.Extensions.Configuration; namespace Oqtane.Repository { public class MasterDBContext : DbContext { private IHttpContextAccessor _accessor; + private IConfiguration _configuration; - public MasterDBContext(DbContextOptions options, IHttpContextAccessor accessor) : base(options) + public MasterDBContext(DbContextOptions options, IHttpContextAccessor accessor, IConfiguration configuration) : base(options) { _accessor = accessor; + _configuration = configuration; + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) + { + optionsBuilder.UseSqlServer(_configuration.GetConnectionString("DefaultConnection") + .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString()) + ); + } + base.OnConfiguring(optionsBuilder); } public virtual DbSet Alias { get; set; } diff --git a/Oqtane.Server/Repository/Interfaces/IAliasRepository.cs b/Oqtane.Server/Repository/Interfaces/IAliasRepository.cs index 4f2583076..5422ab078 100644 --- a/Oqtane.Server/Repository/Interfaces/IAliasRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IAliasRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Oqtane.Models; namespace Oqtane.Repository @@ -9,6 +9,7 @@ public interface IAliasRepository Alias AddAlias(Alias alias); Alias UpdateAlias(Alias alias); Alias GetAlias(int aliasId); + Alias GetAlias(string name); void DeleteAlias(int aliasId); } } diff --git a/Oqtane.Server/Repository/LanguageRepository.cs b/Oqtane.Server/Repository/LanguageRepository.cs index ade74f2df..0ee5105bc 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -17,10 +17,10 @@ public LanguageRepository(TenantDBContext context) public Language AddLanguage(Language language) { - if (language.IsCurrent) + if (language.IsDefault) { // Ensure all other languages are not set to current - _db.Language.ToList().ForEach(l => l.IsCurrent = false); + _db.Language.ToList().ForEach(l => l.IsDefault = false); } _db.Language.Add(language); diff --git a/Oqtane.Server/Repository/TenantResolver.cs b/Oqtane.Server/Repository/TenantResolver.cs index cd273b3ae..815a8c55a 100644 --- a/Oqtane.Server/Repository/TenantResolver.cs +++ b/Oqtane.Server/Repository/TenantResolver.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Http; @@ -9,24 +9,49 @@ namespace Oqtane.Repository { public class TenantResolver : ITenantResolver { - private readonly Alias _alias; - private readonly Tenant _tenant; + private readonly IHttpContextAccessor _accessor; + private readonly IAliasRepository _aliasRepository; + private readonly ITenantRepository _tenantRepository; + private readonly SiteState _siteState; + + private Alias _alias; + private Tenant _tenant; public TenantResolver(IHttpContextAccessor accessor, IAliasRepository aliasRepository, ITenantRepository tenantRepository, SiteState siteState) { - int aliasId = -1; + _accessor = accessor; + _aliasRepository = aliasRepository; + _tenantRepository = tenantRepository; + _siteState = siteState; + } + + public Alias GetAlias() + { + if (_alias == null) ResolveTenant(); + return _alias; + } + + public Tenant GetTenant() + { + if (_tenant == null) ResolveTenant(); + return _tenant; + } - if (siteState != null && siteState.Alias != null) + private void ResolveTenant() + { + if (_siteState != null && _siteState.Alias != null) { // background processes can pass in an alias using the SiteState service - _alias = siteState.Alias; + _alias = _siteState.Alias; } else { + int aliasId = -1; + // get aliasid identifier based on request - if (accessor.HttpContext != null) + if (_accessor.HttpContext != null) { - string[] segments = accessor.HttpContext.Request.Path.Value.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + string[] segments = _accessor.HttpContext.Request.Path.Value.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); if (segments.Length > 1 && (segments[1] == "api" || segments[1] == "pages") && segments[0] != "~") { aliasId = int.Parse(segments[0]); @@ -34,7 +59,7 @@ public TenantResolver(IHttpContextAccessor accessor, IAliasRepository aliasRepos } // get the alias - IEnumerable aliases = aliasRepository.GetAliases().ToList(); // cached + IEnumerable aliases = _aliasRepository.GetAliases().ToList(); // cached if (aliasId != -1) { _alias = aliases.FirstOrDefault(item => item.AliasId == aliasId); @@ -44,19 +69,10 @@ public TenantResolver(IHttpContextAccessor accessor, IAliasRepository aliasRepos if (_alias != null) { // get the tenant - IEnumerable tenants = tenantRepository.GetTenants(); // cached + IEnumerable tenants = _tenantRepository.GetTenants(); // cached _tenant = tenants.FirstOrDefault(item => item.TenantId == _alias.TenantId); } - } - public Alias GetAlias() - { - return _alias; - } - - public Tenant GetTenant() - { - return _tenant; } } } diff --git a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql b/Oqtane.Server/Scripts/Tenant.02.00.01.02.sql similarity index 90% rename from Oqtane.Server/Scripts/Tenant.02.00.02.00.sql rename to Oqtane.Server/Scripts/Tenant.02.00.01.02.sql index 0e6d04ab1..3f3f49768 100644 --- a/Oqtane.Server/Scripts/Tenant.02.00.02.00.sql +++ b/Oqtane.Server/Scripts/Tenant.02.00.01.02.sql @@ -8,8 +8,8 @@ CREATE TABLE [dbo].[Language]( [LanguageId] [int] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](100) NOT NULL, [Code] [nvarchar](10) NOT NULL, - [IsCurrent] [bit] NOT NULL, - [SiteId] [int], + [IsDefault] [bit] NOT NULL, + [SiteId] [int] NOT NULL, [CreatedBy] [nvarchar](256) NOT NULL, [CreatedOn] [datetime] NOT NULL, [ModifiedBy] [nvarchar](256) NOT NULL, diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index 0353bc03e..babe9245a 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -132,10 +132,7 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(); - services.AddDbContext(options => - options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection") - .Replace("|DataDirectory|", AppContext.GetData("DataDirectory")?.ToString()) - )); + services.AddDbContext(options => { }); services.AddDbContext(options => { }); services.AddIdentityCore(options => { }) diff --git a/Oqtane.Shared/Models/Language.cs b/Oqtane.Shared/Models/Language.cs index 2433d0d0b..e0afdd66e 100644 --- a/Oqtane.Shared/Models/Language.cs +++ b/Oqtane.Shared/Models/Language.cs @@ -12,7 +12,7 @@ public class Language : IAuditable public string Code { get; set; } - public bool IsCurrent { get; set; } + public bool IsDefault { get; set; } public string CreatedBy { get; set; } From f637c9137cd98b2e2a0a3b00ead0292aceb4de0b Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 22 Jan 2021 14:19:43 -0500 Subject: [PATCH 144/177] added HTML5 date picker to input controls --- Oqtane.Client/Modules/Admin/Roles/Users.razor | 47 ++++--------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/Roles/Users.razor b/Oqtane.Client/Modules/Admin/Roles/Users.razor index 3fb2bb95c..b9dcd4316 100644 --- a/Oqtane.Client/Modules/Admin/Roles/Users.razor +++ b/Oqtane.Client/Modules/Admin/Roles/Users.razor @@ -38,7 +38,7 @@ else - + @@ -46,7 +46,7 @@ else - + @@ -75,8 +75,8 @@ else private string name = string.Empty; private List users; private int userid = -1; - private string effectivedate = string.Empty; - private string expirydate = string.Empty; + private DateTime? effectivedate = null; + private DateTime? expirydate = null; private List userroles; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; @@ -125,23 +125,8 @@ else var userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault(); if (userrole != null) { - if (string.IsNullOrEmpty(effectivedate)) - { - userrole.EffectiveDate = null; - } - else - { - userrole.EffectiveDate = DateTime.Parse(effectivedate); - } - - if (string.IsNullOrEmpty(expirydate)) - { - userrole.ExpiryDate = null; - } - else - { - userrole.ExpiryDate = DateTime.Parse(expirydate); - } + userrole.EffectiveDate = effectivedate; + userrole.ExpiryDate = expirydate; await UserRoleService.UpdateUserRoleAsync(userrole); } else @@ -149,24 +134,8 @@ else userrole = new UserRole(); userrole.UserId = userid; userrole.RoleId = roleid; - - if (string.IsNullOrEmpty(effectivedate)) - { - userrole.EffectiveDate = null; - } - else - { - userrole.EffectiveDate = DateTime.Parse(effectivedate); - } - - if (string.IsNullOrEmpty(expirydate)) - { - userrole.ExpiryDate = null; - } - else - { - userrole.ExpiryDate = DateTime.Parse(expirydate); - } + userrole.EffectiveDate = effectivedate; + userrole.ExpiryDate = expirydate; await UserRoleService.AddUserRoleAsync(userrole); } From 5a660f2634fc5147863ef5242beb28a7f45a693a Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 23 Jan 2021 23:48:10 +0300 Subject: [PATCH 145/177] Reset IsDefault per site Id for new language --- Oqtane.Server/Repository/LanguageRepository.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Oqtane.Server/Repository/LanguageRepository.cs b/Oqtane.Server/Repository/LanguageRepository.cs index 0ee5105bc..7f92086b5 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -20,7 +20,10 @@ public Language AddLanguage(Language language) if (language.IsDefault) { // Ensure all other languages are not set to current - _db.Language.ToList().ForEach(l => l.IsDefault = false); + _db.Language + .Where(l => l.SiteId == language.SiteId) + .ToList() + .ForEach(l => l.IsDefault = false); } _db.Language.Add(language); From 90ca6aafe91b5eb29e23c640432fead3042b3b46 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sun, 24 Jan 2021 01:06:50 +0300 Subject: [PATCH 146/177] Set default language if the culture not supported --- Oqtane.Server/Pages/_Host.cshtml.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Oqtane.Server/Pages/_Host.cshtml.cs b/Oqtane.Server/Pages/_Host.cshtml.cs index 662beb18f..d93ead044 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -5,6 +5,7 @@ using Oqtane.Models; using Oqtane.Themes; using System; +using System.Globalization; using System.Linq; using System.Reflection; using Microsoft.AspNetCore.Http.Extensions; @@ -45,18 +46,20 @@ public void OnGet() // if framework is installed if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) { - Uri uri = new Uri(Request.GetDisplayUrl()); + var uri = new Uri(Request.GetDisplayUrl()); var alias = _aliases.GetAlias(uri.Authority + "/" + uri.LocalPath.Substring(1)); _state.Alias = alias; - // set default language for site - var language = _languages.GetLanguages(alias.SiteId).Where(item => item.IsDefault).FirstOrDefault(); - if (language != null) + // set default language for site if the culture is not supported + var languages = _languages.GetLanguages(alias.SiteId); + if (languages.All(l => l.Code != CultureInfo.CurrentUICulture.Name)) { + var defaultLanguage = languages.Where(l => l.IsDefault).SingleOrDefault() ?? languages.First(); + HttpContext.Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue( - new RequestCulture(language.Code))); + new RequestCulture(defaultLanguage.Code))); } } } From 6fdbbeb8cee032e6a8581f448d5f57147ad041a8 Mon Sep 17 00:00:00 2001 From: Jayson Furr Date: Sat, 23 Jan 2021 18:24:07 -0600 Subject: [PATCH 147/177] Fixes to horizontal menu logic. Now supports two levels of menu items. --- .../Themes/Controls/MenuHorizontal.razor | 31 +------ .../Themes/Controls/MenuItemsBase.cs | 27 +++++++ .../Themes/Controls/MenuItemsHorizontal.razor | 80 +++++++++++++++++++ .../Controls/MenuItemsHorizontal.razor.cs | 6 ++ 4 files changed, 115 insertions(+), 29 deletions(-) create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsBase.cs create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs diff --git a/Oqtane.Client/Themes/Controls/MenuHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuHorizontal.razor index 575a513ba..c4c45f168 100644 --- a/Oqtane.Client/Themes/Controls/MenuHorizontal.razor +++ b/Oqtane.Client/Themes/Controls/MenuHorizontal.razor @@ -1,4 +1,5 @@ @namespace Oqtane.Themes.Controls + @inherits MenuBase @if (MenuPages.Any()) @@ -10,35 +11,7 @@
} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsBase.cs b/Oqtane.Client/Themes/Controls/MenuItemsBase.cs new file mode 100644 index 000000000..bfdd3cd47 --- /dev/null +++ b/Oqtane.Client/Themes/Controls/MenuItemsBase.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Linq; + +using Microsoft.AspNetCore.Components; + +using Oqtane.Models; +using Oqtane.UI; + +namespace Oqtane.Themes.Controls +{ + public abstract class MenuItemsBase : MenuBase + { + [Parameter()] + public Page ParentPage { get; set; } + + [Parameter()] + public IEnumerable Pages { get; set; } + + protected IEnumerable GetChildPages() + { + return Pages + .Where(e => e.ParentId == ParentPage?.PageId) + .OrderBy(e => e.Order) + .AsEnumerable(); + } + } +} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor new file mode 100644 index 000000000..3a54c855d --- /dev/null +++ b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor @@ -0,0 +1,80 @@ +@namespace Oqtane.Themes.Controls + +@inherits MenuItemsBase + +@if (ParentPage != null) +{ + +} +else +{ + +} \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs new file mode 100644 index 000000000..30226bfbe --- /dev/null +++ b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs @@ -0,0 +1,6 @@ +namespace Oqtane.Themes.Controls +{ + public partial class MenuItemsHorizontal : MenuItemsBase + { + } +} From f60a4af6d2d2a0a1396d1652909c38dbfa00099b Mon Sep 17 00:00:00 2001 From: Jayson Furr Date: Sat, 23 Jan 2021 21:14:44 -0600 Subject: [PATCH 148/177] Fixes to horizontal menu logic. Now supports multiple levels of menu items. Added FontIcon component to reduce duplicate code. --- Oqtane.Client/Themes/Controls/FontIcon.razor | 4 ++ .../Themes/Controls/FontIcon.razor.cs | 10 +++ .../Themes/Controls/MenuItemsHorizontal.razor | 20 +++--- .../Themes/Controls/MenuItemsVertical.razor | 62 +++++++++++++++++++ .../Controls/MenuItemsVertical.razor.cs | 6 ++ .../Themes/Controls/MenuVertical.razor | 20 +----- 6 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 Oqtane.Client/Themes/Controls/FontIcon.razor create mode 100644 Oqtane.Client/Themes/Controls/FontIcon.razor.cs create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsVertical.razor create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor b/Oqtane.Client/Themes/Controls/FontIcon.razor new file mode 100644 index 000000000..04cd682a7 --- /dev/null +++ b/Oqtane.Client/Themes/Controls/FontIcon.razor @@ -0,0 +1,4 @@ +@if (!string.IsNullOrWhiteSpace(Value)) +{ + +} \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor.cs b/Oqtane.Client/Themes/Controls/FontIcon.razor.cs new file mode 100644 index 000000000..07ecda89d --- /dev/null +++ b/Oqtane.Client/Themes/Controls/FontIcon.razor.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Components; + +namespace Oqtane.Themes.Controls +{ + public partial class FontIcon : ComponentBase + { + [Parameter()] + public string Value { get; set; } + } +} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor index 3a54c855d..1ba03d4f7 100644 --- a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor +++ b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor @@ -10,12 +10,14 @@ if (childPage.PageId == PageState.Page.PageId) { - @childPage.Name(current) + + @childPage.Name (current) } else { + @childPage.Name } @@ -33,11 +35,8 @@ else { } @@ -45,10 +44,7 @@ else { @@ -60,7 +56,8 @@ else { @@ -69,6 +66,7 @@ else { + } + else + { + + } + if (Pages.Any(e => e.ParentId == childPage.PageId)) + { + + } + } +} +else +{ + +} \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs new file mode 100644 index 000000000..85ba00b83 --- /dev/null +++ b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs @@ -0,0 +1,6 @@ +namespace Oqtane.Themes.Controls +{ + public partial class MenuItemsVertical : MenuItemsBase + { + } +} diff --git a/Oqtane.Client/Themes/Controls/MenuVertical.razor b/Oqtane.Client/Themes/Controls/MenuVertical.razor index 79b205897..a552ea110 100644 --- a/Oqtane.Client/Themes/Controls/MenuVertical.razor +++ b/Oqtane.Client/Themes/Controls/MenuVertical.razor @@ -10,25 +10,7 @@ } From 5a02ce612481a1bc33fdc9e48ee35e02990fbe5a Mon Sep 17 00:00:00 2001 From: Jayson Furr Date: Sat, 23 Jan 2021 21:14:44 -0600 Subject: [PATCH 149/177] Fixes to vertical menu logic. Now supports multiple levels of menu items. Added FontIcon component to reduce duplicate code. --- Oqtane.Client/Themes/Controls/FontIcon.razor | 4 ++ .../Themes/Controls/FontIcon.razor.cs | 10 +++ .../Themes/Controls/MenuItemsHorizontal.razor | 20 +++--- .../Themes/Controls/MenuItemsVertical.razor | 62 +++++++++++++++++++ .../Controls/MenuItemsVertical.razor.cs | 6 ++ .../Themes/Controls/MenuVertical.razor | 20 +----- 6 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 Oqtane.Client/Themes/Controls/FontIcon.razor create mode 100644 Oqtane.Client/Themes/Controls/FontIcon.razor.cs create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsVertical.razor create mode 100644 Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor b/Oqtane.Client/Themes/Controls/FontIcon.razor new file mode 100644 index 000000000..04cd682a7 --- /dev/null +++ b/Oqtane.Client/Themes/Controls/FontIcon.razor @@ -0,0 +1,4 @@ +@if (!string.IsNullOrWhiteSpace(Value)) +{ + +} \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor.cs b/Oqtane.Client/Themes/Controls/FontIcon.razor.cs new file mode 100644 index 000000000..07ecda89d --- /dev/null +++ b/Oqtane.Client/Themes/Controls/FontIcon.razor.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.Components; + +namespace Oqtane.Themes.Controls +{ + public partial class FontIcon : ComponentBase + { + [Parameter()] + public string Value { get; set; } + } +} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor index 3a54c855d..1ba03d4f7 100644 --- a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor +++ b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor @@ -10,12 +10,14 @@ if (childPage.PageId == PageState.Page.PageId) { - @childPage.Name(current) + + @childPage.Name (current) } else { + @childPage.Name } @@ -33,11 +35,8 @@ else { } @@ -45,10 +44,7 @@ else { @@ -60,7 +56,8 @@ else { @@ -69,6 +66,7 @@ else { + } + else + { + + } + if (Pages.Any(e => e.ParentId == childPage.PageId)) + { + + } + } +} +else +{ + +} \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs new file mode 100644 index 000000000..85ba00b83 --- /dev/null +++ b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs @@ -0,0 +1,6 @@ +namespace Oqtane.Themes.Controls +{ + public partial class MenuItemsVertical : MenuItemsBase + { + } +} diff --git a/Oqtane.Client/Themes/Controls/MenuVertical.razor b/Oqtane.Client/Themes/Controls/MenuVertical.razor index 79b205897..a552ea110 100644 --- a/Oqtane.Client/Themes/Controls/MenuVertical.razor +++ b/Oqtane.Client/Themes/Controls/MenuVertical.razor @@ -10,25 +10,7 @@ } From 531cba715e3d3ca654565edd9a5baf5a36d9a09d Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 4 Feb 2021 08:54:59 -0500 Subject: [PATCH 150/177] performance and user experience improvements --- .../Admin/ModuleDefinitions/Index.razor | 5 +- Oqtane.Client/Modules/Admin/Site/Index.razor | 229 ++++++++++-------- Oqtane.Client/Modules/Admin/Sites/Add.razor | 18 ++ Oqtane.Client/Modules/Admin/Sites/Edit.razor | 60 ++++- .../Modules/Admin/Tenants/Edit.razor | 86 ------- .../Modules/Admin/Tenants/Index.razor | 68 ------ .../Modules/Admin/Themes/Index.razor | 5 +- Oqtane.Client/Modules/Controls/Pager.razor | 104 ++++++-- Oqtane.Client/Themes/Controls/FontIcon.razor | 8 + .../Themes/Controls/FontIcon.razor.cs | 10 - .../Themes/Controls/MenuItemsHorizontal.razor | 3 +- .../Controls/MenuItemsHorizontal.razor.cs | 6 - .../Themes/Controls/MenuItemsVertical.razor | 1 - .../Controls/MenuItemsVertical.razor.cs | 6 - Oqtane.Client/UI/ContainerBuilder.razor | 4 +- .../Controllers/ModuleDefinitionController.cs | 54 +++-- Oqtane.Server/Controllers/ThemeController.cs | 30 ++- .../Infrastructure/InstallationManager.cs | 28 ++- .../Infrastructure/Jobs/HostedServiceBase.cs | 2 +- Oqtane.Server/Oqtane.Server.csproj | 1 + Oqtane.Server/Pages/_Host.cshtml.cs | 11 +- .../Interfaces/IModuleDefinitionRepository.cs | 4 +- .../Repository/Interfaces/IThemeRepository.cs | 3 +- .../Repository/ModuleDefinitionRepository.cs | 112 ++++----- Oqtane.Server/Repository/SiteRepository.cs | 26 -- Oqtane.Server/Repository/ThemeRepository.cs | 33 ++- Oqtane.Server/Scripts/Tenant.02.00.01.02.sql | 2 +- Oqtane.Server/Scripts/Tenant.02.00.01.03.sql | 17 ++ Oqtane.Server/Startup.cs | 4 +- Oqtane.Shared/Models/Site.cs | 3 +- Oqtane.Shared/Shared/InstallConfig.cs | 3 +- 31 files changed, 478 insertions(+), 468 deletions(-) delete mode 100644 Oqtane.Client/Modules/Admin/Tenants/Edit.razor delete mode 100644 Oqtane.Client/Modules/Admin/Tenants/Index.razor delete mode 100644 Oqtane.Client/Themes/Controls/FontIcon.razor.cs delete mode 100644 Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs delete mode 100644 Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs create mode 100644 Oqtane.Server/Scripts/Tenant.02.00.01.03.sql diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor index a3f0b71ed..538bf7001 100644 --- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor @@ -47,7 +47,7 @@ else public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnInitializedAsync() + protected override async Task OnParametersSetAsync() { try { @@ -100,7 +100,8 @@ else try { await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId); - AddModuleMessage(Localizer["Module Deleted Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); + AddModuleMessage(Localizer["Module Deleted Successfully"], MessageType.Success); + StateHasChanged(); } catch (Exception ex) { diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor index 63e588894..acd0105b1 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -10,122 +10,137 @@ @if (_initialized) { - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + +
- - - -
- - - -
- - - -
- - - -
- - - -
- - - + + + + + + + + + + + + + + + + + + + + + + + - - @if (_layouts.Count > 0) - { - - - - - } - - - - - - - - + } + + + + @if (_layouts.Count > 0) + { -
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + -
- - - -
- - - -
- - - -
- + - + + @foreach (var layout in _layouts) + { + + }
+ } +
+ + + +
+ + + +
+ + + +
+ + + +
@@ -244,6 +259,7 @@ private string _themetype = "-"; private string _layouttype = "-"; private string _containertype = "-"; + private string _admincontainertype = "-"; private string _allowregistration; private string _smtphost = string.Empty; private string _smtpport = string.Empty; @@ -298,6 +314,7 @@ _layouttype = site.DefaultLayoutType; _containers = ThemeService.GetContainerControls(_themeList, _themetype); _containertype = site.DefaultContainerType; + _admincontainertype = site.AdminContainerType; _allowregistration = site.AllowRegistration.ToString(); var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); @@ -365,6 +382,7 @@ } _layouttype = "-"; _containertype = "-"; + _admincontainertype = ""; StateHasChanged(); } catch (Exception ex) @@ -405,6 +423,7 @@ site.DefaultThemeType = _themetype; site.DefaultLayoutType = (_layouttype == "-" ? string.Empty : _layouttype); site.DefaultContainerType = _containertype; + site.AdminContainerType = _admincontainertype; site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration)); site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted)); diff --git a/Oqtane.Client/Modules/Admin/Sites/Add.razor b/Oqtane.Client/Modules/Admin/Sites/Add.razor index 2945f23a5..a4b430e9f 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Add.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Add.razor @@ -78,6 +78,21 @@ else + + + + - - - - + + + + + + + + + + + + +
+ + + +
@@ -225,6 +240,7 @@ else private string _themetype = "-"; private string _layouttype = "-"; private string _containertype = "-"; + private string _admincontainertype = ""; private string _sitetemplatetype = "-"; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; @@ -278,6 +294,7 @@ else } _layouttype = "-"; _containertype = "-"; + _admincontainertype = ""; StateHasChanged(); } catch (Exception ex) @@ -378,6 +395,7 @@ else config.DefaultTheme = _themetype; config.DefaultLayout = _layouttype; config.DefaultContainer = _containertype; + config.DefaultAdminContainer = _admincontainertype; config.SiteTemplate = _sitetemplatetype; ShowProgressIndicator(); diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor index 3d01cf2e5..b1afc85ce 100644 --- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor @@ -18,14 +18,6 @@
- - - -
@@ -86,6 +78,21 @@
+ + + +
@@ -97,6 +104,23 @@
+ + + +
+ + + +

@@ -114,13 +138,12 @@ private List _containers = new List(); private Alias _alias; private string _name = string.Empty; - private List _tenantList; - private string _tenant = string.Empty; private List _aliasList; private string _urls = string.Empty; private string _themetype; private string _layouttype; - private string _containertype; + private string _containertype = "-"; + private string _admincontainertype = "-"; private string _createdby; private DateTime _createdon; private string _modifiedby; @@ -128,6 +151,8 @@ private string _deletedby; private DateTime? _deletedon; private string _isdeleted; + private string _tenant = string.Empty; + private string _connectionstring = string.Empty; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; @@ -144,8 +169,6 @@ if (site != null) { _name = site.Name; - _tenantList = await TenantService.GetTenantsAsync(); - _tenant = _tenantList.Find(item => item.TenantId == site.TenantId).Name; foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) { @@ -158,6 +181,7 @@ _layouttype = site.DefaultLayoutType; _containers = ThemeService.GetContainerControls(_themeList, _themetype); _containertype = site.DefaultContainerType; + _admincontainertype = site.AdminContainerType; _createdby = site.CreatedBy; _createdon = site.CreatedOn; _modifiedby = site.ModifiedBy; @@ -166,6 +190,14 @@ _deletedon = site.DeletedOn; _isdeleted = site.IsDeleted.ToString(); + List tenants = await TenantService.GetTenantsAsync(); + Tenant tenant = tenants.Find(item => item.TenantId == site.TenantId); + if (tenant != null) + { + _tenant = tenant.Name; + _connectionstring = tenant.DBConnectionString; + } + _initialized = true; } } @@ -193,6 +225,7 @@ } _layouttype = "-"; _containertype = "-"; + _admincontainertype = ""; StateHasChanged(); } catch (Exception ex) @@ -228,6 +261,7 @@ site.DefaultThemeType = _themetype; site.DefaultLayoutType = _layouttype ?? string.Empty; site.DefaultContainerType = _containertype; + site.AdminContainerType = _admincontainertype; site.IsDeleted = (_isdeleted == null || Boolean.Parse(_isdeleted)); site = await SiteService.UpdateSiteAsync(site); diff --git a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor b/Oqtane.Client/Modules/Admin/Tenants/Edit.razor deleted file mode 100644 index 247b338ab..000000000 --- a/Oqtane.Client/Modules/Admin/Tenants/Edit.razor +++ /dev/null @@ -1,86 +0,0 @@ -@namespace Oqtane.Modules.Admin.Tenants -@inherits ModuleBase -@inject NavigationManager NavigationManager -@inject ITenantService TenantService -@inject IStringLocalizer Localizer - - - - - - - - - - - -
- - - @if (name == TenantNames.Master) - { - - } - else - { - - } -
- - - -
- -@Localizer["Cancel"] - -@code { - private int tenantid; - private string name = string.Empty; - private string connectionstring = string.Empty; - private string schema = string.Empty; - - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - - protected override async Task OnInitializedAsync() - { - try - { - tenantid = Int32.Parse(PageState.QueryString["id"]); - var tenant = await TenantService.GetTenantAsync(tenantid); - if (tenant != null) - { - name = tenant.Name; - connectionstring = tenant.DBConnectionString; - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Loading Tenant {TenantId} {Error}", tenantid, ex.Message); - AddModuleMessage(Localizer["Error Loading Tenant"], MessageType.Error); - } - } - - private async Task SaveTenant() - { - try - { - connectionstring = connectionstring.Replace("\\\\", "\\"); - var tenant = await TenantService.GetTenantAsync(tenantid); - if (tenant != null) - { - tenant.Name = name; - tenant.DBConnectionString = connectionstring; - - await TenantService.UpdateTenantAsync(tenant); - await logger.LogInformation("Tenant Saved {TenantId}", tenantid); - - NavigationManager.NavigateTo(NavigateUrl()); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Saving Tenant {TenantId} {Error}", tenantid, ex.Message); - AddModuleMessage(Localizer["Error Saving Tenant"], MessageType.Error); - } - } -} diff --git a/Oqtane.Client/Modules/Admin/Tenants/Index.razor b/Oqtane.Client/Modules/Admin/Tenants/Index.razor deleted file mode 100644 index 2aa70ecb6..000000000 --- a/Oqtane.Client/Modules/Admin/Tenants/Index.razor +++ /dev/null @@ -1,68 +0,0 @@ -@namespace Oqtane.Modules.Admin.Tenants -@inherits ModuleBase -@inject ITenantService TenantService -@inject IAliasService AliasService -@inject IStringLocalizer Localizer - -@if (tenants == null) -{ -

@Localizer["Loading..."]

-} -else -{ - -
-   -   - @Localizer["Name"] -
- - - - @context.Name - -
- -} - -@code { - private List tenants; - - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - - protected override async Task OnParametersSetAsync() - { - tenants = await TenantService.GetTenantsAsync(); - } - - private async Task DeleteTenant(Tenant Tenant) - { - try - { - string message = string.Empty; - var aliases = await AliasService.GetAliasesAsync(); - foreach (var alias in aliases) - { - if (alias.TenantId == Tenant.TenantId) - { - message += ", " + alias.Name; - } - } - if (string.IsNullOrEmpty(message)) - { - await TenantService.DeleteTenantAsync(Tenant.TenantId); - await logger.LogInformation("Tenant Deleted {Tenant}", Tenant); - StateHasChanged(); - } - else - { - AddModuleMessage(Localizer["Tenant Cannot Be Deleted Until The Following Sites Are Deleted: {0}", message.Substring(2)], MessageType.Warning); - } - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Deleting Tenant {Tenant} {Error}", Tenant, ex.Message); - AddModuleMessage(Localizer["Error Deleting Tenant"], MessageType.Error); - } - } -} \ No newline at end of file diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor index 816bd06f8..9e8677f76 100644 --- a/Oqtane.Client/Modules/Admin/Themes/Index.razor +++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor @@ -49,7 +49,7 @@ else public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnInitializedAsync() + protected override async Task OnParametersSetAsync() { try { @@ -101,7 +101,8 @@ else try { await ThemeService.DeleteThemeAsync(Theme.ThemeName); - AddModuleMessage(Localizer["Theme Deleted Successfully. You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success); + AddModuleMessage(Localizer["Theme Deleted Successfully"], MessageType.Success); + StateHasChanged(); } catch (Exception ex) { diff --git a/Oqtane.Client/Modules/Controls/Pager.razor b/Oqtane.Client/Modules/Controls/Pager.razor index 5f3ae713d..64f327282 100644 --- a/Oqtane.Client/Modules/Controls/Pager.razor +++ b/Oqtane.Client/Modules/Controls/Pager.razor @@ -3,6 +3,43 @@ @typeparam TableItem

+ @if (Toolbar == "Top") + { +

+ @if (_endPage > 1) + { + + } + @if (_page > _maxPages) + { + + } + @if (_endPage > 1) + { + + @for (int i = _startPage; i <= _endPage; i++) + { + var pager = i; + + } + + } + @if (_endPage < _pages) + { + + } + @if (_endPage > 1) + { + + } + @if (_endPage > 1) + { + Page @_page of @_pages + } +
+ } @if (Format == "Table") { @@ -35,32 +72,43 @@ } } -
- @if (_page > _maxPages) - { - - } - @if (_endPage > 1) - { - - @for (int i = _startPage; i <= _endPage; i++) + @if (Toolbar == "Bottom") + { +
+ @if (_endPage > 1) { - var pager = i; - + } - - } - @if (_endPage < _pages) - { - - } - @if (_endPage > 1) - { - Page @_page of @_pages - } -
+ @if (_page > _maxPages) + { + + } + @if (_endPage > 1) + { + + @for (int i = _startPage; i <= _endPage; i++) + { + var pager = i; + + } + + } + @if (_endPage < _pages) + { + + } + @if (_endPage > 1) + { + + } + @if (_endPage > 1) + { + Page @_page of @_pages + } +
+ }

@code { @@ -74,6 +122,9 @@ [Parameter] public string Format { get; set; } + [Parameter] + public string Toolbar { get; set; } + [Parameter] public RenderFragment Header { get; set; } @@ -104,6 +155,11 @@ Format = "Table"; } + if (string.IsNullOrEmpty(Toolbar)) + { + Toolbar = "Top"; + } + if (string.IsNullOrEmpty(Class)) { if (Format == "Table") diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor b/Oqtane.Client/Themes/Controls/FontIcon.razor index 04cd682a7..04aad17e8 100644 --- a/Oqtane.Client/Themes/Controls/FontIcon.razor +++ b/Oqtane.Client/Themes/Controls/FontIcon.razor @@ -1,4 +1,12 @@ +@namespace Oqtane.Themes.Controls +@inherits ThemeControlBase + @if (!string.IsNullOrWhiteSpace(Value)) { +} + +@code { + [Parameter()] + public string Value { get; set; } } \ No newline at end of file diff --git a/Oqtane.Client/Themes/Controls/FontIcon.razor.cs b/Oqtane.Client/Themes/Controls/FontIcon.razor.cs deleted file mode 100644 index 07ecda89d..000000000 --- a/Oqtane.Client/Themes/Controls/FontIcon.razor.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace Oqtane.Themes.Controls -{ - public partial class FontIcon : ComponentBase - { - [Parameter()] - public string Value { get; set; } - } -} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor index 1ba03d4f7..840fbf4e4 100644 --- a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor +++ b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor @@ -1,5 +1,4 @@ @namespace Oqtane.Themes.Controls - @inherits MenuItemsBase @if (ParentPage != null) @@ -75,4 +74,4 @@ else } } -} \ No newline at end of file +} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs deleted file mode 100644 index 30226bfbe..000000000 --- a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Oqtane.Themes.Controls -{ - public partial class MenuItemsHorizontal : MenuItemsBase - { - } -} diff --git a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor index ab6c92d89..a27f9a7aa 100644 --- a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor +++ b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor @@ -1,5 +1,4 @@ @namespace Oqtane.Themes.Controls - @inherits MenuItemsBase @if (ParentPage != null) diff --git a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs deleted file mode 100644 index 85ba00b83..000000000 --- a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Oqtane.Themes.Controls -{ - public partial class MenuItemsVertical : MenuItemsBase - { - } -} diff --git a/Oqtane.Client/UI/ContainerBuilder.razor b/Oqtane.Client/UI/ContainerBuilder.razor index 5a1643090..41f8268af 100644 --- a/Oqtane.Client/UI/ContainerBuilder.razor +++ b/Oqtane.Client/UI/ContainerBuilder.razor @@ -1,4 +1,4 @@ -@namespace Oqtane.UI +@namespace Oqtane.UI @DynamicComponent @@ -21,7 +21,7 @@ string container = _moduleState.ContainerType; if (PageState.ModuleId != -1 && _moduleState.UseAdminContainer) { - container = Constants.DefaultAdminContainer; + container = (!string.IsNullOrEmpty(PageState.Site.AdminContainerType)) ? PageState.Site.AdminContainerType : Constants.DefaultAdminContainer; } DynamicComponent = builder => diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index 299ad6019..dc371214f 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -101,13 +101,12 @@ public void InstallModules() public void Delete(int id, int siteid) { ModuleDefinition moduledefinition = _moduleDefinitions.GetModuleDefinition(id, siteid); - if (moduledefinition != null ) + if (moduledefinition != null && Utilities.GetAssemblyName(moduledefinition.ServerManagerType) != "Oqtane.Server") { - if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType) && Utilities.GetAssemblyName(moduledefinition.ServerManagerType) != "Oqtane.Server") + // execute uninstall logic or scripts + if (!string.IsNullOrEmpty(moduledefinition.ServerManagerType)) { Type moduletype = Type.GetType(moduledefinition.ServerManagerType); - - // execute uninstall logic foreach (Tenant tenant in _tenants.GetTenants()) { try @@ -128,34 +127,45 @@ public void Delete(int id, int siteid) _logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Uninstalling {ModuleDefinitionName} For Tenant {Tenant} {Error}", moduledefinition.ModuleDefinitionName, tenant.Name, ex.Message); } } + } + // remove module assets + string assetpath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName)); + if (System.IO.File.Exists(Path.Combine(assetpath, "assets.json"))) + { // use assets.json to clean up file resources - string assetfilepath = Path.Combine(_environment.WebRootPath, "Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName), "assets.json"); - if (System.IO.File.Exists(assetfilepath)) + List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); + foreach(string asset in assets) { - List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(assetfilepath)); - foreach(string asset in assets) + // legacy support for assets that were stored as absolute paths + string filepath = asset.StartsWith("\\") ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset; + if (System.IO.File.Exists(filepath)) { - if (System.IO.File.Exists(asset)) - { - System.IO.File.Delete(asset); - } + System.IO.File.Delete(filepath); } - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); } - - // clean up module static resource folder - string folder = Path.Combine(_environment.WebRootPath, Path.Combine("Modules", Utilities.GetTypeName(moduledefinition.ModuleDefinitionName))); - if (Directory.Exists(folder)) + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); + } + else + { + // attempt to delete assemblies based on naming convention + foreach(string asset in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(moduledefinition.ModuleDefinitionName) + "*.*")) { - Directory.Delete(folder, true); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); + System.IO.File.Delete(asset); } + _logger.Log(LogLevel.Warning, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}. Please Note That Some Assets May Have Been Missed Due To A Missing Asset Manifest. An Asset Manifest Is Only Created If A Module Is Installed From A Nuget Package.", moduledefinition.Name); + } - // remove module definition - _moduleDefinitions.DeleteModuleDefinition(id, siteid); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name); + // clean up module static resource folder + if (Directory.Exists(assetpath)) + { + Directory.Delete(assetpath, true); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Static Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); } + + // remove module definition + _moduleDefinitions.DeleteModuleDefinition(id); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name); } } diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs index 07ed61526..615080e90 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -57,28 +57,44 @@ public void Delete(string themename) Theme theme = themes.Where(item => item.ThemeName == themename).FirstOrDefault(); if (theme != null && Utilities.GetAssemblyName(theme.ThemeName) != "Oqtane.Client") { - // use assets.json to clean up file resources - string assetfilepath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName), "assets.json"); - if (System.IO.File.Exists(assetfilepath)) + // remove theme assets + string assetpath = Path.Combine(_environment.WebRootPath, "Themes", Utilities.GetTypeName(theme.ThemeName)); + if (System.IO.File.Exists(Path.Combine(assetpath, "assets.json"))) { - List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(assetfilepath)); + // use assets.json to clean up file resources + List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); foreach (string asset in assets) { - if (System.IO.File.Exists(asset)) + // legacy support for assets that were stored as absolute paths + string filepath = (asset.StartsWith("\\")) ? Path.Combine(_environment.ContentRootPath, asset.Substring(1)) : asset; + if (System.IO.File.Exists(filepath)) { - System.IO.File.Delete(asset); + System.IO.File.Delete(filepath); } } _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}", theme.ThemeName); } + else + { + // attempt to delete assemblies based on naming convention + foreach (string asset in Directory.GetFiles(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(theme.ThemeName) + "*.*")) + { + System.IO.File.Delete(asset); + } + _logger.Log(LogLevel.Warning, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}. Please Note That Some Assets May Have Been Missed Due To A Missing Asset Manifest. An Asset Manifest Is Only Created If A Theme Is Installed From A Nuget Package.", theme.ThemeName); + } // clean up theme static resource folder string folder = Path.Combine(_environment.WebRootPath, "Themes" , Utilities.GetTypeName(theme.ThemeName)); if (Directory.Exists(folder)) { Directory.Delete(folder, true); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Resource Folder Removed For {ThemeName}", theme.ThemeName); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Static Resource Folder Removed For {ThemeName}", theme.ThemeName); } + + // remove theme + _themes.DeleteTheme(theme.ThemeName); + _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Removed For {ThemeName}", theme.ThemeName); } } diff --git a/Oqtane.Server/Infrastructure/InstallationManager.cs b/Oqtane.Server/Infrastructure/InstallationManager.cs index 60910484c..f14e8ae1c 100644 --- a/Oqtane.Server/Infrastructure/InstallationManager.cs +++ b/Oqtane.Server/Infrastructure/InstallationManager.cs @@ -28,13 +28,13 @@ public InstallationManager(IHostApplicationLifetime hostApplicationLifetime, IWe public void InstallPackages(string folders) { - if (!InstallPackages(folders, _environment.WebRootPath)) + if (!InstallPackages(folders, _environment.WebRootPath, _environment.ContentRootPath)) { // error installing packages } } - public static bool InstallPackages(string folders, string webRootPath) + public static bool InstallPackages(string folders, string webRootPath, string contentRootPath) { bool install = false; string binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location); @@ -79,6 +79,7 @@ public static bool InstallPackages(string folders, string webRootPath) if (frameworkversion == "" || Version.Parse(Constants.Version).CompareTo(Version.Parse(frameworkversion)) >= 0) { List assets = new List(); + bool manifest = false; // module and theme packages must be in form of name.1.0.0.nupkg string name = Path.GetFileNameWithoutExtension(packagename); @@ -91,36 +92,41 @@ public static bool InstallPackages(string folders, string webRootPath) string foldername = Path.GetDirectoryName(entry.FullName).Split(Path.DirectorySeparatorChar)[0]; string filename = Path.GetFileName(entry.FullName); + if (!manifest && filename == "assets.json") + { + manifest = true; + } + switch (foldername) { case "lib": filename = Path.Combine(binFolder, filename); ExtractFile(entry, filename); - assets.Add(filename); + assets.Add(filename.Replace(contentRootPath, "")); break; case "wwwroot": filename = Path.Combine(webRootPath, Utilities.PathCombine(entry.FullName.Replace("wwwroot/", "").Split('/'))); ExtractFile(entry, filename); - assets.Add(filename); + assets.Add(filename.Replace(contentRootPath, "")); break; case "runtimes": var destSubFolder = Path.GetDirectoryName(entry.FullName); filename = Path.Combine(binFolder, destSubFolder, filename); ExtractFile(entry, filename); - assets.Add(filename); + assets.Add(filename.Replace(contentRootPath, "")); break; } } - // save list of assets - if (assets.Count != 0) + // save dynamic list of assets + if (!manifest && assets.Count != 0) { - string assetfilepath = Path.Combine(webRootPath, folder, name, "assets.json"); - if (File.Exists(assetfilepath)) + string manifestpath = Path.Combine(webRootPath, folder, name, "assets.json"); + if (File.Exists(manifestpath)) { - File.Delete(assetfilepath); + File.Delete(manifestpath); } - File.WriteAllText(assetfilepath, JsonSerializer.Serialize(assets)); + File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets)); } } } diff --git a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs index 36fbefb6e..449f7ae35 100644 --- a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs +++ b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs @@ -181,7 +181,7 @@ public Task StartAsync(CancellationToken cancellationToken) } else { - // auto registration + // auto registration - does not run on initial installation but will run after restart job = new Job { JobType = jobTypeName }; // optional properties var jobType = Type.GetType(jobTypeName); diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 1ac18c292..15ca0a15e 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -36,6 +36,7 @@ + diff --git a/Oqtane.Server/Pages/_Host.cshtml.cs b/Oqtane.Server/Pages/_Host.cshtml.cs index 662beb18f..ee7c43ce4 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -42,8 +42,8 @@ public void OnGet() ProcessThemeControls(assembly); } - // if framework is installed - if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) + // if culture not specified and framework is installed + if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null && !string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection"))) { Uri uri = new Uri(Request.GetDisplayUrl()); var alias = _aliases.GetAlias(uri.Authority + "/" + uri.LocalPath.Substring(1)); @@ -58,6 +58,13 @@ public void OnGet() CookieRequestCultureProvider.MakeCookieValue( new RequestCulture(language.Code))); } + else + { + HttpContext.Response.Cookies.Append( + CookieRequestCultureProvider.DefaultCookieName, + CookieRequestCultureProvider.MakeCookieValue( + new RequestCulture(_configuration.GetSection("Localization").GetValue("DefaultCulture", Constants.DefaultCulture)))); + } } } diff --git a/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs b/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs index dd5164619..48de4c8a0 100644 --- a/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IModuleDefinitionRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Oqtane.Models; namespace Oqtane.Repository @@ -9,6 +9,6 @@ public interface IModuleDefinitionRepository IEnumerable GetModuleDefinitions(int sideId); ModuleDefinition GetModuleDefinition(int moduleDefinitionId, int sideId); void UpdateModuleDefinition(ModuleDefinition moduleDefinition); - void DeleteModuleDefinition(int moduleDefinitionId, int siteId); + void DeleteModuleDefinition(int moduleDefinitionId); } } diff --git a/Oqtane.Server/Repository/Interfaces/IThemeRepository.cs b/Oqtane.Server/Repository/Interfaces/IThemeRepository.cs index 90afa3bdf..61dfc6772 100644 --- a/Oqtane.Server/Repository/Interfaces/IThemeRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IThemeRepository.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using Oqtane.Models; namespace Oqtane.Repository @@ -6,5 +6,6 @@ namespace Oqtane.Repository public interface IThemeRepository { IEnumerable GetThemes(); + void DeleteTheme(string ThemeName); } } diff --git a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs index b0d21ff2c..5a510c4c9 100644 --- a/Oqtane.Server/Repository/ModuleDefinitionRepository.cs +++ b/Oqtane.Server/Repository/ModuleDefinitionRepository.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; using Microsoft.EntityFrameworkCore; @@ -16,7 +17,6 @@ public class ModuleDefinitionRepository : IModuleDefinitionRepository private MasterDBContext _db; private readonly IMemoryCache _cache; private readonly IPermissionRepository _permissions; - private List _moduleDefinitions; // lazy load public ModuleDefinitionRepository(MasterDBContext context, IMemoryCache cache, IPermissionRepository permissions) { @@ -46,45 +46,72 @@ public void UpdateModuleDefinition(ModuleDefinition moduleDefinition) _db.Entry(moduleDefinition).State = EntityState.Modified; _db.SaveChanges(); _permissions.UpdatePermissions(moduleDefinition.SiteId, EntityNames.ModuleDefinition, moduleDefinition.ModuleDefinitionId, moduleDefinition.Permissions); - _cache.Remove("moduledefinitions:" + moduleDefinition.SiteId.ToString()); } - public void DeleteModuleDefinition(int moduleDefinitionId, int siteId) + public void DeleteModuleDefinition(int moduleDefinitionId) { ModuleDefinition moduleDefinition = _db.ModuleDefinition.Find(moduleDefinitionId); - _permissions.DeletePermissions(siteId, EntityNames.ModuleDefinition, moduleDefinitionId); _db.ModuleDefinition.Remove(moduleDefinition); _db.SaveChanges(); + _cache.Remove("moduledefinitions"); } public List LoadModuleDefinitions(int siteId) { - // get module definitions for site - List moduleDefinitions = _cache.GetOrCreate("moduledefinitions:" + siteId.ToString(), entry => + // get module definitions + List moduleDefinitions; + if (siteId != -1) { - entry.SlidingExpiration = TimeSpan.FromMinutes(30); - return LoadSiteModuleDefinitions(siteId); - }); - return moduleDefinitions; - } + moduleDefinitions = _cache.GetOrCreate("moduledefinitions", entry => + { + entry.SlidingExpiration = TimeSpan.FromMinutes(30); + return LoadModuleDefinitions(); + }); - private List LoadSiteModuleDefinitions(int siteId) - { - if (_moduleDefinitions == null) - { - // get module assemblies - _moduleDefinitions = LoadModuleDefinitionsFromAssemblies(); - } + // get all module definition permissions for site + List permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList(); - List moduleDefinitions = _moduleDefinitions; + // populate module definition permissions + foreach (ModuleDefinition moduledefinition in moduleDefinitions) + { + moduledefinition.SiteId = siteId; + if (permissions.Count == 0) + { + _permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, moduledefinition.Permissions); + } + else + { + if (permissions.Where(item => item.EntityId == moduledefinition.ModuleDefinitionId).Any()) + { + moduledefinition.Permissions = permissions.Where(item => item.EntityId == moduledefinition.ModuleDefinitionId).EncodePermissions(); + } + else + { + _permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, moduledefinition.Permissions); + } + } + } - List permissions = new List(); - if (siteId != -1) + // clean up any orphaned permissions + var ids = new HashSet(moduleDefinitions.Select(item => item.ModuleDefinitionId)); + foreach (var permission in permissions.Where(item => !ids.Contains(item.EntityId))) + { + _permissions.DeletePermission(permission.PermissionId); + } + } + else { - // get module definition permissions for site - permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList(); + moduleDefinitions = LoadModuleDefinitions(); } + return moduleDefinitions; + } + + private List LoadModuleDefinitions() + { + // get module assemblies + List moduleDefinitions = LoadModuleDefinitionsFromAssemblies(); + // get module definitions in database List moduledefs = _db.ModuleDefinition.ToList(); @@ -95,13 +122,9 @@ private List LoadSiteModuleDefinitions(int siteId) if (moduledef == null) { // new module definition - moduledef = new ModuleDefinition {ModuleDefinitionName = moduledefinition.ModuleDefinitionName}; + moduledef = new ModuleDefinition { ModuleDefinitionName = moduledefinition.ModuleDefinitionName }; _db.ModuleDefinition.Add(moduledef); _db.SaveChanges(); - if (siteId != -1) - { - _permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledef.ModuleDefinitionId, moduledefinition.Permissions); - } } else { @@ -126,31 +149,11 @@ private List LoadSiteModuleDefinitions(int siteId) moduledefinition.Version = moduledef.Version; } - if (siteId != -1) - { - if (permissions.Count == 0) - { - _permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledef.ModuleDefinitionId, moduledefinition.Permissions); - } - else - { - if (permissions.Where(item => item.EntityId == moduledef.ModuleDefinitionId).Any()) - { - moduledefinition.Permissions = permissions.Where(item => item.EntityId == moduledef.ModuleDefinitionId).EncodePermissions(); - } - else - { - _permissions.UpdatePermissions(siteId, EntityNames.ModuleDefinition, moduledef.ModuleDefinitionId, moduledefinition.Permissions); - } - } - } - // remove module definition from list as it is already synced moduledefs.Remove(moduledef); } moduledefinition.ModuleDefinitionId = moduledef.ModuleDefinitionId; - moduledefinition.SiteId = siteId; moduledefinition.CreatedBy = moduledef.CreatedBy; moduledefinition.CreatedOn = moduledef.CreatedOn; moduledefinition.ModifiedBy = moduledef.ModifiedBy; @@ -160,11 +163,6 @@ private List LoadSiteModuleDefinitions(int siteId) // any remaining module definitions are orphans foreach (ModuleDefinition moduledefinition in moduledefs) { - if (siteId != -1) - { - _permissions.DeletePermissions(siteId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId); - } - _db.ModuleDefinition.Remove(moduledefinition); // delete _db.SaveChanges(); } @@ -175,11 +173,15 @@ private List LoadSiteModuleDefinitions(int siteId) private List LoadModuleDefinitionsFromAssemblies() { List moduleDefinitions = new List(); + // iterate through Oqtane module assemblies var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); foreach (Assembly assembly in assemblies) { - moduleDefinitions = LoadModuleDefinitionsFromAssembly(moduleDefinitions, assembly); + if (System.IO.File.Exists(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(assembly.FullName) + ".dll"))) + { + moduleDefinitions = LoadModuleDefinitionsFromAssembly(moduleDefinitions, assembly); + } } return moduleDefinitions; diff --git a/Oqtane.Server/Repository/SiteRepository.cs b/Oqtane.Server/Repository/SiteRepository.cs index 774d03308..ba23d2188 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -408,32 +408,6 @@ private List CreateAdminPages(List pageTemplates = n Content = "" } } - }); pageTemplates.Add(new PageTemplate - { - Name = "Tenant Management", - Parent = "Admin", - Path = "admin/tenants", - Icon = Icons.List, - IsNavigation = false, - IsPersonalizable = false, - PagePermissions = new List - { - new Permission(PermissionNames.View, RoleNames.Host, true), - new Permission(PermissionNames.Edit, RoleNames.Host, true) - }.EncodePermissions(), - PageTemplateModules = new List - { - new PageTemplateModule - { - ModuleDefinitionName = typeof(Oqtane.Modules.Admin.Tenants.Index).ToModuleDefinitionName(), Title = "Tenant Management", Pane = "Content", - ModulePermissions = new List - { - new Permission(PermissionNames.View, RoleNames.Host, true), - new Permission(PermissionNames.Edit, RoleNames.Host, true) - }.EncodePermissions(), - Content = "" - } - } }); pageTemplates.Add(new PageTemplate { diff --git a/Oqtane.Server/Repository/ThemeRepository.cs b/Oqtane.Server/Repository/ThemeRepository.cs index 24b57598c..f85b7cd74 100644 --- a/Oqtane.Server/Repository/ThemeRepository.cs +++ b/Oqtane.Server/Repository/ThemeRepository.cs @@ -1,7 +1,9 @@ -using System; +using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Reflection; +using Microsoft.Extensions.Caching.Memory; using Oqtane.Models; using Oqtane.Shared; using Oqtane.Themes; @@ -10,7 +12,12 @@ namespace Oqtane.Repository { public class ThemeRepository : IThemeRepository { - private List _themes; // lazy load + private readonly IMemoryCache _cache; + + public ThemeRepository(IMemoryCache cache) + { + _cache = cache; + } public IEnumerable GetThemes() { @@ -19,12 +26,14 @@ public IEnumerable GetThemes() private List LoadThemes() { - if (_themes == null) + // get module definitions + List themes = _cache.GetOrCreate("themes", entry => { - // get themes - _themes = LoadThemesFromAssemblies(); - } - return _themes; + entry.SlidingExpiration = TimeSpan.FromMinutes(30); + return LoadThemesFromAssemblies(); + }); + + return themes; } private List LoadThemesFromAssemblies() @@ -35,7 +44,10 @@ private List LoadThemesFromAssemblies() var assemblies = AppDomain.CurrentDomain.GetOqtaneAssemblies(); foreach (Assembly assembly in assemblies) { - themes = LoadThemesFromAssembly(themes, assembly); + if (System.IO.File.Exists(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Utilities.GetTypeName(assembly.FullName) + ".dll"))) + { + themes = LoadThemesFromAssembly(themes, assembly); + } } return themes; @@ -143,5 +155,10 @@ private List LoadThemesFromAssembly(List themes, Assembly assembly } return themes; } + + public void DeleteTheme(string ThemeName) + { + _cache.Remove("themes"); + } } } diff --git a/Oqtane.Server/Scripts/Tenant.02.00.01.02.sql b/Oqtane.Server/Scripts/Tenant.02.00.01.02.sql index 3f3f49768..6f12d62eb 100644 --- a/Oqtane.Server/Scripts/Tenant.02.00.01.02.sql +++ b/Oqtane.Server/Scripts/Tenant.02.00.01.02.sql @@ -1,6 +1,6 @@ /* -Version 2.0.0 Tenant migration script +Version 2.0.1 Tenant migration script */ diff --git a/Oqtane.Server/Scripts/Tenant.02.00.01.03.sql b/Oqtane.Server/Scripts/Tenant.02.00.01.03.sql new file mode 100644 index 000000000..4b1d28764 --- /dev/null +++ b/Oqtane.Server/Scripts/Tenant.02.00.01.03.sql @@ -0,0 +1,17 @@ +/* + +Version 2.0.1 Tenant migration script + +*/ + +DELETE FROM [dbo].[Page] +WHERE Path = 'admin/tenants'; +GO + +ALTER TABLE [dbo].[Site] ADD + [AdminContainerType] [nvarchar](200) NULL +GO + +UPDATE [dbo].[Site] SET AdminContainerType = '' +GO + diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs index babe9245a..ba2a7d891 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -26,7 +26,6 @@ namespace Oqtane { public class Startup { - private string _webRoot; private Runtime _runtime; private bool _useSwagger; private IWebHostEnvironment _env; @@ -48,7 +47,6 @@ public Startup(IWebHostEnvironment env, ILocalizationManager localizationManager //add possibility to switch off swagger on production. _useSwagger = Configuration.GetSection("UseSwagger").Value != "false"; - _webRoot = env.WebRootPath; AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(env.ContentRootPath, "Data")); _env = env; @@ -181,7 +179,7 @@ public void ConfigureServices(IServiceCollection services) services.AddSingleton(); // install any modules or themes ( this needs to occur BEFORE the assemblies are loaded into the app domain ) - InstallationManager.InstallPackages("Modules,Themes", _webRoot); + InstallationManager.InstallPackages("Modules,Themes", _env.WebRootPath, _env.ContentRootPath); // register transient scoped core services services.AddTransient(); diff --git a/Oqtane.Shared/Models/Site.cs b/Oqtane.Shared/Models/Site.cs index 4b6b7f86f..49f3524e7 100644 --- a/Oqtane.Shared/Models/Site.cs +++ b/Oqtane.Shared/Models/Site.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.ComponentModel.DataAnnotations.Schema; namespace Oqtane.Models @@ -13,6 +13,7 @@ public class Site : IAuditable, IDeletable public string DefaultThemeType { get; set; } public string DefaultLayoutType { get; set; } public string DefaultContainerType { get; set; } + public string AdminContainerType { get; set; } public bool PwaIsEnabled { get; set; } public int? PwaAppIconFileId { get; set; } public int? PwaSplashIconFileId { get; set; } diff --git a/Oqtane.Shared/Shared/InstallConfig.cs b/Oqtane.Shared/Shared/InstallConfig.cs index 2ab74c74b..7658e97db 100644 --- a/Oqtane.Shared/Shared/InstallConfig.cs +++ b/Oqtane.Shared/Shared/InstallConfig.cs @@ -1,4 +1,4 @@ -namespace Oqtane.Shared +namespace Oqtane.Shared { public class InstallConfig { @@ -14,5 +14,6 @@ public class InstallConfig public string DefaultTheme { get; set; } public string DefaultLayout { get; set; } public string DefaultContainer { get; set; } + public string DefaultAdminContainer { get; set; } } } From 988639b6033f6892c3636b310dd171d02e96b700 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Thu, 4 Feb 2021 09:36:19 -0500 Subject: [PATCH 151/177] module creator owner and module name cannot be the same --- Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 79d5eb429..e0826c861 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -113,7 +113,7 @@ else { try { - if (IsValid(_owner) && IsValid(_module) && _template != "-") + if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-") { var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference }; moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition); @@ -126,7 +126,7 @@ else } else { - AddModuleMessage(Localizer["You Must Provide A Valid Owner Name, Module Name, And Template"], MessageType.Warning); + AddModuleMessage(Localizer["You Must Provide A Valid Owner Name And Module Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template"], MessageType.Warning); } } catch (Exception ex) From c3e7fa67f3ca70ba96b5f5f8de9583130f1b1ee3 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 5 Feb 2021 09:37:10 -0500 Subject: [PATCH 152/177] Performance improvement - set IsFixed="true" on ModuleState CascadingValues so that Blazor will not monitor them for changes --- Oqtane.Client/Modules/Controls/TabStrip.razor | 2 +- Oqtane.Client/UI/ContainerBuilder.razor | 2 +- Oqtane.Client/UI/ModuleInstance.razor | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Oqtane.Client/Modules/Controls/TabStrip.razor b/Oqtane.Client/Modules/Controls/TabStrip.razor index be82b9ffb..d51869309 100644 --- a/Oqtane.Client/Modules/Controls/TabStrip.razor +++ b/Oqtane.Client/Modules/Controls/TabStrip.razor @@ -1,7 +1,7 @@ @namespace Oqtane.Modules.Controls @inherits ModuleControlBase - +
- + @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 169/177] 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 acd0105b1..bbfd28f71 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 170/177] 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 589908040..26cd56f9c 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -42,7 +42,7 @@ - + @if (_files.Count == 0) diff --git a/Oqtane.Server/Controllers/FileController.cs b/Oqtane.Server/Controllers/FileController.cs index b65d4c9ef..ce36dae29 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -535,19 +535,16 @@ private Models.File CreateFile(string filename, int folderid, string filepath) 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 171/177] 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 26cd56f9c..589908040 100644 --- a/Oqtane.Client/Modules/Admin/Files/Index.razor +++ b/Oqtane.Client/Modules/Admin/Files/Index.razor @@ -42,7 +42,7 @@ - + @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 172/177] 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 3dd8ab3fa..e21629d85 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs @@ -65,7 +65,7 @@ public List CreateSite(Site site) 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 173/177] 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 51e714505..613f3f39d 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -55,8 +55,8 @@ public class Constants { [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 174/177] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d0bb04cc..bd6646ddb 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 175/177] 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 72024f758..f6ce11c82 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 6b01cba13..c669a8a2b 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 10313bc42..6e68fa196 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 36715c37c..6adfcb6be 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 538e0c8d5..59a934738 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 116d8567a..d4b21d979 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 e41001aa1..57e1de1a2 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 474b9335e..4a6802f56 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 976f255be..65df5df5e 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 613f3f39d..1b05a7e77 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 78c230db1..da295fb4c 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 cd3d0a4cc..f67d23d23 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 176/177] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bd6646ddb..5788b1db9 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 177/177] 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 dc371214f..f417ce331 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -135,6 +135,7 @@ public void Delete(int id, int siteid) { // 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 @@ public void Delete(int id, int siteid) 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 615080e90..851aeb68a 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -63,6 +63,7 @@ public void Delete(string themename) { // 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 @@ public void Delete(string themename) 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 f14e8ae1c..3b627c70e 100644 --- a/Oqtane.Server/Infrastructure/InstallationManager.cs +++ b/Oqtane.Server/Infrastructure/InstallationManager.cs @@ -126,6 +126,10 @@ public static bool InstallPackages(string folders, string webRootPath, string co { File.Delete(manifestpath); } + if (!Directory.Exists(Path.GetDirectoryName(manifestpath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(manifestpath)); + } File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets)); } }
@context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"]@(context.Size / 1000) KB@string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB @context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"]@string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB@(context.Size / 1000) KB @context.Name @context.ModifiedOn @context.Extension.ToUpper() @Localizer["File"]@(context.Size / 1000) KB@string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB