commit
4479304f3f
26
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
26
.github/ISSUE_TEMPLATE/bug-report.md
vendored
Normal file
@ -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?
|
20
.github/ISSUE_TEMPLATE/enhancement-request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/enhancement-request.md
vendored
Normal file
@ -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?
|
@ -86,47 +86,48 @@ else
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
||||
<ActionDialog Header="Clear Events" Message="Are You Sure You Wish To Remove All Log Events?" Action="DeleteLogs" Class="btn btn-danger" OnClick="@(async () => await DeleteLogs())" ResourceKey="DeleteLogs" />
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _level = "-";
|
||||
private string _function = "-";
|
||||
private string _rows = "10";
|
||||
private int _page = 1;
|
||||
private List<Log> _logs;
|
||||
private int _retention = 30;
|
||||
private string _level = "-";
|
||||
private string _function = "-";
|
||||
private string _rows = "10";
|
||||
private int _page = 1;
|
||||
private List<Log> _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)
|
||||
{
|
||||
|
@ -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 = _name;
|
||||
}
|
||||
|
||||
(_path, string parameters) = Utilities.ParsePath(_path);
|
||||
|
||||
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")
|
||||
{
|
||||
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(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
page.Path += parameters;
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
page.Path = Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.Path = _path;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -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 = _name;
|
||||
}
|
||||
|
||||
(_path, string parameters) = Utilities.ParsePath(_path);
|
||||
|
||||
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")
|
||||
{
|
||||
_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(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
_page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
_page.Path += parameters;
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
_page.Path = Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
_page.Path = _path;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -26,6 +26,12 @@
|
||||
<input id="osversion" class="form-control" @bind="@_osversion" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="process" HelpText="Indicates if the current process is 32 bit or 64 bit" ResourceKey="Process">Process: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="process" class="form-control" @bind="@_process" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="machinename" HelpText="Machine Name" ResourceKey="MachineName">Machine Name: </Label>
|
||||
<div class="col-sm-9">
|
||||
@ -62,12 +68,6 @@
|
||||
<input id="servertime" class="form-control" @bind="@_servertime" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="tickcount" HelpText="Amount Of Time The Service Has Been Available And Operational" ResourceKey="TickCount">Service Uptime: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="tickcount" class="form-control" @bind="@_tickcount" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="workingset" HelpText="Memory Allocation Of Service (in MB)" ResourceKey="WorkingSet">Memory Allocation: </Label>
|
||||
<div class="col-sm-9">
|
||||
@ -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";
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ else
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">@Header</h5>
|
||||
<form method="post" @formname="@($"ActionDialogCloseForm{Id}")" @onsubmit="DisplayModal" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<button type="submit" class="btn-close" aria-label="Close"></button>
|
||||
</form>
|
||||
</div>
|
||||
@ -65,12 +65,12 @@ else
|
||||
@if (!string.IsNullOrEmpty(Action))
|
||||
{
|
||||
<form method="post" @formname="@($"ActionDialogConfirmForm{Id}")" @onsubmit="Confirm" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<button type="submit" class="@Class">@((MarkupString)_iconSpan) @Text</button>
|
||||
</form>
|
||||
}
|
||||
<form method="post" @formname="@($"ActionDialogCancelForm{Id}")" @onsubmit="DisplayModal" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<button type="submit" class="btn btn-secondary">@SharedLocalizer["Cancel"]</button>
|
||||
</form>
|
||||
</div>
|
||||
@ -88,7 +88,7 @@ else
|
||||
else
|
||||
{
|
||||
<form method="post" @formname="@($"ActionDialogActionForm{Id}")" @onsubmit="DisplayModal" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<button type="submit" class="@Class">@((MarkupString)_iconSpan) @Text</button>
|
||||
</form>
|
||||
}
|
||||
|
@ -99,7 +99,7 @@
|
||||
|
||||
if (!string.IsNullOrEmpty(Text))
|
||||
{
|
||||
_text = Localize(nameof(Text), _text);
|
||||
_text = Localize(nameof(Text), Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -13,7 +13,7 @@
|
||||
<NavLink class="ms-2" href="@NavigateUrl("admin/log")">View Details</NavLink>
|
||||
}
|
||||
<form method="post" @onsubmit="DismissModal" @formname="@_formname" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<button type="submit" class="btn-close" aria-label="Close"></button>
|
||||
</form>
|
||||
}
|
||||
|
@ -73,7 +73,7 @@
|
||||
@if (!string.IsNullOrEmpty(SearchProperties))
|
||||
{
|
||||
<form method="post" autocomplete="off" @formname="PagerForm" @onsubmit="Search" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<div class="input-group my-3">
|
||||
<input type="text" id="pagersearch" name="_search" class="form-control" placeholder=@string.Format(Localizer["SearchPlaceholder"], FormatSearchProperties()) @bind="@_search" />
|
||||
<button type="submit" class="btn btn-primary">@SharedLocalizer["Search"]</button>
|
||||
|
@ -63,8 +63,7 @@
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<div @ref="@_editorElement">
|
||||
</div>
|
||||
<div @ref="@_editorElement"></div>
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
@ -91,11 +90,11 @@
|
||||
</div>
|
||||
@if (ReadOnly)
|
||||
{
|
||||
<textarea id="rawhtmleditor" class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10" readonly></textarea>
|
||||
<textarea id="@_rawhtmlid" class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10" readonly></textarea>
|
||||
}
|
||||
else
|
||||
{
|
||||
<textarea id="rawhtmleditor" class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10"></textarea>
|
||||
<textarea id="@_rawhtmlid" class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10"></textarea>
|
||||
}
|
||||
</TabPanel>
|
||||
}
|
||||
@ -104,17 +103,25 @@
|
||||
</div>
|
||||
|
||||
@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<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
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 <p> tags which can be used as a signal to set the active tab
|
||||
if (!string.IsNullOrEmpty(Content) && !Content.StartsWith("<p>") && 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 == "<p><br></p>")
|
||||
{
|
||||
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 = "<img src=\"" + file.Url + "\" alt=\"" + ((!string.IsNullOrEmpty(file.Description)) ? file.Description : file.Name) + "\" class=\"img-fluid\">";
|
||||
_rawhtml = _rawhtml.Substring(0, pos) + image + _rawhtml.Substring(pos);
|
||||
_rawfilemanager = false;
|
||||
|
@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -12,7 +12,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
@ -22,9 +22,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -153,7 +153,7 @@
|
||||
<data name="Integrated" xml:space="preserve">
|
||||
<value>Integrated</value>
|
||||
</data>
|
||||
<data name="Encryption,Text" xml:space="preserve">
|
||||
<data name="Encryption.Text" xml:space="preserve">
|
||||
<value>Encryption:</value>
|
||||
</data>
|
||||
<data name="Encryption.HelpText" xml:space="preserve">
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -210,4 +210,16 @@
|
||||
<data name="Success.SaveSiteSettings" xml:space="preserve">
|
||||
<value>Settings Saved Successfully</value>
|
||||
</data>
|
||||
<data name="DeleteLogs.Header" xml:space="preserve">
|
||||
<value>Clear Events</value>
|
||||
</data>
|
||||
<data name="DeleteLogs.Message" xml:space="preserve">
|
||||
<value>Are You Sure You Wish To Remove All Log Events?</value>
|
||||
</data>
|
||||
<data name="DeleteLogs.Text" xml:space="preserve">
|
||||
<value>Clear Events</value>
|
||||
</data>
|
||||
<data name="Error.DeleteLogs" xml:space="preserve">
|
||||
<value>Error Deleting Log Events</value>
|
||||
</data>
|
||||
</root>
|
@ -255,12 +255,6 @@
|
||||
<data name="MachineName.Text" xml:space="preserve">
|
||||
<value>Machine Name:</value>
|
||||
</data>
|
||||
<data name="TickCount.HelpText" xml:space="preserve">
|
||||
<value>Amount Of Time The Service Has Been Available And Operational</value>
|
||||
</data>
|
||||
<data name="TickCount.Text" xml:space="preserve">
|
||||
<value>Service Uptime:</value>
|
||||
</data>
|
||||
<data name="WebRootPath.HelpText" xml:space="preserve">
|
||||
<value>Server Web Root Path</value>
|
||||
</data>
|
||||
@ -294,4 +288,10 @@
|
||||
<data name="Error.ClearLog" xml:space="preserve">
|
||||
<value>Ann Error Occurred Clearing The System Log</value>
|
||||
</data>
|
||||
<data name="Process.HelpText" xml:space="preserve">
|
||||
<value>Indicates if the current process is 32 bit or 64 bit</value>
|
||||
</data>
|
||||
<data name="Process.Text" xml:space="preserve">
|
||||
<value>Process: </value>
|
||||
</data>
|
||||
</root>
|
@ -126,4 +126,7 @@
|
||||
<data name="Message.Require.Image" xml:space="preserve">
|
||||
<value>You Must Select An Image To Insert</value>
|
||||
</data>
|
||||
<data name="Placeholder" xml:space="preserve">
|
||||
<value>Enter Your Content...</value>
|
||||
</data>
|
||||
</root>
|
@ -29,6 +29,13 @@ namespace Oqtane.Services
|
||||
/// <returns></returns>
|
||||
Task<Log> GetLogAsync(int logId);
|
||||
|
||||
/// <summary>
|
||||
/// Clear the entire logs of the given site.
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <returns></returns>
|
||||
Task DeleteLogsAsync(int siteId);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new log entry
|
||||
/// </summary>
|
||||
|
@ -35,6 +35,11 @@ namespace Oqtane.Services
|
||||
return await GetJsonAsync<Log>($"{Apiurl}/{logId}");
|
||||
}
|
||||
|
||||
public async Task DeleteLogsAsync(int siteId)
|
||||
{
|
||||
await DeleteAsync($"{Apiurl}?siteid={siteId}");
|
||||
}
|
||||
|
||||
public async Task Log(int? pageId, int? moduleId, int? userId, string category, string feature, LogFunction function, LogLevel level, Exception exception, string message, params object[] args)
|
||||
{
|
||||
await Log(null, pageId, moduleId, userId, category, feature, function, level, exception, message, args);
|
||||
|
@ -33,7 +33,7 @@ namespace Oqtane.Services
|
||||
|
||||
public async Task<Profile> UpdateProfileAsync(Profile profile)
|
||||
{
|
||||
return await PutJsonAsync<Profile>($"{Apiurl}/{profile.SiteId}", profile);
|
||||
return await PutJsonAsync<Profile>($"{Apiurl}/{profile.ProfileId}", profile);
|
||||
}
|
||||
public async Task DeleteProfileAsync(int profileId)
|
||||
{
|
||||
|
@ -9,7 +9,7 @@
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><ModuleTitle /></h5>
|
||||
<form method="post" class="app-form-inline" @formname="AdminContainerForm" @onsubmit="@CloseModal" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<button type="submit" class="btn-close" aria-label="Close"></button>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@
|
||||
@if (_showEditMode || (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered)))
|
||||
{
|
||||
<form method="post" class="app-form-inline" @formname="EditModeForm" @onsubmit="@(async () => await ToggleEditMode(PageState.EditMode))" data-enhance>
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
@if (PageState.EditMode)
|
||||
{
|
||||
<button type="submit" class="btn @ButtonClass active" aria-pressed="true" autocomplete="off">
|
||||
|
@ -16,7 +16,7 @@
|
||||
else
|
||||
{
|
||||
<form method="post" class="app-form-inline" action="@logouturl" @formname="LogoutForm">
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||
<input type="hidden" name="returnurl" value="@returnurl" />
|
||||
<button type="submit" class="btn btn-primary">@Localizer["Logout"]</button>
|
||||
</form>
|
||||
|
@ -121,15 +121,15 @@
|
||||
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);
|
||||
}
|
||||
if (_footer != "-")
|
||||
{
|
||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer, true);
|
||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer);
|
||||
}
|
||||
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
||||
}
|
||||
|
@ -3,8 +3,6 @@
|
||||
@using Oqtane.Shared
|
||||
@inject SiteState SiteState
|
||||
@implements IDisposable
|
||||
@* the following StreamRendering attribute is required - if it is removed the framework will not render the content in static rendering *@
|
||||
@attribute [StreamRendering]
|
||||
|
||||
@if (!string.IsNullOrEmpty(_title))
|
||||
{
|
||||
|
@ -1,13 +1,13 @@
|
||||
@namespace Oqtane.UI
|
||||
@inject SiteState SiteState
|
||||
|
||||
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Interactive)
|
||||
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Static)
|
||||
{
|
||||
<StreamRenderingDisabled ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<StreamRenderingEnabled ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="@InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, PageState.Site.Prerender)" />
|
||||
}
|
||||
|
||||
@code {
|
||||
|
@ -3,8 +3,6 @@
|
||||
@inject IInstallationService InstallationService
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject SiteState SiteState
|
||||
@* the following StreamRendering attribute is required - if it is removed the framework will not render the content in static rendering *@
|
||||
@attribute [StreamRendering]
|
||||
|
||||
@if (_initialized)
|
||||
{
|
||||
|
@ -124,12 +124,20 @@
|
||||
{
|
||||
if (querystring.ContainsKey("reload") && querystring["reload"] == "post")
|
||||
{
|
||||
// post back so that the cookies are set correctly - required on any change to the principal
|
||||
var interop = new Interop(JSRuntime);
|
||||
var fields = new { returnurl = "/" + NavigationManager.ToBaseRelativePath(_absoluteUri) };
|
||||
string url = Utilities.TenantUrl(SiteState.Alias, "/pages/external/");
|
||||
await interop.SubmitForm(url, fields);
|
||||
return;
|
||||
if (PageState.RenderMode == RenderModes.Interactive)
|
||||
{
|
||||
// post back so that the cookies are set correctly - required on any change to the principal
|
||||
var interop = new Interop(JSRuntime);
|
||||
var fields = new { returnurl = "/" + NavigationManager.ToBaseRelativePath(_absoluteUri) };
|
||||
string url = Utilities.TenantUrl(SiteState.Alias, "/pages/external/");
|
||||
await interop.SubmitForm(url, fields);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo(_absoluteUri.Replace("?reload=post", "").Replace("&reload=post", ""), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -163,9 +171,9 @@
|
||||
visitorId = PageState.VisitorId;
|
||||
}
|
||||
|
||||
if (PageState.RenderMode == RenderModes.Interactive)
|
||||
if (PageState != null && PageState.RenderMode == RenderModes.Interactive)
|
||||
{
|
||||
// process any sync events (for synchrozing the client application with the server)
|
||||
// process any sync events (for synchronizing the client application with the server)
|
||||
var sync = await SyncService.GetSyncEventsAsync(lastsyncdate);
|
||||
lastsyncdate = sync.SyncDate;
|
||||
if (sync.SyncEvents.Any())
|
||||
@ -243,105 +251,97 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (page != null)
|
||||
// check if user is authorized to view page
|
||||
if (page != null && UserSecurity.IsAuthorized(user, PermissionNames.View, page.PermissionList) && (Utilities.IsPageModuleVisible(page.EffectiveDate, page.ExpiryDate) || UserSecurity.IsAuthorized(user, PermissionNames.Edit, page.PermissionList)))
|
||||
{
|
||||
// check if user is authorized to view page
|
||||
if (UserSecurity.IsAuthorized(user, PermissionNames.View, page.PermissionList) && (Utilities.IsPageModuleVisible(page.EffectiveDate, page.ExpiryDate) || UserSecurity.IsAuthorized(user, PermissionNames.Edit, page.PermissionList)))
|
||||
// edit mode
|
||||
if (user != null)
|
||||
{
|
||||
// edit mode
|
||||
if (user != null)
|
||||
if (querystring.ContainsKey("editmode") && querystring["edit"] == "true")
|
||||
{
|
||||
if (querystring.ContainsKey("editmode") && querystring["edit"] == "true")
|
||||
editmode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
editmode = (page.PageId == ((user.Settings.ContainsKey("CP-editmode")) ? int.Parse(user.Settings["CP-editmode"]) : -1));
|
||||
if (!editmode)
|
||||
{
|
||||
editmode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
editmode = (page.PageId == ((user.Settings.ContainsKey("CP-editmode")) ? int.Parse(user.Settings["CP-editmode"]) : -1));
|
||||
if (!editmode)
|
||||
{
|
||||
var userSettings = new Dictionary<string, string> { { "CP-editmode", "-1" } };
|
||||
await SettingService.UpdateUserSettingsAsync(userSettings, user.UserId);
|
||||
}
|
||||
var userSettings = new Dictionary<string, string> { { "CP-editmode", "-1" } };
|
||||
await SettingService.UpdateUserSettingsAsync(userSettings, user.UserId);
|
||||
}
|
||||
}
|
||||
|
||||
// load additional metadata for current page
|
||||
page = ProcessPage(page, site, user, SiteState.Alias);
|
||||
}
|
||||
|
||||
// load additional metadata for modules
|
||||
(page, site.Modules) = ProcessModules(page, site.Modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType, SiteState.Alias);
|
||||
// load additional metadata for current page
|
||||
page = ProcessPage(page, site, user, SiteState.Alias);
|
||||
|
||||
// populate page state (which acts as a client-side cache for subsequent requests)
|
||||
_pagestate = new PageState
|
||||
// load additional metadata for modules
|
||||
(page, site.Modules) = ProcessModules(page, site.Modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType, SiteState.Alias);
|
||||
|
||||
// populate page state (which acts as a client-side cache for subsequent requests)
|
||||
_pagestate = new PageState
|
||||
{
|
||||
Alias = SiteState.Alias,
|
||||
Site = site,
|
||||
Page = page,
|
||||
User = user,
|
||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||
Route = route,
|
||||
QueryString = querystring,
|
||||
UrlParameters = route.UrlParameters,
|
||||
ModuleId = moduleid,
|
||||
Action = action,
|
||||
EditMode = editmode,
|
||||
LastSyncDate = lastsyncdate,
|
||||
RenderMode = RenderMode,
|
||||
Runtime = (Shared.Runtime)Enum.Parse(typeof(Shared.Runtime), Runtime),
|
||||
VisitorId = visitorId,
|
||||
RemoteIPAddress = SiteState.RemoteIPAddress,
|
||||
ReturnUrl = returnurl,
|
||||
IsInternalNavigation = _isInternalNavigation,
|
||||
RenderId = Guid.NewGuid(),
|
||||
Refresh = false
|
||||
};
|
||||
OnStateChange?.Invoke(_pagestate);
|
||||
|
||||
if (PageState.RenderMode == RenderModes.Interactive)
|
||||
{
|
||||
await ScrollToFragment(_pagestate.Uri);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (page == null)
|
||||
{
|
||||
// check for url mapping
|
||||
var urlMapping = await UrlMappingService.GetUrlMappingAsync(site.SiteId, route.PagePath);
|
||||
if (urlMapping != null && !string.IsNullOrEmpty(urlMapping.MappedUrl))
|
||||
{
|
||||
Alias = SiteState.Alias,
|
||||
Site = site,
|
||||
Page = page,
|
||||
User = user,
|
||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||
Route = route,
|
||||
QueryString = querystring,
|
||||
UrlParameters = route.UrlParameters,
|
||||
ModuleId = moduleid,
|
||||
Action = action,
|
||||
EditMode = editmode,
|
||||
LastSyncDate = lastsyncdate,
|
||||
RenderMode = RenderMode,
|
||||
Runtime = (Shared.Runtime)Enum.Parse(typeof(Shared.Runtime), Runtime),
|
||||
VisitorId = visitorId,
|
||||
RemoteIPAddress = SiteState.RemoteIPAddress,
|
||||
ReturnUrl = returnurl,
|
||||
IsInternalNavigation = _isInternalNavigation,
|
||||
RenderId = Guid.NewGuid(),
|
||||
Refresh = false
|
||||
};
|
||||
OnStateChange?.Invoke(_pagestate);
|
||||
|
||||
if (PageState.RenderMode == RenderModes.Interactive)
|
||||
{
|
||||
await ScrollToFragment(_pagestate.Uri);
|
||||
var url = (urlMapping.MappedUrl.StartsWith("http")) ? urlMapping.MappedUrl : route.SiteUrl + "/" + urlMapping.MappedUrl + route.Query;
|
||||
NavigationManager.NavigateTo(url, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Need to redirect 404 as page doesnot exist in a Permission or Timeframe
|
||||
if (route.PagePath != "404")
|
||||
{
|
||||
// redirect to 404 page
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "404", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
else // page not found
|
||||
{
|
||||
// look for url mapping
|
||||
var urlMapping = await UrlMappingService.GetUrlMappingAsync(site.SiteId, route.PagePath);
|
||||
if (urlMapping != null && !string.IsNullOrEmpty(urlMapping.MappedUrl))
|
||||
{
|
||||
var url = (urlMapping.MappedUrl.StartsWith("http")) ? urlMapping.MappedUrl : route.SiteUrl + "/" + urlMapping.MappedUrl + route.Query;
|
||||
NavigationManager.NavigateTo(url, false);
|
||||
}
|
||||
else // not mapped
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
// redirect to login page if user not logged in as they may need to be authenticated
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + WebUtility.UrlEncode(route.PathAndQuery)));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (route.PagePath != "404")
|
||||
{
|
||||
// redirect to 404 page
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "404", ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
// redirect to home page as a fallback
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// page not found or user does not have sufficient access
|
||||
if (route.PagePath != "404")
|
||||
{
|
||||
// redirect to 404 page
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "404", ""));
|
||||
}
|
||||
else
|
||||
{
|
||||
// redirect to home page as a fallback
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
@attribute [StreamRendering(false)]
|
||||
|
||||
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Static)
|
||||
{
|
||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="@InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, PageState.Site.Prerender)" />
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public SiteState SiteState { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public PageState PageState { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Module ModuleState { get; set; }
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
@attribute [StreamRendering(true)]
|
||||
|
||||
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Static)
|
||||
{
|
||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="@InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, PageState.Site.Prerender)" />
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public SiteState SiteState { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public PageState PageState { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public Module ModuleState { get; set; }
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -10,7 +10,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -10,7 +10,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.4" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -10,7 +10,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -33,7 +33,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -10,7 +10,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -33,7 +33,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<!-- <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks> -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -14,7 +14,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane.Maui</RootNamespace>
|
||||
@ -31,7 +31,7 @@
|
||||
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>5.1.0</ApplicationDisplayVersion>
|
||||
<ApplicationDisplayVersion>5.1.1</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
||||
@ -65,15 +65,15 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="8.0.10" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="8.0.20" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="8.0.20" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="8.0.20" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>5.1.0</version>
|
||||
<version>5.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>5.1.0</version>
|
||||
<version>5.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -11,8 +11,8 @@
|
||||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v5.1.0/Oqtane.Framework.5.1.0.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</releaseNotes>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v5.1.1/Oqtane.Framework.5.1.1.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane framework</tags>
|
||||
</metadata>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>5.1.0</version>
|
||||
<version>5.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>5.1.0</version>
|
||||
<version>5.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Updater</id>
|
||||
<version>5.1.0</version>
|
||||
<version>5.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
@ -1 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.0.Install.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.1.Install.zip" -Force
|
@ -1 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.0.Upgrade.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.1.1.Upgrade.zip" -Force
|
@ -76,5 +76,20 @@ namespace Oqtane.Controllers
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -365,8 +365,8 @@ namespace Oqtane.Controllers
|
||||
{
|
||||
{ "FrameworkVersion", moduleDefinition.Version },
|
||||
{ "ClientReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{moduleDefinition.Version}\" />" },
|
||||
{ "ServerReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{moduleDefinition.Version}\" />" },
|
||||
{ "SharedReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{moduleDefinition.Version}\" />" },
|
||||
{ "ServerReference", $"<PackageReference Include=\"Oqtane.Server\" Version=\"{moduleDefinition.Version}\" />" },
|
||||
{ "SharedReference", $"<PackageReference Include=\"Oqtane.Shared\" Version=\"{moduleDefinition.Version}\" />" },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ namespace Oqtane.Controllers
|
||||
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());
|
||||
|
@ -157,7 +157,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
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 =>
|
||||
{
|
||||
|
@ -93,6 +93,7 @@ namespace Oqtane.Infrastructure
|
||||
}
|
||||
|
||||
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 @@ namespace Oqtane.Infrastructure
|
||||
result.Append(match.Result("${text}"));
|
||||
}
|
||||
}
|
||||
|
||||
result.Replace("[$_", "["); //restore the changes.
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -11,7 +11,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
@ -33,19 +33,19 @@
|
||||
<EmbeddedResource Include="Scripts\MigrateTenant.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.3">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.3" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.4" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.8" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -47,14 +47,23 @@ namespace Oqtane.Pages
|
||||
var sitemap = new List<Sitemap>();
|
||||
|
||||
// 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))
|
||||
{
|
||||
|
@ -59,14 +59,14 @@ namespace Oqtane.Repository
|
||||
// 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;
|
||||
|
@ -22,6 +22,7 @@ using Oqtane.UI;
|
||||
using OqtaneSSR.Extensions;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Oqtane.Providers;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
|
||||
namespace Oqtane
|
||||
{
|
||||
@ -135,7 +136,7 @@ namespace Oqtane
|
||||
{
|
||||
// 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 @@ 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, ISyncManager sync, ILogger<Startup> logger)
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ISyncManager sync, ICorsService corsService, ICorsPolicyProvider corsPolicyProvider, ILogger<Startup> logger)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_configureServicesErrors))
|
||||
{
|
||||
@ -198,7 +199,16 @@ namespace Oqtane
|
||||
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();
|
||||
|
@ -13,9 +13,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
||||
|
@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<AccelerateBuildsInVisualStudio>false</AccelerateBuildsInVisualStudio>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -19,10 +19,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -12,9 +12,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -3,6 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<AccelerateBuildsInVisualStudio>false</AccelerateBuildsInVisualStudio>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -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 */
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -11,7 +11,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
@ -19,8 +19,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.3" />
|
||||
|
@ -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";
|
||||
|
@ -21,86 +21,50 @@ namespace Oqtane.Shared
|
||||
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 @@ namespace Oqtane.Shared
|
||||
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);
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>5.1.0</Version>
|
||||
<Version>5.1.1</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -11,7 +11,7 @@
|
||||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
10
README.md
10
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.
|
||||
|
||||
[](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
|
||||
|
Loading…
x
Reference in New Issue
Block a user