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 fa992e97..ac7e4690 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 3869d8b4..85e65d14 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 80222e66..657494d7 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -24,10 +24,25 @@ namespace Oqtane.Modules.Controls { 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 573a536b..fd8b9a52 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 9472bab3..7c2eaa24 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 34e93e2d..1f6c520f 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 a583aedc..e7ccd726 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 3a920652..7afebdf1 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 4b15ce82..3df78894 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 e7ccd726..17028d43 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 17028d43..ecd7cb91 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 e8af37fe..2598c810 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 727dc184..6344925d 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 87a6a387..ed24d3cc 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 efcd89a2..d0d0d76d 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 9a056a43..322fb939 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 3df78894..d669f678 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 ed24d3cc..edabc73d 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 d0d0d76d..8087f2bf 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 322fb939..92229829 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 b19bae1d..af3782af 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 c017db00..758dddb4 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 195b0180..eb9871c9 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 f320edef..6ab6fde3 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 245ce1cb..cc0c1d77 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 cc0c1d77..34f58934 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 5858a059..9ecefb69 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 9ecefb69..fda4c3a4 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 ca7c7f2c..98c95892 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 e27350f8..69191bab 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 7ee36435..2c9ca321 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 f666441b..cd243df0 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 43599e98..d27a1392 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 44843e8e..9a27c2a9 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 49815187..2a1b4793 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 60bbb781..d923b012 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 cde1779b..325f15d2 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 @@ namespace Oqtane.UI 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 dcc886b1..2d7e6b00 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 f95f8607..56360ca9 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 3afb023b..bcfdf9a8 100644 --- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs +++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs @@ -8,7 +8,6 @@ using Oqtane.Infrastructure; 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 8671e0f7..b008ee30 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -21,7 +21,6 @@ using Oqtane.Repository; 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 00000000..4cca8235 --- /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 728641cf..2800b342 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 220f5ffe..beaa74c1 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 9a27c2a9..4eab45b9 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 80c7f5a2..e7985f51 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 ee191dd8..2ae692d7 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 7c54bfa2..4e3966f9 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 1baac265..03c0d629 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 02d1d14c..7c54bfa2 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 cd243df0..1d205ba5 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 2ae692d7..19f58753 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 03c0d629..7c2c1303 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 3fcb0fb5..f4ae994e 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 (!string.IsNullOrEmpty(_exception)) + { - - - - - @if (_pageName != string.Empty) - { - - - - - } - @if (_moduleTitle != string.Empty) - { - - - - - } - @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 f4ae994e..59830a0d 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 2a1b4793..25d5b2ae 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 65361e41..c216d83d 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 2d4ef706..f5d8a391 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 9f19370d..4822b3af 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 25d8e4fb..8fbed632 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 c216d83d..fde389bf 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 6ba8c69b..e99a09b0 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 8fbed632..62929440 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 e99a09b0..cbc137f7 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 4822b3af..df16cac8 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 73cac84d..bde883c3 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 ccb8a135..f1897de8 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 379e9d7f..1ec0107d 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 bde883c3..81829d3a 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 f1897de8..bff90388 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 2ea64944..dfff44e0 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 b6e4eb66..1a04eb46 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 cafecf3b..2ad8f8ed 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 526f1af4..32233f6c 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 eaa0bc92..6a7942b6 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 0e15706f..25ef9b63 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 36e7c35c..c38009c5 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 6ee0bba4..8c1fc95a 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 51ed8992..71e5d170 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 32233f6c..23bc7a10 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 71e5d170..b47700eb 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 fabf6973..3d0fe338 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 3d0fe338..7d5cbd90 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 1d99bcb9..632486d2 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 31cedb01..acf15177 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 6a7942b6..80010036 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 632486d2..b3ace332 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 acf15177..95bb5cec 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"]


+ + + + + + + + + + + + + + + + @if (!string.IsNullOrEmpty(_location)) + { + + + + + } +
- + @@ -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 84ef808e..f4c415c9 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 a5d95aeb..e939d633 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 7629066b..02ae862c 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 204aa21f..000f54be 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 3d7d2327..40af9497 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 d923b012..ed9eb289 100644 --- a/Oqtane.Client/Themes/Controls/LoginBase.cs +++ b/Oqtane.Client/Themes/Controls/LoginBase.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using Oqtane.Providers; using Oqtane.Services; -using Oqtane.Shared; +using Oqtane.UI; namespace Oqtane.Themes.Controls { @@ -29,7 +29,7 @@ namespace Oqtane.Themes.Controls { 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 cbc137f7..ffd32c17 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 | 137 +++++++++--------- 1 file changed, 72 insertions(+), 65 deletions(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 2ad8f8ed..9da0deec 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 2800b342..356567ac 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 9da0deec..28b1c6e0 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 23bc7a10..22d08ac2 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 7d5cbd90..da1f58a8 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 98c95892..5a1e485a 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 6ab6fde3..fa896dd4 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 758dddb4..8b64bff8 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 ee846b13..04a1056e 100644 --- a/Oqtane.Client/Modules/Controls/ModuleMessage.razor +++ b/Oqtane.Client/Modules/Controls/ModuleMessage.razor @@ -5,7 +5,7 @@ @if (!string.IsNullOrEmpty(_message)) {
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ +} +else +{ + +} @code { + private string _moduledefinitionname = ""; private string _owner = string.Empty; private string _module = string.Empty; private string _description = string.Empty; @@ -86,6 +94,21 @@ public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + protected override void OnInitialized() + { + _moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", ""); + if (string.IsNullOrEmpty(_moduledefinitionname)) + { + _owner = ModuleState.Title; + _module = ModuleState.Title; + _description = ModuleState.Title; + } + else + { + AddModuleMessage("Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below", MessageType.Info); + } + } + private async Task CreateModule() { try @@ -93,8 +116,13 @@ if (IsValid(_owner) && IsValid(_module) && _template != "-") { 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); + moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition); + + var settings = ModuleState.Settings; + SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName); + await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId); + + AddModuleMessage("The Source Code For Your Module Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application To Apply These Changes.", MessageType.Success); } else { @@ -107,6 +135,25 @@ } } + private async Task ActivateModule() + { + try + { + if (!string.IsNullOrEmpty(_moduledefinitionname)) + { + Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId); + module.ModuleDefinitionName = _moduledefinitionname; + await ModuleService.UpdateModuleAsync(module); + StateHasChanged(); + NavigationManager.NavigateTo(NavigateUrl()); + } + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Activating Module"); + } + } + private bool IsValid(string name) { // must contain letters, underscores and digits and first character must be letter or underscore diff --git a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs index cca5e642..e4b8ce64 100644 --- a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs +++ b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; using Oqtane.UI; using System.Collections.Generic; using System.Threading.Tasks; @@ -12,6 +12,6 @@ namespace Oqtane.Services Task UpdateModuleDefinitionAsync(ModuleDefinition moduleDefinition); Task InstallModuleDefinitionsAsync(); Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId); - Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition, int moduleId); + Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition); } } diff --git a/Oqtane.Client/Services/ModuleDefinitionService.cs b/Oqtane.Client/Services/ModuleDefinitionService.cs index 8486e417..87ae7e09 100644 --- a/Oqtane.Client/Services/ModuleDefinitionService.cs +++ b/Oqtane.Client/Services/ModuleDefinitionService.cs @@ -1,4 +1,4 @@ -using Oqtane.Models; +using Oqtane.Models; using System.Collections.Generic; using System.Linq; using System.Net.Http; @@ -49,9 +49,9 @@ namespace Oqtane.Services await DeleteAsync($"{Apiurl}/{moduleDefinitionId}?siteid={siteId}"); } - public async Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition, int moduleId) + public async Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition) { - await PostJsonAsync($"{Apiurl}?moduleid={moduleId}", moduleDefinition); + return await PostJsonAsync($"{Apiurl}", moduleDefinition); } } } diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs index e30fffee..299ad601 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -23,26 +23,22 @@ namespace Oqtane.Controllers public class ModuleDefinitionController : Controller { private readonly IModuleDefinitionRepository _moduleDefinitions; - private readonly IModuleRepository _modules; private readonly ITenantRepository _tenants; private readonly ISqlRepository _sql; private readonly IUserPermissions _userPermissions; private readonly IInstallationManager _installationManager; private readonly IWebHostEnvironment _environment; - private readonly IConfigurationRoot _config; private readonly IServiceProvider _serviceProvider; private readonly ILogManager _logger; - public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, IModuleRepository modules,ITenantRepository tenants, ISqlRepository sql, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, IConfigurationRoot config, IServiceProvider serviceProvider, ILogManager logger) + public ModuleDefinitionController(IModuleDefinitionRepository moduleDefinitions, ITenantRepository tenants, ISqlRepository sql, IUserPermissions userPermissions, IInstallationManager installationManager, IWebHostEnvironment environment, IServiceProvider serviceProvider, ILogManager logger) { _moduleDefinitions = moduleDefinitions; - _modules = modules; _tenants = tenants; _sql = sql; _userPermissions = userPermissions; _installationManager = installationManager; _environment = environment; - _config = config; _serviceProvider = serviceProvider; _logger = logger; } @@ -166,7 +162,7 @@ namespace Oqtane.Controllers // POST api/?moduleid=x [HttpPost] [Authorize(Roles = RoleNames.Host)] - public void Post([FromBody] ModuleDefinition moduleDefinition, string moduleid) + public ModuleDefinition Post([FromBody] ModuleDefinition moduleDefinition) { if (ModelState.IsValid) { @@ -190,19 +186,17 @@ namespace Oqtane.Controllers ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition); _logger.Log(LogLevel.Information, this, LogFunction.Create, "Module Definition Created {ModuleDefinition}", moduleDefinition); - Models.Module module = _modules.GetModule(int.Parse(moduleid)); - module.ModuleDefinitionName = moduleDefinition.ModuleDefinitionName; - _modules.UpdateModule(module); - if (moduleDefinition.Template == "internal") { - // add embedded resources to project + // add embedded resources to project file List resources = new List(); resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".1.0.0.sql")); resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".Uninstall.sql")); EmbedResourceFiles(Utilities.PathCombine(rootPath, "Oqtane.Server", "Oqtane.Server.csproj"), resources); } } + + return moduleDefinition; } private void ProcessTemplatesRecursively(DirectoryInfo current, string rootPath, string rootFolder, string templatePath, ModuleDefinition moduleDefinition) From 7fd0c6c3aa36c56f473460d5b791a045b35351fd Mon Sep 17 00:00:00 2001 From: hishamco Date: Thu, 26 Nov 2020 00:04:47 +0300 Subject: [PATCH 052/177] Fix localization issue in ActionLink --- Oqtane.Client/Modules/Controls/ActionLink.razor | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Controls/ActionLink.razor b/Oqtane.Client/Modules/Controls/ActionLink.razor index b375038d..eacc9813 100644 --- a/Oqtane.Client/Modules/Controls/ActionLink.razor +++ b/Oqtane.Client/Modules/Controls/ActionLink.razor @@ -97,7 +97,7 @@ if (IsLocalizable) { - _text = Localize(nameof(Text)); + _text = Localize(nameof(Text), _text); } _url = EditUrl(Action, _parameters); From 3fcbc07406d1f11e2564d1dd58df6244a39b21c4 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Wed, 25 Nov 2020 16:51:39 -0500 Subject: [PATCH 053/177] Module Creator activation improvement --- Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor | 2 +- Oqtane.Client/Modules/ModuleBase.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor index 6ca85d5d..f3712317 100644 --- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor +++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor @@ -144,7 +144,7 @@ else Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId); module.ModuleDefinitionName = _moduledefinitionname; await ModuleService.UpdateModuleAsync(module); - StateHasChanged(); + ClearModuleMessage(); NavigationManager.NavigateTo(NavigateUrl()); } } diff --git a/Oqtane.Client/Modules/ModuleBase.cs b/Oqtane.Client/Modules/ModuleBase.cs index e51b9873..bfd9d395 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -173,6 +173,11 @@ namespace Oqtane.Modules ModuleInstance.AddModuleMessage(message, type); } + public void ClearModuleMessage() + { + ModuleInstance.AddModuleMessage("", MessageType.Undefined); + } + public void ShowProgressIndicator() { ModuleInstance.ShowProgressIndicator(); From 2ea0b7199b6b3c65b9218a3e6486a1dea32e35e6 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 27 Nov 2020 21:48:52 +0300 Subject: [PATCH 054/177] Localize log messages --- Oqtane.Server/Infrastructure/LogManager.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Oqtane.Server/Infrastructure/LogManager.cs b/Oqtane.Server/Infrastructure/LogManager.cs index 52a4736a..19f579ee 100644 --- a/Oqtane.Server/Infrastructure/LogManager.cs +++ b/Oqtane.Server/Infrastructure/LogManager.cs @@ -1,15 +1,14 @@ -using Oqtane.Shared; using System; -using Oqtane.Models; -using System.Text.Json; -using Microsoft.Extensions.Configuration; -using Microsoft.AspNetCore.Http; using System.Collections.Generic; +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; using Oqtane.Security; -// ReSharper disable StringIndexOfIsCultureSpecific.2 -// ReSharper disable StringIndexOfIsCultureSpecific.1 +using Oqtane.Shared; namespace Oqtane.Infrastructure { @@ -20,14 +19,16 @@ namespace Oqtane.Infrastructure 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) + public LogManager(ILogRepository logs, ITenantResolver tenantResolver, IConfigurationRoot config, IUserPermissions userPermissions, IHttpContextAccessor accessor, IStringLocalizer localizer) { _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) @@ -123,6 +124,7 @@ namespace Oqtane.Infrastructure log.LogDate = DateTime.UtcNow; log.Server = Environment.MachineName; log.MessageTemplate = log.Message; + log.Message = _localizer[log.Message]; log = ProcessStructuredLog(log); try { From d5e48296edb68539704e08b4e4e2228f263c5372 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 27 Nov 2020 22:06:40 +0300 Subject: [PATCH 055/177] Set RootNamespace --- Oqtane.Server/AssemblyInfo.cs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Oqtane.Server/AssemblyInfo.cs diff --git a/Oqtane.Server/AssemblyInfo.cs b/Oqtane.Server/AssemblyInfo.cs new file mode 100644 index 00000000..d598bfb9 --- /dev/null +++ b/Oqtane.Server/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using Microsoft.Extensions.Localization; + +[assembly: RootNamespace("Oqtane")] From d964c25596608003cf7eb1fb4851e32126b240f4 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 27 Nov 2020 22:06:54 +0300 Subject: [PATCH 056/177] Add Resources folder --- Oqtane.Server/Resources/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Oqtane.Server/Resources/.gitkeep diff --git a/Oqtane.Server/Resources/.gitkeep b/Oqtane.Server/Resources/.gitkeep new file mode 100644 index 00000000..e69de29b From e9a58138fc8003697fea4f2b91a09493426af6c4 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Mon, 30 Nov 2020 18:59:44 -0500 Subject: [PATCH 057/177] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 356567ac..5a7477a6 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 ) - [ ] Complete Static Localization of Admin UI +- [ ] Cross Platform Database Support ( ie. SQLite ) - [ ] 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 From 418c9888c46547b2d4a65c0e9bec39650463fce2 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 01:38:00 +0300 Subject: [PATCH 058/177] Add LocalizationController --- .../Controllers/LocalizationController.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Oqtane.Server/Controllers/LocalizationController.cs diff --git a/Oqtane.Server/Controllers/LocalizationController.cs b/Oqtane.Server/Controllers/LocalizationController.cs new file mode 100644 index 00000000..f8b7433a --- /dev/null +++ b/Oqtane.Server/Controllers/LocalizationController.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using Oqtane.Infrastructure; +using Oqtane.Shared; + +namespace Oqtane.Controllers +{ + [Route(ControllerRoutes.Default)] + public class LocalizationController : Controller + { + private readonly ILocalizationManager _localizationManager; + + public LocalizationController(ILocalizationManager localizationManager) + { + _localizationManager = localizationManager; + } + + // GET: api/localization/getSupportedCultures + [HttpGet("getSupportedCultures")] + public IEnumerable GetSupportedCultures() => _localizationManager.GetSupportedCultures(); + + // GET api/localization/getDefaultCulture + [HttpGet("getDefaultCulture")] + public string GetDefaultCulture() => _localizationManager.GetDefaultCulture(); + } +} From c67e893b6ea8cb5da6917cfed99988737d6d1412 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 01:38:32 +0300 Subject: [PATCH 059/177] Add LocalizationService APIs --- .../Interfaces/ILocalizationService.cs | 11 ++++++++++ Oqtane.Client/Services/LocalizationService.cs | 22 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 Oqtane.Client/Services/Interfaces/ILocalizationService.cs create mode 100644 Oqtane.Client/Services/LocalizationService.cs diff --git a/Oqtane.Client/Services/Interfaces/ILocalizationService.cs b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs new file mode 100644 index 00000000..c025ee45 --- /dev/null +++ b/Oqtane.Client/Services/Interfaces/ILocalizationService.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Oqtane.Services +{ + public interface ILocalizationService + { + Task GetDefaultCulture(); + + Task GetSupportedCultures(); + } +} diff --git a/Oqtane.Client/Services/LocalizationService.cs b/Oqtane.Client/Services/LocalizationService.cs new file mode 100644 index 00000000..4c658c50 --- /dev/null +++ b/Oqtane.Client/Services/LocalizationService.cs @@ -0,0 +1,22 @@ +using System.Net.Http; +using System.Threading.Tasks; +using Oqtane.Shared; + +namespace Oqtane.Services +{ + public class LocalizationService : ServiceBase, ILocalizationService + { + private readonly SiteState _siteState; + + public LocalizationService(HttpClient http, SiteState siteState) : base(http) + { + _siteState = siteState; + } + + private string Apiurl => CreateApiUrl(_siteState.Alias, "Localization"); + + public async Task GetDefaultCulture() => await GetJsonAsync($"{Apiurl}/getDefaultCulture"); + + public async Task GetSupportedCultures() => await GetJsonAsync($"{Apiurl}/getSupportedCultures"); + } +} From c4d1b16abb16f713a950d37325e4d14bcc68edd1 Mon Sep 17 00:00:00 2001 From: hishamco Date: Wed, 2 Dec 2020 01:52:46 +0300 Subject: [PATCH 060/177] Add LanguageSwitcher component --- Oqtane.Client/Program.cs | 5 ++-- .../Themes/Controls/ControlPanel.razor | 2 ++ .../Themes/Controls/LanguageSwitcher.razor | 30 +++++++++++++++++++ Oqtane.Server/Pages/_Host.cshtml | 6 ++++ Oqtane.Server/Startup.cs | 1 + 5 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 Oqtane.Client/Themes/Controls/LanguageSwitcher.razor diff --git a/Oqtane.Client/Program.cs b/Oqtane.Client/Program.cs index af283cec..7fdfa6bd 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -5,15 +5,15 @@ using System.IO.Compression; using System.Linq; using System.Net.Http; using System.Reflection; -using System.Threading.Tasks; using System.Runtime.Loader; +using System.Threading.Tasks; using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; using Oqtane.Modules; using Oqtane.Providers; -using Oqtane.Shared; using Oqtane.Services; +using Oqtane.Shared; namespace Oqtane.Client { @@ -62,6 +62,7 @@ namespace Oqtane.Client builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); await LoadClientAssemblies(httpClient); diff --git a/Oqtane.Client/Themes/Controls/ControlPanel.razor b/Oqtane.Client/Themes/Controls/ControlPanel.razor index 02ae862c..0ea20a8a 100644 --- a/Oqtane.Client/Themes/Controls/ControlPanel.razor +++ b/Oqtane.Client/Themes/Controls/ControlPanel.razor @@ -198,6 +198,8 @@
} + + @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 00000000..3b630a7a --- /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 2aa0dd9d..92dea6bc 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 b008ee30..b134a19e 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -127,6 +127,7 @@ namespace Oqtane 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 3ce83439..da11a472 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 7fdfa6bd..6689db41 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 System.Threading.Tasks; 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 @@ namespace Oqtane.Client } 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 3b630a7a..8ce1c52d 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 6689db41..43dc617a 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -16,6 +16,7 @@ using Oqtane.Modules; using Oqtane.Providers; using Oqtane.Services; using Oqtane.Shared; +using Oqtane.UI; namespace Oqtane.Client { @@ -92,7 +93,8 @@ namespace Oqtane.Client 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 8ce1c52d..ddde387b 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 53b8df4f..83a88ad5 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 @@ namespace Oqtane.UI } } + 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 92dea6bc..ecf906e4 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 2e4092e4..dc3f0394 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 ddde387b..9c67f24c 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 9c67f24c..e14e8a8e 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 80010036..fd1aa71c 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 b3ace332..585aeeda 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 95bb5cec..a4bd4188 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 0dd706ee..24a5da86 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 80af124d..c619f268 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 028fca3f..0c04ff94 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 f8406a13..082e04ee 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 188160a0..8956bac7 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 @@ namespace Oqtane.Controllers 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 43dc617a..fcc03099 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -94,7 +94,7 @@ namespace Oqtane.Client 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 e14e8a8e..4b0a3acd 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 83a88ad5..10c37d44 100644 --- a/Oqtane.Client/UI/Interop.cs +++ b/Oqtane.Client/UI/Interop.cs @@ -234,13 +234,13 @@ namespace Oqtane.UI } } - 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 @@ namespace Oqtane.UI } } - 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 dc3f0394..e71f4b81 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 c025ee45..8a580cc6 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 4c658c50..ea6e5fd8 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 @@ namespace Oqtane.Services 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 4b0a3acd..7c3ca1d2 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 f8b7433a..46e475ef 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 @@ namespace Oqtane.Controllers // 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 00000000..78d249d6 --- /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 7c3ca1d2..c8e7bfb9 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 da11a472..72024f75 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 cc85b9b9..4c2d1201 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -10,6 +10,7 @@ using System.Runtime.Loader; 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 @@ namespace Oqtane.Client 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 e1d16002..6f748e88 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 10c37d44..3964b070 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 @@ namespace Oqtane.UI 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 67676d16..81ca19ac 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 @@ namespace Oqtane.Extensions 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 ecf906e4..cf2d69f0 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 e71f4b81..2e4092e4 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 81ca19ac..4f43068e 100644 --- a/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs +++ b/Oqtane.Server/Extensions/ApplicationBuilderExtensions.cs @@ -32,7 +32,7 @@ namespace Oqtane.Extensions 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 082e04ee..667816ab 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 fb43a7cb..5389b423 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -17,6 +17,7 @@ using Oqtane.Enums; using Oqtane.Infrastructure; using Oqtane.Repository; using Microsoft.AspNetCore.Routing.Constraints; +using Oqtane.Extensions; // ReSharper disable StringIndexOfIsCultureSpecific.1 @@ -314,9 +315,9 @@ namespace Oqtane.Controllers { 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 @@ namespace Oqtane.Controllers [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 49b3b2cd..a2c7c88b 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 @@ namespace Oqtane.Extensions { 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 5a7477a6..c8cfec4e 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 ac7e4690..4770729b 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 df16cac8..33633fe0 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 291b2acb..e1c4b3f9 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 000f54be..d11b0795 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 ed9eb289..27f43497 100644 --- a/Oqtane.Client/Themes/Controls/LoginBase.cs +++ b/Oqtane.Client/Themes/Controls/LoginBase.cs @@ -22,7 +22,7 @@ namespace Oqtane.Themes.Controls { 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 667816ab..469a0a7b 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 026a2986..aa2cf790 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 ffd32c17..f2a02c75 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 f5d8a391..b0049db7 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 59830a0d..a0ea8b04 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 4770729b..73723fa5 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 eacc9813..1ba9ef12 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 85e65d14..05f2b790 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 657494d7..40f2eda5 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -15,27 +15,22 @@ namespace Oqtane.Modules.Controls 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 @@ namespace Oqtane.Modules.Controls 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 fd8b9a52..027b0e85 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 7c2eaa24..e618c896 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 40f2eda5..773df857 100644 --- a/Oqtane.Client/Modules/Controls/LocalizableComponent.cs +++ b/Oqtane.Client/Modules/Controls/LocalizableComponent.cs @@ -34,7 +34,15 @@ namespace Oqtane.Modules.Controls } 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 05f2b790..b67143cb 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 6344925d..b221904d 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 ecd7cb91..a4b40921 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 69191bab..c003d1b4 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 fda4c3a4..bf27d99f 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 8b64bff8..8d27b057 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 d669f678..15c14bce 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 8087f2bf..8ac788ee 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 d8df82b6..64791442 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -502,6 +502,33 @@ namespace Oqtane.Repository } }); 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 8eb6eef3..a52e8022 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 da1e0342..5f5d29cb 100644 --- a/Oqtane.Client/Services/LanguageService.cs +++ b/Oqtane.Client/Services/LanguageService.cs @@ -23,7 +23,7 @@ namespace Oqtane.Services { 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 79270ffb..d6fd06c4 100644 --- a/Oqtane.Server/Repository/Context/TenantDBContext.cs +++ b/Oqtane.Server/Repository/Context/TenantDBContext.cs @@ -21,7 +21,7 @@ namespace Oqtane.Repository 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 2f59a047..bdfd1b3e 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -13,22 +13,22 @@ namespace Oqtane.Repository _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 a52e8022..8eb54714 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 00000000..baa287e5 --- /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 bff90388..82da2bb7 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 beaa74c1..15725daa 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 92229829..b5988315 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 316b17ea..c9ec1c61 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 845db70b..26991f37 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 e1c4b3f9..f4650202 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 0435b2b1..a5ca7327 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 8f8f91ba..d47b8dcf 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 0ea20a8a..c1ba3e54 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 0ea20a8a..d38db7de 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 6f748e88..4dca37bc 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 34f58934..247b338a 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 bf27d99f..2aa70ecb 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 fa896dd4..ab042ed5 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 8d27b057..816bd06f 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 eb9871c9..2510759d 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 9642a090..c0475d59 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 7803a769..d3212726 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 a5ca7327..4b2874b6 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 c9ec1c61..fcd7340c 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 15c14bce..89b1e775 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 edabc73d..be68ff7d 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 b5988315..037daabb 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 d11b0795..a35a5209 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 40af9497..3a33cc33 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 25ef9b63..311c4cd7 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 8c1fc95a..9231e092 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 c619f268..273404e9 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 469a0a7b..6b42f15b 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 5a7477a6..c2462077 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 19f579ee..648f873f 100644 --- a/Oqtane.Server/Infrastructure/LogManager.cs +++ b/Oqtane.Server/Infrastructure/LogManager.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; 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 @@ namespace Oqtane.Infrastructure 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 @@ namespace Oqtane.Infrastructure 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 bfd9d395..3fd548ac 100644 --- a/Oqtane.Client/Modules/ModuleBase.cs +++ b/Oqtane.Client/Modules/ModuleBase.cs @@ -116,7 +116,12 @@ namespace Oqtane.Modules 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 5389b423..a5f0ffdd 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -66,7 +66,7 @@ namespace Oqtane.Controllers { 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 @@ namespace Oqtane.Controllers { 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 @@ namespace Oqtane.Controllers { _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 @@ namespace Oqtane.Controllers { _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 @@ namespace Oqtane.Controllers if (!file.FileName.IsPathOrFileValid()) { - HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict; + HttpContext.Response.StatusCode = (int) HttpStatusCode.Conflict; return; } @@ -432,9 +434,38 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers _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 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers 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 00000000..f5983da6 --- /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 a2c7c88b..ede3bce9 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 @@ namespace Oqtane.Extensions 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 c2cfc90f..3de29f59 100644 --- a/Oqtane.Shared/Shared/Utilities.cs +++ b/Oqtane.Shared/Shared/Utilities.cs @@ -95,11 +95,17 @@ namespace Oqtane.Shared 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 @@ namespace Oqtane.Shared 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 7e3004fb..650eaee6 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 72bc3c6f..2a253ed1 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 7cd500a6..4a99881c 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 73723fa5..43d6e0af 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 1ba9ef12..cf2cd1df 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 4400ad71..575a513b 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 a269df15..79b20589 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 6373a11d..dbc8c15b 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 688a1b25..3dd8ab3f 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs @@ -39,7 +39,7 @@ namespace Oqtane.SiteTemplates Name = "Home", Parent = "", Path = "", - Icon = "home", + Icon = "oi oi-home", IsNavigation = true, IsPersonalizable = false, PagePermissions = new List { @@ -85,7 +85,7 @@ namespace Oqtane.SiteTemplates Name = "Private", Parent = "", Path = "private", - Icon = "lock-locked", + Icon = "oi oi-lock-locked", IsNavigation = true, IsPersonalizable = false, PagePermissions = new List { @@ -109,7 +109,7 @@ namespace Oqtane.SiteTemplates 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 408fa3fe..e37cbbcb 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 @@ namespace Oqtane.SiteTemplates 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 9053bea7..699eccf8 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 00000000..149728be --- /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 586d0bae..521c3c12 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 931f3ff3..8018be30 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 8018be30..931f3ff3 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 4dca37bc..16391513 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 0130e5e3..d8df82b6 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 @@ namespace Oqtane.Repository }); 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 @@ namespace Oqtane.Repository }); 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 a4bd4188..c6ebe5c3 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 00000000..c5753099 --- /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 2a253ed1..171ab885 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 4a99881c..5efdd992 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 931f3ff3..eee04121 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 3910ab9b..ddf17450 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 2e18950f..404829d7 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 @@ namespace Oqtane.Infrastructure // 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 @@ namespace Oqtane.Infrastructure } 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 c1971223..2137d929 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 2a2a8a2f..cfce1a60 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 00000000..5a324d79 --- /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 ddf17450..63e58889 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 404829d7..deafe30a 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -50,7 +50,7 @@ namespace Oqtane.Infrastructure 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 @@ namespace Oqtane.Infrastructure 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 @@ namespace Oqtane.Infrastructure } 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 00000000..b2a38ee5 --- /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 be085b20..79270ffb 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 @@ namespace Oqtane.Repository 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 00000000..0ec10442 --- /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 00000000..2f59a047 --- /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 b134a19e..b4e9569d 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -213,6 +213,7 @@ namespace Oqtane 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 00000000..2433d0d0 --- /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 4c2d1201..558b8290 100644 --- a/Oqtane.Client/Program.cs +++ b/Oqtane.Client/Program.cs @@ -67,6 +67,7 @@ namespace Oqtane.Client 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 00000000..82fbcc78 --- /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 00000000..432a2312 --- /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 b4e9569d..0353bc03 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -128,6 +128,7 @@ namespace Oqtane 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 432a2312..da1e0342 100644 --- a/Oqtane.Client/Services/LanguageService.cs +++ b/Oqtane.Client/Services/LanguageService.cs @@ -29,7 +29,7 @@ namespace Oqtane.Services 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 b2a38ee5..2b8f7cf0 100644 --- a/Oqtane.Server/Controllers/LanguageController.cs +++ b/Oqtane.Server/Controllers/LanguageController.cs @@ -17,8 +17,8 @@ namespace Oqtane.Controllers public LanguageController(ILanguageRepository language, ILogManager logger) { - _languages = roles; - _logger = language; + _languages = language; + _logger = logger; } [HttpGet] @@ -36,9 +36,9 @@ namespace Oqtane.Controllers 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 00000000..8eb6eef3 --- /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 00000000..c45a8bc2 --- /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 c45a8bc2..933903cc 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 bdfd1b3e..ade74f2d 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -17,6 +17,12 @@ namespace Oqtane.Repository 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 7f57ec70..a2ca3c86 100644 --- a/Oqtane.Client/Themes/ThemeBase.cs +++ b/Oqtane.Client/Themes/ThemeBase.cs @@ -88,5 +88,10 @@ namespace Oqtane.Themes { 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 a5f0ffdd..ce36dae2 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -142,13 +142,13 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers { _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 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers if (virtualFolder != null && _userPermissions.IsAuthorized(User, PermissionNames.Edit, virtualFolder.Permissions)) { - folderPath = GetFolderPath(virtualFolder); + folderPath = _folders.GetFolderPath(virtualFolder); } } else @@ -291,7 +291,7 @@ namespace Oqtane.Controllers } } - if (folderPath != "") + if (!String.IsNullOrEmpty(folderPath)) { CreateDirectory(folderPath); using (var stream = new FileStream(Path.Combine(folderPath, file.FileName), FileMode.Create)) @@ -472,7 +472,7 @@ namespace Oqtane.Controllers { 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 @@ namespace Oqtane.Controllers 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 0e5fa798..07866810 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 @@ namespace Oqtane.Repository { 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 @@ namespace Oqtane.Repository _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 dbaed6c1..dc7125bb 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 @@ namespace Oqtane.Repository { 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 @@ namespace Oqtane.Repository _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 7ef99025..adfe8f89 100644 --- a/Oqtane.Server/Repository/Interfaces/IFileRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IFileRepository.cs @@ -11,5 +11,7 @@ namespace Oqtane.Repository 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 52b67e5b..5ce7467f 100644 --- a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs +++ b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs @@ -12,5 +12,7 @@ namespace Oqtane.Repository 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 baa287e5..efd5f22b 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 16391513..dd92bf15 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 efd5f22b..02b8e0c2 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 dd92bf15..bd4ac6fc 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 8eb54714..0e6d04ab 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 2b8f7cf0..c63988bb 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 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers } [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 64791442..774d0330 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -512,7 +512,9 @@ namespace Oqtane.Repository 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 @@ namespace Oqtane.Repository 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 c63988bb..2b8f7cf0 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 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers } [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 4f598322..35f93353 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 @@ namespace Oqtane.Infrastructure 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 5fb49934..96ab55a0 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 @@ namespace Oqtane.Infrastructure // 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 @@ namespace Oqtane.Infrastructure // 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); + } + } + + _executingTask = ExecuteAsync(_cancellationTokenSource.Token); + + if (_executingTask.IsCompleted) + { + return _executingTask; } } catch { - // can occur during the initial installation as there is no DBContext - } - - _executingTask = ExecuteAsync(_cancellationTokenSource.Token); - - if (_executingTask.IsCompleted) - { - 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 deafe30a..bc1a2d31 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -14,7 +14,13 @@ namespace Oqtane.Infrastructure { // 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 | 162 ++++++++---------- 2 files changed, 83 insertions(+), 89 deletions(-) diff --git a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs index 96ab55a0..36fbefb6 100644 --- a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs +++ b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs @@ -91,7 +91,15 @@ namespace Oqtane.Infrastructure // 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 bc1a2d31..92d1d336 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -26,103 +26,89 @@ namespace Oqtane.Infrastructure { 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) + // get services + 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) { - if (tenants.Contains(alias.TenantId)) continue; - tenants.Add(alias.TenantId); + log += "Processing Notifications For Site: " + site.Name + "
"; - // use the SiteState to set the Alias explicitly so the tenant can be resolved - var siteState = provider.GetRequiredService(); - siteState.Alias = alias; - - // 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) + // 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 + "
"; - - // 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"] != "") + // construct SMTP Client + var client = new SmtpClient() { - // 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"]); - } + 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"]); + } - // iterate through notifications - int sent = 0; - List notifications = notificationRepository.GetNotifications(site.SiteId, -1, -1).ToList(); - foreach (Notification notification in notifications) + // iterate through 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) { - 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.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; - // 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 8535d2c0..00000000 --- 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 65043de8..9a436b6d 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 7a435f77..5aefdcbe 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 d3212726..dcc96ff4 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 fcd7340c..ff9f3937 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 5a97087a..9819994b 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 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers 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 92d1d336..7818d9d3 100644 --- a/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs +++ b/Oqtane.Server/Infrastructure/Jobs/NotificationJob.cs @@ -22,16 +22,18 @@ namespace Oqtane.Infrastructure 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 @@ namespace Oqtane.Infrastructure 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 + if ((string.IsNullOrEmpty(notification.ToEmail) || string.IsNullOrEmpty(notification.ToDisplayName)) && notification.ToUserId != null) { - mailMessage.Body = "From: " + site.Name + "\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; + } } - mailMessage.Body += "Sent: " + notification.CreatedOn + "\n"; - if (notification.ToUserId != null) + + // validate recipient + if (string.IsNullOrEmpty(notification.ToEmail)) { - 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; + 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 43025c3a..38ec8559 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 @@ namespace Oqtane.Repository { 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 7ccdbd9d..6795c954 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 @@ namespace Oqtane.Models 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 02b8e0c2..7efbcf85 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 933903cc..748c875b 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 8956bac7..4d8dac8d 100644 --- a/Oqtane.Server/Controllers/AliasController.cs +++ b/Oqtane.Server/Controllers/AliasController.cs @@ -50,29 +50,13 @@ namespace Oqtane.Controllers [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 @@ namespace Oqtane.Controllers 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 8176804d..1ac18c29 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 c50e5b1f..662beb18 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -7,11 +7,28 @@ using Oqtane.Themes; 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 @@ namespace Oqtane.Pages 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 ccb26681..f25c4c03 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 @@ namespace Oqtane.Repository 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 247006bd..522bf0d9 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 65312819..976874cf 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 4f258307..5422ab07 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 @@ namespace Oqtane.Repository 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 ade74f2d..0ee5105b 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -17,10 +17,10 @@ namespace Oqtane.Repository 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 cd273b3a..815a8c55 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; + } - if (siteState != null && siteState.Alias != null) + public Alias GetAlias() + { + if (_alias == null) ResolveTenant(); + return _alias; + } + + public Tenant GetTenant() + { + if (_tenant == null) ResolveTenant(); + return _tenant; + } + + 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 @@ namespace Oqtane.Repository } // 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 @@ namespace Oqtane.Repository 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 0e6d04ab..3f3f4976 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 0353bc03..babe9245 100644 --- a/Oqtane.Server/Startup.cs +++ b/Oqtane.Server/Startup.cs @@ -132,10 +132,7 @@ namespace Oqtane 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 2433d0d0..e0afdd66 100644 --- a/Oqtane.Shared/Models/Language.cs +++ b/Oqtane.Shared/Models/Language.cs @@ -12,7 +12,7 @@ namespace Oqtane.Models 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 3fb2bb95..b9dcd431 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 0ee5105b..7f92086b 100644 --- a/Oqtane.Server/Repository/LanguageRepository.cs +++ b/Oqtane.Server/Repository/LanguageRepository.cs @@ -20,7 +20,10 @@ namespace Oqtane.Repository 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 662beb18..d93ead04 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -5,6 +5,7 @@ using Oqtane.Modules; 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 @@ namespace Oqtane.Pages // 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 575a513b..c4c45f16 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 00000000..bfdd3cd4 --- /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 00000000..3a54c855 --- /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 00000000..30226bfb --- /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 00000000..04cd682a --- /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 00000000..07ecda89 --- /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 3a54c855..1ba03d4f 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 00000000..85ba00b8 --- /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 79b20589..a552ea11 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 00000000..04cd682a --- /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 00000000..07ecda89 --- /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 3a54c855..1ba03d4f 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 00000000..85ba00b8 --- /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 79b20589..a552ea11 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 | 241 ++++++++++-------- 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 | 72 +++--- 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 | 114 +++++---- 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, 494 insertions(+), 484 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 a3f0b71e..538bf700 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 63e58889..acd0105b 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) - { - - - - - } - - - - - - - - - - - - -
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +
- - - -
- - - -
- - - -
- - - -
+ } +
+ + + +
+ + + +
+ + + +
+ + + +
@@ -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 2945f23a..a4b430e9 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 3d01cf2e..b1afc85c 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 247b338a..00000000 --- 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 2aa70ecb..00000000 --- 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 816bd06f..9e8677f7 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 5f3ae713..64f32728 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 04cd682a..04aad17e 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 07ecda89..00000000 --- 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 1ba03d4f..840fbf4e 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 30226bfb..00000000 --- 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 ab6c92d8..a27f9a7a 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 85ba00b8..00000000 --- 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 5a164309..41f8268a 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 299ad601..dc371214 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -101,13 +101,12 @@ namespace Oqtane.Controllers 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 @@ namespace Oqtane.Controllers _logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Uninstalling {ModuleDefinitionName} For Tenant {Tenant} {Error}", moduledefinition.ModuleDefinitionName, tenant.Name, ex.Message); } } - - // 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(assetfilepath)); - foreach(string asset in assets) - { - if (System.IO.File.Exists(asset)) - { - System.IO.File.Delete(asset); - } - } - _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)) - { - Directory.Delete(folder, true); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Resources Folder Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); - } - - // remove module definition - _moduleDefinitions.DeleteModuleDefinition(id, siteid); - _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name); } + + // 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 + List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); + 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)) + { + System.IO.File.Delete(filepath); + } + } + _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) + "*.*")) + { + 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); + } + + // 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 07ed6152..615080e9 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -57,28 +57,44 @@ namespace Oqtane.Controllers 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 60910484..f14e8ae1 100644 --- a/Oqtane.Server/Infrastructure/InstallationManager.cs +++ b/Oqtane.Server/Infrastructure/InstallationManager.cs @@ -28,13 +28,13 @@ namespace Oqtane.Infrastructure 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 @@ namespace Oqtane.Infrastructure 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 @@ namespace Oqtane.Infrastructure 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 36fbefb6..449f7ae3 100644 --- a/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs +++ b/Oqtane.Server/Infrastructure/Jobs/HostedServiceBase.cs @@ -181,7 +181,7 @@ namespace Oqtane.Infrastructure } 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 1ac18c29..15ca0a15 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 662beb18..ee7c43ce 100644 --- a/Oqtane.Server/Pages/_Host.cshtml.cs +++ b/Oqtane.Server/Pages/_Host.cshtml.cs @@ -42,8 +42,8 @@ namespace Oqtane.Pages 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 @@ namespace Oqtane.Pages 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 dd516461..48de4c8a 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 @@ namespace Oqtane.Repository 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 90afa3bd..61dfc677 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 b0d21ff2..5a510c4c 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 @@ namespace Oqtane.Repository 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,44 +46,71 @@ namespace Oqtane.Repository _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); - }); + moduleDefinitions = _cache.GetOrCreate("moduledefinitions", entry => + { + entry.SlidingExpiration = TimeSpan.FromMinutes(30); + return LoadModuleDefinitions(); + }); + + // get all module definition permissions for site + List permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList(); + + // 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); + } + } + } + + // 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 + { + moduleDefinitions = LoadModuleDefinitions(); + } + return moduleDefinitions; } - private List LoadSiteModuleDefinitions(int siteId) + private List LoadModuleDefinitions() { - if (_moduleDefinitions == null) - { - // get module assemblies - _moduleDefinitions = LoadModuleDefinitionsFromAssemblies(); - } - - List moduleDefinitions = _moduleDefinitions; - - List permissions = new List(); - if (siteId != -1) - { - // get module definition permissions for site - permissions = _permissions.GetPermissions(siteId, EntityNames.ModuleDefinition).ToList(); - } + // get module assemblies + List moduleDefinitions = LoadModuleDefinitionsFromAssemblies(); // get module definitions in database List moduledefs = _db.ModuleDefinition.ToList(); @@ -95,13 +122,9 @@ namespace Oqtane.Repository 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 @@ namespace Oqtane.Repository 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 @@ namespace Oqtane.Repository // 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 @@ namespace Oqtane.Repository 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 774d0330..ba23d218 100644 --- a/Oqtane.Server/Repository/SiteRepository.cs +++ b/Oqtane.Server/Repository/SiteRepository.cs @@ -408,32 +408,6 @@ namespace Oqtane.Repository 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 24b57598..f85b7cd7 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 @@ namespace Oqtane.Repository 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 @@ namespace Oqtane.Repository 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 @@ namespace Oqtane.Repository } 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 3f3f4976..6f12d62e 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 00000000..4b1d2876 --- /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 babe9245..ba2a7d89 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 @@ namespace Oqtane //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 @@ namespace Oqtane 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 4b6b7f86..49f3524e 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 @@ namespace Oqtane.Models 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 2ab74c74..7658e97d 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 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 79d5eb42..e0826c86 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 be82b9ff..d5186930 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 acd0105b..bbfd28f7 100644 --- a/Oqtane.Client/Modules/Admin/Site/Index.razor +++ b/Oqtane.Client/Modules/Admin/Site/Index.razor @@ -420,6 +420,13 @@ site.LogoFileId = logofileid; } + + var faviconFieldId = _faviconfilemanager.GetFileId(); + if (faviconFieldId != -1) + { + site.FaviconFileId = faviconFieldId; + } + site.DefaultThemeType = _themetype; site.DefaultLayoutType = (_layouttype == "-" ? string.Empty : _layouttype); site.DefaultContainerType = _containertype; From eda2a5637f50d215fef9748b0c27748bfda90c1e Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Wed, 24 Feb 2021 17:26:54 -0500 Subject: [PATCH 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 58990804..26cd56f9 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 b65d4c9e..ce36dae2 100644 --- a/Oqtane.Server/Controllers/FileController.cs +++ b/Oqtane.Server/Controllers/FileController.cs @@ -535,19 +535,16 @@ namespace Oqtane.Controllers file.ImageHeight = 0; file.ImageWidth = 0; - //svg has no image and height, the attributes for svg are held in the XML viewport - if(file.Extension != "svg") - { - if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + if (Constants.ImageFiles.Split(',').Contains(file.Extension.ToLower())) + { + FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); + using (var image = Image.FromStream(stream)) { - FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read); - using (var image = Image.FromStream(stream)) - { - file.ImageHeight = image.Height; - file.ImageWidth = image.Width; - } - stream.Close(); + file.ImageHeight = image.Height; + file.ImageWidth = image.Width; } + + stream.Close(); } return file; From 6c79006dd754e94bc6385d7334510daacd0c8e6d Mon Sep 17 00:00:00 2001 From: Leigh Pointer Date: Thu, 25 Feb 2021 07:44:19 +0100 Subject: [PATCH 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 26cd56f9..58990804 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 3dd8ab3f..e21629d8 100644 --- a/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs +++ b/Oqtane.Server/Infrastructure/SiteTemplates/DefaultSiteTemplate.cs @@ -65,7 +65,7 @@ namespace Oqtane.SiteTemplates new Permission(PermissionNames.View, RoleNames.Admin, true), new Permission(PermissionNames.Edit, RoleNames.Admin, true) }.EncodePermissions(), - Content = "

