Merge branch 'oqtane:dev' into dev
This commit is contained in:
@ -14,10 +14,16 @@
|
||||
@if (_containers != null)
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="module" HelpText="The name of the module" ResourceKey="Module">Module: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="module" type="text" class="form-control" @bind="@_module" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="title" type="text" name="Title" class="form-control" @bind="@_title" required />
|
||||
<input id="title" type="text" class="form-control" @bind="@_title" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
@ -104,6 +110,7 @@
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _module;
|
||||
private string _title;
|
||||
private string _containerType;
|
||||
private string _allPages = "false";
|
||||
@ -125,6 +132,7 @@
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_module = ModuleState.ModuleDefinition.Name;
|
||||
_title = ModuleState.Title;
|
||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||
_containerType = ModuleState.ContainerType;
|
||||
|
@ -144,6 +144,11 @@ else
|
||||
<TabPanel Name="Notifications" ResourceKey="Notifications">
|
||||
@if (notifications != null)
|
||||
{
|
||||
<select class="form-select" @onchange="(e => FilterChanged(e))">
|
||||
<option value="to">@Localizer["Inbox"]</option>
|
||||
<option value="from">@Localizer["Items.Sent"]</option>
|
||||
</select>
|
||||
<br />
|
||||
<ActionLink Action="Add" Text="Send Notification" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="SendNotification" />
|
||||
<br /><br />
|
||||
@if (filter == "to")
|
||||
@ -159,22 +164,41 @@ else
|
||||
<Row>
|
||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
||||
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
|
||||
<td>@context.FromDisplayName</td>
|
||||
<td>@context.Subject</td>
|
||||
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
|
||||
|
||||
@if (context.IsRead)
|
||||
{
|
||||
<td>@context.FromDisplayName</td>
|
||||
<td>@context.Subject</td>
|
||||
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td><b>@context.FromDisplayName</b></td>
|
||||
<td><b>@context.Subject</b></td>
|
||||
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
|
||||
}
|
||||
</Row>
|
||||
<Detail>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">
|
||||
@{
|
||||
string input = "___";
|
||||
if (context.Body.Contains(input))
|
||||
{
|
||||
context.Body = context.Body.Split(input)[0];
|
||||
context.Body = context.Body.Replace("\n", "");
|
||||
context.Body = context.Body.Replace("\r", "");
|
||||
} }
|
||||
@(context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body)
|
||||
string input = "___";
|
||||
if (context.Body.Contains(input))
|
||||
{
|
||||
context.Body = context.Body.Split(input)[0];
|
||||
context.Body = context.Body.Replace("\n", "");
|
||||
context.Body = context.Body.Replace("\r", "");
|
||||
}
|
||||
notificationSummary = context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body;
|
||||
}
|
||||
@if (context.IsRead)
|
||||
{
|
||||
@notificationSummary
|
||||
}
|
||||
else
|
||||
{
|
||||
<b>@notificationSummary</b>
|
||||
}
|
||||
</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
@ -192,22 +216,42 @@ else
|
||||
<Row>
|
||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
||||
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
|
||||
<td>@context.ToDisplayName</td>
|
||||
<td>@context.Subject</td>
|
||||
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
|
||||
|
||||
@if (context.IsRead)
|
||||
{
|
||||
<td>@context.ToDisplayName</td>
|
||||
<td>@context.Subject</td>
|
||||
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td><b>@context.ToDisplayName</b></td>
|
||||
<td><b>@context.Subject</b></td>
|
||||
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
|
||||
}
|
||||
|
||||
</Row>
|
||||
<Detail>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">
|
||||
@{
|
||||
string input = "___";
|
||||
if (context.Body.Contains(input))
|
||||
{
|
||||
context.Body = context.Body.Split(input)[0];
|
||||
context.Body = context.Body.Replace("\n", "");
|
||||
context.Body = context.Body.Replace("\r", "");
|
||||
} }
|
||||
@(context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body)
|
||||
string input = "___";
|
||||
if (context.Body.Contains(input))
|
||||
{
|
||||
context.Body = context.Body.Split(input)[0];
|
||||
context.Body = context.Body.Replace("\n", "");
|
||||
context.Body = context.Body.Replace("\r", "");
|
||||
}
|
||||
notificationSummary = context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body;
|
||||
}
|
||||
@if (context.IsRead)
|
||||
{
|
||||
@notificationSummary
|
||||
}
|
||||
else
|
||||
{
|
||||
<b>@notificationSummary</b>
|
||||
}
|
||||
</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
@ -217,11 +261,6 @@ else
|
||||
<br />
|
||||
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
|
||||
}
|
||||
<br /><hr />
|
||||
<select class="form-select" @onchange="(e => FilterChanged(e))">
|
||||
<option value="to">@Localizer["Inbox"]</option>
|
||||
<option value="from">@Localizer["Items.Sent"]</option>
|
||||
</select>
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
@ -246,6 +285,7 @@ else
|
||||
private string category = string.Empty;
|
||||
private string filter = "to";
|
||||
private List<Notification> notifications;
|
||||
private string notificationSummary = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||
|
||||
|
@ -118,6 +118,9 @@
|
||||
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
|
||||
if (notification != null)
|
||||
{
|
||||
notification.IsRead = true;
|
||||
notification = await NotificationService.UpdateNotificationAsync(notification);
|
||||
|
||||
int userid = -1;
|
||||
if (notification.ToUserId == PageState.User.UserId)
|
||||
{
|
||||
|
@ -219,7 +219,14 @@
|
||||
if (folder != null)
|
||||
{
|
||||
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, folder.PermissionList);
|
||||
_files = await FileService.GetFilesAsync(FolderId);
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Browse, folder.PermissionList))
|
||||
{
|
||||
_files = await FileService.GetFilesAsync(FolderId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_files = new List<File>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -322,27 +329,29 @@
|
||||
var folder = (Folder == Constants.PackagesFolder) ? Folder : FolderId.ToString();
|
||||
await interop.UploadFiles(posturl, folder, _guid, SiteState.AntiForgeryToken);
|
||||
|
||||
// uploading is asynchronous so we need to wait for the uploads to complete
|
||||
// note that this will only wait a maximum of 15 seconds which may not be long enough for very large file uploads
|
||||
bool success = false;
|
||||
int attempts = 0;
|
||||
while (attempts < 5 && !success)
|
||||
// uploading is asynchronous so we need to poll to determine if uploads are completed
|
||||
var success = true;
|
||||
int upload = 0;
|
||||
while (upload < uploads.Length && success)
|
||||
{
|
||||
attempts += 1;
|
||||
Thread.Sleep(1000 * attempts); // progressive retry
|
||||
|
||||
success = true;
|
||||
List<File> files = await FileService.GetFilesAsync(folder);
|
||||
if (files.Count > 0)
|
||||
success = false;
|
||||
// note that progressive retry will only wait a maximum of 15 seconds which may not be long enough for very large file uploads
|
||||
int attempts = 0;
|
||||
while (attempts < 5 && !success)
|
||||
{
|
||||
foreach (string upload in uploads)
|
||||
attempts += 1;
|
||||
Thread.Sleep(1000 * attempts); // progressive retry
|
||||
|
||||
var file = await FileService.GetFileAsync(int.Parse(folder), uploads[upload]);
|
||||
if (file != null)
|
||||
{
|
||||
if (!files.Exists(item => item.Name == upload))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
upload++;
|
||||
}
|
||||
}
|
||||
|
||||
// reset progress indicators
|
||||
@ -372,14 +381,14 @@
|
||||
else
|
||||
{
|
||||
// set FileId to first file in upload collection
|
||||
await GetFiles();
|
||||
var file = _files.Where(item => item.Name == uploads[0]).FirstOrDefault();
|
||||
var file = await FileService.GetFileAsync(int.Parse(folder), uploads[0]);
|
||||
if (file != null)
|
||||
{
|
||||
FileId = file.FileId;
|
||||
await SetImage();
|
||||
await OnUpload.InvokeAsync(FileId);
|
||||
}
|
||||
await GetFiles();
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,10 @@
|
||||
<hr class="app-rule" />
|
||||
</div>
|
||||
<div class="collapse @_show" id="@Name">
|
||||
@ChildContent
|
||||
@if (ChildContent != null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
</div>
|
||||
|
||||
@code {
|
||||
@ -26,7 +29,7 @@
|
||||
private string _show = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
public RenderFragment ChildContent { get; set; } = null;
|
||||
|
||||
[Parameter]
|
||||
public string Name { get; set; } // required - the name of the section
|
||||
|
@ -9,7 +9,6 @@ using Oqtane.UI;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.JSInterop;
|
||||
using System.Linq;
|
||||
using Oqtane.Themes;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
|
@ -4,7 +4,7 @@
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>4.0.0</Version>
|
||||
<Version>4.0.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/v4.0.0</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
@ -150,4 +150,10 @@
|
||||
<data name="Error.Module.Load" xml:space="preserve">
|
||||
<value>A Problem Was Encountered Loading Module {0}. The Module Is Either Invalid Or Does Not Exist.</value>
|
||||
</data>
|
||||
<data name="Module.HelpText" xml:space="preserve">
|
||||
<value>The name of the module</value>
|
||||
</data>
|
||||
<data name="Module.Text" xml:space="preserve">
|
||||
<value>Module:</value>
|
||||
</data>
|
||||
</root>
|
@ -46,6 +46,11 @@ namespace Oqtane.Services
|
||||
return await GetJsonAsync<File>($"{Apiurl}/{fileId}");
|
||||
}
|
||||
|
||||
public async Task<File> GetFileAsync(int folderId, string name)
|
||||
{
|
||||
return await GetJsonAsync<File>($"{Apiurl}/name/{name}/{folderId}");
|
||||
}
|
||||
|
||||
public async Task<File> AddFileAsync(File file)
|
||||
{
|
||||
return await PostJsonAsync<File>(Apiurl, file);
|
||||
|
@ -1,5 +1,6 @@
|
||||
using Oqtane.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Services
|
||||
@ -33,6 +34,15 @@ namespace Oqtane.Services
|
||||
/// <returns></returns>
|
||||
Task<File> GetFileAsync(int fileId);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="File"/> based on the <see cref="Folder"/> and file name.
|
||||
/// </summary>
|
||||
/// <param name="folderId">Reference to the <see cref="Folder"/></param>
|
||||
/// <param name="name">name of the file
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
Task<File> GetFileAsync(int folderId, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Add / store a <see cref="File"/> record.
|
||||
/// This does not contain the file contents.
|
||||
|
@ -18,6 +18,27 @@ namespace Oqtane.Services
|
||||
/// <returns></returns>
|
||||
Task<List<Notification>> GetNotificationsAsync(int siteId, string direction, int userId);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="direction"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="count"></param>
|
||||
/// <param name="isRead"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<Notification>> GetNotificationsAsync(int siteId, string direction, int userId, int count, bool isRead);
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="siteId"></param>
|
||||
/// <param name="direction"></param>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="isRead"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> GetNotificationCountAsync(int siteId, string direction, int userId, bool isRead);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a specific notifications
|
||||
/// </summary>
|
||||
|
@ -27,6 +27,17 @@ namespace Oqtane.Services
|
||||
/// <returns></returns>
|
||||
Task<List<Package>> GetPackagesAsync(string type, string search, string price, string package);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of packages matching the given parameters
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="search"></param>
|
||||
/// <param name="price"></param>
|
||||
/// <param name="package"></param>
|
||||
/// <param name="sort"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<Package>> GetPackagesAsync(string type, string search, string price, string package, string sort);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a specific package
|
||||
/// </summary>
|
||||
|
@ -22,6 +22,20 @@ namespace Oqtane.Services
|
||||
return notifications.OrderByDescending(item => item.CreatedOn).ToList();
|
||||
}
|
||||
|
||||
public async Task<List<Notification>> GetNotificationsAsync(int siteId, string direction, int userId, int count, bool isRead)
|
||||
{
|
||||
var notifications = await GetJsonAsync<List<Notification>>($"{Apiurl}/read?siteid={siteId}&direction={direction.ToLower()}&userid={userId}&count={count}&isread={isRead}");
|
||||
|
||||
return notifications.OrderByDescending(item => item.CreatedOn).ToList();
|
||||
}
|
||||
|
||||
public async Task<int> GetNotificationCountAsync(int siteId, string direction, int userId, bool isRead)
|
||||
{
|
||||
var notificationCount = await GetJsonAsync<int>($"{Apiurl}/read-count?siteid={siteId}&direction={direction.ToLower()}&userid={userId}&isread={isRead}");
|
||||
|
||||
return notificationCount;
|
||||
}
|
||||
|
||||
public async Task<Notification> GetNotificationAsync(int notificationId)
|
||||
{
|
||||
return await GetJsonAsync<Notification>($"{Apiurl}/{notificationId}");
|
||||
|
@ -23,7 +23,12 @@ namespace Oqtane.Services
|
||||
|
||||
public async Task<List<Package>> GetPackagesAsync(string type, string search, string price, string package)
|
||||
{
|
||||
return await GetJsonAsync<List<Package>>($"{Apiurl}?type={type}&search={WebUtility.UrlEncode(search)}&price={price}&package={package}");
|
||||
return await GetPackagesAsync(type, search, price, package, "");
|
||||
}
|
||||
|
||||
public async Task<List<Package>> GetPackagesAsync(string type, string search, string price, string package, string sort)
|
||||
{
|
||||
return await GetJsonAsync<List<Package>>($"{Apiurl}?type={type}&search={WebUtility.UrlEncode(search)}&price={price}&package={package}&sort={sort}");
|
||||
}
|
||||
|
||||
public async Task<Package> GetPackageAsync(string packageId, string version)
|
||||
|
@ -21,7 +21,7 @@ namespace Oqtane.Services
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private HttpClient GetHttpClient()
|
||||
public HttpClient GetHttpClient()
|
||||
{
|
||||
if (!_httpClient.DefaultRequestHeaders.Contains(Constants.AntiForgeryTokenHeaderName) && _siteState != null && !string.IsNullOrEmpty(_siteState.AntiForgeryToken))
|
||||
{
|
||||
@ -206,7 +206,6 @@ namespace Oqtane.Services
|
||||
Console.WriteLine($"Request: {response.RequestMessage.RequestUri}");
|
||||
Console.WriteLine($"Response status: {response.StatusCode} {response.ReasonPhrase}");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
@if (_canViewAdminDashboard || UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel">
|
||||
<button type="button" class="btn @ButtonClass ms-1" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel">
|
||||
<span class="oi oi-cog"></span>
|
||||
</button>
|
||||
|
||||
@ -471,6 +471,12 @@
|
||||
|
||||
private async Task ToggleEditMode(bool EditMode)
|
||||
{
|
||||
Page page = null;
|
||||
if (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered))
|
||||
{
|
||||
page = await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
||||
}
|
||||
|
||||
if (_showEditMode)
|
||||
{
|
||||
if (EditMode)
|
||||
@ -490,9 +496,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PageState.Page.IsPersonalizable && PageState.User != null)
|
||||
if (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered))
|
||||
{
|
||||
var page = await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
||||
PageState.EditMode = true;
|
||||
NavigationManager.NavigateTo(NavigateUrl(page.Path, "edit=" + ((PageState.EditMode) ? "true" : "false")));
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ namespace Oqtane.Themes.Controls
|
||||
[Inject] public IUserService UserService { get; set; }
|
||||
[Inject] public IJSRuntime jsRuntime { get; set; }
|
||||
[Inject] public IServiceProvider ServiceProvider { get; set; }
|
||||
[Inject] public ILogService LoggingService { get; set; }
|
||||
|
||||
protected void LoginUser()
|
||||
{
|
||||
|
@ -1,6 +1,9 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Services;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.UI;
|
||||
using System;
|
||||
@ -13,6 +16,9 @@ namespace Oqtane.Themes
|
||||
{
|
||||
public abstract class ThemeBase : ComponentBase, IThemeControl
|
||||
{
|
||||
[Inject]
|
||||
protected ILogService LoggingService { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
@ -186,6 +192,148 @@ namespace Oqtane.Themes
|
||||
await interop.ScrollTo(0, 0, "smooth");
|
||||
}
|
||||
|
||||
// logging methods
|
||||
public async Task Log(Alias alias, LogLevel level, string function, Exception exception, string message, params object[] args)
|
||||
{
|
||||
LogFunction logFunction;
|
||||
if (string.IsNullOrEmpty(function))
|
||||
{
|
||||
// try to infer from page action
|
||||
function = PageState.Action;
|
||||
}
|
||||
if (!Enum.TryParse(function, out logFunction))
|
||||
{
|
||||
switch (function.ToLower())
|
||||
{
|
||||
case "add":
|
||||
logFunction = LogFunction.Create;
|
||||
break;
|
||||
case "edit":
|
||||
logFunction = LogFunction.Update;
|
||||
break;
|
||||
case "delete":
|
||||
logFunction = LogFunction.Delete;
|
||||
break;
|
||||
case "":
|
||||
logFunction = LogFunction.Read;
|
||||
break;
|
||||
default:
|
||||
logFunction = LogFunction.Other;
|
||||
break;
|
||||
}
|
||||
}
|
||||
await Log(alias, level, logFunction, exception, message, args);
|
||||
}
|
||||
|
||||
public async Task Log(Alias alias, LogLevel level, LogFunction function, Exception exception, string message, params object[] args)
|
||||
{
|
||||
int pageId = PageState.Page.PageId;
|
||||
string category = GetType().AssemblyQualifiedName;
|
||||
string feature = Utilities.GetTypeNameLastSegment(category, 1);
|
||||
|
||||
await LoggingService.Log(alias, pageId, null, PageState.User?.UserId, category, feature, function, level, exception, message, args);
|
||||
}
|
||||
|
||||
public class Logger
|
||||
{
|
||||
private readonly ModuleBase _moduleBase;
|
||||
|
||||
public Logger(ModuleBase moduleBase)
|
||||
{
|
||||
_moduleBase = moduleBase;
|
||||
}
|
||||
|
||||
public async Task LogTrace(string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Trace, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogTrace(LogFunction function, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Trace, function, null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogTrace(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Trace, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogDebug(string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Debug, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogDebug(LogFunction function, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Debug, function, null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogDebug(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Debug, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogInformation(string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Information, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogInformation(LogFunction function, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Information, function, null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogInformation(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Information, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogWarning(string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Warning, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogWarning(LogFunction function, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Warning, function, null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogWarning(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Warning, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogError(string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Error, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogError(LogFunction function, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Error, function, null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Error, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogCritical(string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Critical, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogCritical(LogFunction function, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Critical, function, null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogCritical(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await _moduleBase.Log(null, LogLevel.Critical, "", exception, message, args);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("ContentUrl(int fileId) is deprecated. Use FileUrl(int fileId) instead.", false)]
|
||||
public string ContentUrl(int fileid)
|
||||
{
|
||||
|
@ -223,12 +223,12 @@
|
||||
}
|
||||
if (page == null)
|
||||
{
|
||||
// look for personalized page
|
||||
page = await PageService.GetPageAsync(route.PagePath, site.SiteId);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (user != null && page.IsPersonalizable)
|
||||
// look for personalized page
|
||||
if (user != null && page.IsPersonalizable && !UserSecurity.IsAuthorized(user, PermissionNames.Edit, page.PermissionList))
|
||||
{
|
||||
var personalized = await PageService.GetPageAsync(route.PagePath + "/" + user.Username, site.SiteId);
|
||||
if (personalized != null)
|
||||
|
Reference in New Issue
Block a user