diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 000000000..e16dcee6f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,26 @@ +--- +name: Bug Report +about: Create a bug report to help us improve the product +title: "[BUG] " +labels: '' +assignees: '' + +--- + +### Oqtane Info + +Version - #.#.# +Render Mode - Static +Interactivity - Server +Database - SQL Server + +### Describe the bug + + +### Expected Behavior + + +### Steps To Reproduce + + +### Anything else? diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.md b/.github/ISSUE_TEMPLATE/enhancement-request.md new file mode 100644 index 000000000..c9890f6d9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/enhancement-request.md @@ -0,0 +1,20 @@ +--- +name: Enhancement Request +about: 'Suggest a product enhancement ' +title: "[ENH] " +labels: '' +assignees: '' + +--- + +### Oqtane Info + +Version - #.#.# +Render Mode - Static +Interactivity - Server +Database - SQL Server + +### Describe the enhancement + + +### Anything else? diff --git a/Oqtane.Client/Modules/Admin/Logs/Index.razor b/Oqtane.Client/Modules/Admin/Logs/Index.razor index cf2f7cbc5..6932f7843 100644 --- a/Oqtane.Client/Modules/Admin/Logs/Index.razor +++ b/Oqtane.Client/Modules/Admin/Logs/Index.razor @@ -86,47 +86,48 @@ else
- + + } @code { - private string _level = "-"; - private string _function = "-"; - private string _rows = "10"; - private int _page = 1; - private List _logs; - private int _retention = 30; + private string _level = "-"; + private string _function = "-"; + private string _rows = "10"; + private int _page = 1; + private List _logs; + private int _retention = 30; - public override string UrlParametersTemplate => "/{level}/{function}/{rows}/{page}"; - public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; + public override string UrlParametersTemplate => "/{level}/{function}/{rows}/{page}"; + public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; - protected override async Task OnParametersSetAsync() - { - try - { - if (UrlParameters.ContainsKey("level")) - { - _level = UrlParameters["level"]; - } - if (UrlParameters.ContainsKey("function")) - { - _function = UrlParameters["function"]; - } - if (UrlParameters.ContainsKey("rows")) - { - _rows = UrlParameters["rows"]; - } - if (UrlParameters.ContainsKey("page") && int.TryParse(UrlParameters["page"], out int page)) - { - _page = page; - } + protected override async Task OnParametersSetAsync() + { + try + { + if (UrlParameters.ContainsKey("level")) + { + _level = UrlParameters["level"]; + } + if (UrlParameters.ContainsKey("function")) + { + _function = UrlParameters["function"]; + } + if (UrlParameters.ContainsKey("rows")) + { + _rows = UrlParameters["rows"]; + } + if (UrlParameters.ContainsKey("page") && int.TryParse(UrlParameters["page"], out int page)) + { + _page = page; + } await GetLogs(); - var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); - _retention = int.Parse( SettingService.GetSetting(settings, "LogRetention", "30")); + var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); + _retention = int.Parse( SettingService.GetSetting(settings, "LogRetention", "30")); } catch (Exception ex) { @@ -213,22 +214,37 @@ else return classname; } - private async Task SaveSiteSettings() - { - try - { - var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); - settings = SettingService.SetSetting(settings, "LogRetention", _retention.ToString(), true); + private async Task SaveSiteSettings() + { + try + { + var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId); + settings = SettingService.SetSetting(settings, "LogRetention", _retention.ToString(), true); await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId); - AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success); - } - catch (Exception ex) - { - await logger.LogError(ex, "Error Saving Site Settings {Error}", ex.Message); - AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error); - } - } + AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Saving Site Settings {Error}", ex.Message); + AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error); + } + } + + private async Task DeleteLogs() + { + try + { + await LogService.DeleteLogsAsync(PageState.Site.SiteId); + await GetLogs(); + StateHasChanged(); + } + catch (Exception ex) + { + await logger.LogError(ex, "Error Deleting Logs {Error}", ex.Message); + AddModuleMessage(Localizer["Error.DeleteLogs"], MessageType.Error); + } + } private void OnPageChange(int page) { diff --git a/Oqtane.Client/Modules/Admin/Pages/Add.razor b/Oqtane.Client/Modules/Admin/Pages/Add.razor index 9009ba29b..edaebf1af 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Add.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Add.razor @@ -385,45 +385,34 @@ page.ParentId = Int32.Parse(_parentid); } - // path can be a link to an external url - if (!_path.Contains("://")) + if (string.IsNullOrEmpty(_path)) { - if (string.IsNullOrEmpty(_path)) - { - _path = _name; - } - - (_path, string parameters) = Utilities.ParsePath(_path); + _path = _name; + } - if (_path.Contains("/")) + if (_path.Contains("/")) + { + if (_path.EndsWith("/") && _path != "/") { - if (_path.EndsWith("/") && _path != "/") - { - _path = _path.Substring(0, _path.Length - 1); - } - _path = _path.Substring(_path.LastIndexOf("/") + 1); + _path = _path.Substring(0, _path.Length - 1); } - if (_parentid == "-1") + _path = _path.Substring(_path.LastIndexOf("/") + 1); + } + if (_parentid == "-1") + { + page.Path = Utilities.GetFriendlyUrl(_path); + } + else + { + Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId); + if (parent.Path == string.Empty) { - page.Path = Utilities.GetFriendlyUrl(_path); + page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); } else { - Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId); - if (parent.Path == string.Empty) - { - page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); - } - else - { - page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); - } + page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); } - page.Path += parameters; - } - else - { - page.Path = _path; } var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId); @@ -497,14 +486,7 @@ } else { - if (!page.Path.Contains("://")) - { - NavigationManager.NavigateTo(page.Path); // redirect to new page created - } - else - { - NavigationManager.NavigateTo(NavigateUrl("admin/pages")); - } + NavigationManager.NavigateTo(page.Path); // redirect to new page created } } else diff --git a/Oqtane.Client/Modules/Admin/Pages/Edit.razor b/Oqtane.Client/Modules/Admin/Pages/Edit.razor index 46ba727b4..453f1f696 100644 --- a/Oqtane.Client/Modules/Admin/Pages/Edit.razor +++ b/Oqtane.Client/Modules/Admin/Pages/Edit.razor @@ -380,7 +380,7 @@ } else { - if (_path.Contains("/") & !_path.Contains("://")) + if (_path.Contains("/")) { _path = _path.Substring(_path.LastIndexOf("/") + 1); } @@ -529,45 +529,34 @@ _page.ParentId = Int32.Parse(_parentid); } - // path can be a link to an external url - if (!_path.Contains("://")) + if (string.IsNullOrEmpty(_path)) { - if (string.IsNullOrEmpty(_path)) - { - _path = _name; - } - - (_path, string parameters) = Utilities.ParsePath(_path); + _path = _name; + } - if (_path.Contains("/")) + if (_path.Contains("/")) + { + if (_path.EndsWith("/") && _path != "/") { - if (_path.EndsWith("/") && _path != "/") - { - _path = _path.Substring(0, _path.Length - 1); - } - _path = _path.Substring(_path.LastIndexOf("/") + 1); + _path = _path.Substring(0, _path.Length - 1); } - if (_parentid == "-1") + _path = _path.Substring(_path.LastIndexOf("/") + 1); + } + if (_parentid == "-1") + { + _page.Path = Utilities.GetFriendlyUrl(_path); + } + else + { + Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId); + if (parent.Path == string.Empty) { - _page.Path = Utilities.GetFriendlyUrl(_path); + _page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); } else { - Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId); - if (parent.Path == string.Empty) - { - _page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path); - } - else - { - _page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); - } + _page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path); } - _page.Path += parameters; - } - else - { - _page.Path = _path; } var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId); @@ -658,14 +647,7 @@ } else { - if (!_page.Path.Contains("://")) - { - NavigationManager.NavigateTo(NavigateUrl(), true); // redirect to page being edited - } - else - { - NavigationManager.NavigateTo(NavigateUrl("admin/pages")); - } + NavigationManager.NavigateTo(NavigateUrl(), true); // redirect to page being edited } } else diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor index 7063a0844..eb3cb2830 100644 --- a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor +++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor @@ -26,6 +26,12 @@ +
+ +
+ +
+
@@ -62,12 +68,6 @@
-
- -
- -
-
@@ -165,13 +165,13 @@ private string _version = string.Empty; private string _clrversion = string.Empty; private string _osversion = string.Empty; - private string _machinename = string.Empty; + private string _process = string.Empty; + private string _machinename = string.Empty; private string _ipaddress = string.Empty; private string _environment = string.Empty; private string _contentrootpath = string.Empty; private string _webrootpath = string.Empty; private string _servertime = string.Empty; - private string _tickcount = string.Empty; private string _workingset = string.Empty; private string _installationid = string.Empty; @@ -192,13 +192,13 @@ { _clrversion = systeminfo["CLRVersion"].ToString(); _osversion = systeminfo["OSVersion"].ToString(); - _machinename = systeminfo["MachineName"].ToString(); + _process = systeminfo["Process"].ToString(); + _machinename = systeminfo["MachineName"].ToString(); _ipaddress = systeminfo["IPAddress"].ToString(); _environment = systeminfo["Environment"].ToString(); _contentrootpath = systeminfo["ContentRootPath"].ToString(); _webrootpath = systeminfo["WebRootPath"].ToString(); _servertime = systeminfo["ServerTime"].ToString() + " UTC"; - _tickcount = TimeSpan.FromMilliseconds(Convert.ToInt64(systeminfo["TickCount"].ToString())).ToString(); _workingset = (Convert.ToInt64(systeminfo["WorkingSet"].ToString()) / 1000000).ToString() + " MB"; } diff --git a/Oqtane.Client/Modules/Controls/ActionDialog.razor b/Oqtane.Client/Modules/Controls/ActionDialog.razor index f21d5a647..1125d7b07 100644 --- a/Oqtane.Client/Modules/Controls/ActionDialog.razor +++ b/Oqtane.Client/Modules/Controls/ActionDialog.razor @@ -54,7 +54,7 @@ else @@ -65,12 +65,12 @@ else @if (!string.IsNullOrEmpty(Action)) {
- +
}
- +
@@ -88,7 +88,7 @@ else else {
- +
} diff --git a/Oqtane.Client/Modules/Controls/ActionLink.razor b/Oqtane.Client/Modules/Controls/ActionLink.razor index 45b1e7848..9517e275b 100644 --- a/Oqtane.Client/Modules/Controls/ActionLink.razor +++ b/Oqtane.Client/Modules/Controls/ActionLink.razor @@ -99,7 +99,7 @@ if (!string.IsNullOrEmpty(Text)) { - _text = Localize(nameof(Text), _text); + _text = Localize(nameof(Text), Text); } else { diff --git a/Oqtane.Client/Modules/Controls/ModuleMessage.razor b/Oqtane.Client/Modules/Controls/ModuleMessage.razor index 7771a7a94..d8155b3d8 100644 --- a/Oqtane.Client/Modules/Controls/ModuleMessage.razor +++ b/Oqtane.Client/Modules/Controls/ModuleMessage.razor @@ -13,7 +13,7 @@ View Details }
- +
} diff --git a/Oqtane.Client/Modules/Controls/Pager.razor b/Oqtane.Client/Modules/Controls/Pager.razor index fd593c737..a37166ec0 100644 --- a/Oqtane.Client/Modules/Controls/Pager.razor +++ b/Oqtane.Client/Modules/Controls/Pager.razor @@ -73,7 +73,7 @@ @if (!string.IsNullOrEmpty(SearchProperties)) {
- +
diff --git a/Oqtane.Client/Modules/Controls/RichTextEditor.razor b/Oqtane.Client/Modules/Controls/RichTextEditor.razor index b99032a4d..ad237acbf 100644 --- a/Oqtane.Client/Modules/Controls/RichTextEditor.razor +++ b/Oqtane.Client/Modules/Controls/RichTextEditor.razor @@ -63,8 +63,7 @@ }
-
-
+
@@ -91,11 +90,11 @@ @if (ReadOnly) { - + } else { - + } } @@ -104,17 +103,25 @@ @code { + private bool _initialized = false; + + private RichTextEditorInterop interop; + private FileManager _fileManager; + private string _activetab = "Rich"; + private ElementReference _editorElement; private ElementReference _toolBar; private bool _richfilemanager = false; - private FileManager _fileManager; private string _richhtml = string.Empty; private string _originalrichhtml = string.Empty; + private bool _rawfilemanager = false; + private string _rawhtmlid = "RawHtmlEditor_" + Guid.NewGuid().ToString("N"); private string _rawhtml = string.Empty; private string _originalrawhtml = string.Empty; + private string _message = string.Empty; - private string _activetab = "Rich"; + private bool _contentchanged = false; [Parameter] public string Content { get; set; } @@ -123,7 +130,7 @@ public bool ReadOnly { get; set; } = false; [Parameter] - public string Placeholder { get; set; } = "Enter Your Content..."; + public string Placeholder { get; set; } [Parameter] public bool AllowFileManagement { get; set; } = true; @@ -146,20 +153,29 @@ public override List Resources => new List() { - new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill.min.js" }, - new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" }, - new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" } + new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill.min.js", Location = ResourceLocation.Body }, + new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js", Location = ResourceLocation.Body }, + new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js", Location = ResourceLocation.Body } }; + protected override void OnInitialized() + { + interop = new RichTextEditorInterop(JSRuntime); + if (string.IsNullOrEmpty(Placeholder)) + { + Placeholder = Localizer["Placeholder"]; + } + } + protected override void OnParametersSet() { _richhtml = Content; _rawhtml = Content; _originalrawhtml = _rawhtml; // preserve for comparison later _originalrichhtml = ""; + _contentchanged = true; // identifies when Content parameter has changed - // Quill wraps content in

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.0 Exe Debug;Release - 5.1.0 + 5.1.1 Oqtane Shaun Walker .NET Foundation @@ -12,7 +12,7 @@ .NET Foundation https://www.oqtane.org https://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.1 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -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.1 Oqtane Shaun Walker .NET Foundation @@ -14,7 +14,7 @@ .NET Foundation https://www.oqtane.org https://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.1 https://github.com/oqtane/oqtane.framework Git Oqtane.Maui @@ -31,7 +31,7 @@ 0E29FC31-1B83-48ED-B6E0-9F3C67B775D4 - 5.1.0 + 5.1.1 1 14.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.1 Shaun Walker .NET Foundation Oqtane Framework @@ -12,7 +12,7 @@ false MIT https://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.1 icon.png oqtane 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.1 Shaun Walker .NET Foundation Oqtane Framework @@ -11,8 +11,8 @@ .NET Foundation false MIT - 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.1 icon.png oqtane 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.1 Shaun Walker .NET Foundation Oqtane Framework @@ -12,7 +12,7 @@ false MIT https://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.1 icon.png oqtane 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.1 Shaun Walker .NET Foundation Oqtane Framework @@ -12,7 +12,7 @@ false MIT https://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.1 icon.png oqtane 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.1 Shaun Walker .NET Foundation Oqtane Framework @@ -12,7 +12,7 @@ false MIT https://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.1 icon.png oqtane 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.0 Debug;Release - 5.1.0 + 5.1.1 Oqtane Shaun Walker .NET Foundation @@ -11,7 +11,7 @@ .NET Foundation https://www.oqtane.org https://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.1 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -33,19 +33,19 @@ - - + + - - + + all runtime; 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.0 false + 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.0 false + 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.0 Debug;Release - 5.1.0 + 5.1.1 Oqtane Shaun Walker .NET Foundation @@ -11,7 +11,7 @@ .NET Foundation https://www.oqtane.org https://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.1 https://github.com/oqtane/oqtane.framework Git Oqtane @@ -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.0 Exe - 5.1.0 + 5.1.1 Oqtane Shaun Walker .NET Foundation @@ -11,7 +11,7 @@ .NET Foundation https://www.oqtane.org https://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.1 https://github.com/oqtane/oqtane.framework Git Oqtane 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