-
- |
-
- FunctionChanged(e))">
+
+ FunctionChanged(e))">
@@ -36,8 +36,8 @@ else
|
-
- RowsChanged(e))">
+
+ RowsChanged(e))">
diff --git a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor
index 66794ad5..6baa0376 100644
--- a/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor
+++ b/Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor
@@ -9,7 +9,7 @@
@using System.Text.RegularExpressions
@using System.IO;
-@if (string.IsNullOrEmpty(_moduledefinitionname))
+@if (string.IsNullOrEmpty(_moduledefinitionname) && _systeminfo != null && _templates != null)
{
@@ -38,13 +38,15 @@
-
+
|
TemplateChanged(e))">
-
-
+ @foreach (string template in _templates)
+ {
+
+ }
|
@@ -85,28 +87,41 @@ else
}
@code {
- private string _moduledefinitionname = "";
+ private string _moduledefinitionname = string.Empty;
private string _owner = string.Empty;
private string _module = string.Empty;
private string _description = string.Empty;
private string _template = "-";
- public string _reference = Constants.Version;
+ private string _reference = Constants.Version;
private string _location = string.Empty;
+ private Dictionary _systeminfo;
+ private List _templates;
+
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
- protected override void OnInitialized()
+ protected override async Task OnInitializedAsync()
{
- _moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", "");
- if (string.IsNullOrEmpty(_moduledefinitionname))
+ try
{
- _owner = ModuleState.Title;
- _module = ModuleState.Title;
- _description = ModuleState.Title;
+ _moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", "");
+ _systeminfo = await SystemService.GetSystemInfoAsync();
+ _templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
+
+ if (string.IsNullOrEmpty(_moduledefinitionname))
+ {
+ _owner = ModuleState.Title;
+ _module = ModuleState.Title;
+ _description = ModuleState.Title;
+ }
+ else
+ {
+ AddModuleMessage(Localizer["Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below"], MessageType.Info);
+ }
}
- else
+ catch (Exception ex)
{
- AddModuleMessage(Localizer["Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below"], MessageType.Info);
+ await logger.LogError(ex, "Error Loading Module Creator");
}
}
@@ -123,6 +138,8 @@ else
SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName);
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
+ GetLocation();
+
AddModuleMessage(Localizer["The Source Code For Your Module Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must Restart Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
}
else
@@ -161,38 +178,21 @@ else
return !string.IsNullOrEmpty(name) && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
}
- private async void TemplateChanged(ChangeEventArgs e)
+ private void TemplateChanged(ChangeEventArgs e)
{
- try
+ _template = (string)e.Value;
+ GetLocation();
+ }
+
+ private void GetLocation()
+ {
+ _location = string.Empty;
+ if (_template != "-" && _systeminfo != null && _systeminfo.ContainsKey("serverpath"))
{
- _location = string.Empty;
- _template = (string)e.Value;
- if (_template != "-")
- {
- Dictionary systeminfo = await SystemService.GetSystemInfoAsync();
- if (systeminfo != null)
- {
- string[] path = systeminfo["serverpath"].Split(Path.DirectorySeparatorChar);
- if (_template == "internal")
- {
- _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 1) +
- Path.DirectorySeparatorChar + "Oqtane.Client" +
- Path.DirectorySeparatorChar + "Modules" +
- Path.DirectorySeparatorChar + _owner + "." + _module;
- }
- else
- {
- _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) +
- Path.DirectorySeparatorChar + _owner + "." + _module;
- }
- }
- }
- StateHasChanged();
- }
- catch (Exception ex)
- {
- await logger.LogError(ex, "Error Getting System Info {Error}", ex.Message);
- AddModuleMessage(Localizer["Error Getting System Info"], MessageType.Error);
+ string[] path = _systeminfo["serverpath"].Split(Path.DirectorySeparatorChar);
+ _location = string.Join(Path.DirectorySeparatorChar, path, 0, path.Length - 2) +
+ Path.DirectorySeparatorChar + _owner + "." + _module;
}
+ StateHasChanged();
}
}
diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
index 538bf700..3ebfed0b 100644
--- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
+++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
@@ -26,7 +26,7 @@ else
@if (context.AssemblyName != "Oqtane.Client")
{
-
+
}
|
@context.Name |
diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor
index 171ab885..b0234619 100644
--- a/Oqtane.Client/Modules/Admin/Pages/Add.razor
+++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor
@@ -101,18 +101,11 @@
- ThemeChanged(e))">
+ ThemeChanged(e))">
@foreach (var theme in _themes)
{
- if (theme.TypeName == _themetype)
- {
-
- }
- else
- {
-
- }
+
}
|
diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor
index 5efdd992..e1229e43 100644
--- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor
+++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor
@@ -23,18 +23,11 @@
- ParentChanged(e))">
+ ParentChanged(e))">
@foreach (Page page in _pageList)
{
- if (page.PageId.ToString() == _parentid)
- {
-
- }
- else
- {
-
- }
+
}
|
@@ -112,18 +105,11 @@
- ThemeChanged(e))">
-
+ ThemeChanged(e))">
+
@foreach (var theme in _themes)
{
- if (theme.TypeName == _themetype)
- {
-
- }
- else
- {
-
- }
+
}
|
diff --git a/Oqtane.Client/Modules/Admin/Pages/Index.razor b/Oqtane.Client/Modules/Admin/Pages/Index.razor
index 4ff925fc..fef67427 100644
--- a/Oqtane.Client/Modules/Admin/Pages/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Pages/Index.razor
@@ -16,7 +16,7 @@
|
- |
+ |
@(new string('-', context.Level * 2))@(context.Name) |
diff --git a/Oqtane.Client/Modules/Admin/Profiles/Index.razor b/Oqtane.Client/Modules/Admin/Profiles/Index.razor
index 0bdf8554..4705b290 100644
--- a/Oqtane.Client/Modules/Admin/Profiles/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Profiles/Index.razor
@@ -19,7 +19,7 @@ else
|
- |
+ |
@context.Name |
@@ -30,9 +30,9 @@ else
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
- protected override async Task OnInitializedAsync()
+ protected override async Task OnParametersSetAsync()
{
- _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
+ await GetProfilesAsync();
}
private async Task DeleteProfile(int profileId)
@@ -41,7 +41,12 @@ else
{
await ProfileService.DeleteProfileAsync(profileId);
await logger.LogInformation("Profile Deleted {ProfileId}", profileId);
+
AddModuleMessage(Localizer["Profile Deleted"], MessageType.Success);
+
+ await GetProfilesAsync();
+
+ StateHasChanged();
}
catch (Exception ex)
{
@@ -49,4 +54,9 @@ else
AddModuleMessage(Localizer["Error Deleting Profile"], MessageType.Error);
}
}
+
+ private async Task GetProfilesAsync()
+ {
+ _profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
+ }
}
diff --git a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor
index 2d81476a..47e2a47a 100644
--- a/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor
+++ b/Oqtane.Client/Modules/Admin/RecycleBin/Index.razor
@@ -31,6 +31,12 @@
@context.DeletedOn |
+ @if (_pages.Any())
+ {
+
+ }
}
@@ -59,6 +65,13 @@
@context.DeletedOn |
+ @if (_modules.Any())
+ {
+
+ }
+
}
@@ -126,6 +139,28 @@
}
}
+ private async Task DeleteAllPages()
+ {
+ try
+ {
+ foreach (Page page in _pages)
+ {
+ await PageService.DeletePageAsync(page.PageId);
+ await logger.LogInformation("Page Permanently Deleted {Page}", page);
+ }
+
+ await logger.LogInformation("Pages Permanently Deleted");
+ await Load();
+ StateHasChanged();
+ NavigationManager.NavigateTo(NavigateUrl());
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "Error Permanently Deleting Pages {Error}", ex.Message);
+ AddModuleMessage(ex.Message, MessageType.Error);
+ }
+ }
+
private async Task RestoreModule(Module module)
{
try
@@ -167,4 +202,31 @@
AddModuleMessage(Localizer["Error Permanently Deleting Module"], MessageType.Error);
}
}
+
+ private async Task DeleteAllModules()
+ {
+ try
+ {
+ foreach (Module module in _modules)
+ {
+ await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
+ // check if there are any remaining module instances in the site
+ _modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId);
+
+ if (!_modules.Exists(item => item.ModuleId == module.ModuleId))
+ {
+ await ModuleService.DeleteModuleAsync(module.ModuleId);
+ }
+ }
+
+ await logger.LogInformation("Modules Permanently Deleted");
+ await Load();
+ StateHasChanged();
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "Error Permanently Deleting Modules {Error}", ex.Message);
+ AddModuleMessage(Localizer["Error Permanently Deleting Modules"], MessageType.Error);
+ }
+ }
}
diff --git a/Oqtane.Client/Modules/Admin/Site/Index.razor b/Oqtane.Client/Modules/Admin/Site/Index.razor
index acd0105b..4fcb5dd3 100644
--- a/Oqtane.Client/Modules/Admin/Site/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Site/Index.razor
@@ -7,146 +7,143 @@
@inject IThemeService ThemeService
@inject ISettingService SettingService
@inject IStringLocalizer Localizer
+@inject INotificationService NotificationService
@if (_initialized)
{
-
+
- @Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In the Scheduled Jobs"]
+ @Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In Scheduled Jobs"]
|
@@ -201,6 +198,8 @@
+
+
@@ -420,6 +419,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;
@@ -475,7 +481,6 @@
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
await logger.LogInformation("Site Settings Saved {Site}", site);
-
AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success);
}
}
@@ -495,4 +500,36 @@
AddModuleMessage(Localizer["Error Saving Site"], MessageType.Error);
}
}
+
+ private async Task SendEmail()
+ {
+ if (_smtphost != "" && _smtpport != "" && _smtpsender != "")
+ {
+ try
+ {
+ var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
+ SettingService.SetSetting(settings, "SMTPHost", _smtphost);
+ SettingService.SetSetting(settings, "SMTPPort", _smtpport);
+ SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
+ SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
+ SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
+ SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
+ await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
+ await logger.LogInformation("Site SMTP Settings Saved");
+
+ await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User.DisplayName, PageState.User.Email, PageState.User.DisplayName, PageState.User.Email, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly."));
+ AddModuleMessage(Localizer["SMTP Settings Saved And A Message Has Been Sent To The Email Address Associated To Your User Account... Please Wait A Few Minutes For Delivery. If You Do Not Receive The Email Please Review The Notification Job In Scheduled Jobs For Any Log Details."], MessageType.Info);
+ }
+ catch (Exception ex)
+ {
+ await logger.LogError(ex, "Error Testing SMTP Configuration");
+ AddModuleMessage(Localizer["Error Testing SMTP Configuration"], MessageType.Error);
+ }
+ }
+ else
+ {
+ AddModuleMessage(Localizer["You Must Specify The SMTP Host, Port, And Sender"], MessageType.Warning);
+ }
+
+ }
}
diff --git a/Oqtane.Client/Modules/Admin/Sites/Edit.razor b/Oqtane.Client/Modules/Admin/Sites/Edit.razor
index b1afc85c..6d28aee6 100644
--- a/Oqtane.Client/Modules/Admin/Sites/Edit.razor
+++ b/Oqtane.Client/Modules/Admin/Sites/Edit.razor
@@ -31,18 +31,11 @@
- ThemeChanged(e))">
+ ThemeChanged(e))">
@foreach (var theme in _themes)
{
- if (theme.TypeName == _themetype)
- {
-
- }
- else
- {
-
- }
+
}
|
diff --git a/Oqtane.Client/Modules/Admin/Sites/Index.razor b/Oqtane.Client/Modules/Admin/Sites/Index.razor
index 3a571cd3..9d028e1d 100644
--- a/Oqtane.Client/Modules/Admin/Sites/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Sites/Index.razor
@@ -22,7 +22,7 @@ else
|
|
- @context.Name |
+ @context.Name |
}
diff --git a/Oqtane.Client/Modules/Admin/Themes/View.razor b/Oqtane.Client/Modules/Admin/Themes/View.razor
index 2510759d..d6d4b4de 100644
--- a/Oqtane.Client/Modules/Admin/Themes/View.razor
+++ b/Oqtane.Client/Modules/Admin/Themes/View.razor
@@ -24,7 +24,7 @@
-
+
|
diff --git a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor
index dcc96ff4..48959e80 100644
--- a/Oqtane.Client/Modules/Admin/UserProfile/Add.razor
+++ b/Oqtane.Client/Modules/Admin/UserProfile/Add.razor
@@ -55,7 +55,7 @@
{
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, null);
notification = await NotificationService.AddNotificationAsync(notification);
- await logger.LogInformation("Notification Created {Notification}", notification);
+ await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
}
else
diff --git a/Oqtane.Client/Modules/Admin/UserProfile/View.razor b/Oqtane.Client/Modules/Admin/UserProfile/View.razor
index ff9f3937..263a0345 100644
--- a/Oqtane.Client/Modules/Admin/UserProfile/View.razor
+++ b/Oqtane.Client/Modules/Admin/UserProfile/View.razor
@@ -183,7 +183,7 @@
{
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
notification = await NotificationService.AddNotificationAsync(notification);
- await logger.LogInformation("Notification Created {Notification}", notification);
+ await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
}
else
diff --git a/Oqtane.Client/Modules/Admin/Users/Index.razor b/Oqtane.Client/Modules/Admin/Users/Index.razor
index 8ac788ee..e648083f 100644
--- a/Oqtane.Client/Modules/Admin/Users/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Users/Index.razor
@@ -85,7 +85,7 @@ else
var user = await UserService.GetUserAsync(UserRole.UserId, PageState.Site.SiteId);
if (user != null)
{
- await UserService.DeleteUserAsync(user.UserId);
+ await UserService.DeleteUserAsync(user.UserId, PageState.Site.SiteId);
await logger.LogInformation("User Deleted {User}", UserRole.User);
StateHasChanged();
}
diff --git a/Oqtane.Client/Modules/Controls/FileManager.razor b/Oqtane.Client/Modules/Controls/FileManager.razor
index f4650202..90bc48c5 100644
--- a/Oqtane.Client/Modules/Controls/FileManager.razor
+++ b/Oqtane.Client/Modules/Controls/FileManager.razor
@@ -12,21 +12,14 @@
@if (ShowFolders || FolderId <= 0)
{
- FolderChanged(e))">
+ FolderChanged(e))">
@if (string.IsNullOrEmpty(Folder))
{
}
@foreach (Folder folder in _folders)
{
- if (folder.FolderId == FolderId)
- {
-
- }
- else
- {
-
- }
+
}
@@ -34,18 +27,11 @@
@if (ShowFiles)
{
- FileChanged(e))">
+ FileChanged(e))">
@foreach (File file in _files)
{
- if (file.FileId == FileId)
- {
-
- }
- else
- {
-
- }
+
}
diff --git a/Oqtane.Client/Modules/Controls/Pager.razor b/Oqtane.Client/Modules/Controls/Pager.razor
index 64f32728..c89b1301 100644
--- a/Oqtane.Client/Modules/Controls/Pager.razor
+++ b/Oqtane.Client/Modules/Controls/Pager.razor
@@ -1,4 +1,4 @@
-@namespace Oqtane.Modules.Controls
+@namespace Oqtane.Modules.Controls
@inherits ModuleControlBase
@typeparam TableItem
@@ -114,10 +114,10 @@
@code {
private int _pages = 0;
private int _page = 1;
- private int _maxItems;
- private int _maxPages;
- private int _startPage;
- private int _endPage;
+ private int _maxItems = 10;
+ private int _maxPages = 5;
+ private int _startPage = 0;
+ private int _endPage = 0;
[Parameter]
public string Format { get; set; }
@@ -172,24 +172,20 @@
}
}
- if (string.IsNullOrEmpty(PageSize))
- {
- _maxItems = 10;
- }
- else
+ if (!string.IsNullOrEmpty(PageSize))
{
_maxItems = int.Parse(PageSize);
}
- if (string.IsNullOrEmpty(DisplayPages))
- {
- _maxPages = 5;
- }
- else
+ if (!string.IsNullOrEmpty(DisplayPages))
{
_maxPages = int.Parse(DisplayPages);
}
+ _page = 1;
+ _startPage = 0;
+ _endPage = 0;
+
if (Items != null)
{
ItemList = Items.Skip((_page - 1) * _maxItems).Take(_maxItems);
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.Client/Resources/.gitkeep b/Oqtane.Client/Resources/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs
index e4b8ce64..55f8ad91 100644
--- a/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs
+++ b/Oqtane.Client/Services/Interfaces/IModuleDefinitionService.cs
@@ -13,5 +13,6 @@ namespace Oqtane.Services
Task InstallModuleDefinitionsAsync();
Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId);
Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition);
+ Task> GetModuleDefinitionTemplatesAsync();
}
}
diff --git a/Oqtane.Client/Services/Interfaces/IUserService.cs b/Oqtane.Client/Services/Interfaces/IUserService.cs
index eca072c5..b47b3481 100644
--- a/Oqtane.Client/Services/Interfaces/IUserService.cs
+++ b/Oqtane.Client/Services/Interfaces/IUserService.cs
@@ -1,4 +1,4 @@
-using Oqtane.Models;
+using Oqtane.Models;
using System.Threading.Tasks;
namespace Oqtane.Services
@@ -13,7 +13,7 @@ namespace Oqtane.Services
Task UpdateUserAsync(User user);
- Task DeleteUserAsync(int userId);
+ Task DeleteUserAsync(int userId, int siteId);
Task LoginUserAsync(User user, bool setCookie, bool isPersistent);
diff --git a/Oqtane.Client/Services/ModuleDefinitionService.cs b/Oqtane.Client/Services/ModuleDefinitionService.cs
index 87ae7e09..9f8984c0 100644
--- a/Oqtane.Client/Services/ModuleDefinitionService.cs
+++ b/Oqtane.Client/Services/ModuleDefinitionService.cs
@@ -53,5 +53,11 @@ namespace Oqtane.Services
{
return await PostJsonAsync($"{Apiurl}", moduleDefinition);
}
+
+ public async Task> GetModuleDefinitionTemplatesAsync()
+ {
+ List templates = await GetJsonAsync>($"{Apiurl}/templates");
+ return templates;
+ }
}
}
diff --git a/Oqtane.Client/Services/UserService.cs b/Oqtane.Client/Services/UserService.cs
index 34aaaebb..3538ecb7 100644
--- a/Oqtane.Client/Services/UserService.cs
+++ b/Oqtane.Client/Services/UserService.cs
@@ -1,4 +1,4 @@
-using Oqtane.Shared;
+using Oqtane.Shared;
using Oqtane.Models;
using System.Net.Http;
using System.Threading.Tasks;
@@ -36,9 +36,9 @@ namespace Oqtane.Services
return await PutJsonAsync($"{Apiurl}/{user.UserId}", user);
}
- public async Task DeleteUserAsync(int userId)
+ public async Task DeleteUserAsync(int userId, int siteId)
{
- await DeleteAsync($"{Apiurl}/{userId}");
+ await DeleteAsync($"{Apiurl}/{userId}?siteid={siteId}");
}
public async Task LoginUserAsync(User user, bool setCookie, bool isPersistent)
diff --git a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor
index 840fbf4e..5e75738b 100644
--- a/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor
+++ b/Oqtane.Client/Themes/Controls/MenuItemsHorizontal.razor
@@ -8,15 +8,15 @@
{
if (childPage.PageId == PageState.Page.PageId)
{
-
-
- @childPage.Name (current)
+
+
+ @childPage.Name (current)
}
else
{
-
-
+
+
@childPage.Name
}
@@ -34,7 +34,7 @@ else
{
-
+
@childPage.Name (current)
@@ -43,7 +43,7 @@ else
{
-
+
@childPage.Name
@@ -55,7 +55,7 @@ else
{
-
+
@childPage.Name (current)
@@ -65,7 +65,7 @@ else
{
-
+
@childPage.Name
diff --git a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor
index a27f9a7a..2f314ca0 100644
--- a/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor
+++ b/Oqtane.Client/Themes/Controls/MenuItemsVertical.razor
@@ -9,7 +9,7 @@
{
-
+
@childPage.Name (current)
@@ -18,7 +18,7 @@
{
-
+
@childPage.Name
@@ -38,7 +38,7 @@ else
{
-
+
@childPage.Name (current)
@@ -47,7 +47,7 @@ else
{
-
+
@childPage.Name
diff --git a/Oqtane.Client/UI/Pane.razor b/Oqtane.Client/UI/Pane.razor
index 0c04ff94..139135b9 100644
--- a/Oqtane.Client/UI/Pane.razor
+++ b/Oqtane.Client/UI/Pane.razor
@@ -18,7 +18,7 @@ else
@code {
private bool _useadminborder = false;
- private string _paneadminborder = "container";
+ private string _paneadminborder = "app-pane-admin-border";
private string _panetitle = "";
[CascadingParameter]
@@ -34,12 +34,11 @@ else
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) && Name != PaneNames.Admin)
{
_useadminborder = true;
- _paneadminborder = "app-pane-admin-border";
_panetitle = "" + Name + " Pane ";
}
else
{
- _paneadminborder = "container";
+ _useadminborder = false;
_panetitle = "";
}
@@ -130,4 +129,4 @@ else
builder.SetKey(module.PageModuleId);
builder.CloseComponent();
}
-}
\ No newline at end of file
+}
diff --git a/Oqtane.Client/UI/SiteRouter.razor b/Oqtane.Client/UI/SiteRouter.razor
index 6b42f15b..70bda7df 100644
--- a/Oqtane.Client/UI/SiteRouter.razor
+++ b/Oqtane.Client/UI/SiteRouter.razor
@@ -80,7 +80,7 @@
var urlparameters = string.Empty;
var editmode = false;
var reload = Reload.None;
- var lastsyncdate = DateTime.UtcNow;
+ var lastsyncdate = DateTime.UtcNow.AddHours(-1);
var runtime = GetRuntime();
Uri uri = new Uri(_absoluteUri);
@@ -107,9 +107,14 @@
SiteState.Alias = alias; // set state for services
lastsyncdate = alias.SyncDate;
- // process any sync events for site
+ // process any sync events
if (reload != Reload.Site && alias.SyncEvents.Any())
{
+ // if running on WebAssembly reload the client application if the server application was restarted
+ if (runtime == Shared.Runtime.WebAssembly && PageState != null && alias.SyncEvents.Exists(item => item.TenantId == -1))
+ {
+ NavigationManager.NavigateTo(_absoluteUri + (!_absoluteUri.Contains("?") ? "?" : "&") + "reload", true);
+ }
if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == alias.SiteId))
{
reload = Reload.Site;
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/Controllers/InstallationController.cs b/Oqtane.Server/Controllers/InstallationController.cs
index cac15728..2d8491d6 100644
--- a/Oqtane.Server/Controllers/InstallationController.cs
+++ b/Oqtane.Server/Controllers/InstallationController.cs
@@ -55,8 +55,7 @@ namespace Oqtane.Controllers
[HttpGet("installed")]
public Installation IsInstalled()
{
- bool isInstalled = _databaseManager.IsInstalled();
- return new Installation {Success = isInstalled, Message = string.Empty};
+ return _databaseManager.IsInstalled();
}
[HttpGet("upgrade")]
@@ -130,7 +129,14 @@ namespace Oqtane.Controllers
var instance = Activator.CreateInstance(type) as IModule;
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
- if (!list.Contains(name)) list.Insert(0, name);
+ if (System.IO.File.Exists(Path.Combine(binFolder, name + ".dll")))
+ {
+ if (!list.Contains(name)) list.Insert(0, name);
+ }
+ else
+ {
+ Console.WriteLine("Module " + instance.ModuleDefinition.ModuleDefinitionName + " dependency " + name + ".dll does not exist");
+ }
}
}
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
@@ -138,7 +144,14 @@ namespace Oqtane.Controllers
var instance = Activator.CreateInstance(type) as ITheme;
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
- if (!list.Contains(name)) list.Insert(0, name);
+ if (System.IO.File.Exists(Path.Combine(binFolder, name + ".dll")))
+ {
+ if (!list.Contains(name)) list.Insert(0, name);
+ }
+ else
+ {
+ Console.WriteLine("Theme " + instance.Theme.ThemeName + " dependency " + name + ".dll does not exist" );
+ }
}
}
}
diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs
index dc371214..8769c120 100644
--- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs
+++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs
@@ -13,8 +13,6 @@ using Oqtane.Repository;
using Oqtane.Security;
using System;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Configuration;
-using System.Xml.Linq;
using System.Text.Json;
namespace Oqtane.Controllers
@@ -135,6 +133,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 +141,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);
@@ -169,6 +172,20 @@ namespace Oqtane.Controllers
}
}
+ // GET: api//templates
+ [HttpGet("templates")]
+ [Authorize(Roles = RoleNames.Host)]
+ public List Get()
+ {
+ var templates = new List();
+ string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", Path.DirectorySeparatorChar.ToString());
+ foreach (string directory in Directory.GetDirectories(templatePath))
+ {
+ templates.Add(directory.Replace(templatePath, ""));
+ }
+ return templates;
+ }
+
// POST api/?moduleid=x
[HttpPost]
[Authorize(Roles = RoleNames.Host)]
@@ -180,30 +197,12 @@ namespace Oqtane.Controllers
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,Path.DirectorySeparatorChar.ToString());
- if (moduleDefinition.Template == "internal")
- {
- rootPath = Utilities.PathCombine(rootFolder.FullName,Path.DirectorySeparatorChar.ToString());
- moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", Oqtane.Client";
- moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
- }
- else
- {
- rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name,Path.DirectorySeparatorChar.ToString());
- moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane";
- moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane";
- }
+ rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name,Path.DirectorySeparatorChar.ToString());
+ moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane";
+ moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane";
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Module Definition Created {ModuleDefinition}", moduleDefinition);
-
- if (moduleDefinition.Template == "internal")
- {
- // add embedded resources to project file
- List resources = new List();
- resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".1.0.0.sql"));
- resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".Uninstall.sql"));
- EmbedResourceFiles(Utilities.PathCombine(rootPath, "Oqtane.Server", "Oqtane.Server.csproj"), resources);
- }
}
return moduleDefinition;
@@ -264,19 +263,5 @@ namespace Oqtane.Controllers
}
}
}
-
- private void EmbedResourceFiles(string projectfile, List resources)
- {
- XDocument project = XDocument.Load(projectfile);
- var itemGroup = project.Descendants("ItemGroup").Descendants("EmbeddedResource").FirstOrDefault().Parent;
- if (itemGroup != null)
- {
- foreach (var resource in resources)
- {
- itemGroup.Add(new XElement("EmbeddedResource", new XAttribute("Include", resource)));
- }
- }
- project.Save(projectfile);
- }
}
}
diff --git a/Oqtane.Server/Controllers/NotificationController.cs b/Oqtane.Server/Controllers/NotificationController.cs
index 5c73eb78..8fbb4872 100644
--- a/Oqtane.Server/Controllers/NotificationController.cs
+++ b/Oqtane.Server/Controllers/NotificationController.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Oqtane.Enums;
@@ -65,7 +65,7 @@ namespace Oqtane.Controllers
if (IsAuthorized(notification.FromUserId))
{
notification = _notifications.AddNotification(notification);
- _logger.Log(LogLevel.Information, this, LogFunction.Create, "Notification Added {Notification}", notification);
+ _logger.Log(LogLevel.Information, this, LogFunction.Create, "Notification Added {NotificationId}", notification.NotificationId);
}
return notification;
}
@@ -78,7 +78,7 @@ namespace Oqtane.Controllers
if (IsAuthorized(notification.FromUserId))
{
notification = _notifications.UpdateNotification(notification);
- _logger.Log(LogLevel.Information, this, LogFunction.Update, "Notification Updated {Folder}", notification);
+ _logger.Log(LogLevel.Information, this, LogFunction.Update, "Notification Updated {NotificationId}", notification.NotificationId);
}
return notification;
}
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/Controllers/UserController.cs b/Oqtane.Server/Controllers/UserController.cs
index 9819994b..4d3f1abc 100644
--- a/Oqtane.Server/Controllers/UserController.cs
+++ b/Oqtane.Server/Controllers/UserController.cs
@@ -111,7 +111,6 @@ namespace Oqtane.Controllers
return null;
}
- //TODO shoud be moved to another layer
private async Task CreateUser(User user)
{
User newUser = null;
@@ -261,18 +260,50 @@ namespace Oqtane.Controllers
// DELETE api//5?siteid=x
[HttpDelete("{id}")]
[Authorize(Roles = RoleNames.Admin)]
- public async Task Delete(int id)
+ public async Task Delete(int id, string siteid)
{
- IdentityUser identityuser = await _identityUserManager.FindByNameAsync(_users.GetUser(id).Username);
-
- if (identityuser != null)
+ User user = _users.GetUser(id);
+ if (user != null)
{
- var result = await _identityUserManager.DeleteAsync(identityuser);
-
- if (result != null)
+ // remove user roles for site
+ foreach (UserRole userrole in _userRoles.GetUserRoles(user.UserId, Int32.Parse(siteid)).ToList())
{
- _users.DeleteUser(id);
- _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", id);
+ _userRoles.DeleteUserRole(userrole.UserRoleId);
+ _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Role Deleted {UserRole}", userrole);
+ }
+
+ // remove user folder for site
+ var folder = _folders.GetFolder(Int32.Parse(siteid), Utilities.PathCombine("Users", user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()));
+ if (folder != null)
+ {
+ if (Directory.Exists(_folders.GetFolderPath(folder)))
+ {
+ Directory.Delete(_folders.GetFolderPath(folder), true);
+ }
+ _folders.DeleteFolder(folder.FolderId);
+ _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Folder Deleted {Folder}", folder);
+ }
+
+ // delete user if they are not a member of any other sites
+ if (!_userRoles.GetUserRoles(user.UserId, -1).Any())
+ {
+ // get identity user
+ IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
+ if (identityuser != null)
+ {
+ // delete identity user
+ var result = await _identityUserManager.DeleteAsync(identityuser);
+ if (result != null)
+ {
+ // delete user
+ _users.DeleteUser(user.UserId);
+ _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", user.UserId);
+ }
+ else
+ {
+ _logger.Log(LogLevel.Error, this, LogFunction.Delete, "Error Deleting User {UserId}", user.UserId, result.ToString());
+ }
+ }
}
}
}
diff --git a/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
new file mode 100644
index 00000000..e34d1563
--- /dev/null
+++ b/Oqtane.Server/Extensions/DbContextOptionsBuilderExtensions.cs
@@ -0,0 +1,15 @@
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.EntityFrameworkCore;
+
+namespace Oqtane.Extensions
+{
+ public static class DbContextOptionsBuilderExtensions
+ {
+ public static DbContextOptionsBuilder UseOqtaneDatabase([NotNull] this DbContextOptionsBuilder optionsBuilder, string connectionString)
+ {
+ optionsBuilder.UseSqlServer(connectionString);
+
+ return optionsBuilder;
+ }
+ }
+}
diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs
index 35f93353..9ee98e25 100644
--- a/Oqtane.Server/Infrastructure/DatabaseManager.cs
+++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs
@@ -33,27 +33,30 @@ namespace Oqtane.Infrastructure
_cache = cache;
}
- public bool IsInstalled()
+ public Installation IsInstalled()
{
- var defaultConnectionString = NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey));
- var result = !string.IsNullOrEmpty(defaultConnectionString);
- if (result)
+ var result = new Installation { Success = false, Message = string.Empty };
+ if (!string.IsNullOrEmpty(_config.GetConnectionString(SettingKeys.ConnectionStringKey)))
{
+ result.Success = true;
using (var scope = _serviceScopeFactory.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService();
- result = db.Database.CanConnect();
- if (result)
+ if (db.Database.CanConnect())
{
try
{
- result = db.Tenant.Any();
+ var provisioned = db.Tenant.Any();
}
catch
{
- result = false;
+ result.Message = "Master Database Not Installed Correctly";
}
}
+ else
+ {
+ result.Message = "Cannot Connect To Master Database";
+ }
}
}
return result;
@@ -74,7 +77,8 @@ namespace Oqtane.Infrastructure
// startup or silent installation
install = new InstallConfig { ConnectionString = _config.GetConnectionString(SettingKeys.ConnectionStringKey), TenantName = TenantNames.Master, IsNewTenant = false };
- if (!IsInstalled())
+ var installation = IsInstalled();
+ if (!installation.Success)
{
install.Aliases = GetInstallationConfig(SettingKeys.DefaultAliasKey, string.Empty);
install.HostPassword = GetInstallationConfig(SettingKeys.HostPasswordKey, string.Empty);
@@ -97,6 +101,14 @@ namespace Oqtane.Infrastructure
install.ConnectionString = "";
}
}
+ else
+ {
+ if (!string.IsNullOrEmpty(installation.Message))
+ {
+ // problem with prior installation
+ install.ConnectionString = "";
+ }
+ }
}
else
{
@@ -168,9 +180,10 @@ namespace Oqtane.Infrastructure
var dataDirectory = AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString();
if (!Directory.Exists(dataDirectory)) Directory.CreateDirectory(dataDirectory);
- using (var dbc = new DbContext(new DbContextOptionsBuilder().UseSqlServer(NormalizeConnectionString(install.ConnectionString)).Options))
+ var connectionString = NormalizeConnectionString(install.ConnectionString);
+ using (var dbc = new DbContext(new DbContextOptionsBuilder().UseOqtaneDatabase(connectionString).Options))
{
- // create empty database if it does not exist
+ // create empty database if it does not exist
dbc.Database.EnsureCreated();
result.Success = true;
}
@@ -235,7 +248,7 @@ namespace Oqtane.Infrastructure
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases))
{
- using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
+ using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
{
Tenant tenant;
if (install.IsNewTenant)
@@ -274,7 +287,7 @@ namespace Oqtane.Infrastructure
using (var scope = _serviceScopeFactory.CreateScope())
{
var upgrades = scope.ServiceProvider.GetRequiredService();
-
+
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
{
foreach (var tenant in db.Tenant.ToList())
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));
}
}
diff --git a/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs b/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs
index ffb0ff9c..6257db16 100644
--- a/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs
+++ b/Oqtane.Server/Infrastructure/Interfaces/IDatabaseManager.cs
@@ -1,11 +1,11 @@
-using Oqtane.Models;
+using Oqtane.Models;
using Oqtane.Shared;
namespace Oqtane.Infrastructure
{
public interface IDatabaseManager
{
- bool IsInstalled();
+ Installation IsInstalled();
Installation Install();
Installation Install(InstallConfig install);
}
diff --git a/Oqtane.Server/Infrastructure/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. "
diff --git a/Oqtane.Server/Infrastructure/SyncManager.cs b/Oqtane.Server/Infrastructure/SyncManager.cs
index f41c01b0..d70cc456 100644
--- a/Oqtane.Server/Infrastructure/SyncManager.cs
+++ b/Oqtane.Server/Infrastructure/SyncManager.cs
@@ -1,4 +1,4 @@
-using Oqtane.Models;
+using Oqtane.Models;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -17,7 +17,7 @@ namespace Oqtane.Infrastructure
public List GetSyncEvents(int tenantId, DateTime lastSyncDate)
{
- return SyncEvents.Where(item => item.TenantId == tenantId && item.ModifiedOn >= lastSyncDate).ToList();
+ return SyncEvents.Where(item => (item.TenantId == tenantId || item.TenantId == -1) && item.ModifiedOn >= lastSyncDate).ToList();
}
public void AddSyncEvent(int tenantId, string entityName, int entityId)
diff --git a/Oqtane.Server/Infrastructure/UpgradeManager.cs b/Oqtane.Server/Infrastructure/UpgradeManager.cs
index 0344de6e..b2385b2b 100644
--- a/Oqtane.Server/Infrastructure/UpgradeManager.cs
+++ b/Oqtane.Server/Infrastructure/UpgradeManager.cs
@@ -1,9 +1,11 @@
-using Microsoft.Extensions.DependencyInjection;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
using Oqtane.Extensions;
using Oqtane.Models;
using Oqtane.Repository;
using Oqtane.Shared;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
namespace Oqtane.Infrastructure
@@ -12,23 +14,23 @@ namespace Oqtane.Infrastructure
{
private readonly IAliasRepository _aliases;
private readonly IServiceScopeFactory _serviceScopeFactory;
+ private readonly IWebHostEnvironment _environment;
- public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScopeFactory)
+ public UpgradeManager(IAliasRepository aliases, IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment)
{
_aliases = aliases;
_serviceScopeFactory = serviceScopeFactory;
+ _environment = environment;
}
public void Upgrade(Tenant tenant, string version)
{
- // core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute logic once
- var pageTemplates = new List();
-
+ // core framework upgrade logic - note that you can check if current tenant is Master if you only want to execute the logic once
switch (version)
{
case "0.9.0":
- // add a page to all existing sites on upgrade
-
+ // this code is commented out on purpose - it provides an example of how to programmatically add a page to all existing sites on upgrade
+ var pageTemplates = new List();
//pageTemplates.Add(new PageTemplate
//{
// Name = "Test",
@@ -61,6 +63,17 @@ namespace Oqtane.Infrastructure
//});
CreateSitePages(tenant, pageTemplates);
break;
+ case "2.0.2":
+ if (tenant.Name == TenantNames.Master)
+ {
+ // remove Internal module template files as they are no longer supported
+ var internalTemplatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", "Internal", Path.DirectorySeparatorChar.ToString());
+ if (Directory.Exists(internalTemplatePath))
+ {
+ Directory.Delete(internalTemplatePath, true);
+ }
+ }
+ break;
}
}
diff --git a/Oqtane.Server/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.Server/Pages/_Host.cshtml b/Oqtane.Server/Pages/_Host.cshtml
index cf2d69f0..1678969c 100644
--- a/Oqtane.Server/Pages/_Host.cshtml
+++ b/Oqtane.Server/Pages/_Host.cshtml
@@ -1,4 +1,4 @@
-@page "/"
+@page "/"
@namespace Oqtane.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Configuration
@@ -35,6 +35,13 @@
🗙
+ @if (Model.Message != "")
+ {
+
+ @Model.Message
+
+ }
+
@if (Configuration.GetSection("Runtime").Value == "WebAssembly")
diff --git a/Oqtane.Server/Pages/_Host.cshtml.cs b/Oqtane.Server/Pages/_Host.cshtml.cs
index 4dc9cb7e..156b5fac 100644
--- a/Oqtane.Server/Pages/_Host.cshtml.cs
+++ b/Oqtane.Server/Pages/_Host.cshtml.cs
@@ -39,6 +39,7 @@ namespace Oqtane.Pages
public string HeadResources = "";
public string BodyResources = "";
+ public string Message = "";
public void OnGet()
{
@@ -54,20 +55,28 @@ namespace Oqtane.Pages
if (HttpContext.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName] == null && !string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
{
var uri = new Uri(Request.GetDisplayUrl());
- var alias = _aliases.GetAlias(uri.Authority + "/" + uri.LocalPath.Substring(1));
- _state.Alias = alias;
-
- // set default language for site if the culture is not supported
- var languages = _languages.GetLanguages(alias.SiteId);
- if (languages.Any() && languages.All(l => l.Code != CultureInfo.CurrentUICulture.Name))
+ var hostname = uri.Authority + "/" + uri.LocalPath.Substring(1);
+ var alias = _aliases.GetAlias(hostname);
+ if (alias != null)
{
- var defaultLanguage = languages.Where(l => l.IsDefault).SingleOrDefault() ?? languages.First();
+ _state.Alias = alias;
- SetLocalizationCookie(defaultLanguage.Code);
+ // set default language for site if the culture is not supported
+ var languages = _languages.GetLanguages(alias.SiteId);
+ if (languages.Any() && languages.All(l => l.Code != CultureInfo.CurrentUICulture.Name))
+ {
+ var defaultLanguage = languages.Where(l => l.IsDefault).SingleOrDefault() ?? languages.First();
+
+ SetLocalizationCookie(defaultLanguage.Code);
+ }
+ else
+ {
+ SetLocalizationCookie(_localizationManager.GetDefaultCulture());
+ }
}
else
{
- SetLocalizationCookie(_localizationManager.GetDefaultCulture());
+ Message = $"No Matching Alias For Host Name {hostname}";
}
}
}
diff --git a/Oqtane.Server/Repository/Context/DBContextBase.cs b/Oqtane.Server/Repository/Context/DBContextBase.cs
index 522bf0d9..9d488f45 100644
--- a/Oqtane.Server/Repository/Context/DBContextBase.cs
+++ b/Oqtane.Server/Repository/Context/DBContextBase.cs
@@ -4,11 +4,12 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
+using Oqtane.Extensions;
using Oqtane.Models;
namespace Oqtane.Repository
{
- public class DBContextBase : IdentityUserContext
+ public class DBContextBase : IdentityUserContext
{
private ITenantResolver _tenantResolver;
private IHttpContextAccessor _accessor;
@@ -24,63 +25,16 @@ namespace Oqtane.Repository
var tenant = _tenantResolver.GetTenant();
if (tenant != null)
{
- optionsBuilder.UseSqlServer(tenant.DBConnectionString
- .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString())
- );
+ var connectionString = tenant.DBConnectionString
+ .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
+ optionsBuilder.UseOqtaneDatabase(connectionString);
}
base.OnConfiguring(optionsBuilder);
}
public override int SaveChanges()
{
- ChangeTracker.DetectChanges();
-
- string username = "";
- if (_accessor.HttpContext != null && _accessor.HttpContext.User.Identity.Name != null)
- {
- username = _accessor.HttpContext.User.Identity.Name;
- }
- DateTime date = DateTime.UtcNow;
-
- var created = ChangeTracker.Entries()
- .Where(x => x.State == EntityState.Added);
-
- foreach(var item in created)
- {
- if (item.Entity is IAuditable)
- {
- item.CurrentValues[nameof(IAuditable.CreatedBy)] = username;
- item.CurrentValues[nameof(IAuditable.CreatedOn)] = date;
- }
- }
-
- var modified = ChangeTracker.Entries()
- .Where(x => x.State == EntityState.Modified || x.State == EntityState.Added);
-
- foreach (var item in modified)
- {
- if (item.Entity is IAuditable)
- {
- item.CurrentValues[nameof(IAuditable.ModifiedBy)] = username;
- item.CurrentValues[nameof(IAuditable.ModifiedOn)] = date;
- }
-
- if (item.Entity is IDeletable && item.State != EntityState.Added)
- {
- if ((bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
- && !item.GetDatabaseValues().GetValue(nameof(IDeletable.IsDeleted)))
- {
- item.CurrentValues[nameof(IDeletable.DeletedBy)] = username;
- item.CurrentValues[nameof(IDeletable.DeletedOn)] = date;
- }
- else if (!(bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
- && item.GetDatabaseValues().GetValue(nameof(IDeletable.IsDeleted)))
- {
- item.CurrentValues[nameof(IDeletable.DeletedBy)] = null;
- item.CurrentValues[nameof(IDeletable.DeletedOn)] = null;
- }
- }
- }
+ DbContextUtils.SaveChanges(this, _accessor);
return base.SaveChanges();
}
diff --git a/Oqtane.Server/Repository/Context/DbContextUtils.cs b/Oqtane.Server/Repository/Context/DbContextUtils.cs
new file mode 100644
index 00000000..1b4014cb
--- /dev/null
+++ b/Oqtane.Server/Repository/Context/DbContextUtils.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Linq;
+using Microsoft.AspNetCore.Http;
+using Microsoft.EntityFrameworkCore;
+using Oqtane.Models;
+
+namespace Oqtane.Repository
+{
+ public class DbContextUtils
+ {
+ public static void SaveChanges(DbContext context, IHttpContextAccessor accessor)
+ {
+ var changeTracker = context.ChangeTracker;
+
+ changeTracker.DetectChanges();
+
+ string username = "";
+ if (accessor.HttpContext != null && accessor.HttpContext.User.Identity.Name != null)
+ {
+ username = accessor.HttpContext.User.Identity.Name;
+ }
+ DateTime date = DateTime.UtcNow;
+
+ var created = changeTracker.Entries()
+ .Where(x => x.State == EntityState.Added);
+
+ foreach(var item in created)
+ {
+ if (item.Entity is IAuditable)
+ {
+ item.CurrentValues[nameof(IAuditable.CreatedBy)] = username;
+ item.CurrentValues[nameof(IAuditable.CreatedOn)] = date;
+ }
+ }
+
+ var modified = changeTracker.Entries()
+ .Where(x => x.State == EntityState.Modified || x.State == EntityState.Added);
+
+ foreach (var item in modified)
+ {
+ if (item.Entity is IAuditable)
+ {
+ item.CurrentValues[nameof(IAuditable.ModifiedBy)] = username;
+ item.CurrentValues[nameof(IAuditable.ModifiedOn)] = date;
+ }
+
+ if (item.Entity is IDeletable && item.State != EntityState.Added)
+ {
+ if ((bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
+ && !item.GetDatabaseValues().GetValue(nameof(IDeletable.IsDeleted)))
+ {
+ item.CurrentValues[nameof(IDeletable.DeletedBy)] = username;
+ item.CurrentValues[nameof(IDeletable.DeletedOn)] = date;
+ }
+ else if (!(bool)item.CurrentValues[nameof(IDeletable.IsDeleted)]
+ && item.GetDatabaseValues().GetValue(nameof(IDeletable.IsDeleted)))
+ {
+ item.CurrentValues[nameof(IDeletable.DeletedBy)] = null;
+ item.CurrentValues[nameof(IDeletable.DeletedOn)] = null;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/Oqtane.Server/Repository/Context/InstallationContext.cs b/Oqtane.Server/Repository/Context/InstallationContext.cs
index 29bfc281..6eaf5a65 100644
--- a/Oqtane.Server/Repository/Context/InstallationContext.cs
+++ b/Oqtane.Server/Repository/Context/InstallationContext.cs
@@ -1,10 +1,11 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.EntityFrameworkCore;
+using Oqtane.Extensions;
using Oqtane.Models;
namespace Oqtane.Repository
{
-
+
public class InstallationContext : DbContext
{
private readonly string _connectionString;
@@ -15,7 +16,7 @@ namespace Oqtane.Repository
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- => optionsBuilder.UseSqlServer(_connectionString);
+ => optionsBuilder.UseOqtaneDatabase(_connectionString);
public virtual DbSet Alias { get; set; }
public virtual DbSet Tenant { get; set; }
diff --git a/Oqtane.Server/Repository/Context/MasterDBContext.cs b/Oqtane.Server/Repository/Context/MasterDBContext.cs
index 976874cf..dd94dedd 100644
--- a/Oqtane.Server/Repository/Context/MasterDBContext.cs
+++ b/Oqtane.Server/Repository/Context/MasterDBContext.cs
@@ -4,13 +4,14 @@ using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Oqtane.Models;
using Microsoft.Extensions.Configuration;
+using Oqtane.Extensions;
namespace Oqtane.Repository
{
public class MasterDBContext : DbContext
{
- private IHttpContextAccessor _accessor;
- private IConfiguration _configuration;
+ private readonly IHttpContextAccessor _accessor;
+ private readonly IConfiguration _configuration;
public MasterDBContext(DbContextOptions options, IHttpContextAccessor accessor, IConfiguration configuration) : base(options)
{
@@ -20,11 +21,12 @@ namespace Oqtane.Repository
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
- if (!string.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
+ if (!String.IsNullOrEmpty(_configuration.GetConnectionString("DefaultConnection")))
{
- optionsBuilder.UseSqlServer(_configuration.GetConnectionString("DefaultConnection")
- .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString())
- );
+ var connectionString = _configuration.GetConnectionString("DefaultConnection")
+ .Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory")?.ToString());
+
+ optionsBuilder.UseOqtaneDatabase(connectionString);
}
base.OnConfiguring(optionsBuilder);
}
@@ -37,38 +39,7 @@ namespace Oqtane.Repository
public override int SaveChanges()
{
- ChangeTracker.DetectChanges();
-
- string username = "";
- if (_accessor.HttpContext != null && _accessor.HttpContext.User.Identity.Name != null)
- {
- username = _accessor.HttpContext.User.Identity.Name;
- }
- DateTime date = DateTime.UtcNow;
-
- var created = ChangeTracker.Entries()
- .Where(x => x.State == EntityState.Added);
-
- foreach (var item in created)
- {
- if (item.Entity is IAuditable)
- {
- item.CurrentValues[nameof(IAuditable.CreatedBy)] = username;
- item.CurrentValues[nameof(IAuditable.CreatedOn)] = date;
- }
- }
-
- var modified = ChangeTracker.Entries()
- .Where(x => x.State == EntityState.Modified || x.State == EntityState.Added);
-
- foreach (var item in modified)
- {
- if (item.Entity is IAuditable)
- {
- item.CurrentValues[nameof(IAuditable.ModifiedBy)] = username;
- item.CurrentValues[nameof(IAuditable.ModifiedOn)] = date;
- }
- }
+ DbContextUtils.SaveChanges(this, _accessor);
return base.SaveChanges();
}
diff --git a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs
index 5ce7467f..dba914a7 100644
--- a/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs
+++ b/Oqtane.Server/Repository/Interfaces/IFolderRepository.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using Oqtane.Models;
namespace Oqtane.Repository
diff --git a/Oqtane.Server/Repository/UserRoleRepository.cs b/Oqtane.Server/Repository/UserRoleRepository.cs
index 79f8a629..b47bd6f7 100644
--- a/Oqtane.Server/Repository/UserRoleRepository.cs
+++ b/Oqtane.Server/Repository/UserRoleRepository.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Oqtane.Models;
@@ -27,7 +27,7 @@ namespace Oqtane.Repository
return _db.UserRole.Where(item => item.UserId == userId)
.Include(item => item.Role) // eager load roles
.Include(item => item.User) // eager load users
- .Where(item => item.Role.SiteId == siteId || item.Role.SiteId == null);
+ .Where(item => item.Role.SiteId == siteId || item.Role.SiteId == null || siteId == -1);
}
public UserRole AddUserRole(UserRole userRole)
diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs
index ba2a7d89..1e744c01 100644
--- a/Oqtane.Server/Startup.cs
+++ b/Oqtane.Server/Startup.cs
@@ -226,7 +226,7 @@ namespace Oqtane
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncManager sync)
{
ServiceActivator.Configure(app.ApplicationServices);
@@ -264,6 +264,9 @@ namespace Oqtane
endpoints.MapControllers();
endpoints.MapFallbackToPage("/_Host");
});
+
+ // create a sync event to identify server application startup
+ sync.AddSyncEvent(-1, "Application", -1);
}
}
}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Edit.razor b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Edit.razor
similarity index 100%
rename from Oqtane.Server/wwwroot/Modules/Templates/External/Client/Edit.razor
rename to Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Edit.razor
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Index.razor b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Index.razor
similarity index 100%
rename from Oqtane.Server/wwwroot/Modules/Templates/External/Client/Index.razor
rename to Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Index.razor
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/ModuleInfo.cs b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/ModuleInfo.cs
similarity index 100%
rename from Oqtane.Server/wwwroot/Modules/Templates/External/Client/ModuleInfo.cs
rename to Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/ModuleInfo.cs
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Settings.razor b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Settings.razor
similarity index 100%
rename from Oqtane.Server/wwwroot/Modules/Templates/External/Client/Settings.razor
rename to Oqtane.Server/wwwroot/Modules/Templates/External/Client/Modules/[Owner].[Module]/Settings.razor
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj
index cfce1a60..ec0e8e4a 100644
--- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj
+++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].[Module].Server.csproj
@@ -2,7 +2,6 @@
net5.0
- 7.3
true
1.0.0
[Owner].[Module]
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor
deleted file mode 100644
index 339879f8..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Edit.razor
+++ /dev/null
@@ -1,100 +0,0 @@
-@using Oqtane.Modules.Controls
-@using [Owner].[Module].Services
-@using [Owner].[Module].Models
-
-@namespace [Owner].[Module]
-@inherits ModuleBase
-@inject I[Module]Service [Module]Service
-@inject NavigationManager NavigationManager
-
-
-
-Cancel
-
-
-@if (PageState.Action == "Edit")
-{
-
-}
-
-@code {
- public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
-
- public override string Actions => "Add,Edit";
-
- public override string Title => "Manage [Module]";
-
- public override List Resources => new List()
- {
- new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
- };
-
- int _id;
- string _name;
- string _createdby;
- DateTime _createdon;
- string _modifiedby;
- DateTime _modifiedon;
-
- protected override async Task OnInitializedAsync()
- {
- try
- {
- if (PageState.Action == "Edit")
- {
- _id = Int32.Parse(PageState.QueryString["id"]);
- [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
- if ([Module] != null)
- {
- _name = [Module].Name;
- _createdby = [Module].CreatedBy;
- _createdon = [Module].CreatedOn;
- _modifiedby = [Module].ModifiedBy;
- _modifiedon = [Module].ModifiedOn;
- }
- }
- }
- catch (Exception ex)
- {
- await logger.LogError(ex, "Error Loading [Module] {[Module]Id} {Error}", _id, ex.Message);
- AddModuleMessage("Error Loading [Module]", MessageType.Error);
- }
- }
-
- private async Task Save()
- {
- try
- {
- if (PageState.Action == "Add")
- {
- [Module] [Module] = new [Module]();
- [Module].ModuleId = ModuleState.ModuleId;
- [Module].Name = _name;
- [Module] = await [Module]Service.Add[Module]Async([Module]);
- await logger.LogInformation("[Module] Added {[Module]}", [Module]);
- }
- else
- {
- [Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
- [Module].Name = _name;
- await [Module]Service.Update[Module]Async([Module]);
- await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
- }
- NavigationManager.NavigateTo(NavigateUrl());
- }
- catch (Exception ex)
- {
- await logger.LogError(ex, "Error Saving [Module] {Error}", ex.Message);
- AddModuleMessage("Error Saving [Module]", MessageType.Error);
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor
deleted file mode 100644
index 37cfef2a..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Index.razor
+++ /dev/null
@@ -1,100 +0,0 @@
-@using [Owner].[Module].Services
-@using [Owner].[Module].Models
-
-@namespace [Owner].[Module]
-@inherits ModuleBase
-@inject I[Module]Service [Module]Service
-@inject NavigationManager NavigationManager
-
-@if (_[Module]s == null)
-{
- Loading...
-}
-else
-{
-
-
-
- @if (@_[Module]s.Count != 0)
- {
-
-
-
- |
- |
- @context.Name |
-
-
- }
- else
- {
- No [Module]s To Display
- }
-}
-
-
-
-
-[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:
-[RootPath]Oqtane.Client\Modules\[Module]\
-- Edit.razor - component for adding or editing content
-- Index.razor - main component for your module **the content you are reading is in this file**
-- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module
-- Settings.razor - component for managing module settings
-- Services\I[Module]Service.cs - interface for defining service API methods
-- Services\[Module]Service.cs - implements service API interface methods
-[RootPath]Oqtane.Server\Modules\[Module]\
-- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern
-- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content
-- Repository\I[Module]Repository.cs - interface for defining repository methods
-- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core
-- Repository\[Module]Context.cs - provides a DB Context for data access
-- Scripts\[Owner].[Module]s.1.0.0.sql - database schema definition script
-- Scripts\[Owner].[Module]s.Uninstall.sql - database uninstall script
-[RootPath]Oqtane.Shared\Modules\[Module]\
-- Models\[Module].cs - model definition
-
-
-
-@code {
- public override List Resources => new List()
- {
- new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
- new Resource { ResourceType = ResourceType.Script, Url = ModulePath() + "Module.js" }
- };
-
- List<[Module]> _[Module]s;
-
- protected override async Task OnInitializedAsync()
- {
- try
- {
- _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
- }
- catch (Exception ex)
- {
- await logger.LogError(ex, "Error Loading [Module] {Error}", ex.Message);
- AddModuleMessage("Error Loading [Module]", MessageType.Error);
- }
- }
-
- private async Task Delete([Module] [Module])
- {
- try
- {
- await [Module]Service.Delete[Module]Async([Module].[Module]Id, ModuleState.ModuleId);
- await logger.LogInformation("[Module] Deleted {[Module]}", [Module]);
- _[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
- StateHasChanged();
- }
- catch (Exception ex)
- {
- await logger.LogError(ex, "Error Deleting [Module] {[Module]} {Error}", [Module], ex.Message);
- AddModuleMessage("Error Deleting [Module]", MessageType.Error);
- }
- }
-}
\ No newline at end of file
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs
deleted file mode 100644
index 9d6f0a4e..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Interop.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Microsoft.JSInterop;
-using System.Threading.Tasks;
-
-namespace [Owner].[Module]
-{
- public class Interop
- {
- private readonly IJSRuntime _jsRuntime;
-
- public Interop(IJSRuntime jsRuntime)
- {
- _jsRuntime = jsRuntime;
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs
deleted file mode 100644
index 6586d51d..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/ModuleInfo.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-using Oqtane.Models;
-using Oqtane.Modules;
-
-namespace [Owner].[Module]
-{
- public class ModuleInfo : IModule
- {
- public ModuleDefinition ModuleDefinition => new ModuleDefinition
- {
- Name = "[Module]",
- Description = "[Module]",
- Version = "1.0.0",
- ServerManagerType = "[ServerManagerType]",
- ReleaseVersions = "1.0.0"
- };
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs
deleted file mode 100644
index 601eba6a..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/I[Module]Service.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using [Owner].[Module].Models;
-
-namespace [Owner].[Module].Services
-{
- public interface I[Module]Service
- {
- Task> Get[Module]sAsync(int ModuleId);
-
- Task Get[Module]Async(int [Module]Id, int ModuleId);
-
- Task Add[Module]Async(Models.[Module] [Module]);
-
- Task Update[Module]Async(Models.[Module] [Module]);
-
- Task Delete[Module]Async(int [Module]Id, int ModuleId);
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs
deleted file mode 100644
index 05a85ac7..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Services/[Module]Service.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Http;
-using System.Threading.Tasks;
-using Oqtane.Modules;
-using Oqtane.Services;
-using Oqtane.Shared;
-using [Owner].[Module].Models;
-
-namespace [Owner].[Module].Services
-{
- public class [Module]Service : ServiceBase, I[Module]Service, IService
- {
- private readonly SiteState _siteState;
-
- public [Module]Service(HttpClient http, SiteState siteState) : base(http)
- {
- _siteState = siteState;
- }
-
- private string Apiurl => CreateApiUrl(_siteState.Alias, "[Module]");
-
- public async Task> Get[Module]sAsync(int ModuleId)
- {
- List [Module]s = await GetJsonAsync>(CreateAuthorizationPolicyUrl($"{Apiurl}?moduleid={ModuleId}", ModuleId));
- return [Module]s.OrderBy(item => item.Name).ToList();
- }
-
- public async Task Get[Module]Async(int [Module]Id, int ModuleId)
- {
- return await GetJsonAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId));
- }
-
- public async Task Add[Module]Async(Models.[Module] [Module])
- {
- return await PostJsonAsync(CreateAuthorizationPolicyUrl($"{Apiurl}", [Module].ModuleId), [Module]);
- }
-
- public async Task Update[Module]Async(Models.[Module] [Module])
- {
- return await PutJsonAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{[Module].[Module]Id}", [Module].ModuleId), [Module]);
- }
-
- public async Task Delete[Module]Async(int [Module]Id, int ModuleId)
- {
- await DeleteAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{[Module]Id}", ModuleId));
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor
deleted file mode 100644
index 7989d7c9..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Client/Modules/[Owner].[Module]/Settings.razor
+++ /dev/null
@@ -1,47 +0,0 @@
-@namespace [Owner].[Module]
-@inherits ModuleBase
-@inject ISettingService SettingService
-
-
-
-@code {
- public override string Title => "[Module] Settings";
-
- string _value;
-
- protected override async Task OnInitializedAsync()
- {
- try
- {
- Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
- _value = SettingService.GetSetting(settings, "SettingName", "");
- }
- catch (Exception ex)
- {
- ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
- }
- }
-
- public async Task UpdateSettings()
- {
- try
- {
- Dictionary settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
- SettingService.SetSetting(settings, "SettingName", _value);
- await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
- }
- catch (Exception ex)
- {
- ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs
deleted file mode 100644
index 3e2fe7b8..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Controllers/[Module]Controller.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Authorization;
-using System.Collections.Generic;
-using Microsoft.AspNetCore.Http;
-using Oqtane.Shared;
-using Oqtane.Enums;
-using Oqtane.Infrastructure;
-using [Owner].[Module].Models;
-using [Owner].[Module].Repository;
-
-namespace [Owner].[Module].Controllers
-{
- [Route(ControllerRoutes.Default)]
- public class [Module]Controller : Controller
- {
- private readonly I[Module]Repository _[Module]Repository;
- private readonly ILogManager _logger;
- protected int _entityId = -1;
-
- public [Module]Controller(I[Module]Repository [Module]Repository, ILogManager logger, IHttpContextAccessor accessor)
- {
- _[Module]Repository = [Module]Repository;
- _logger = logger;
-
- if (accessor.HttpContext.Request.Query.ContainsKey("entityid"))
- {
- _entityId = int.Parse(accessor.HttpContext.Request.Query["entityid"]);
- }
- }
-
- // GET: api/?moduleid=x
- [HttpGet]
- [Authorize(Policy = PolicyNames.ViewModule)]
- public IEnumerable Get(string moduleid)
- {
- return _[Module]Repository.Get[Module]s(int.Parse(moduleid));
- }
-
- // GET api//5
- [HttpGet("{id}")]
- [Authorize(Policy = PolicyNames.ViewModule)]
- public Models.[Module] Get(int id)
- {
- Models.[Module] [Module] = _[Module]Repository.Get[Module](id);
- if ([Module] != null && [Module].ModuleId != _entityId)
- {
- [Module] = null;
- }
- return [Module];
- }
-
- // POST api/
- [HttpPost]
- [Authorize(Policy = PolicyNames.EditModule)]
- public Models.[Module] Post([FromBody] Models.[Module] [Module])
- {
- if (ModelState.IsValid && [Module].ModuleId == _entityId)
- {
- [Module] = _[Module]Repository.Add[Module]([Module]);
- _logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]);
- }
- return [Module];
- }
-
- // PUT api//5
- [HttpPut("{id}")]
- [Authorize(Policy = PolicyNames.EditModule)]
- public Models.[Module] Put(int id, [FromBody] Models.[Module] [Module])
- {
- if (ModelState.IsValid && [Module].ModuleId == _entityId)
- {
- [Module] = _[Module]Repository.Update[Module]([Module]);
- _logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]);
- }
- return [Module];
- }
-
- // DELETE api//5
- [HttpDelete("{id}")]
- [Authorize(Policy = PolicyNames.EditModule)]
- public void Delete(int id)
- {
- Models.[Module] [Module] = _[Module]Repository.Get[Module](id);
- if ([Module] != null && [Module].ModuleId == _entityId)
- {
- _[Module]Repository.Delete[Module](id);
- _logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id);
- }
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs
deleted file mode 100644
index 486c8ddf..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Manager/[Module]Manager.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Text.Json;
-using Oqtane.Modules;
-using Oqtane.Models;
-using Oqtane.Infrastructure;
-using Oqtane.Repository;
-using [Owner].[Module].Models;
-using [Owner].[Module].Repository;
-
-namespace [Owner].[Module].Manager
-{
- public class [Module]Manager : IInstallable, IPortable
- {
- private I[Module]Repository _[Module]Repository;
- private ISqlRepository _sql;
-
- public [Module]Manager(I[Module]Repository [Module]Repository, ISqlRepository sql)
- {
- _[Module]Repository = [Module]Repository;
- _sql = sql;
- }
-
- public bool Install(Tenant tenant, string version)
- {
- return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module]." + version + ".sql");
- }
-
- public bool Uninstall(Tenant tenant)
- {
- return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module].Uninstall.sql");
- }
-
- public string ExportModule(Module module)
- {
- string content = "";
- List [Module]s = _[Module]Repository.Get[Module]s(module.ModuleId).ToList();
- if ([Module]s != null)
- {
- content = JsonSerializer.Serialize([Module]s);
- }
- return content;
- }
-
- public void ImportModule(Module module, string content, string version)
- {
- List [Module]s = null;
- if (!string.IsNullOrEmpty(content))
- {
- [Module]s = JsonSerializer.Deserialize>(content);
- }
- if ([Module]s != null)
- {
- foreach(var [Module] in [Module]s)
- {
- _[Module]Repository.Add[Module](new Models.[Module] { ModuleId = module.ModuleId, Name = [Module].Name });
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs
deleted file mode 100644
index 52b7913a..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/I[Module]Repository.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Collections.Generic;
-using [Owner].[Module].Models;
-
-namespace [Owner].[Module].Repository
-{
- public interface I[Module]Repository
- {
- IEnumerable Get[Module]s(int ModuleId);
- Models.[Module] Get[Module](int [Module]Id);
- Models.[Module] Add[Module](Models.[Module] [Module]);
- Models.[Module] Update[Module](Models.[Module] [Module]);
- void Delete[Module](int [Module]Id);
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs
deleted file mode 100644
index a10d7219..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Context.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using Microsoft.AspNetCore.Http;
-using Oqtane.Modules;
-using Oqtane.Repository;
-using [Owner].[Module].Models;
-
-namespace [Owner].[Module].Repository
-{
- public class [Module]Context : DBContextBase, IService
- {
- public virtual DbSet [Module] { get; set; }
-
- public [Module]Context(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor)
- {
- // ContextBase handles multi-tenant database connections
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs
deleted file mode 100644
index 9c8c3628..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Repository/[Module]Repository.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using Microsoft.EntityFrameworkCore;
-using System.Linq;
-using System.Collections.Generic;
-using Oqtane.Modules;
-using [Owner].[Module].Models;
-
-namespace [Owner].[Module].Repository
-{
- public class [Module]Repository : I[Module]Repository, IService
- {
- private readonly [Module]Context _db;
-
- public [Module]Repository([Module]Context context)
- {
- _db = context;
- }
-
- public IEnumerable Get[Module]s(int ModuleId)
- {
- return _db.[Module].Where(item => item.ModuleId == ModuleId);
- }
-
- public Models.[Module] Get[Module](int [Module]Id)
- {
- return _db.[Module].Find([Module]Id);
- }
-
- public Models.[Module] Add[Module](Models.[Module] [Module])
- {
- _db.[Module].Add([Module]);
- _db.SaveChanges();
- return [Module];
- }
-
- public Models.[Module] Update[Module](Models.[Module] [Module])
- {
- _db.Entry([Module]).State = EntityState.Modified;
- _db.SaveChanges();
- return [Module];
- }
-
- public void Delete[Module](int [Module]Id)
- {
- Models.[Module] [Module] = _db.[Module].Find([Module]Id);
- _db.[Module].Remove([Module]);
- _db.SaveChanges();
- }
- }
-}
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql
deleted file mode 100644
index 7a1b99ea..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].1.0.0.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Create [Owner][Module] table
-*/
-
-CREATE TABLE [dbo].[[Owner][Module]](
- [[Module]Id] [int] IDENTITY(1,1) NOT NULL,
- [ModuleId] [int] NOT NULL,
- [Name] [nvarchar](256) NOT NULL,
- [CreatedBy] [nvarchar](256) NOT NULL,
- [CreatedOn] [datetime] NOT NULL,
- [ModifiedBy] [nvarchar](256) NOT NULL,
- [ModifiedOn] [datetime] NOT NULL,
- CONSTRAINT [PK_[Owner][Module]] PRIMARY KEY CLUSTERED
- (
- [[Module]Id] ASC
- )
-)
-GO
-
-/*
-Create foreign key relationships
-*/
-ALTER TABLE [dbo].[[Owner][Module]] WITH CHECK ADD CONSTRAINT [FK_[Owner][Module]_Module] FOREIGN KEY([ModuleId])
-REFERENCES [dbo].Module ([ModuleId])
-ON DELETE CASCADE
-GO
\ No newline at end of file
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql
deleted file mode 100644
index 47baecc9..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/Modules/[Owner].[Module]/Scripts/[Owner].[Module].Uninstall.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
-Remove [Owner][Module] table
-*/
-
-DROP TABLE [dbo].[[Owner][Module]]
-GO
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css
deleted file mode 100644
index 0856a263..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.css
+++ /dev/null
@@ -1 +0,0 @@
-/* Module Custom Styles */
\ No newline at end of file
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js
deleted file mode 100644
index 8f072470..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Server/wwwroot/Modules/[Owner].[Module]/Module.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Module Script */
-var [Owner] = [Owner] || {};
-
-[Owner].[Module] = {
-};
\ No newline at end of file
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs b/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs
deleted file mode 100644
index 94f73ffa..00000000
--- a/Oqtane.Server/wwwroot/Modules/Templates/Internal/Oqtane.Shared/Modules/[Owner].[Module]/Models/[Module].cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-using System.ComponentModel.DataAnnotations.Schema;
-using Oqtane.Models;
-
-namespace [Owner].[Module].Models
-{
- [Table("[Owner][Module]")]
- public class [Module] : IAuditable
- {
- public int [Module]Id { get; set; }
- public int ModuleId { get; set; }
- public string Name { get; set; }
-
- public string CreatedBy { get; set; }
- public DateTime CreatedOn { get; set; }
- public string ModifiedBy { get; set; }
- public DateTime ModifiedOn { get; set; }
- }
-}
diff --git a/Oqtane.Server/wwwroot/css/app.css b/Oqtane.Server/wwwroot/css/app.css
index ce87887d..eebf63a6 100644
--- a/Oqtane.Server/wwwroot/css/app.css
+++ b/Oqtane.Server/wwwroot/css/app.css
@@ -1,4 +1,4 @@
-@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
+@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
@@ -125,6 +125,13 @@ app {
vertical-align: inherit;
}
+.app-alert {
+ padding: 20px;
+ background-color: #f44336; /* red */
+ color: white;
+ margin-bottom: 15px;
+}
+
/* Tooltips */
.app-tooltip {
cursor: help;
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 51e71450..60106dd2 100644
--- a/Oqtane.Shared/Shared/Constants.cs
+++ b/Oqtane.Shared/Shared/Constants.cs
@@ -5,8 +5,8 @@ namespace Oqtane.Shared {
public class Constants {
public const string PackageId = "Oqtane.Framework";
- public const string Version = "2.0.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.2";
+ public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2";
public const string PageComponent = "Oqtane.UI.ThemeBuilder, Oqtane.Client";
public const string ContainerComponent = "Oqtane.UI.ContainerBuilder, Oqtane.Client";
@@ -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 =
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
diff --git a/Oqtane.sln b/Oqtane.sln
index 2755bdb2..70e85123 100644
--- a/Oqtane.sln
+++ b/Oqtane.sln
@@ -16,6 +16,8 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{77EECA8C-B58E-469E-B8C5-D543AFC9A654}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
+ .gitignore = .gitignore
+ README.md = README.md
EndProjectSection
EndProject
Global
diff --git a/README.md b/README.md
index 5d0bb04c..20559301 100644
--- a/README.md
+++ b/README.md
@@ -50,9 +50,11 @@ 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 )
+- [ ] Cross Platform Database Support ( ie. SQLite ) - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964)
+- [ ] EF Core Migrations for Database Installation/Upgrade - see [#964](https://github.com/oqtane/oqtane.framework/discussions/964)
+
+V.2.0.1 ( Feb 27, 2021 )
- [x] Complete Static Localization of Admin UI
-- [ ] Cross Platform Database Support ( ie. SQLite )
-- [ ] EF Core Migrations for Database Installation/Upgrade
V.2.0.0 ( released in conjuntion with .NET 5 on Nov 11, 2020 )
- [x] Migration to .NET 5
| |