Copyright (c) 2019-2020 .NET Foundation

" + + Content = "

Copyright (c) 2019-2021 .NET Foundation

" + "

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

" + "

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

" + "

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

" From 99665800c4d146fd5545fb5dc7807c071ab90ef1 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 07:48:16 -0500 Subject: [PATCH 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 51e71450..613f3f39 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -55,8 +55,8 @@ namespace Oqtane.Shared { [Obsolete(RoleObsoleteMessage)] public const string RegisteredRole = RoleNames.Registered; - public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png,svg,ico"; - public const string UploadableFiles = "jpg,jpeg,jpe,gif,bmp,png,svg,ico,mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg,csv"; + public const string ImageFiles = "jpg,jpeg,jpe,gif,bmp,png,ico"; + public const string UploadableFiles = ImageFiles + ",mov,wmv,avi,mp4,mp3,doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,nupkg,csv"; public const string ReservedDevices = "CON,NUL,PRN,COM0,COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8,COM9,LPT0,LPT1,LPT2,LPT3,LPT4,LPT5,LPT6,LPT7,LPT8,LPT9,CONIN$,CONOUT$"; public static readonly char[] InvalidFileNameChars = From 8762809a832e9fba7b72e28147413075e7d5861d Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 08:04:39 -0500 Subject: [PATCH 174/177] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5d0bb04c..bd6646dd 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ This project is a work in progress and the schedule for implementing enhancement V.2.1.0 ( Q1 2021 ) - [x] Complete Static Localization of Admin UI -- [ ] Cross Platform Database Support ( ie. SQLite ) -- [ ] EF Core Migrations for Database Installation/Upgrade +- [ ] Cross Platform Database Support ( ie. SQLite ) - see #964 +- [ ] EF Core Migrations for Database Installation/Upgrade - see #964 V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 ) - [x] Migration to .NET 5 From ba54076c614cce389022157a94c78b46d389abd2 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 08:04:44 -0500 Subject: [PATCH 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 72024f75..f6ce11c8 100644 --- a/Oqtane.Client/Oqtane.Client.csproj +++ b/Oqtane.Client/Oqtane.Client.csproj @@ -5,7 +5,7 @@ Exe 3.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -14,7 +14,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane true true diff --git a/Oqtane.Package/Oqtane.Client.nuspec b/Oqtane.Package/Oqtane.Client.nuspec index 6b01cba1..c669a8a2 100644 --- a/Oqtane.Package/Oqtane.Client.nuspec +++ b/Oqtane.Package/Oqtane.Client.nuspec @@ -2,7 +2,7 @@ Oqtane.Client - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/Oqtane.Framework.nuspec b/Oqtane.Package/Oqtane.Framework.nuspec index 10313bc4..6e68fa19 100644 --- a/Oqtane.Package/Oqtane.Framework.nuspec +++ b/Oqtane.Package/Oqtane.Framework.nuspec @@ -2,7 +2,7 @@ Oqtane.Framework - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane framework - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/Oqtane.Server.nuspec b/Oqtane.Package/Oqtane.Server.nuspec index 36715c37..6adfcb6b 100644 --- a/Oqtane.Package/Oqtane.Server.nuspec +++ b/Oqtane.Package/Oqtane.Server.nuspec @@ -2,7 +2,7 @@ Oqtane.Server - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/Oqtane.Shared.nuspec b/Oqtane.Package/Oqtane.Shared.nuspec index 538e0c8d..59a93473 100644 --- a/Oqtane.Package/Oqtane.Shared.nuspec +++ b/Oqtane.Package/Oqtane.Shared.nuspec @@ -2,7 +2,7 @@ Oqtane.Shared - 2.0.0 + 2.0.1 Shaun Walker .NET Foundation Oqtane Framework @@ -13,7 +13,7 @@ https://github.com/oqtane/oqtane.framework https://www.oqtane.org/Portals/0/icon.jpg oqtane - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 A modular application framework for Blazor diff --git a/Oqtane.Package/install.ps1 b/Oqtane.Package/install.ps1 index 116d8567..d4b21d97 100644 --- a/Oqtane.Package/install.ps1 +++ b/Oqtane.Package/install.ps1 @@ -1 +1 @@ -Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.0.Install.zip" -Force \ No newline at end of file +Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.1.Install.zip" -Force \ No newline at end of file diff --git a/Oqtane.Package/upgrade.ps1 b/Oqtane.Package/upgrade.ps1 index e41001aa..57e1de1a 100644 --- a/Oqtane.Package/upgrade.ps1 +++ b/Oqtane.Package/upgrade.ps1 @@ -1 +1 @@ -Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.0.Upgrade.zip" -Force \ No newline at end of file +Compress-Archive -Path "..\Oqtane.Server\bin\Release\net5.0\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.2.0.1.Upgrade.zip" -Force \ No newline at end of file diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj index 474b9335..4a6802f5 100644 --- a/Oqtane.Server/Oqtane.Server.csproj +++ b/Oqtane.Server/Oqtane.Server.csproj @@ -3,7 +3,7 @@ net5.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane true diff --git a/Oqtane.Shared/Oqtane.Shared.csproj b/Oqtane.Shared/Oqtane.Shared.csproj index 976f255b..65df5df5 100644 --- a/Oqtane.Shared/Oqtane.Shared.csproj +++ b/Oqtane.Shared/Oqtane.Shared.csproj @@ -3,7 +3,7 @@ net5.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane true diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs index 613f3f39..1b05a7e7 100644 --- a/Oqtane.Shared/Shared/Constants.cs +++ b/Oqtane.Shared/Shared/Constants.cs @@ -5,8 +5,8 @@ namespace Oqtane.Shared { public class Constants { public const string PackageId = "Oqtane.Framework"; - public const string Version = "2.0.0"; - public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0"; + public const string Version = "2.0.1"; + public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1"; public const string PageComponent = "Oqtane.UI.ThemeBuilder, Oqtane.Client"; public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client"; diff --git a/Oqtane.Test/Oqtane.Test.csproj b/Oqtane.Test/Oqtane.Test.csproj index 78c230db..da295fb4 100644 --- a/Oqtane.Test/Oqtane.Test.csproj +++ b/Oqtane.Test/Oqtane.Test.csproj @@ -3,7 +3,7 @@ net5.0 Debug;Release - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane false diff --git a/Oqtane.Upgrade/Oqtane.Upgrade.csproj b/Oqtane.Upgrade/Oqtane.Upgrade.csproj index cd3d0a4c..f67d23d2 100644 --- a/Oqtane.Upgrade/Oqtane.Upgrade.csproj +++ b/Oqtane.Upgrade/Oqtane.Upgrade.csproj @@ -3,7 +3,7 @@ net5.0 Exe - 2.0.0 + 2.0.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ https://www.oqtane.org https://github.com/oqtane Git - https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.0 + https://github.com/oqtane/oqtane.framework/releases/tag/v2.0.1 Oqtane false From 5b9196cfd4b030067d4aaa8aa34315e78b60ce56 Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 08:05:36 -0500 Subject: [PATCH 176/177] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bd6646dd..5788b1db 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ This project is a work in progress and the schedule for implementing enhancement V.2.1.0 ( Q1 2021 ) - [x] Complete Static Localization of Admin UI -- [ ] Cross Platform Database Support ( ie. SQLite ) - see #964 -- [ ] EF Core Migrations for Database Installation/Upgrade - see #964 +- [ ] Cross Platform Database Support ( ie. SQLite ) - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964) +- [ ] EF Core Migrations for Database Installation/Upgrade - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964) V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 ) - [x] Migration to .NET 5 From 12fd845ed593d920e82b940de2f51ba7383382db Mon Sep 17 00:00:00 2001 From: Shaun Walker Date: Fri, 26 Feb 2021 09:08:25 -0500 Subject: [PATCH 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 dc371214..f417ce33 100644 --- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs +++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs @@ -135,6 +135,7 @@ namespace Oqtane.Controllers { // use assets.json to clean up file resources List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); + assets.Reverse(); foreach(string asset in assets) { // legacy support for assets that were stored as absolute paths @@ -142,6 +143,10 @@ namespace Oqtane.Controllers if (System.IO.File.Exists(filepath)) { System.IO.File.Delete(filepath); + if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any()) + { + Directory.Delete(Path.GetDirectoryName(filepath)); + } } } _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Assets Removed For {ModuleDefinitionName}", moduledefinition.ModuleDefinitionName); diff --git a/Oqtane.Server/Controllers/ThemeController.cs b/Oqtane.Server/Controllers/ThemeController.cs index 615080e9..851aeb68 100644 --- a/Oqtane.Server/Controllers/ThemeController.cs +++ b/Oqtane.Server/Controllers/ThemeController.cs @@ -63,6 +63,7 @@ namespace Oqtane.Controllers { // use assets.json to clean up file resources List assets = JsonSerializer.Deserialize>(System.IO.File.ReadAllText(Path.Combine(assetpath, "assets.json"))); + assets.Reverse(); foreach (string asset in assets) { // legacy support for assets that were stored as absolute paths @@ -70,6 +71,10 @@ namespace Oqtane.Controllers if (System.IO.File.Exists(filepath)) { System.IO.File.Delete(filepath); + if (!Directory.EnumerateFiles(Path.GetDirectoryName(filepath)).Any()) + { + Directory.Delete(Path.GetDirectoryName(filepath)); + } } } _logger.Log(LogLevel.Information, this, LogFunction.Delete, "Theme Assets Removed For {ThemeName}", theme.ThemeName); diff --git a/Oqtane.Server/Infrastructure/InstallationManager.cs b/Oqtane.Server/Infrastructure/InstallationManager.cs index f14e8ae1..3b627c70 100644 --- a/Oqtane.Server/Infrastructure/InstallationManager.cs +++ b/Oqtane.Server/Infrastructure/InstallationManager.cs @@ -126,6 +126,10 @@ namespace Oqtane.Infrastructure { File.Delete(manifestpath); } + if (!Directory.Exists(Path.GetDirectoryName(manifestpath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(manifestpath)); + } File.WriteAllText(manifestpath, JsonSerializer.Serialize(assets)); } }
@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