tags which can be used as a signal to set the active tab
- if (!string.IsNullOrEmpty(Content) && !Content.StartsWith("
") && AllowRawHtml)
+ if (!AllowRichText)
{
_activetab = "Raw";
}
@@ -171,8 +187,6 @@
if (AllowRichText)
{
- var interop = new RichTextEditorInterop(JSRuntime);
-
if (firstRender)
{
await interop.CreateEditor(
@@ -182,15 +196,38 @@
Placeholder,
Theme,
DebugLevel);
- }
- await interop.LoadEditorContent(_editorElement, _richhtml);
+ await interop.LoadEditorContent(_editorElement, _richhtml);
- if (string.IsNullOrEmpty(_originalrichhtml))
- {
- // preserve a copy of the rich text content (Quill sanitizes content so we need to retrieve it from the editor)
+ // preserve a copy of the content (Quill sanitizes content so we need to retrieve it from the editor as it may have been modified)
_originalrichhtml = await interop.GetHtml(_editorElement);
+
+ _initialized = true;
}
+ else
+ {
+ if (_initialized)
+ {
+ if (_contentchanged)
+ {
+ // reload editor if Content passed to component has changed
+ await interop.LoadEditorContent(_editorElement, _richhtml);
+ _originalrichhtml = await interop.GetHtml(_editorElement);
+ }
+ else
+ {
+ // preserve changed content on re-render event
+ var richhtml = await interop.GetHtml(_editorElement);
+ if (richhtml != _richhtml)
+ {
+ _richhtml = richhtml;
+ await interop.LoadEditorContent(_editorElement, _richhtml);
+ }
+ }
+ }
+ }
+
+ _contentchanged = false;
}
}
@@ -218,23 +255,27 @@
else
{
var richhtml = "";
+
if (AllowRichText)
{
- // return rich text content if it has changed
- var interop = new RichTextEditorInterop(JSRuntime);
richhtml = await interop.GetHtml(_editorElement);
}
- // rich text value will only be blank if AllowRichText is disabled or the JS Interop method failed
- if (richhtml != _originalrichhtml && !string.IsNullOrEmpty(richhtml) && !string.IsNullOrEmpty(_originalrichhtml))
- {
- return richhtml;
- }
- else
- {
- // return original raw html content
- return _originalrawhtml;
- }
- }
+
+ if (richhtml != _originalrichhtml && !string.IsNullOrEmpty(richhtml))
+ {
+ // convert Quill's empty content to empty string
+ if (richhtml == "
")
+ {
+ richhtml = string.Empty;
+ }
+ return richhtml;
+ }
+ else
+ {
+ // return original raw html content
+ return _originalrawhtml;
+ }
+ }
}
public async Task InsertRichImage()
@@ -245,7 +286,6 @@
var file = _fileManager.GetFile();
if (file != null)
{
- var interop = new RichTextEditorInterop(JSRuntime);
await interop.InsertImage(_editorElement, file.Url, ((!string.IsNullOrEmpty(file.Description)) ? file.Description : file.Name));
_richhtml = await interop.GetHtml(_editorElement);
_richfilemanager = false;
@@ -271,7 +311,7 @@
if (file != null)
{
var interop = new Interop(JSRuntime);
- int pos = await interop.GetCaretPosition("rawhtmleditor");
+ int pos = await interop.GetCaretPosition(_rawhtmlid);
var image = "";
_rawhtml = _rawhtml.Substring(0, pos) + image + _rawhtml.Substring(pos);
_rawfilemanager = false;
diff --git a/Oqtane.Client/Oqtane.Client.csproj b/Oqtane.Client/Oqtane.Client.csproj
index 16bc0156a..f99895836 100644
--- a/Oqtane.Client/Oqtane.Client.csproj
+++ b/Oqtane.Client/Oqtane.Client.csproj
@@ -4,7 +4,7 @@
net8.0ExeDebug;Release
- 5.1.0
+ 5.1.1OqtaneShaun Walker.NET Foundation
@@ -12,7 +12,7 @@
.NET Foundationhttps://www.oqtane.orghttps://github.com/oqtane/oqtane.framework/blob/dev/LICENSE
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1https://github.com/oqtane/oqtane.frameworkGitOqtane
@@ -22,9 +22,9 @@
-
-
-
+
+
+
diff --git a/Oqtane.Client/Resources/Installer/Controls/SqlServerConfig.resx b/Oqtane.Client/Resources/Installer/Controls/SqlServerConfig.resx
index e54f584a6..7909364d0 100644
--- a/Oqtane.Client/Resources/Installer/Controls/SqlServerConfig.resx
+++ b/Oqtane.Client/Resources/Installer/Controls/SqlServerConfig.resx
@@ -1,4 +1,4 @@
-
+
Exe
- 5.1.0
+ 5.1.1OqtaneShaun Walker.NET Foundation
@@ -14,7 +14,7 @@
.NET Foundationhttps://www.oqtane.orghttps://github.com/oqtane/oqtane.framework/blob/dev/LICENSE
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1https://github.com/oqtane/oqtane.frameworkGitOqtane.Maui
@@ -31,7 +31,7 @@
0E29FC31-1B83-48ED-B6E0-9F3C67B775D4
- 5.1.0
+ 5.1.1114.2
@@ -65,15 +65,15 @@
-
-
+
+
-
+
-
-
-
+
+
+
diff --git a/Oqtane.Package/Oqtane.Client.nuspec b/Oqtane.Package/Oqtane.Client.nuspec
index e2762ec73..49cf9bd57 100644
--- a/Oqtane.Package/Oqtane.Client.nuspec
+++ b/Oqtane.Package/Oqtane.Client.nuspec
@@ -2,7 +2,7 @@
Oqtane.Client
- 5.1.0
+ 5.1.1Shaun Walker.NET FoundationOqtane Framework
@@ -12,7 +12,7 @@
falseMIThttps://github.com/oqtane/oqtane.framework
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1icon.pngoqtane
diff --git a/Oqtane.Package/Oqtane.Framework.nuspec b/Oqtane.Package/Oqtane.Framework.nuspec
index ebd0b4eda..cfaef73d6 100644
--- a/Oqtane.Package/Oqtane.Framework.nuspec
+++ b/Oqtane.Package/Oqtane.Framework.nuspec
@@ -2,7 +2,7 @@
Oqtane.Framework
- 5.1.0
+ 5.1.1Shaun Walker.NET FoundationOqtane Framework
@@ -11,8 +11,8 @@
.NET FoundationfalseMIT
- https://github.com/oqtane/oqtane.framework/releases/download/v5.1.0/Oqtane.Framework.5.1.0.Upgrade.zip
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/download/v5.1.1/Oqtane.Framework.5.1.1.Upgrade.zip
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1icon.pngoqtane framework
diff --git a/Oqtane.Package/Oqtane.Server.nuspec b/Oqtane.Package/Oqtane.Server.nuspec
index 6e783ae21..93c2942e1 100644
--- a/Oqtane.Package/Oqtane.Server.nuspec
+++ b/Oqtane.Package/Oqtane.Server.nuspec
@@ -2,7 +2,7 @@
Oqtane.Server
- 5.1.0
+ 5.1.1Shaun Walker.NET FoundationOqtane Framework
@@ -12,7 +12,7 @@
falseMIThttps://github.com/oqtane/oqtane.framework
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1icon.pngoqtane
diff --git a/Oqtane.Package/Oqtane.Shared.nuspec b/Oqtane.Package/Oqtane.Shared.nuspec
index bc41fd154..ac34a8112 100644
--- a/Oqtane.Package/Oqtane.Shared.nuspec
+++ b/Oqtane.Package/Oqtane.Shared.nuspec
@@ -2,7 +2,7 @@
Oqtane.Shared
- 5.1.0
+ 5.1.1Shaun Walker.NET FoundationOqtane Framework
@@ -12,7 +12,7 @@
falseMIThttps://github.com/oqtane/oqtane.framework
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1icon.pngoqtane
diff --git a/Oqtane.Package/Oqtane.Updater.nuspec b/Oqtane.Package/Oqtane.Updater.nuspec
index d2958199a..fe7d85bd6 100644
--- a/Oqtane.Package/Oqtane.Updater.nuspec
+++ b/Oqtane.Package/Oqtane.Updater.nuspec
@@ -2,7 +2,7 @@
Oqtane.Updater
- 5.1.0
+ 5.1.1Shaun Walker.NET FoundationOqtane Framework
@@ -12,7 +12,7 @@
falseMIThttps://github.com/oqtane/oqtane.framework
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1icon.pngoqtane
diff --git a/Oqtane.Package/install.ps1 b/Oqtane.Package/install.ps1
index 21103c062..ed93995d5 100644
--- a/Oqtane.Package/install.ps1
+++ b/Oqtane.Package/install.ps1
@@ -1 +1 @@
-Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.0.Install.zip" -Force
\ No newline at end of file
+Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.1.Install.zip" -Force
\ No newline at end of file
diff --git a/Oqtane.Package/upgrade.ps1 b/Oqtane.Package/upgrade.ps1
index 762ca550f..c5c23da0c 100644
--- a/Oqtane.Package/upgrade.ps1
+++ b/Oqtane.Package/upgrade.ps1
@@ -1 +1 @@
-Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.0.Upgrade.zip" -Force
\ No newline at end of file
+Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.1.Upgrade.zip" -Force
\ No newline at end of file
diff --git a/Oqtane.Server/Controllers/LogController.cs b/Oqtane.Server/Controllers/LogController.cs
index 34fc5b7cf..341d35e5d 100644
--- a/Oqtane.Server/Controllers/LogController.cs
+++ b/Oqtane.Server/Controllers/LogController.cs
@@ -76,5 +76,20 @@ public void Post([FromBody] Log log)
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
}
}
+
+ [HttpDelete]
+ [Authorize(Roles = RoleNames.Admin)]
+ public void Delete(string siteId)
+ {
+ if (int.TryParse(siteId, out int parsedSiteId) && parsedSiteId == _alias.SiteId)
+ {
+ _logs.DeleteLogs(parsedSiteId, 0); // specifying zero for age results in all logs being deleted
+ }
+ else
+ {
+ _logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Log Delete Attempt {SiteId}", siteId);
+ HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
+ }
+ }
}
}
diff --git a/Oqtane.Server/Controllers/ModuleDefinitionController.cs b/Oqtane.Server/Controllers/ModuleDefinitionController.cs
index 291f183ce..2176c9f3b 100644
--- a/Oqtane.Server/Controllers/ModuleDefinitionController.cs
+++ b/Oqtane.Server/Controllers/ModuleDefinitionController.cs
@@ -365,8 +365,8 @@ private ITokenReplace InitializeTokenReplace(string rootPath, string rootFolder,
{
{ "FrameworkVersion", moduleDefinition.Version },
{ "ClientReference", $"" },
- { "ServerReference", $"" },
- { "SharedReference", $"" },
+ { "ServerReference", $"" },
+ { "SharedReference", $"" },
};
});
}
diff --git a/Oqtane.Server/Controllers/SystemController.cs b/Oqtane.Server/Controllers/SystemController.cs
index 8c0dce624..b34611f41 100644
--- a/Oqtane.Server/Controllers/SystemController.cs
+++ b/Oqtane.Server/Controllers/SystemController.cs
@@ -34,6 +34,7 @@ public Dictionary Get(string type)
case "environment":
systeminfo.Add("CLRVersion", Environment.Version.ToString());
systeminfo.Add("OSVersion", Environment.OSVersion.ToString());
+ systeminfo.Add("Process", (Environment.Is64BitProcess) ? "64 Bit" : "32 Bit");
systeminfo.Add("MachineName", Environment.MachineName);
systeminfo.Add("WorkingSet", Environment.WorkingSet.ToString());
systeminfo.Add("TickCount", Environment.TickCount64.ToString());
diff --git a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs
index 635b67239..19eb4cbe3 100644
--- a/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs
+++ b/Oqtane.Server/Extensions/OqtaneServiceCollectionExtensions.cs
@@ -157,7 +157,7 @@ public static IServiceCollection ConfigureOqtaneCookieOptions(this IServiceColle
services.ConfigureApplicationCookie(options =>
{
options.Cookie.HttpOnly = true;
- options.Cookie.SameSite = SameSiteMode.Strict;
+ options.Cookie.SameSite = SameSiteMode.Lax;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Events.OnRedirectToLogin = context =>
{
diff --git a/Oqtane.Server/Infrastructure/TokenReplace.cs b/Oqtane.Server/Infrastructure/TokenReplace.cs
index 3c7e8a8c0..d2b40db4c 100644
--- a/Oqtane.Server/Infrastructure/TokenReplace.cs
+++ b/Oqtane.Server/Infrastructure/TokenReplace.cs
@@ -93,6 +93,7 @@ public string ReplaceTokens(string source)
}
var result = new StringBuilder();
+ source = source.Replace("[[", "[$_["); //avoid nested square bracket issue.
foreach (Match match in this.TokenizerRegex.Matches(source))
{
var key = match.Result("${key}");
@@ -126,7 +127,7 @@ public string ReplaceTokens(string source)
result.Append(match.Result("${text}"));
}
}
-
+ result.Replace("[$_", "["); //restore the changes.
return result.ToString();
}
diff --git a/Oqtane.Server/Oqtane.Server.csproj b/Oqtane.Server/Oqtane.Server.csproj
index 8dabf5643..7fe28c3d7 100644
--- a/Oqtane.Server/Oqtane.Server.csproj
+++ b/Oqtane.Server/Oqtane.Server.csproj
@@ -3,7 +3,7 @@
net8.0Debug;Release
- 5.1.0
+ 5.1.1OqtaneShaun Walker.NET Foundation
@@ -11,7 +11,7 @@
.NET Foundationhttps://www.oqtane.orghttps://github.com/oqtane/oqtane.framework/blob/dev/LICENSE
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1https://github.com/oqtane/oqtane.frameworkGitOqtane
@@ -33,19 +33,19 @@
-
-
+
+
-
-
+
+ allruntime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
-
-
+
+
diff --git a/Oqtane.Server/Pages/Sitemap.cshtml.cs b/Oqtane.Server/Pages/Sitemap.cshtml.cs
index 461bc3d63..c79957c35 100644
--- a/Oqtane.Server/Pages/Sitemap.cshtml.cs
+++ b/Oqtane.Server/Pages/Sitemap.cshtml.cs
@@ -47,14 +47,23 @@ public IActionResult OnGet()
var sitemap = new List();
// build site map
+ var rooturl = _alias.Protocol + (string.IsNullOrEmpty(_alias.Path) ? _alias.Name : _alias.Name.Substring(0, _alias.Name.IndexOf("/")));
var moduleDefinitions = _moduleDefinitions.GetModuleDefinitions(_alias.SiteId).ToList();
var pageModules = _pageModules.GetPageModules(_alias.SiteId);
foreach (var page in _pages.GetPages(_alias.SiteId))
{
if (_userPermissions.IsAuthorized(null, PermissionNames.View, page.PermissionList) && page.IsNavigation)
{
- var rooturl = _alias.Protocol + (string.IsNullOrEmpty(_alias.Path) ? _alias.Name : _alias.Name.Substring(0, _alias.Name.IndexOf("/")));
- sitemap.Add(new Sitemap { Url = rooturl + Utilities.NavigateUrl(_alias.Path, page.Path, ""), ModifiedOn = DateTime.UtcNow });
+ var pageurl = rooturl;
+ if (string.IsNullOrEmpty(page.Url))
+ {
+ pageurl += Utilities.NavigateUrl(_alias.Path, page.Path, "");
+ }
+ else
+ {
+ pageurl += (page.Url.StartsWith("/") ? "" : "/") + page.Url;
+ }
+ sitemap.Add(new Sitemap { Url = pageurl, ModifiedOn = DateTime.UtcNow });
foreach (var pageModule in pageModules.Where(item => item.PageId == page.PageId))
{
diff --git a/Oqtane.Server/Repository/LogRepository.cs b/Oqtane.Server/Repository/LogRepository.cs
index 6c388f156..313c98817 100644
--- a/Oqtane.Server/Repository/LogRepository.cs
+++ b/Oqtane.Server/Repository/LogRepository.cs
@@ -59,14 +59,14 @@ public int DeleteLogs(int siteId, int age)
// delete logs in batches of 100 records
var count = 0;
var purgedate = DateTime.UtcNow.AddDays(-age);
- var logs = db.Log.Where(item => item.SiteId == siteId && item.Level != "Error" && item.LogDate < purgedate)
+ var logs = db.Log.Where(item => item.SiteId == siteId && item.LogDate < purgedate)
.OrderBy(item => item.LogDate).Take(100).ToList();
while (logs.Count > 0)
{
count += logs.Count;
db.Log.RemoveRange(logs);
db.SaveChanges();
- logs = db.Log.Where(item => item.SiteId == siteId && item.Level != "Error" && item.LogDate < purgedate)
+ logs = db.Log.Where(item => item.SiteId == siteId && item.LogDate < purgedate)
.OrderBy(item => item.LogDate).Take(100).ToList();
}
return count;
diff --git a/Oqtane.Server/Startup.cs b/Oqtane.Server/Startup.cs
index 8180ea9b6..0a83d2754 100644
--- a/Oqtane.Server/Startup.cs
+++ b/Oqtane.Server/Startup.cs
@@ -22,6 +22,7 @@
using OqtaneSSR.Extensions;
using Microsoft.AspNetCore.Components.Authorization;
using Oqtane.Providers;
+using Microsoft.AspNetCore.Cors.Infrastructure;
namespace Oqtane
{
@@ -135,7 +136,7 @@ public void ConfigureServices(IServiceCollection services)
{
// allow .NET MAUI client cross origin calls
policy.WithOrigins("https://0.0.0.0", "http://0.0.0.0", "app://0.0.0.0")
- .AllowAnyHeader().AllowCredentials();
+ .AllowAnyHeader().AllowAnyMethod().AllowCredentials();
});
});
@@ -169,7 +170,7 @@ public void ConfigureServices(IServiceCollection services)
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncManager sync, ILogger logger)
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncManager sync, ICorsService corsService, ICorsPolicyProvider corsPolicyProvider, ILogger logger)
{
if (!string.IsNullOrEmpty(_configureServicesErrors))
{
@@ -198,7 +199,16 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncMan
app.UseOqtaneLocalization();
app.UseHttpsRedirection();
- app.UseStaticFiles();
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ ServeUnknownFileTypes = true,
+ OnPrepareResponse = (ctx) =>
+ {
+ var policy = corsPolicyProvider.GetPolicyAsync(ctx.Context, Constants.MauiCorsPolicy)
+ .ConfigureAwait(false).GetAwaiter().GetResult();
+ corsService.ApplyResult(corsService.EvaluatePolicy(ctx.Context, policy), ctx.Context.Response);
+ }
+ });
app.UseExceptionMiddleWare();
app.UseTenantResolution();
app.UseJwtAuthorization();
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj
index 6653d33fb..285cf9b71 100644
--- a/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj
+++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Client/[Owner].Module.[Module].Client.csproj
@@ -13,9 +13,9 @@
-
-
-
+
+
+
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj
index c7fe75a77..e7843bfff 100644
--- a/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj
+++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Package/[Owner].Module.[Module].Package.csproj
@@ -3,6 +3,7 @@
net8.0false
+ false
diff --git a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj
index 0e89e987d..d80b6abd5 100644
--- a/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj
+++ b/Oqtane.Server/wwwroot/Modules/Templates/External/Server/[Owner].Module.[Module].Server.csproj
@@ -19,10 +19,10 @@
-
-
-
-
+
+
+
+
diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/ThemeSettings.razor b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/ThemeSettings.razor
index 8db32e1f6..3c9d2723e 100644
--- a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/ThemeSettings.razor
+++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/Themes/ThemeSettings.razor
@@ -108,12 +108,12 @@
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
if (_login != "-")
{
- settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login, true);
+ settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
}
if (_register != "-")
{
- settings = SettingService.SetSetting(settings, GetType().Namespace + ":Register", _register, true);
+ settings = SettingService.SetSetting(settings, GetType().Namespace + ":Register", _register);
}
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
}
diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj
index d44657047..e143330bb 100644
--- a/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj
+++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Client/[Owner].Theme.[Theme].Client.csproj
@@ -12,9 +12,9 @@
-
-
-
+
+
+
diff --git a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj
index 908a23b43..0f6cc8ea6 100644
--- a/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj
+++ b/Oqtane.Server/wwwroot/Themes/Templates/External/Package/[Owner].Theme.[Theme].Package.csproj
@@ -3,6 +3,7 @@
net8.0false
+ false
diff --git a/Oqtane.Server/wwwroot/css/app.css b/Oqtane.Server/wwwroot/css/app.css
index 863d10d25..f5a65a80a 100644
--- a/Oqtane.Server/wwwroot/css/app.css
+++ b/Oqtane.Server/wwwroot/css/app.css
@@ -35,6 +35,9 @@ app {
}
/* Action Dialog */
+.app-actiondialog{
+ position: absolute;
+}
.app-actiondialog .modal {
position: fixed; /* Stay in place */
z-index: 9999; /* Sit on top */
diff --git a/Oqtane.Shared/Oqtane.Shared.csproj b/Oqtane.Shared/Oqtane.Shared.csproj
index 4874e7ae2..3d8d4a78f 100644
--- a/Oqtane.Shared/Oqtane.Shared.csproj
+++ b/Oqtane.Shared/Oqtane.Shared.csproj
@@ -3,7 +3,7 @@
net8.0Debug;Release
- 5.1.0
+ 5.1.1OqtaneShaun Walker.NET Foundation
@@ -11,7 +11,7 @@
.NET Foundationhttps://www.oqtane.orghttps://github.com/oqtane/oqtane.framework/blob/dev/LICENSE
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1https://github.com/oqtane/oqtane.frameworkGitOqtane
@@ -19,8 +19,8 @@
-
-
+
+
diff --git a/Oqtane.Shared/Shared/Constants.cs b/Oqtane.Shared/Shared/Constants.cs
index e538ef9d1..a7d1173e6 100644
--- a/Oqtane.Shared/Shared/Constants.cs
+++ b/Oqtane.Shared/Shared/Constants.cs
@@ -4,8 +4,8 @@ namespace Oqtane.Shared
{
public class Constants
{
- public static readonly string Version = "5.1.0";
- 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,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0";
+ public static readonly string Version = "5.1.1";
+ public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1";
public const string PackageId = "Oqtane.Framework";
public const string ClientId = "Oqtane.Client";
public const string UpdaterPackageId = "Oqtane.Updater";
diff --git a/Oqtane.Shared/Shared/Utilities.cs b/Oqtane.Shared/Shared/Utilities.cs
index 49905c1ef..b9e364c39 100644
--- a/Oqtane.Shared/Shared/Utilities.cs
+++ b/Oqtane.Shared/Shared/Utilities.cs
@@ -21,86 +21,50 @@ public static string ToModuleDefinitionName(this Type type)
return $"{type.Namespace}, {assemblyName}";
}
- public static (string UrlParameters, string Querystring, string Fragment) ParseParameters(string url)
+ public static (string UrlParameters, string Querystring, string Fragment) ParseParameters(string parameters)
{
- // /path/urlparameters
// /urlparameters /urlparameters?Id=1 /urlparameters#5 /urlparameters?Id=1#5 /urlparameters?reload#5
// Id=1 Id=1#5 reload#5 reload
// #5
- if (!url.Contains("://"))
- {
- if (!url.StartsWith("/")) // urlparameters always start with "/"
- {
- url = ((!url.StartsWith("#")) ? "?" : "/") + url;
- }
- url = Constants.PackageRegistryUrl + url; // create absolute url
- }
-
- var uri = new Uri(url);
+ // create absolute url to convert to Uri
+ parameters = (!parameters.StartsWith("/") && !parameters.StartsWith("#") ? "?" : "") + parameters;
+ parameters = Constants.PackageRegistryUrl + parameters;
+ var uri = new Uri(parameters);
var querystring = uri.Query.Replace("?", "");
var fragment = uri.Fragment.Replace("#", "");
var urlparameters = uri.LocalPath;
urlparameters = (urlparameters == "/") ? "" : urlparameters;
- if (urlparameters.Contains(Constants.UrlParametersDelimiter))
- {
- urlparameters = urlparameters.Substring(urlparameters.IndexOf(Constants.UrlParametersDelimiter) + 1);
- }
-
return (urlparameters, querystring, fragment);
}
- public static (string Path, string Parameters) ParsePath(string url)
- {
- url = ((!url.StartsWith("/") && !url.Contains("://")) ? "/" : "") + url;
-
- (string path, string querystring, string fragment) = ParseParameters(url);
-
- var uriBuilder = new UriBuilder
- {
- Path = path,
- Query = querystring,
- Fragment = fragment
- };
-
- return (uriBuilder.Path, uriBuilder.Uri.Query + uriBuilder.Uri.Fragment);
- }
-
public static string NavigateUrl(string alias, string path, string parameters)
{
+ string querystring = "";
+ string fragment = "";
+
if (!string.IsNullOrEmpty(parameters))
{
- // parse path
- (path, _) = ParsePath(path);
-
// parse parameters
- (string urlparameters, string querystring, string fragment) = ParseParameters(parameters);
-
- // add urlparameters to path
+ (string urlparameters, querystring, fragment) = ParseParameters(parameters);
if (!string.IsNullOrEmpty(urlparameters))
{
- if (urlparameters.StartsWith("/")) urlparameters = urlparameters.Remove(0, 1);
- path += $"/{Constants.UrlParametersDelimiter}/{urlparameters}";
+ path += (path.EndsWith("/") ? "" : "/") + $"{Constants.UrlParametersDelimiter}/{urlparameters.Substring(1)}";
}
-
- // build url
- var uriBuilder = new UriBuilder
- {
- Path = !string.IsNullOrEmpty(alias)
- ? (!string.IsNullOrEmpty(path)) ? $"{alias}{path}": $"{alias}"
- : $"{path}",
- Query = querystring,
- Fragment = fragment
- };
- path = uriBuilder.Uri.PathAndQuery;
}
- else
+
+ // build url
+ var uriBuilder = new UriBuilder
{
- path = ((!string.IsNullOrEmpty(alias)) ? alias + (!path.StartsWith("/") ? "/" : "") : "") + path;
- }
+ Path = !string.IsNullOrEmpty(alias)
+ ? (!string.IsNullOrEmpty(path)) ? $"{alias}{path}": $"{alias}"
+ : $"{path}",
+ Query = querystring,
+ Fragment = fragment
+ };
- return path;
+ return uriBuilder.Uri.PathAndQuery;
}
public static string EditUrl(string alias, string path, int moduleid, string action, string parameters)
@@ -185,6 +149,7 @@ public static string FormatContent(string content, Alias alias, string operation
break;
case "render":
content = content.Replace(Constants.FileUrl, alias?.BaseUrl + aliasUrl + Constants.FileUrl);
+ content = content.Replace("[wwwroot]", alias?.BaseUrl + aliasUrl + "/");
// legacy
content = content.Replace("[siteroot]", UrlCombine("Content", "Tenants", alias.TenantId.ToString(), "Sites", alias.SiteId.ToString()));
content = content.Replace(Constants.ContentUrl, alias.Path + Constants.ContentUrl);
diff --git a/Oqtane.Updater/Oqtane.Updater.csproj b/Oqtane.Updater/Oqtane.Updater.csproj
index 231694c5d..4554897c4 100644
--- a/Oqtane.Updater/Oqtane.Updater.csproj
+++ b/Oqtane.Updater/Oqtane.Updater.csproj
@@ -3,7 +3,7 @@
net8.0Exe
- 5.1.0
+ 5.1.1OqtaneShaun Walker.NET Foundation
@@ -11,7 +11,7 @@
.NET Foundationhttps://www.oqtane.orghttps://github.com/oqtane/oqtane.framework/blob/dev/LICENSE
- https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0
+ https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1https://github.com/oqtane/oqtane.frameworkGitOqtane
diff --git a/README.md b/README.md
index 18226e276..0a56d241f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Latest Release
-[5.0.2](https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.2) was released on Jan 25, 2024 and is a stabilization release targeted at .NET 8. This release includes 51 pull requests by 6 different contributors, pushing the total number of project commits all-time to over 4600. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
+[5.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0) was released on Mar 27, 2024 and is a major release providing Static Server Rendering support for Blazor in .NET 8. This release includes 263 pull requests by 6 different contributors, pushing the total number of project commits all-time to over 5100. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Foqtane%2Foqtane.framework%2Fmaster%2Fazuredeploy.json)
@@ -63,8 +63,12 @@ Backlog (TBD)
- [ ] Folder Providers
- [ ] Generative AI Integration
-5.1.0 (Q1 2024)
-- [ ] Full Stack Blazor (Static Server-Side Rendering)
+5.1.1 (Apr 2024)
+- [ ] Stabilization improvements
+
+[5.1.0](https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0) (Mar 27, 2024)
+- [x] Migration to the new unified Blazor approach in .NET 8 (ie. blazor.web.js)
+- [x] Static Server Rendering (SSR) support
[5.0.2](https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.2) (Jan 25, 2024)
- [x] Stabilization improvements