commit
8b5004c628
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -12,3 +12,4 @@ Oqtane.Server/appsettings.json
|
|||
Oqtane.Server/Data/*.mdf
|
||||
Oqtane.Server/Data/*.ldf
|
||||
|
||||
/Oqtane.Server/Properties/PublishProfiles/FolderProfile.pubxml
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2019 .NET Foundation
|
||||
Copyright (c) 2018-2020 .NET Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
@inject IInstallationService InstallationService
|
||||
|
||||
@if (Initialized)
|
||||
@if (_initialized)
|
||||
{
|
||||
@if (!Installed)
|
||||
@if (!_installed)
|
||||
{
|
||||
<Installer />
|
||||
}
|
||||
|
@ -17,20 +17,21 @@
|
|||
}
|
||||
|
||||
@code {
|
||||
private bool Initialized = false;
|
||||
private bool Installed = false;
|
||||
private bool _initialized;
|
||||
private bool _installed;
|
||||
|
||||
private PageState PageState { get; set; }
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
var response = await InstallationService.IsInstalled();
|
||||
Installed = response.Success;
|
||||
Initialized = true;
|
||||
var installation = await InstallationService.IsInstalled();
|
||||
_installed = installation.Success;
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
private void ChangeState(PageState pagestate)
|
||||
private void ChangeState(PageState pageState)
|
||||
{
|
||||
PageState = pagestate;
|
||||
PageState = pageState;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
@inject IUserService UserService
|
||||
|
||||
<div class="row">
|
||||
@foreach (var p in pages)
|
||||
@foreach (var p in _pages)
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, "View", p.Permissions))
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
string url = NavigateUrl(p.Path);
|
||||
<div class="col-md-2 mx-auto text-center">
|
||||
|
@ -19,13 +19,13 @@
|
|||
</div>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<Page> _pages;
|
||||
|
||||
List<Page> pages;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Page admin = PageState.Pages.Where(item => item.Path == "admin").FirstOrDefault();
|
||||
pages = PageState.Pages.Where(item => item.ParentId == admin.PageId).ToList();
|
||||
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
||||
_pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList();
|
||||
}
|
||||
}
|
||||
|
|
19
Oqtane.Client/Modules/Admin/Error/Index.razor
Normal file
19
Oqtane.Client/Modules/Admin/Error/Index.razor
Normal file
|
@ -0,0 +1,19 @@
|
|||
@namespace Oqtane.Modules.Admin.Error
|
||||
@inherits ModuleBase
|
||||
@inject IModuleService ModuleService
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId);
|
||||
if (UserSecurity.IsAuthorized(PageState.User, Constants.HostRole))
|
||||
{
|
||||
string message = "A Problem Was Encountered Loading Module " + module.ModuleDefinitionName;
|
||||
AddModuleMessage(message, MessageType.Error);
|
||||
}
|
||||
|
||||
await logger.LogCritical("Error Loading Module {Module}", module);
|
||||
}
|
||||
}
|
|
@ -1,56 +1,107 @@
|
|||
@namespace Oqtane.Modules.Admin.Files
|
||||
@using System.IO
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IFileService FileService
|
||||
@inject IFolderService FolderService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<TabStrip>
|
||||
<TabPanel Name="Upload" Heading="Upload Files">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Files: </label>
|
||||
<Label For="upload" HelpText="Upload the file you want">Upload: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileUpload Multiple="true" @ref="fileupload"></FileUpload>
|
||||
<FileManager UploadMultiple="true" ShowFiles="false" FolderId="@_folderId" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
</table>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Download" Heading="Download Files">
|
||||
@if (_folders != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="url" HelpText="Enter the url of the file you wish to download">Url: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="url" class="form-control" @bind="@url" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="folder" HelpText="Select the folder to save the file in">Folder: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="folder" class="form-control" @bind="@_folderId">
|
||||
<option value="-1"><Select Folder></option>
|
||||
@foreach (Folder folder in _folders)
|
||||
{
|
||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="Download">Download</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private string url = string.Empty;
|
||||
private List<Folder> _folders;
|
||||
private int _folderId = -1;
|
||||
|
||||
FileUpload fileupload;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private async Task UploadFile()
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
string[] files = await fileupload.GetFiles();
|
||||
if (files.Length > 0)
|
||||
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
|
||||
|
||||
if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
_folderId = int.Parse(PageState.QueryString["id"]);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Download()
|
||||
{
|
||||
if (url == string.Empty || _folderId == -1)
|
||||
{
|
||||
AddModuleMessage("You Must Enter A Url And Select A Folder", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
var filename = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal) + 1);
|
||||
|
||||
if (!Constants.UploadableFiles.Split(',')
|
||||
.Contains(Path.GetExtension(filename).ToLower().Replace(".", "")))
|
||||
{
|
||||
AddModuleMessage("File Could Not Be Downloaded From Url Due To Its File Extension", MessageType.Warning);
|
||||
return ;
|
||||
}
|
||||
|
||||
if (!filename.IsPathOrFileValid())
|
||||
{
|
||||
AddModuleMessage("You Must Enter A Url With A Valid File Name", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
|
||||
string result = await FileService.UploadFilesAsync(PageState.Site.SiteRootPath, files, "");
|
||||
if (result == "")
|
||||
{
|
||||
await logger.LogInformation("Files Uploaded Successfully");
|
||||
AddModuleMessage("Files Uploaded Successfully", MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Upload Failed For {Files}", result.Replace(",",", "));
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
await FileService.UploadFileAsync(url, _folderId);
|
||||
await logger.LogInformation("File Downloaded Successfully From Url {Url}", url);
|
||||
AddModuleMessage("File Downloaded Successfully From Url", MessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Upload Failed {Error}", ex.Message);
|
||||
AddModuleMessage("Upload Failed. " + ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Select Some Files To Upload", MessageType.Warning);
|
||||
await logger.LogError(ex, "Error Downloading File From Url {Url} {Error}", url, ex.Message);
|
||||
AddModuleMessage("Error Downloading File From Url. Please Verify That The Url Is Valid.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,83 +3,193 @@
|
|||
@inject IFolderService FolderService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<table class="table table-borderless">
|
||||
@if (_folders != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="parent" HelpText="Select the parent folder">Parent: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<select id="parent" class="form-control" @bind="@_parentId">
|
||||
@if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
<option value="-1"><No Parent></option>
|
||||
}
|
||||
@foreach (Folder folder in _folders)
|
||||
{
|
||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Permissions: </label>
|
||||
<Label for="name" HelpText="Enter the folder name">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionGrid EntityName="Folder" PermissionNames="View,Edit" Permissions="@permissions" @ref="permissiongrid" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveFolder">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
|
||||
<tr>
|
||||
<td colspan="2" align="center">
|
||||
<Label For="permissions" HelpText="Select the permissions you want for the folder">Permissions: </Label>
|
||||
<PermissionGrid EntityName="@EntityNames.Folder" PermissionNames="Browse,View,Edit" Permissions="@_permissions" @ref="_permissionGrid" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@if (!_isSystem)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick="SaveFolder">Save</button>
|
||||
}
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
@if (!_isSystem && PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick="DeleteFolder">Delete</button>
|
||||
}
|
||||
<br />
|
||||
<br />
|
||||
@if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<Folder> _folders;
|
||||
private int _folderId = -1;
|
||||
private string _name;
|
||||
private int _parentId = -1;
|
||||
private bool _isSystem;
|
||||
private string _permissions = string.Empty;
|
||||
private string _createdBy;
|
||||
private DateTime _createdOn;
|
||||
private string _modifiedBy;
|
||||
private DateTime _modifiedOn;
|
||||
|
||||
int FolderId;
|
||||
string name;
|
||||
string permissions;
|
||||
string createdby;
|
||||
DateTime createdon;
|
||||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
#pragma warning disable 649
|
||||
private PermissionGrid _permissionGrid;
|
||||
#pragma warning restore 649
|
||||
|
||||
PermissionGrid permissiongrid;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
public override string Title => "Folder Management";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
FolderId = Int32.Parse(PageState.QueryString["id"]);
|
||||
Folder folder = await FolderService.GetFolderAsync(FolderId);
|
||||
_folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
|
||||
|
||||
if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
_folderId = Int32.Parse(PageState.QueryString["id"]);
|
||||
Folder folder = await FolderService.GetFolderAsync(_folderId);
|
||||
if (folder != null)
|
||||
{
|
||||
name = folder.Name;
|
||||
permissions = folder.Permissions;
|
||||
createdby = folder.CreatedBy;
|
||||
createdon = folder.CreatedOn;
|
||||
modifiedby = folder.ModifiedBy;
|
||||
modifiedon = folder.ModifiedOn;
|
||||
_parentId = folder.ParentId ?? -1;
|
||||
_name = folder.Name;
|
||||
_isSystem = folder.IsSystem;
|
||||
_permissions = folder.Permissions;
|
||||
_createdBy = folder.CreatedBy;
|
||||
_createdOn = folder.CreatedOn;
|
||||
_modifiedBy = folder.ModifiedBy;
|
||||
_modifiedOn = folder.ModifiedOn;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_parentId = _folders[0].FolderId;
|
||||
_permissions = string.Empty;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", FolderId, ex.Message);
|
||||
AddModuleMessage("Error Loading Module", MessageType.Error);
|
||||
await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", _folderId, ex.Message);
|
||||
AddModuleMessage("Error Loading Folder", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveFolder()
|
||||
{
|
||||
if (_name == string.Empty || _parentId == -1)
|
||||
{
|
||||
AddModuleMessage("Folders Must Have A Parent And A Name", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_name.IsPathOrFileValid())
|
||||
{
|
||||
AddModuleMessage("Folder Name Not Valid.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Folder folder = await FolderService.GetFolderAsync(FolderId);
|
||||
Folder folder;
|
||||
if (_folderId != -1)
|
||||
{
|
||||
folder = await FolderService.GetFolderAsync(_folderId);
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = new Folder();
|
||||
}
|
||||
|
||||
folder.SiteId = PageState.Site.SiteId;
|
||||
|
||||
if (_parentId == -1)
|
||||
{
|
||||
folder.ParentId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
folder.ParentId = _parentId;
|
||||
}
|
||||
|
||||
folder.Name = _name;
|
||||
folder.IsSystem = _isSystem;
|
||||
folder.Permissions = _permissionGrid.GetPermissions();
|
||||
|
||||
if (_folderId != -1)
|
||||
{
|
||||
folder = await FolderService.UpdateFolderAsync(folder);
|
||||
}
|
||||
else
|
||||
{
|
||||
folder = await FolderService.AddFolderAsync(folder);
|
||||
}
|
||||
|
||||
if (folder != null)
|
||||
{
|
||||
folder.Permissions = permissiongrid.GetPermissions();
|
||||
await FolderService.UpdateFolderAsync(folder);
|
||||
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
|
||||
await logger.LogInformation("Folder Saved {Folder}", folder);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("An Error Was Encountered Saving The Folder", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", FolderId, ex.Message);
|
||||
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message);
|
||||
AddModuleMessage("Error Saving Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteFolder()
|
||||
{
|
||||
try
|
||||
{
|
||||
await FolderService.DeleteFolderAsync(_folderId);
|
||||
await logger.LogInformation("Folder Deleted {Folder}", _folderId);
|
||||
AddModuleMessage("Folder Deleted", MessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Folder {Folder} {Error}", _folderId, ex.Message);
|
||||
AddModuleMessage("Error Deleting Folder", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,71 @@
|
|||
@namespace Oqtane.Modules.Admin.Files
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IFolderService FolderService
|
||||
@inject IFileService FileService
|
||||
|
||||
@if (Files == null)
|
||||
@if (_files != null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Add Files" />
|
||||
|
||||
<Pager Items="@Files">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Folder: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => FolderChanged(e))">
|
||||
@foreach (Folder folder in _folders)
|
||||
{
|
||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<ActionLink Action="Edit" Text="Edit Folder" Class="btn btn-secondary" Parameters="@($"id=" + _folderId.ToString())" />
|
||||
<ActionLink Action="Edit" Text="Add Folder" Class="btn btn-secondary" />
|
||||
<ActionLink Action="Add" Text="Upload Files" Parameters="@($"id=" + _folderId.ToString())" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<Pager Items="@_files">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th>Name</th>
|
||||
<th>Modified</th>
|
||||
<th>Type</th>
|
||||
<th>Size</th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionDialog Header="Delete File" Message="@("Are You Sure You Wish To Delete " + context + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" /></td>
|
||||
<td><a href="@(uri.Scheme + "://" + uri.Authority + "/" + PageState.Site.SiteRootPath + context)" target="_new">@context</a></td>
|
||||
<td><ActionDialog Header="Delete File" Message="@("Are You Sure You Wish To Delete " + context.Name + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" /></td>
|
||||
<td><a href="@(ContentUrl(context.FileId))" target="_new">@context.Name</a></td>
|
||||
<td>@context.ModifiedOn</td>
|
||||
<td>@context.Extension.ToUpper() File</td>
|
||||
<td>@(context.Size / 1000) KB</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
@if (_files.Count == 0)
|
||||
{
|
||||
<div class="text-center">No Files Exist In Selected Folder</div>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<Folder> _folders;
|
||||
private int _folderId = -1;
|
||||
private List<File> _files;
|
||||
|
||||
List<string> Files;
|
||||
Uri uri;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Files = await FileService.GetFilesAsync(PageState.Site.SiteRootPath);
|
||||
uri = new Uri(NavigationManager.Uri);
|
||||
_folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
|
||||
|
||||
if (_folderId == -1 && _folders.Count > 0)
|
||||
{
|
||||
_folderId = _folders[0].FolderId;
|
||||
await GetFiles();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -43,19 +74,40 @@ else
|
|||
}
|
||||
}
|
||||
|
||||
private async Task DeleteFile(string filename)
|
||||
private async Task GetFiles()
|
||||
{
|
||||
_files = await FileService.GetFilesAsync(_folderId);
|
||||
}
|
||||
|
||||
private async void FolderChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
await FileService.DeleteFileAsync(PageState.Site.SiteRootPath, filename);
|
||||
Files = await FileService.GetFilesAsync(PageState.Site.SiteRootPath);
|
||||
await logger.LogInformation("File Deleted {File}", filename);
|
||||
AddModuleMessage("File " + filename + " Deleted", MessageType.Success);
|
||||
_folderId = int.Parse((string)e.Value);
|
||||
await GetFiles();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting File {File} {Error}", filename, ex.Message);
|
||||
AddModuleMessage("Error Deleting File " + filename, MessageType.Error);
|
||||
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Files", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteFile(File file)
|
||||
{
|
||||
try
|
||||
{
|
||||
await FileService.DeleteFileAsync(file.FileId);
|
||||
await logger.LogInformation("File Deleted {File}", file.Name);
|
||||
AddModuleMessage("File " + file.Name + " Deleted", MessageType.Success);
|
||||
await GetFiles();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting File {File} {Error}", file.Name, ex.Message);
|
||||
AddModuleMessage("Error Deleting File " + file.Name, MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,29 +3,29 @@
|
|||
@inject NavigationManager NavigationManager
|
||||
@inject IJobService JobService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="Enter the job name">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Type: </label>
|
||||
<Label For="type" HelpText="Enter the job type">Type: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@jobtype" />
|
||||
<input id="type" class="form-control" @bind="@_jobType" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Enabled? </label>
|
||||
<Label For="enabled" HelpText="Select whether you want the job enabled or not">Enabled? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isenabled">
|
||||
<select id="enabled" class="form-control" @bind="@_isEnabled">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -33,11 +33,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Runs Every: </label>
|
||||
<Label For="runs-every" HelpText="Select how often you want the job to run">Runs Every: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@interval" />
|
||||
<select class="form-control" @bind="@frequency">
|
||||
<input id="runs-every" class="form-control" @bind="@_interval" />
|
||||
<select id="runs-every" class="form-control" @bind="@_frequency">
|
||||
<option value="m">Minute(s)</option>
|
||||
<option value="H">Hour(s)</option>
|
||||
<option value="d">Day(s)</option>
|
||||
|
@ -47,71 +47,74 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Starting: </label>
|
||||
<Label For="starting" HelpText="What time do you want the job to start">Starting: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@startdate" />
|
||||
<input id="starting" class="form-control" @bind="@_startDate" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Ending: </label>
|
||||
<Label For="ending" HelpText="When do you want the job to end">Ending: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@enddate" />
|
||||
<input id="ending" class="form-control" @bind="@_endDate" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Retention Log (Items): </label>
|
||||
<Label For="retention-log" HelpText="What items do you want in the retention log">Retention Log (Items): </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@retentionhistory" />
|
||||
<input id="retention-log" class="form-control" @bind="@_retentionHistory" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveJob">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private string _name = string.Empty;
|
||||
private string _jobType = string.Empty;
|
||||
private string _isEnabled = "True";
|
||||
private string _interval = string.Empty;
|
||||
private string _frequency = string.Empty;
|
||||
private string _startDate = string.Empty;
|
||||
private string _endDate = string.Empty;
|
||||
private string _retentionHistory = "10";
|
||||
|
||||
string name = "";
|
||||
string jobtype = "";
|
||||
string isenabled = "True";
|
||||
string interval = "";
|
||||
string frequency = "";
|
||||
string startdate = "";
|
||||
string enddate = "";
|
||||
string retentionhistory = "10";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
private async Task SaveJob()
|
||||
{
|
||||
if (name != "" && !string.IsNullOrEmpty(jobtype) && frequency != "" && interval != "" && retentionhistory != "")
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_jobType) && _frequency != string.Empty && _interval != string.Empty && _retentionHistory != string.Empty)
|
||||
{
|
||||
Job job = new Job();
|
||||
job.Name = name;
|
||||
job.JobType = jobtype;
|
||||
job.IsEnabled = Boolean.Parse(isenabled);
|
||||
job.Frequency = frequency;
|
||||
job.Interval = int.Parse(interval);
|
||||
if (startdate == "")
|
||||
var job = new Job();
|
||||
job.Name = _name;
|
||||
job.JobType = _jobType;
|
||||
job.IsEnabled = Boolean.Parse(_isEnabled);
|
||||
job.Frequency = _frequency;
|
||||
job.Interval = int.Parse(_interval);
|
||||
|
||||
if (_startDate == string.Empty)
|
||||
{
|
||||
job.StartDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
job.StartDate = DateTime.Parse(startdate);
|
||||
job.StartDate = DateTime.Parse(_startDate);
|
||||
}
|
||||
if (enddate == "")
|
||||
|
||||
if (_endDate == string.Empty)
|
||||
{
|
||||
job.EndDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
job.EndDate = DateTime.Parse(enddate);
|
||||
job.EndDate = DateTime.Parse(_endDate);
|
||||
}
|
||||
job.RetentionHistory = int.Parse(retentionhistory);
|
||||
|
||||
job.RetentionHistory = int.Parse(_retentionHistory);
|
||||
job.IsStarted = false;
|
||||
job.IsExecuting = false;
|
||||
job.NextExecution = null;
|
||||
|
|
|
@ -3,29 +3,29 @@
|
|||
@inject NavigationManager NavigationManager
|
||||
@inject IJobService JobService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="Enter the job name">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Type: </label>
|
||||
<Label For="type" HelpText="Enter the job type">Type: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@jobtype" />
|
||||
<input id="type" class="form-control" @bind="@_jobType" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Enabled? </label>
|
||||
<Label For="enabled" HelpText="Select whether you want the job enabled or not">Enabled? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isenabled">
|
||||
<select id="enabled" class="form-control" @bind="@_isEnabled">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -33,11 +33,11 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Runs Every: </label>
|
||||
<Label For="runs-every" HelpText="Select how often you want the job to run">Runs Every: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@interval" />
|
||||
<select class="form-control" @bind="@frequency">
|
||||
<input id="runs-every" class="form-control" @bind="@_interval" />
|
||||
<select id="runs-every" class="form-control" @bind="@_frequency">
|
||||
<option value="m">Minute(s)</option>
|
||||
<option value="H">Hour(s)</option>
|
||||
<option value="d">Day(s)</option>
|
||||
|
@ -47,97 +47,100 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Starting: </label>
|
||||
<Label For="starting" HelpText="What time do you want the job to start">Starting: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@startdate" />
|
||||
<input id="starting" class="form-control" @bind="@_startDate" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Ending: </label>
|
||||
<Label For="ending" HelpText="When do you want the job to end">Ending: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@enddate" />
|
||||
<input id="ending" class="form-control" @bind="@_endDate" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Retention Log (Items): </label>
|
||||
<Label For="retention-log" HelpText="What items do you want in the retention log">Retention Log (Items): </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@retentionhistory" />
|
||||
<input id="retention-log" class="form-control" @bind="@_retentionHistory" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveJob">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private int _jobId;
|
||||
private string _name = string.Empty;
|
||||
private string _jobType = string.Empty;
|
||||
private string _isEnabled = "True";
|
||||
private string _interval = string.Empty;
|
||||
private string _frequency = string.Empty;
|
||||
private string _startDate = string.Empty;
|
||||
private string _endDate = string.Empty;
|
||||
private string _retentionHistory = string.Empty;
|
||||
|
||||
int jobid;
|
||||
string name = "";
|
||||
string jobtype = "";
|
||||
string isenabled = "True";
|
||||
string interval = "";
|
||||
string frequency = "";
|
||||
string startdate = "";
|
||||
string enddate = "";
|
||||
string retentionhistory = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
jobid = Int32.Parse(PageState.QueryString["id"]);
|
||||
Job job = await JobService.GetJobAsync(jobid);
|
||||
_jobId = Int32.Parse(PageState.QueryString["id"]);
|
||||
Job job = await JobService.GetJobAsync(_jobId);
|
||||
if (job != null)
|
||||
{
|
||||
name = job.Name;
|
||||
jobtype = job.JobType;
|
||||
isenabled = job.IsEnabled.ToString();
|
||||
interval = job.Interval.ToString();
|
||||
frequency = job.Frequency;
|
||||
startdate = (job.StartDate != null) ? job.StartDate.ToString() : "";
|
||||
enddate = (job.EndDate != null) ? job.EndDate.ToString() : "";
|
||||
retentionhistory = job.RetentionHistory.ToString();
|
||||
_name = job.Name;
|
||||
_jobType = job.JobType;
|
||||
_isEnabled = job.IsEnabled.ToString();
|
||||
_interval = job.Interval.ToString();
|
||||
_frequency = job.Frequency;
|
||||
_startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty;
|
||||
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
|
||||
_retentionHistory = job.RetentionHistory.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Job {JobId} {Error}", jobid, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message);
|
||||
AddModuleMessage("Error Loading Job", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveJob()
|
||||
{
|
||||
if (name != "" && !string.IsNullOrEmpty(jobtype) && frequency != "" && interval != "" && retentionhistory != "")
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_jobType) && _frequency != string.Empty && _interval != string.Empty && _retentionHistory != string.Empty)
|
||||
{
|
||||
Job job = await JobService.GetJobAsync(jobid);
|
||||
job.Name = name;
|
||||
job.JobType = jobtype;
|
||||
job.IsEnabled = Boolean.Parse(isenabled);
|
||||
job.Frequency = frequency;
|
||||
job.Interval = int.Parse(interval);
|
||||
if (startdate == "")
|
||||
var job = await JobService.GetJobAsync(_jobId);
|
||||
job.Name = _name;
|
||||
job.JobType = _jobType;
|
||||
job.IsEnabled = Boolean.Parse(_isEnabled);
|
||||
job.Frequency = _frequency;
|
||||
job.Interval = int.Parse(_interval);
|
||||
|
||||
if (_startDate == string.Empty)
|
||||
{
|
||||
job.StartDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
job.StartDate = DateTime.Parse(startdate);
|
||||
job.StartDate = DateTime.Parse(_startDate);
|
||||
}
|
||||
if (enddate == "")
|
||||
|
||||
if (_endDate == string.Empty)
|
||||
{
|
||||
job.EndDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
job.EndDate = DateTime.Parse(enddate);
|
||||
job.EndDate = DateTime.Parse(_endDate);
|
||||
}
|
||||
job.RetentionHistory = int.Parse(retentionhistory);
|
||||
|
||||
job.RetentionHistory = int.Parse(_retentionHistory);
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@inherits ModuleBase
|
||||
@inject IJobService JobService
|
||||
|
||||
@if (Jobs == null)
|
||||
@if (_jobs == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ else
|
|||
<button type="button" class="btn btn-secondary" @onclick="(async () => await Refresh())">Refresh</button>
|
||||
<br /><br />
|
||||
|
||||
<Pager Items="@Jobs">
|
||||
<Pager Items="@_jobs">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
|
@ -47,25 +47,25 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<Job> _jobs;
|
||||
|
||||
List<Job> Jobs;
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Jobs = await JobService.GetJobsAsync();
|
||||
_jobs = await JobService.GetJobsAsync();
|
||||
}
|
||||
|
||||
private string DisplayStatus(bool IsEnabled, bool IsExecuting)
|
||||
private string DisplayStatus(bool isEnabled, bool isExecuting)
|
||||
{
|
||||
string status = "";
|
||||
if (!IsEnabled)
|
||||
var status = string.Empty;
|
||||
if (!isEnabled)
|
||||
{
|
||||
status = "Disabled";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsExecuting)
|
||||
if (isExecuting)
|
||||
{
|
||||
status = "Executing";
|
||||
}
|
||||
|
@ -79,59 +79,61 @@ else
|
|||
}
|
||||
|
||||
|
||||
private string DisplayFrequency(int Interval, string Frequency)
|
||||
private string DisplayFrequency(int interval, string frequency)
|
||||
{
|
||||
string frequency = "Every " + Interval.ToString() + " ";
|
||||
switch (Frequency)
|
||||
var result = "Every " + interval.ToString() + " ";
|
||||
switch (frequency)
|
||||
{
|
||||
case "m":
|
||||
frequency += "Minute";
|
||||
result += "Minute";
|
||||
break;
|
||||
case "H":
|
||||
frequency += "Hour";
|
||||
result += "Hour";
|
||||
break;
|
||||
case "d":
|
||||
frequency += "Day";
|
||||
result += "Day";
|
||||
break;
|
||||
case "M":
|
||||
frequency += "Month";
|
||||
result += "Month";
|
||||
break;
|
||||
}
|
||||
if (Interval > 1)
|
||||
|
||||
if (interval > 1)
|
||||
{
|
||||
frequency += "s";
|
||||
}
|
||||
return frequency;
|
||||
result += "s";
|
||||
}
|
||||
|
||||
private async Task DeleteJob(Job Job)
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task DeleteJob(Job job)
|
||||
{
|
||||
try
|
||||
{
|
||||
await JobService.DeleteJobAsync(Job.JobId);
|
||||
await logger.LogInformation("Job Deleted {Job}", Job);
|
||||
await JobService.DeleteJobAsync(job.JobId);
|
||||
await logger.LogInformation("Job Deleted {Job}", job);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Job {Job} {Error}", Job, ex.Message);
|
||||
await logger.LogError(ex, "Error Deleting Job {Job} {Error}", job, ex.Message);
|
||||
AddModuleMessage("Error Deleting Job", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartJob(int JobId)
|
||||
private async Task StartJob(int jobId)
|
||||
{
|
||||
await JobService.StartJobAsync(JobId);
|
||||
await JobService.StartJobAsync(jobId);
|
||||
}
|
||||
|
||||
private async Task StopJob(int JobId)
|
||||
private async Task StopJob(int jobId)
|
||||
{
|
||||
await JobService.StopJobAsync(JobId);
|
||||
await JobService.StopJobAsync(jobId);
|
||||
}
|
||||
|
||||
private async Task Refresh()
|
||||
{
|
||||
Jobs = await JobService.GetJobsAsync();
|
||||
_jobs = await JobService.GetJobsAsync();
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
|
@ -2,13 +2,13 @@
|
|||
@inherits ModuleBase
|
||||
@inject IJobLogService JobLogService
|
||||
|
||||
@if (JobLogs == null)
|
||||
@if (_jobLogs == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Pager Items="@JobLogs">
|
||||
<Pager Items="@_jobLogs">
|
||||
<Header>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
|
@ -28,30 +28,32 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<JobLog> _jobLogs;
|
||||
|
||||
List<JobLog> JobLogs;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
JobLogs = await JobLogService.GetJobLogsAsync();
|
||||
_jobLogs = await JobLogService.GetJobLogsAsync();
|
||||
|
||||
if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
JobLogs = JobLogs.Where(item => item.JobId == Int32.Parse(PageState.QueryString["id"])).ToList();
|
||||
}
|
||||
JobLogs = JobLogs.OrderByDescending(item => item.JobLogId).ToList();
|
||||
_jobLogs = _jobLogs.Where(item => item.JobId == Int32.Parse(PageState.QueryString["id"])).ToList();
|
||||
}
|
||||
|
||||
private string DisplayStatus(bool IsExecuting, bool? Succeeded)
|
||||
_jobLogs = _jobLogs.OrderByDescending(item => item.JobLogId).ToList();
|
||||
}
|
||||
|
||||
private string DisplayStatus(bool isExecuting, bool? succeeded)
|
||||
{
|
||||
string status = "";
|
||||
if (IsExecuting)
|
||||
var status = string.Empty;
|
||||
if (isExecuting)
|
||||
{
|
||||
status = "Executing";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Succeeded.Value)
|
||||
if (succeeded != null && succeeded.Value)
|
||||
{
|
||||
status = "Succeeded";
|
||||
}
|
||||
|
@ -60,6 +62,7 @@ else
|
|||
status = "Failed";
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
|
@ -1,35 +1,35 @@
|
|||
@namespace Oqtane.Modules.Admin.Login
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IJSRuntime jsRuntime
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inject IUserService UserService
|
||||
@inject IServiceProvider ServiceProvider
|
||||
|
||||
@if (Message != "")
|
||||
@if (_message != string.Empty)
|
||||
{
|
||||
<ModuleMessage Message="@Message" Type="@Type" />
|
||||
<ModuleMessage Message="@_message" Type="@_type" />
|
||||
}
|
||||
<AuthorizeView>
|
||||
<Authorizing>
|
||||
<text>...</text>
|
||||
</Authorizing>
|
||||
<Authorized>
|
||||
You are already logged in
|
||||
<ModuleMessage Message="You Are Already Logged In" Type="MessageType.Info" />
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<div class="container">
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">Username: </label>
|
||||
<input type="text" name="Username" class="form-control" placeholder="Username" @bind="@Username" />
|
||||
<input type="text" name="Username" class="form-control" placeholder="Username" @bind="@_username" id="Username" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">Password: </label>
|
||||
<input type="password" name="Password" class="form-control" placeholder="Password" @bind="@Password" />
|
||||
<input type="password" name="Password" class="form-control" placeholder="Password" @bind="@_password" id="Password" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="form-check form-check-inline">
|
||||
<label class="form-check-label" for="Remember">Remember Me?</label>
|
||||
<input type="checkbox" class="form-check-input" name="Remember" @bind="@Remember" />
|
||||
<input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" @onclick="Login">Login</button>
|
||||
|
@ -41,87 +41,90 @@
|
|||
</AuthorizeView>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } }
|
||||
private string _returnUrl = string.Empty;
|
||||
private string _message = string.Empty;
|
||||
private MessageType _type = MessageType.Info;
|
||||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private bool _remember = false;
|
||||
|
||||
string ReturnUrl = "";
|
||||
public string Message = "";
|
||||
public MessageType Type = MessageType.Info;
|
||||
public string Username = "";
|
||||
public string Password = "";
|
||||
public bool Remember = false;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
||||
{
|
||||
ReturnUrl = PageState.QueryString["returnurl"];
|
||||
_returnUrl = PageState.QueryString["returnurl"];
|
||||
}
|
||||
|
||||
if (PageState.QueryString.ContainsKey("name"))
|
||||
{
|
||||
Username = PageState.QueryString["name"];
|
||||
_username = PageState.QueryString["name"];
|
||||
}
|
||||
|
||||
if (PageState.QueryString.ContainsKey("token"))
|
||||
{
|
||||
User user = new User();
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user.Username = _username;
|
||||
user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
Message = "User Account Verified Successfully. You Can Now Login With Your Username And Password Below.";
|
||||
_message = "User Account Verified Successfully. You Can Now Login With Your Username And Password Below.";
|
||||
}
|
||||
else
|
||||
{
|
||||
Message = "User Account Could Not Be Verified. Please Contact Your Administrator For Further Instructions.";
|
||||
Type = MessageType.Warning;
|
||||
_message = "User Account Could Not Be Verified. Please Contact Your Administrator For Further Instructions.";
|
||||
_type = MessageType.Warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Login()
|
||||
{
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
if (authstateprovider == null)
|
||||
if (PageState.Runtime == Runtime.Server)
|
||||
{
|
||||
// server-side Blazor
|
||||
User user = new User();
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user.Password = Password;
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", Username);
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
// complete the login on the server so that the cookies are set correctly on SignalR
|
||||
var interop = new Interop(jsRuntime);
|
||||
var interop = new Interop(JsRuntime);
|
||||
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, username = Username, password = Password, remember = Remember, returnurl = ReturnUrl };
|
||||
await interop.SubmitForm("/pages/login/", fields);
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Login Failed For Username {Username}", Username);
|
||||
await logger.LogInformation("Login Failed For Username {Username}", _username);
|
||||
AddModuleMessage("Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Email Verification When They Initially Created.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// client-side Blazor
|
||||
User user = new User();
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user.Password = Password;
|
||||
user = await UserService.LoginUserAsync(user, true, Remember);
|
||||
user.Username = _username;
|
||||
user.Password = _password;
|
||||
user = await UserService.LoginUserAsync(user, true, _remember);
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", Username);
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
authstateprovider.NotifyAuthenticationChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl(ReturnUrl, Reload.Site));
|
||||
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Login Failed For Username {Username}", Username);
|
||||
await logger.LogInformation("Login Failed For Username {Username}", _username);
|
||||
AddModuleMessage("Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -129,29 +132,30 @@
|
|||
|
||||
private void Cancel()
|
||||
{
|
||||
NavigationManager.NavigateTo(ReturnUrl);
|
||||
NavigationManager.NavigateTo(_returnUrl);
|
||||
}
|
||||
|
||||
private async Task Forgot()
|
||||
{
|
||||
if (Username != "")
|
||||
if (_username != string.Empty)
|
||||
{
|
||||
User user = await UserService.GetUserAsync(Username, PageState.Site.SiteId);
|
||||
var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId);
|
||||
if (user != null)
|
||||
{
|
||||
await UserService.ForgotPasswordAsync(user);
|
||||
Message = "Please Check The Email Address Associated To Your User Account For A Password Reset Notification";
|
||||
_message = "Please Check The Email Address Associated To Your User Account For A Password Reset Notification";
|
||||
}
|
||||
else
|
||||
{
|
||||
Message = "User Does Not Exist";
|
||||
Type = MessageType.Warning;
|
||||
_message = "User Does Not Exist";
|
||||
_type = MessageType.Warning;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again";
|
||||
_message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again";
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@namespace Oqtane.Modules.Admin.Logs
|
||||
@using System.Globalization
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ILogService LogService
|
||||
|
@ -9,198 +10,202 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Date/Time: </label>
|
||||
<Label For="dateTime" HelpText="The date and time of this log">Date/Time: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@logdate" disabled />
|
||||
<input id="dateTime" class="form-control" @bind="@_logDate" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Level: </label>
|
||||
<Label For="level" HelpText="The level of this log">Level: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@level" disabled />
|
||||
<input id="level" class="form-control" @bind="@_level" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Feature: </label>
|
||||
<Label For="feature" HelpText="The feature that was affected">Feature: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@feature" disabled />
|
||||
<input id="feature" class="form-control" @bind="@_feature" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Function: </label>
|
||||
<Label For="function" HelpText="The function that was performed">Function: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@function" disabled />
|
||||
<input id="function" class="form-control" @bind="@_function" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Category: </label>
|
||||
<Label For="category" HelpText="The categories that were affected">Category: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@category" disabled />
|
||||
<input id="category" class="form-control" @bind="@_category" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
@if (pagename != "")
|
||||
@if (_pageName != string.Empty)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Page: </label>
|
||||
<Label For="page" HelpText="The page that was affected">Page: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@pagename" disabled />
|
||||
<input id="page" class="form-control" @bind="@_pageName" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (moduletitle != "")
|
||||
@if (_moduleTitle != string.Empty)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Module: </label>
|
||||
<Label For="module" HelpText="The module that was affected">Module: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@moduletitle" disabled />
|
||||
<input id="module" class="form-control" @bind="@_moduleTitle" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (username != "")
|
||||
@if (_username != string.Empty)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">User: </label>
|
||||
<Label For="user" HelpText="The user that caused this log">User: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@username" disabled />
|
||||
<input id="user" class="form-control" @bind="@_username" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Url: </label>
|
||||
<Label For="url" HelpText="The url the log comes from">Url: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@url" disabled />
|
||||
<input id="url" class="form-control" @bind="@_url" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Template: </label>
|
||||
<Label For="template" HelpText="What the log is about">Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@template" disabled />
|
||||
<input id="template" class="form-control" @bind="@_template" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Message: </label>
|
||||
<Label For="message" HelpText="The message that the system generated"class="control-label">Message: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@message" rows="5" disabled />
|
||||
<textarea id="message" class="form-control" @bind="@_message" rows="5" readonly></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!string.IsNullOrEmpty(exception))
|
||||
@if (!string.IsNullOrEmpty(_exception))
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Exception: </label>
|
||||
<Label For="exception" HelpText="The exceptions generated by the system">Exception: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@exception" rows="5" disabled />
|
||||
<textarea id="exception" class="form-control" @bind="@_exception" rows="5" readonly></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Properties: </label>
|
||||
<Label For="properties" HelpText="The properties that were affected">Properties: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@properties" rows="5" disabled />
|
||||
<textarea id="properties" class="form-control" @bind="@_properties" rows="5" readonly></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Server: </label>
|
||||
<Label For="server" HelpText="The server that was affected">Server: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@server" disabled />
|
||||
<input id="server" class="form-control" @bind="@_server" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private int _logId;
|
||||
private string _logDate = string.Empty;
|
||||
private string _level = string.Empty;
|
||||
private string _feature = string.Empty;
|
||||
private string _function = string.Empty;
|
||||
private string _category = string.Empty;
|
||||
private string _pageName = string.Empty;
|
||||
private string _moduleTitle = string.Empty;
|
||||
private string _username = string.Empty;
|
||||
private string _url = string.Empty;
|
||||
private string _template = string.Empty;
|
||||
private string _message = string.Empty;
|
||||
private string _exception = string.Empty;
|
||||
private string _properties = string.Empty;
|
||||
private string _server = string.Empty;
|
||||
|
||||
int logid;
|
||||
string logdate = "";
|
||||
string level = "";
|
||||
string feature = "";
|
||||
string function = "";
|
||||
string category = "";
|
||||
string pagename = "";
|
||||
string moduletitle = "";
|
||||
string username = "";
|
||||
string url = "";
|
||||
string template = "";
|
||||
string message = "";
|
||||
string exception = "";
|
||||
string properties = "";
|
||||
string server = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
logid = Int32.Parse(PageState.QueryString["id"]);
|
||||
Log log = await LogService.GetLogAsync(logid);
|
||||
_logId = Int32.Parse(PageState.QueryString["id"]);
|
||||
var log = await LogService.GetLogAsync(_logId);
|
||||
if (log != null)
|
||||
{
|
||||
logdate = log.LogDate.ToString();
|
||||
level = log.Level;
|
||||
feature = log.Feature;
|
||||
function = log.Function;
|
||||
category = log.Category;
|
||||
_logDate = log.LogDate.ToString(CultureInfo.CurrentCulture);
|
||||
_level = log.Level;
|
||||
_feature = log.Feature;
|
||||
_function = log.Function;
|
||||
_category = log.Category;
|
||||
|
||||
if (log.PageId != null)
|
||||
{
|
||||
Page page = await PageService.GetPageAsync(log.PageId.Value);
|
||||
var page = await PageService.GetPageAsync(log.PageId.Value);
|
||||
if (page != null)
|
||||
{
|
||||
pagename = page.Name;
|
||||
_pageName = page.Name;
|
||||
}
|
||||
}
|
||||
|
||||
if (log.PageId != null && log.ModuleId != null)
|
||||
{
|
||||
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value);
|
||||
var pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value);
|
||||
if (pagemodule != null)
|
||||
{
|
||||
moduletitle = pagemodule.Title;
|
||||
_moduleTitle = pagemodule.Title;
|
||||
}
|
||||
}
|
||||
|
||||
if (log.UserId != null)
|
||||
{
|
||||
User user = await UserService.GetUserAsync(log.UserId.Value, PageState.Site.SiteId);
|
||||
var user = await UserService.GetUserAsync(log.UserId.Value, PageState.Site.SiteId);
|
||||
if (user != null)
|
||||
{
|
||||
username = user.Username;
|
||||
_username = user.Username;
|
||||
}
|
||||
}
|
||||
url = log.Url;
|
||||
template = log.MessageTemplate;
|
||||
message = log.Message;
|
||||
exception = log.Exception;
|
||||
properties = log.Properties;
|
||||
server = log.Server;
|
||||
|
||||
_url = log.Url;
|
||||
_template = log.MessageTemplate;
|
||||
_message = log.Message;
|
||||
_exception = log.Exception;
|
||||
_properties = log.Properties;
|
||||
_server = log.Server;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Log {LogId} {Error}", logid, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Log {LogId} {Error}", _logId, ex.Message);
|
||||
AddModuleMessage("Error Loading Log", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
@inherits ModuleBase
|
||||
@inject ILogService LogService
|
||||
|
||||
@if (Logs == null)
|
||||
@if (_logs == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="form-group">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label>Level: </label>
|
||||
<select class="form-control" @onchange="(e => LevelChanged(e))">
|
||||
<option value="-"><All Levels></option>
|
||||
|
@ -19,6 +21,8 @@ else
|
|||
<option value="Error">Error</option>
|
||||
<option value="Critical">Critical</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label>Function: </label>
|
||||
<select class="form-control" @onchange="(e => FunctionChanged(e))">
|
||||
<option value="-"><All Functions></option>
|
||||
|
@ -29,16 +33,21 @@ else
|
|||
<option value="Security">Security</option>
|
||||
<option value="Other">Other</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<label>Rows: </label>
|
||||
<select class="form-control" @onchange="(e => RowsChanged(e))">
|
||||
<option value="10">10</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
</div>
|
||||
@if (Logs.Any())
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@if (_logs.Any())
|
||||
{
|
||||
<Pager Items="@Logs">
|
||||
<Pager Items="@_logs">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th>Date</th>
|
||||
|
@ -62,12 +71,12 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private string _level = "-";
|
||||
private string _function = "-";
|
||||
private string _rows = "10";
|
||||
private List<Log> _logs;
|
||||
|
||||
string level = "-";
|
||||
string function = "-";
|
||||
string rows = "10";
|
||||
List<Log> Logs;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -86,7 +95,7 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
level = (string)e.Value;
|
||||
_level = (string)e.Value;
|
||||
await GetLogs();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
@ -101,7 +110,7 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
function = (string)e.Value;
|
||||
_function = (string)e.Value;
|
||||
await GetLogs();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
@ -117,7 +126,7 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
rows = (string)e.Value;
|
||||
_rows = (string)e.Value;
|
||||
await GetLogs();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
@ -130,12 +139,12 @@ else
|
|||
|
||||
private async Task GetLogs()
|
||||
{
|
||||
Logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((level == "-") ? "" : level), ((function == "-") ? "" : function), int.Parse(rows));
|
||||
_logs = await LogService.GetLogsAsync(PageState.Site.SiteId, ((_level == "-") ? string.Empty : _level), ((_function == "-") ? string.Empty : _function), int.Parse(_rows));
|
||||
}
|
||||
|
||||
private string GetClass(string function)
|
||||
{
|
||||
string classname = "";
|
||||
string classname = string.Empty;
|
||||
switch (function)
|
||||
{
|
||||
case "Create":
|
||||
|
@ -154,7 +163,7 @@ else
|
|||
classname = "table-secondary";
|
||||
break;
|
||||
default:
|
||||
classname = "";
|
||||
classname = string.Empty;
|
||||
break;
|
||||
}
|
||||
return classname;
|
||||
|
|
124
Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor
Normal file
124
Oqtane.Client/Modules/Admin/ModuleCreator/Index.razor
Normal file
|
@ -0,0 +1,124 @@
|
|||
@namespace Oqtane.Modules.Admin.ModuleCreator
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@inject IModuleService ModuleService
|
||||
@inject ISystemService SystemService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation.">Owner Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="owner" class="form-control" @bind="@_owner" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="module" HelpText="Enter a name for this module. It should be in singular form (ie. Car) and not contain spaces or punctuation.">Module Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_module" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="description" HelpText="Enter s short description for the module">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="template" HelpText="Select a module template. Internal modules are created inside of the Oqtane solution. External modules are created outside of the Oqtane solution.">Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
|
||||
<option value="-"><Select Template></option>
|
||||
<option value="internal">Internal</option>
|
||||
<option value="external">External</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!string.IsNullOrEmpty(_location))
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="location" HelpText="Location where the module will be created">Location: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="module" class="form-control" @bind="@_location" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
|
||||
<button type="button" class="btn btn-success" @onclick="CreateModule">Create Module</button>
|
||||
|
||||
@code {
|
||||
private string _owner = string.Empty;
|
||||
private string _module = string.Empty;
|
||||
private string _description = string.Empty;
|
||||
private string _template = "-";
|
||||
private string _location = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
AddModuleMessage("Please Note That Once You Select The Create Module Button The Application Must Restart In Order To Complete The Process. If You Create An External Module You Will Need To Compile The Source Code In Order To Make It Functional.", MessageType.Info);
|
||||
}
|
||||
|
||||
private async Task CreateModule()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_owner) && !string.IsNullOrEmpty(_module) && _template != "-")
|
||||
{
|
||||
var moduleDefinition = new ModuleDefinition { Owner = _owner.Replace(" ", ""), Name = _module.Replace(" ", ""), Description = _description, Template = _template };
|
||||
await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition, ModuleState.ModuleId);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide An Owner, Module Name, And Template", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Creating Module");
|
||||
}
|
||||
}
|
||||
|
||||
private async void TemplateChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_location = string.Empty;
|
||||
_template = (string)e.Value;
|
||||
if (_template != "-")
|
||||
{
|
||||
Dictionary<string, string> systeminfo = await SystemService.GetSystemInfoAsync();
|
||||
if (systeminfo != null)
|
||||
{
|
||||
string[] path = systeminfo["serverpath"].Split('\\');
|
||||
if (_template == "internal")
|
||||
{
|
||||
_location = string.Join("\\", path, 0, path.Length - 1) + "\\Oqtane.Client\\Modules\\" + _owner + "." + _module + "s";
|
||||
}
|
||||
else
|
||||
{
|
||||
_location = string.Join("\\", path, 0, path.Length - 2) + "\\" + _owner + "." + _module + "s";
|
||||
}
|
||||
}
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Getting System Info {Error}", ex.Message);
|
||||
AddModuleMessage("Error Getting System Info", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
15
Oqtane.Client/Modules/Admin/ModuleCreator/ModuleInfo.cs
Normal file
15
Oqtane.Client/Modules/Admin/ModuleCreator/ModuleInfo.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Modules.Admin.ModuleCreator
|
||||
{
|
||||
public class ModuleInfo : IModule
|
||||
{
|
||||
public ModuleDefinition ModuleDefinition => new ModuleDefinition
|
||||
{
|
||||
Name = "Module Creator",
|
||||
Description = "Enables software developers to quickly create modules by automating many of the initial module creation tasks",
|
||||
Version = "1.0.0",
|
||||
Categories = "Developer"
|
||||
};
|
||||
}
|
||||
}
|
|
@ -5,24 +5,14 @@
|
|||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@inject IPackageService PackageService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Module: </label>
|
||||
</td>
|
||||
<td>
|
||||
<FileUpload Filter=".nupkg" @ref="fileupload"></FileUpload>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload Module</button>
|
||||
|
||||
@if (packages != null)
|
||||
@if (_packages != null)
|
||||
{
|
||||
<hr class="app-rule" />
|
||||
<div class="mx-auto text-center"><h2>Available Modules</h2></div>
|
||||
|
||||
<Pager Items="@packages">
|
||||
<TabStrip>
|
||||
@if (_packages.Count > 0)
|
||||
{
|
||||
<TabPanel Name="Download">
|
||||
<ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
|
||||
<Pager Items="@_packages">
|
||||
<Header>
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
|
@ -32,37 +22,47 @@
|
|||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>Download Module</button>
|
||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>Download</button>
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
</TabPanel>
|
||||
}
|
||||
<TabPanel Name="Upload">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation.">Module: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager Filter="nupkg" ShowFiles="false" Folder="Modules" UploadMultiple="true" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
@if (uploaded)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick="InstallModules">Install</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
}
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<Package> _packages;
|
||||
|
||||
bool uploaded = false;
|
||||
List<Package> packages;
|
||||
FileUpload fileupload;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<ModuleDefinition> moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||
packages = await PackageService.GetPackagesAsync("module");
|
||||
foreach(Package package in packages.ToArray())
|
||||
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||
_packages = await PackageService.GetPackagesAsync("module");
|
||||
|
||||
foreach (Package package in _packages.ToArray())
|
||||
{
|
||||
if (moduledefinitions.Exists(item => Utilities.GetTypeName(item.ModuleDefinitionName) == package.PackageId))
|
||||
{
|
||||
packages.Remove(package);
|
||||
_packages.Remove(package);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,53 +73,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
private async Task UploadFile()
|
||||
{
|
||||
string[] files = await fileupload.GetFiles();
|
||||
if (files.Length > 0)
|
||||
{
|
||||
if (files[0].Contains(".Module."))
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = await FileService.UploadFilesAsync("Modules", files, "");
|
||||
if (result == "")
|
||||
{
|
||||
await logger.LogInformation("Module Uploaded Successfully {Package}", files[0]);
|
||||
AddModuleMessage("Module Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Module Upload Failed For {Package}", files[0]);
|
||||
AddModuleMessage("Module Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Module Upload Failed For {Package} {Error}", files[0], ex.Message);
|
||||
AddModuleMessage("Module Upload Failed.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Invalid Module Package {Package}", files[0]);
|
||||
AddModuleMessage("Invalid Module Package", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Select A Module To Upload", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InstallModules()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -127,19 +86,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
private async Task DownloadModule(string moduledefinitionname, string version)
|
||||
private async Task DownloadModule(string packageid, string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
|
||||
await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", moduledefinitionname, version);
|
||||
AddModuleMessage("Module Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
await PackageService.DownloadPackageAsync(packageid, version, "Modules");
|
||||
await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", packageid, version);
|
||||
AddModuleMessage("Modules Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
||||
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version}", packageid, version);
|
||||
AddModuleMessage("Error Downloading Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,62 +3,152 @@
|
|||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<table class="table table-borderless">
|
||||
<TabStrip>
|
||||
<TabPanel Name="Definition">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="The name of the module">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Permissions: </label>
|
||||
<Label For="description" HelpText="The description of the module">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionGrid EntityName="ModuleDefinition" PermissionNames="Utilize" Permissions="@permissions" @ref="permissiongrid" />
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="2"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="categories" HelpText="Comma delimited list of module categories">Categories: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="categories" class="form-control" @bind="@_categories" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<Section Name="Information">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="moduledefinitionname" HelpText="The internal name of the module">Internal Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="moduledefinitionname" class="form-control" @bind="@_moduledefinitionname" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="version" HelpText="The version of the module">Version: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="owner" HelpText="The owner or creator of the module">Owner: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="url" HelpText="The reference url of the module">Reference Url: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="contact" HelpText="The contact for the module">Contact: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="license" HelpText="The license of the module">License: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Permissions">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" Permissions="@_permissions" @ref="_permissionGrid" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
|
||||
<br /><br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private int _moduleDefinitionId;
|
||||
private string _name;
|
||||
private string _version;
|
||||
private string _categories;
|
||||
private string _moduledefinitionname = "";
|
||||
private string _description = "";
|
||||
private string _owner = "";
|
||||
private string _url = "";
|
||||
private string _contact = "";
|
||||
private string _license = "";
|
||||
private string _permissions;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
|
||||
int ModuleDefinitionId;
|
||||
string name;
|
||||
string permissions;
|
||||
string createdby;
|
||||
DateTime createdon;
|
||||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
#pragma warning disable 649
|
||||
private PermissionGrid _permissionGrid;
|
||||
#pragma warning restore 649
|
||||
|
||||
PermissionGrid permissiongrid;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
ModuleDefinitionId = Int32.Parse(PageState.QueryString["id"]);
|
||||
ModuleDefinition moduledefinition = PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionId == ModuleDefinitionId).FirstOrDefault();
|
||||
if (moduledefinition != null)
|
||||
_moduleDefinitionId = Int32.Parse(PageState.QueryString["id"]);
|
||||
var moduleDefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
|
||||
if (moduleDefinition != null)
|
||||
{
|
||||
name = moduledefinition.Name;
|
||||
permissions = moduledefinition.Permissions;
|
||||
createdby = moduledefinition.CreatedBy;
|
||||
createdon = moduledefinition.CreatedOn;
|
||||
modifiedby = moduledefinition.ModifiedBy;
|
||||
modifiedon = moduledefinition.ModifiedOn;
|
||||
_name = moduleDefinition.Name;
|
||||
_version = moduleDefinition.Version;
|
||||
_categories = moduleDefinition.Categories;
|
||||
_moduledefinitionname = moduleDefinition.ModuleDefinitionName;
|
||||
_description = moduleDefinition.Description;
|
||||
_owner = moduleDefinition.Owner;
|
||||
_url = moduleDefinition.Url;
|
||||
_contact = moduleDefinition.Contact;
|
||||
_license = moduleDefinition.License;
|
||||
_permissions = moduleDefinition.Permissions;
|
||||
_createdby = moduleDefinition.CreatedBy;
|
||||
_createdon = moduleDefinition.CreatedOn;
|
||||
_modifiedby = moduleDefinition.ModifiedBy;
|
||||
_modifiedon = moduleDefinition.ModifiedOn;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading ModuleDefinition {ModuleDefinitionId} {Error}", ModuleDefinitionId, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message);
|
||||
AddModuleMessage("Error Loading Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -67,15 +157,27 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
ModuleDefinition moduledefinition = PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionId == ModuleDefinitionId).FirstOrDefault();
|
||||
moduledefinition.Permissions = permissiongrid.GetPermissions();
|
||||
var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
|
||||
if (moduledefinition.Name != _name)
|
||||
{
|
||||
moduledefinition.Name = _name;
|
||||
}
|
||||
if (moduledefinition.Description != _description)
|
||||
{
|
||||
moduledefinition.Description = _description;
|
||||
}
|
||||
if (moduledefinition.Categories != _categories)
|
||||
{
|
||||
moduledefinition.Categories = _categories;
|
||||
}
|
||||
moduledefinition.Permissions = _permissionGrid.GetPermissions();
|
||||
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
|
||||
await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving ModuleDefinition {ModuleDefinitionId} {Error}", ModuleDefinitionId, ex.Message);
|
||||
await logger.LogError(ex, "Error Saving ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message);
|
||||
AddModuleMessage("Error Saving Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@inject IPackageService PackageService
|
||||
|
||||
@if (moduledefinitions == null)
|
||||
@if (_moduleDefinitions == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Install Module" />
|
||||
|
||||
<Pager Items="@moduledefinitions">
|
||||
<Pager Items="@_moduleDefinitions">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
|
@ -41,17 +41,17 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<ModuleDefinition> _moduleDefinitions;
|
||||
private List<Package> _packages;
|
||||
|
||||
List<ModuleDefinition> moduledefinitions;
|
||||
List<Package> packages;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||
packages = await PackageService.GetPackagesAsync("module");
|
||||
_moduleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||
_packages = await PackageService.GetPackagesAsync("module");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -62,12 +62,13 @@ else
|
|||
|
||||
private bool UpgradeAvailable(string moduledefinitionname, string version)
|
||||
{
|
||||
bool upgradeavailable = false;
|
||||
Package package = packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault();
|
||||
var upgradeavailable = false;
|
||||
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault();
|
||||
if (package != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||
}
|
||||
|
||||
return upgradeavailable;
|
||||
}
|
||||
|
||||
|
@ -78,7 +79,7 @@ else
|
|||
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
|
||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -87,17 +88,17 @@ else
|
|||
}
|
||||
}
|
||||
|
||||
private async Task DeleteModule(ModuleDefinition ModuleDefinition)
|
||||
private async Task DeleteModule(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(ModuleDefinition.ModuleDefinitionId, ModuleDefinition.SiteId);
|
||||
await logger.LogInformation("Module Deleted {ModuleDefinition}", ModuleDefinition);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||
await logger.LogInformation("Module Deleted {ModuleDefinition}", moduleDefinition);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Module {ModuleDefinition} {Error}", ModuleDefinition, ex.Message);
|
||||
await logger.LogError(ex, "Error Deleting Module {ModuleDefinition} {Error}", moduleDefinition, ex.Message);
|
||||
AddModuleMessage("Error Deleting Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Title" class="control-label">Content: </label>
|
||||
<Label For="content" HelpText="Enter the module content">Content: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@content" rows="5" />
|
||||
<textarea id="content" class="form-control" @bind="@_content" rows="5"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -20,13 +20,14 @@
|
|||
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
public override string Title { get { return "Export Module"; } }
|
||||
private string _content = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
public override string Title => "Export Module";
|
||||
|
||||
string content = "";
|
||||
|
||||
private async Task ExportModule()
|
||||
{
|
||||
content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId);
|
||||
_content = await ModuleService.ExportModuleAsync(ModuleState.ModuleId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Title" class="control-label">Content: </label>
|
||||
<Label For="content" HelpText="Enter the module content">Content: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@content" rows="5" />
|
||||
<textarea id="content" class="form-control" @bind="@_content" rows="5"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -20,20 +20,20 @@
|
|||
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
public override string Title { get { return "Import Module"; } }
|
||||
|
||||
string content = "";
|
||||
private string _content = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
public override string Title => "Import Module";
|
||||
|
||||
private async Task ImportModule()
|
||||
{
|
||||
if (content != "")
|
||||
if (_content != string.Empty)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleService.ImportModuleAsync(ModuleState.ModuleId, content);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Page));
|
||||
await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -5,24 +5,27 @@
|
|||
@inject IModuleService ModuleService
|
||||
@inject IPageModuleService PageModuleService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tbody>
|
||||
<TabStrip>
|
||||
<TabPanel Name="Settings" Heading="Module Settings">
|
||||
@if (_containers != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Title" class="control-label">Title: </label>
|
||||
<Label For="title" HelpText="Enter the title of the module">Title: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="Title" class="form-control" @bind="@title" />
|
||||
<input id="title" type="text" name="Title" class="form-control" @bind="@_title" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Container" class="control-label">Container: </label>
|
||||
<Label For="container" HelpText="Select the module's container">Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@containertype">
|
||||
<option value=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string> container in containers)
|
||||
<select id="container" class="form-control" @bind="@_containerType">
|
||||
<option value="-"><Inherit From Page Or Site></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
}
|
||||
|
@ -31,91 +34,143 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Permissions: </label>
|
||||
<Label For="allpages" HelpText="Indicate if this module should be displayed on all pages">Display On All Pages? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionGrid EntityName="Module" PermissionNames="@permissionnames" Permissions="@permissions" @ref="permissiongrid" />
|
||||
<select id="allpages" class="form-control" @bind="@_allPages">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Page" class="control-label">Page: </label>
|
||||
<Label For="page" HelpText="The page that the module is on">Page: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@pageid">
|
||||
<select id="page" class="form-control" @bind="@_pageId">
|
||||
@foreach (Page p in PageState.Pages)
|
||||
{
|
||||
<option value="@p.PageId">@p.Name</option>
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@DynamicComponent
|
||||
|
||||
</table>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Permissions">
|
||||
@if (_containers != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<PermissionGrid EntityName="@EntityNames.Module" PermissionNames="@_permissionNames" Permissions="@_permissions" @ref="_permissionGrid" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
}
|
||||
</TabPanel>
|
||||
@if (_settingsModuleType != null)
|
||||
{
|
||||
<TabPanel Name="ModuleSettings" Heading="@_settingstitle">
|
||||
@DynamicComponent
|
||||
</TabPanel>
|
||||
}
|
||||
</TabStrip>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveModule">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Edit; } }
|
||||
public override string Title { get { return "Module Settings"; } }
|
||||
private Dictionary<string, string> _containers;
|
||||
private string _title;
|
||||
private string _containerType;
|
||||
private string _allPages = "false";
|
||||
private string _permissionNames = "";
|
||||
private string _permissions;
|
||||
private string _pageId;
|
||||
private PermissionGrid _permissionGrid;
|
||||
private Type _settingsModuleType;
|
||||
private string _settingstitle = "Other Settings";
|
||||
private object _settings;
|
||||
|
||||
Dictionary<string, string> containers = new Dictionary<string, string>();
|
||||
string title;
|
||||
string containertype;
|
||||
string permissionnames = "";
|
||||
string permissions;
|
||||
string pageid;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
public override string Title => "Module Settings";
|
||||
|
||||
PermissionGrid permissiongrid;
|
||||
|
||||
RenderFragment DynamicComponent { get; set; }
|
||||
object settings;
|
||||
private RenderFragment DynamicComponent { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
title = ModuleState.Title;
|
||||
containers = ThemeService.GetContainerTypes(await ThemeService.GetThemesAsync());
|
||||
containertype = ModuleState.ContainerType;
|
||||
permissions = ModuleState.Permissions;
|
||||
permissionnames = PageState.ModuleDefinitions.Find(item => item.ModuleDefinitionName == ModuleState.ModuleDefinitionName).PermissionNames;
|
||||
pageid = ModuleState.PageId.ToString();
|
||||
_title = ModuleState.Title;
|
||||
_containers = ThemeService.GetContainerTypes(await ThemeService.GetThemesAsync());
|
||||
_containerType = ModuleState.ContainerType;
|
||||
if (!string.IsNullOrEmpty(PageState.Page.DefaultContainerType) && _containerType == PageState.Page.DefaultContainerType)
|
||||
{
|
||||
_containerType = "-";
|
||||
}
|
||||
if (_containerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
_containerType = "-";
|
||||
}
|
||||
_allPages = ModuleState.AllPages.ToString();
|
||||
_permissions = ModuleState.Permissions;
|
||||
_permissionNames = ModuleState.ModuleDefinition.PermissionNames;
|
||||
_pageId = ModuleState.PageId.ToString();
|
||||
|
||||
_settingsModuleType = Type.GetType(ModuleState.ModuleType);
|
||||
if (_settingsModuleType != null)
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(_settingsModuleType) as IModuleControl;
|
||||
_settingstitle = moduleobject.Title;
|
||||
if (string.IsNullOrEmpty(_settingstitle))
|
||||
{
|
||||
_settingstitle = "Other Settings";
|
||||
}
|
||||
|
||||
DynamicComponent = builder =>
|
||||
{
|
||||
Type moduleType = Type.GetType(ModuleState.ModuleType);
|
||||
if (moduleType != null)
|
||||
{
|
||||
builder.OpenComponent(0, moduleType);
|
||||
builder.AddComponentReferenceCapture(1, inst => { settings = Convert.ChangeType(inst, moduleType); });
|
||||
builder.OpenComponent(0, _settingsModuleType);
|
||||
builder.AddComponentReferenceCapture(1, inst => { _settings = Convert.ChangeType(inst, _settingsModuleType); });
|
||||
builder.CloseComponent();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveModule()
|
||||
{
|
||||
Module module = ModuleState;
|
||||
module.Permissions = permissiongrid.GetPermissions();
|
||||
await ModuleService.UpdateModuleAsync(module);
|
||||
|
||||
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
||||
pagemodule.PageId = int.Parse(pageid);
|
||||
pagemodule.Title = title;
|
||||
pagemodule.ContainerType = containertype;
|
||||
var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
||||
pagemodule.PageId = int.Parse(_pageId);
|
||||
pagemodule.Title = _title;
|
||||
pagemodule.ContainerType = (_containerType != "-") ? _containerType : string.Empty;
|
||||
if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Page.DefaultContainerType)
|
||||
{
|
||||
pagemodule.ContainerType = string.Empty;
|
||||
}
|
||||
if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
pagemodule.ContainerType = string.Empty;
|
||||
}
|
||||
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
||||
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
|
||||
|
||||
Type moduleType = Type.GetType(ModuleState.ModuleType);
|
||||
var module = ModuleState;
|
||||
module.AllPages = bool.Parse(_allPages);
|
||||
module.Permissions = _permissionGrid.GetPermissions();
|
||||
await ModuleService.UpdateModuleAsync(module);
|
||||
|
||||
if (_settingsModuleType != null)
|
||||
{
|
||||
var moduleType = Type.GetType(ModuleState.ModuleType);
|
||||
if (moduleType != null)
|
||||
{
|
||||
moduleType.GetMethod("UpdateSettings").Invoke(settings, null); // method must be public in settings component
|
||||
moduleType.GetMethod("UpdateSettings")?.Invoke(_settings, null); // method must be public in settings component
|
||||
}
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Page));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,31 +4,27 @@
|
|||
@inject IPageService PageService
|
||||
@inject IThemeService ThemeService
|
||||
|
||||
<TabStrip>
|
||||
<TabPanel Name="Settings">
|
||||
@if (_themeList != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="Name" HelpText="Enter the page name">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="Name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Path: </label>
|
||||
<Label For="Parent" HelpText="Select the parent for the page in the site hierarchy">Parent: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@path" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Parent: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => ParentChanged(e))">
|
||||
<select id="Parent" class="form-control" @onchange="(e => ParentChanged(e))">
|
||||
<option value="-1"><Site Root></option>
|
||||
@foreach (Page page in pages)
|
||||
@foreach (Page page in _pageList)
|
||||
{
|
||||
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||
}
|
||||
|
@ -37,23 +33,23 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Insert: </label>
|
||||
<Label For="Insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages">Insert: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@insert">
|
||||
<select id="Insert" class="form-control" @bind="@_insert">
|
||||
<option value="<<">At Beginning</option>
|
||||
@if (children != null && children.Count > 0)
|
||||
@if (_children != null && _children.Count > 0)
|
||||
{
|
||||
<option value="<">Before</option>
|
||||
<option value=">">After</option>
|
||||
}
|
||||
<option value=">>">At End</option>
|
||||
</select>
|
||||
@if (children != null && children.Count > 0 && (insert == "<" || insert == ">"))
|
||||
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
|
||||
{
|
||||
<select class="form-control" @bind="@childid">
|
||||
<select class="form-control" @bind="@_childid">
|
||||
<option value="-1"><Select Page></option>
|
||||
@foreach (Page page in children)
|
||||
@foreach (Page page in _children)
|
||||
{
|
||||
<option value="@(page.PageId)">@(page.Name)</option>
|
||||
}
|
||||
|
@ -63,10 +59,10 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Navigation? </label>
|
||||
<Label For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden">Navigation? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isnavigation">
|
||||
<select id="Navigation" class="form-control" @bind="@_isnavigation">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -74,21 +70,101 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Personalizable? </label>
|
||||
<Label For="Path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used.">Url Path: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@ispersonalizable">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
<input id="Path" class="form-control" @bind="@_path" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it">Redirect: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="Url" class="form-control" @bind="@_url" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<Section Name="Appearance">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used.">Title: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="Title" class="form-control" @bind="@_title" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Theme" HelpText="Select the theme for this page">Theme: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
{
|
||||
if (item.Key == _themetype)
|
||||
{
|
||||
<option value="@item.Key" selected>@item.Value</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@item.Key">@item.Value</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Mode? </label>
|
||||
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@mode">
|
||||
<select id="Layout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
||||
{
|
||||
if (panelayout.Key == _layouttype)
|
||||
{
|
||||
<option value="@panelayout.Key" selected>@panelayout.Value</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Icon" HelpText="Optionally provide an icon for this page which will be displayed in the site navigation">Icon: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Default-Mode" class="form-control" @bind="@_mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
|
@ -96,92 +172,71 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Theme: </label>
|
||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in themes)
|
||||
{
|
||||
<option value="@item.Key">@item.Value</option>
|
||||
}
|
||||
<select id="Personalizable" class="form-control" @bind="@_ispersonalizable">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Layout: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@layouttype">
|
||||
<option value=""><Select Layout></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
|
||||
{
|
||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Icon: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@icon" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Permissions: </label>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionGrid EntityName="Page" Permissions="@permissions" @ref="permissiongrid" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Permissions">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
<button type="button" class="btn btn-success" @onclick="SavePage">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private Dictionary<string, string> _themes;
|
||||
private Dictionary<string, string> _panelayouts;
|
||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
||||
private List<Theme> _themeList;
|
||||
private List<Page> _pageList;
|
||||
private string _name;
|
||||
private string _title;
|
||||
private string _path = string.Empty;
|
||||
private string _parentid;
|
||||
private string _insert = ">>";
|
||||
private List<Page> _children;
|
||||
private int _childid = -1;
|
||||
private string _isnavigation = "True";
|
||||
private string _url;
|
||||
private string _ispersonalizable = "False";
|
||||
private string _mode = "view";
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _containertype = "-";
|
||||
private string _icon = string.Empty;
|
||||
private string _permissions = string.Empty;
|
||||
private PermissionGrid _permissionGrid;
|
||||
|
||||
Dictionary<string, string> themes = new Dictionary<string, string>();
|
||||
Dictionary<string, string> panelayouts = new Dictionary<string, string>();
|
||||
|
||||
List<Page> pages;
|
||||
string name;
|
||||
string path = "";
|
||||
string parentid;
|
||||
string insert = ">>";
|
||||
List<Page> children;
|
||||
int childid = -1;
|
||||
string isnavigation = "True";
|
||||
string ispersonalizable = "False";
|
||||
string mode = "view";
|
||||
string themetype = "";
|
||||
string layouttype = "";
|
||||
string icon = "";
|
||||
string permissions = ""; // need to set default permissions
|
||||
|
||||
PermissionGrid permissiongrid;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
pages = PageState.Pages;
|
||||
children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_pageList = PageState.Pages;
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
|
||||
themes = ThemeService.GetThemeTypes(PageState.Themes);
|
||||
themetype = PageState.Site.DefaultThemeType;
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
layouttype = PageState.Site.DefaultLayoutType;
|
||||
|
||||
List<PermissionString> permissionstrings = new List<PermissionString>();
|
||||
permissionstrings.Add(new PermissionString { PermissionName = "View", Permissions = Constants.AdminRole });
|
||||
permissionstrings.Add(new PermissionString { PermissionName = "Edit", Permissions = Constants.AdminRole });
|
||||
permissions = UserSecurity.SetPermissionStrings(permissionstrings);
|
||||
_permissions = string.Empty;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -194,20 +249,33 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
parentid = (string)e.Value;
|
||||
if (parentid == "-1")
|
||||
_parentid = (string)e.Value;
|
||||
_children = new List<Page>();
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
children = PageState.Pages.Where(item => item.ParentId == int.Parse(parentid)).ToList();
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", parentid, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
||||
AddModuleMessage("Error Loading Child Pages For Parent", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -216,20 +284,20 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
themetype = (string)e.Value;
|
||||
if (themetype != "")
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != "-")
|
||||
{
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
panelayouts = new Dictionary<string, string>();
|
||||
_panelayouts = new Dictionary<string, string>();
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -239,78 +307,88 @@
|
|||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (name != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype)))
|
||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)))
|
||||
{
|
||||
page = new Page();
|
||||
page.SiteId = PageState.Page.SiteId;
|
||||
page.Name = name;
|
||||
if (path == "")
|
||||
page.Name = _name;
|
||||
page.Title = _title;
|
||||
if (_path == "")
|
||||
{
|
||||
path = name;
|
||||
_path = _name;
|
||||
}
|
||||
if (path.Contains("/"))
|
||||
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
path = path.Substring(path.LastIndexOf("/") + 1);
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
if (string.IsNullOrEmpty(parentid))
|
||||
|
||||
if (string.IsNullOrEmpty(_parentid))
|
||||
{
|
||||
page.ParentId = null;
|
||||
page.Path = Utilities.GetFriendlyUrl(path);
|
||||
page.Path = Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.ParentId = Int32.Parse(parentid);
|
||||
Page parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault();
|
||||
if (parent.Path == "")
|
||||
page.ParentId = Int32.Parse(_parentid);
|
||||
var parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault();
|
||||
if (parent.Path == string.Empty)
|
||||
{
|
||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(path);
|
||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(path);
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
Page child;
|
||||
switch (insert)
|
||||
switch (_insert)
|
||||
{
|
||||
case "<<":
|
||||
page.Order = 0;
|
||||
break;
|
||||
case "<":
|
||||
child = PageState.Pages.Where(item => item.PageId == childid).FirstOrDefault();
|
||||
child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault();
|
||||
page.Order = child.Order - 1;
|
||||
break;
|
||||
case ">":
|
||||
child = PageState.Pages.Where(item => item.PageId == childid).FirstOrDefault();
|
||||
child = PageState.Pages.Where(item => item.PageId == _childid).FirstOrDefault();
|
||||
page.Order = child.Order + 1;
|
||||
break;
|
||||
case ">>":
|
||||
page.Order = int.MaxValue;
|
||||
break;
|
||||
}
|
||||
page.IsNavigation = (isnavigation == null ? true : Boolean.Parse(isnavigation));
|
||||
page.EditMode = (mode == "edit" ? true : false);
|
||||
page.ThemeType = themetype;
|
||||
page.LayoutType = (layouttype == null ? "" : layouttype);
|
||||
page.Icon = (icon == null ? "" : icon);
|
||||
page.Permissions = permissiongrid.GetPermissions();
|
||||
|
||||
if (page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
||||
page.Url = _url;
|
||||
page.EditMode = (_mode == "edit" ? true : false);
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
page.ThemeType = "";
|
||||
page.ThemeType = string.Empty;
|
||||
}
|
||||
if (page.LayoutType == PageState.Site.DefaultLayoutType)
|
||||
page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.LayoutType) && page.LayoutType == PageState.Site.DefaultLayoutType)
|
||||
{
|
||||
page.LayoutType = "";
|
||||
page.LayoutType = string.Empty;
|
||||
}
|
||||
page.IsPersonalizable = (ispersonalizable == null ? false : Boolean.Parse(ispersonalizable));
|
||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
page.DefaultContainerType = string.Empty;
|
||||
}
|
||||
page.Icon = (_icon == null ? string.Empty : _icon);
|
||||
page.Permissions = _permissionGrid.GetPermissions();
|
||||
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
||||
page.UserId = null;
|
||||
|
||||
await PageService.AddPageAsync(page);
|
||||
page = await PageService.AddPageAsync(page);
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||
|
||||
await logger.LogInformation("Page Added {Page}", page);
|
||||
NavigationManager.NavigateTo(NavigateUrl(page.Path, Reload.Site));
|
||||
NavigationManager.NavigateTo(NavigateUrl(page.Path));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -4,33 +4,29 @@
|
|||
@inject IPageService PageService
|
||||
@inject IThemeService ThemeService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Path: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@path" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Parent: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => ParentChanged(e))">
|
||||
<option value="-1"><Site Root></option>
|
||||
@foreach (Page page in pages)
|
||||
<TabStrip>
|
||||
<TabPanel Name="Settings">
|
||||
@if (_themeList != null)
|
||||
{
|
||||
if (page.PageId.ToString() == parentid)
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Name" HelpText="Enter the page name">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="Name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Parent" HelpText="Select the parent for the page in the site hierarchy">Parent: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Parent" class="form-control" @onchange="(e => ParentChanged(e))">
|
||||
<option value="-1"><Site Root></option>
|
||||
@foreach (Page page in _pageList)
|
||||
{
|
||||
if (page.PageId.ToString() == _parentid)
|
||||
{
|
||||
<option value="@(page.PageId)" selected>@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||
}
|
||||
|
@ -44,27 +40,27 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Move : </label>
|
||||
<Label For="Move" HelpText="Select the location where you would like the page to be moved in relation to other pages">Move: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@insert">
|
||||
@if (parentid == currentparentid)
|
||||
<select id="Move" class="form-control" @bind="@_insert">
|
||||
@if (_parentid == _currentparentid)
|
||||
{
|
||||
<option value="="><Maintain Current Location></option>
|
||||
}
|
||||
<option value="<<">To Beginning</option>
|
||||
@if (children != null && children.Count > 0)
|
||||
@if (_children != null && _children.Count > 0)
|
||||
{
|
||||
<option value="<">Before</option>
|
||||
<option value=">">After</option>
|
||||
}
|
||||
<option value=">>">To End</option>
|
||||
</select>
|
||||
@if (children != null && children.Count > 0 && (insert == "<" || insert == ">"))
|
||||
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
|
||||
{
|
||||
<select class="form-control" @bind="@childid">
|
||||
<select class="form-control" @bind="@_childid">
|
||||
<option value="-1"><Select Page></option>
|
||||
@foreach (Page page in children)
|
||||
@foreach (Page page in _children)
|
||||
{
|
||||
<option value="@(page.PageId)">@(page.Name)</option>
|
||||
}
|
||||
|
@ -74,10 +70,10 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Navigation? </label>
|
||||
<Label For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden">Navigation? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isnavigation">
|
||||
<select id="Navigation" class="form-control" @bind="@_isnavigation">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -85,36 +81,41 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Personalizable? </label>
|
||||
<Label For="Path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used.">Url Path: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@ispersonalizable">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
<input id="Path" class="form-control" @bind="@_path" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Mode? </label>
|
||||
<Label For="Url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it">Redirect: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
<input id="Url" class="form-control" @bind="@_url" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<Section Name="Appearance">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used.">Title: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="Title" class="form-control" @bind="@_title" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Theme: </label>
|
||||
<Label For="Theme" HelpText="Select the theme for this page">Theme: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in themes)
|
||||
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
{
|
||||
if (item.Key == themetype)
|
||||
if (item.Key == _themetype)
|
||||
{
|
||||
<option value="@item.Key" selected>@item.Value</option>
|
||||
}
|
||||
|
@ -128,119 +129,192 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Layout: </label>
|
||||
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@layouttype">
|
||||
<option value=""><Select Layout></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
|
||||
<select id="Layout" class="form-control" @bind="@_layouttype">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
||||
{
|
||||
if (panelayout.Key == _layouttype)
|
||||
{
|
||||
<option value="@panelayout.Key" selected>@panelayout.Value</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Icon: </label>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@icon" />
|
||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Permissions: </label>
|
||||
<Label For="Icon" HelpText="Optionally provide an icon for this page which will be displayed in the site navigation">Icon: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<PermissionGrid EntityName="Page" Permissions="@permissions" @ref="permissiongrid" />
|
||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Default-Mode" class="form-control" @bind="@_mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Personalizable" class="form-control" @bind="@_ispersonalizable">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
<br /><br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Permissions">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
<button type="button" class="btn btn-success" @onclick="SavePage">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private Dictionary<string, string> _themes;
|
||||
private Dictionary<string, string> _panelayouts;
|
||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
||||
private List<Theme> _themeList;
|
||||
private List<Page> _pageList;
|
||||
private int _pageId;
|
||||
private string _name;
|
||||
private string _title;
|
||||
private string _path;
|
||||
private string _currentparentid;
|
||||
private string _parentid;
|
||||
private string _insert = "=";
|
||||
private List<Page> _children;
|
||||
private int _childid = -1;
|
||||
private string _isnavigation;
|
||||
private string _url;
|
||||
private string _ispersonalizable;
|
||||
private string _mode;
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _containertype = "-";
|
||||
private string _icon;
|
||||
private string _permissions;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
|
||||
Dictionary<string, string> themes = new Dictionary<string, string>();
|
||||
Dictionary<string, string> panelayouts = new Dictionary<string, string>();
|
||||
#pragma warning disable 649
|
||||
private PermissionGrid _permissionGrid;
|
||||
#pragma warning restore 649
|
||||
|
||||
List<Page> pages;
|
||||
int PageId;
|
||||
string name;
|
||||
string path;
|
||||
string currentparentid;
|
||||
string parentid;
|
||||
string insert = "=";
|
||||
List<Page> children;
|
||||
int childid = -1;
|
||||
string isnavigation;
|
||||
string ispersonalizable;
|
||||
string mode;
|
||||
string themetype;
|
||||
string layouttype;
|
||||
string icon;
|
||||
string permissions;
|
||||
string createdby;
|
||||
DateTime createdon;
|
||||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
string deletedby;
|
||||
DateTime? deletedon;
|
||||
|
||||
PermissionGrid permissiongrid;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
pages = PageState.Pages;
|
||||
children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_pageList = PageState.Pages;
|
||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
|
||||
themes = ThemeService.GetThemeTypes(PageState.Themes);
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
|
||||
PageId = Int32.Parse(PageState.QueryString["id"]);
|
||||
Page page = PageState.Pages.Where(item => item.PageId == PageId).FirstOrDefault();
|
||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||
var page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
if (page != null)
|
||||
{
|
||||
name = page.Name;
|
||||
path = page.Path;
|
||||
if (path.Contains("/"))
|
||||
_name = page.Name;
|
||||
_title = page.Title;
|
||||
_path = page.Path;
|
||||
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
path = path.Substring(path.LastIndexOf("/") + 1);
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
if (page.ParentId == null)
|
||||
{
|
||||
parentid = "";
|
||||
_parentid = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
parentid = page.ParentId.ToString();
|
||||
_parentid = page.ParentId.ToString();
|
||||
}
|
||||
currentparentid = parentid;
|
||||
isnavigation = page.IsNavigation.ToString();
|
||||
ispersonalizable = page.IsPersonalizable.ToString();
|
||||
mode = (page.EditMode) ? "edit" : "view";
|
||||
themetype = page.ThemeType;
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
layouttype = page.LayoutType;
|
||||
icon = page.Icon;
|
||||
permissions = page.Permissions;
|
||||
createdby = page.CreatedBy;
|
||||
createdon = page.CreatedOn;
|
||||
modifiedby = page.ModifiedBy;
|
||||
modifiedon = page.ModifiedOn;
|
||||
deletedby = page.DeletedBy;
|
||||
deletedon = page.DeletedOn;
|
||||
|
||||
_currentparentid = _parentid;
|
||||
_isnavigation = page.IsNavigation.ToString();
|
||||
_url = page.Url;
|
||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||
_mode = (page.EditMode) ? "edit" : "view";
|
||||
_themetype = page.ThemeType;
|
||||
if (_themetype == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
_themetype = "-";
|
||||
}
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
_layouttype = page.LayoutType;
|
||||
if (_layouttype == PageState.Site.DefaultLayoutType)
|
||||
{
|
||||
_layouttype = "-";
|
||||
}
|
||||
_containertype = page.DefaultContainerType;
|
||||
if (string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
_containertype = "-";
|
||||
}
|
||||
_icon = page.Icon;
|
||||
_permissions = page.Permissions;
|
||||
_createdby = page.CreatedBy;
|
||||
_createdon = page.CreatedOn;
|
||||
_modifiedby = page.ModifiedBy;
|
||||
_modifiedon = page.ModifiedOn;
|
||||
_deletedby = page.DeletedBy;
|
||||
_deletedon = page.DeletedOn;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Page {PageId} {Error}", PageId, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message);
|
||||
AddModuleMessage("Error Loading Page", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -249,28 +323,41 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
parentid = (string)e.Value;
|
||||
if (parentid == "-1")
|
||||
_parentid = (string)e.Value;
|
||||
_children = new List<Page>();
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||
foreach(Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
children = PageState.Pages.Where(item => item.ParentId == int.Parse(parentid)).ToList();
|
||||
}
|
||||
if (parentid == currentparentid)
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
||||
{
|
||||
insert = "=";
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
_children.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_parentid == _currentparentid)
|
||||
{
|
||||
_insert = "=";
|
||||
}
|
||||
else
|
||||
{
|
||||
insert = ">>";
|
||||
_insert = ">>";
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", parentid, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
||||
AddModuleMessage("Error Loading Child Pages For Parent", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -279,20 +366,20 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
themetype = (string)e.Value;
|
||||
if (themetype != "")
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != "-")
|
||||
{
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
panelayouts = new Dictionary<string, string>();
|
||||
_panelayouts = new Dictionary<string, string>();
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -302,104 +389,111 @@
|
|||
Page page = null;
|
||||
try
|
||||
{
|
||||
if (name != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype)))
|
||||
if (_name != string.Empty)
|
||||
{
|
||||
page = PageState.Pages.Where(item => item.PageId == PageId).FirstOrDefault();
|
||||
string currentpath = page.Path;
|
||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||
string currentPath = page.Path;
|
||||
|
||||
page.Name = name;
|
||||
if (path == "" && name.ToLower() != "home")
|
||||
page.Name = _name;
|
||||
page.Title = _title;
|
||||
if (_path == "" && _name.ToLower() != "home")
|
||||
if (_path == string.Empty && _name.ToLower() != "home")
|
||||
{
|
||||
path = name;
|
||||
_path = _name;
|
||||
}
|
||||
if (path.Contains("/"))
|
||||
if (_path.Contains("/"))
|
||||
{
|
||||
path = path.Substring(path.LastIndexOf("/") + 1);
|
||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||
}
|
||||
if (string.IsNullOrEmpty(parentid))
|
||||
if (string.IsNullOrEmpty(_parentid) || _parentid == "-1")
|
||||
{
|
||||
page.ParentId = null;
|
||||
page.Path = Utilities.GetFriendlyUrl(path);
|
||||
page.Path = Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.ParentId = Int32.Parse(parentid);
|
||||
Page parent = PageState.Pages.Where(item => item.PageId == page.ParentId).FirstOrDefault();
|
||||
if (parent.Path == "")
|
||||
page.ParentId = Int32.Parse(_parentid);
|
||||
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
|
||||
if (parent.Path == string.Empty)
|
||||
{
|
||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(path);
|
||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(path);
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
if (insert != "=")
|
||||
if (_insert != "=")
|
||||
{
|
||||
Page child;
|
||||
switch (insert)
|
||||
switch (_insert)
|
||||
{
|
||||
case "<<":
|
||||
page.Order = 0;
|
||||
break;
|
||||
case "<":
|
||||
child = PageState.Pages.Where(item => item.PageId == childid).FirstOrDefault();
|
||||
page.Order = child.Order - 1;
|
||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||
if (child != null) page.Order = child.Order - 1;
|
||||
break;
|
||||
case ">":
|
||||
child = PageState.Pages.Where(item => item.PageId == childid).FirstOrDefault();
|
||||
page.Order = child.Order + 1;
|
||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||
if (child != null) page.Order = child.Order + 1;
|
||||
break;
|
||||
case ">>":
|
||||
page.Order = int.MaxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
page.IsNavigation = (isnavigation == null ? true : Boolean.Parse(isnavigation));
|
||||
page.EditMode = (mode == "edit" ? true : false);
|
||||
page.ThemeType = themetype;
|
||||
page.LayoutType = (layouttype == null ? "" : layouttype);
|
||||
page.Icon = (icon == null ? "" : icon);
|
||||
page.Permissions = permissiongrid.GetPermissions();
|
||||
|
||||
if (page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||
page.Url = _url;
|
||||
page.EditMode = (_mode == "edit");
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
page.ThemeType = "";
|
||||
page.ThemeType = string.Empty;
|
||||
}
|
||||
if (page.LayoutType == PageState.Site.DefaultLayoutType)
|
||||
page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.LayoutType) && page.LayoutType == PageState.Site.DefaultLayoutType)
|
||||
{
|
||||
page.LayoutType = "";
|
||||
page.LayoutType = string.Empty;
|
||||
}
|
||||
page.IsPersonalizable = (ispersonalizable == null ? false : Boolean.Parse(ispersonalizable));
|
||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
page.DefaultContainerType = string.Empty;
|
||||
}
|
||||
page.Icon = _icon ?? string.Empty;
|
||||
page.Permissions = _permissionGrid.GetPermissions();
|
||||
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
||||
page.UserId = null;
|
||||
|
||||
await PageService.UpdatePageAsync(page);
|
||||
page = await PageService.UpdatePageAsync(page);
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||
if (currentparentid == "")
|
||||
if (_currentparentid == string.Empty)
|
||||
{
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(currentparentid));
|
||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(_currentparentid));
|
||||
}
|
||||
|
||||
// update child paths
|
||||
if (parentid != currentparentid)
|
||||
if (_parentid != _currentparentid)
|
||||
{
|
||||
foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentpath)))
|
||||
foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath)))
|
||||
{
|
||||
p.Path = p.Path.Replace(currentpath, page.Path);
|
||||
p.Path = p.Path.Replace(currentPath, page.Path);
|
||||
await PageService.UpdatePageAsync(p);
|
||||
}
|
||||
}
|
||||
|
||||
await logger.LogInformation("Page Saved {Page}", page);
|
||||
NavigationManager.NavigateTo(NavigateUrl(page.Path, Reload.Site));
|
||||
NavigationManager.NavigateTo(NavigateUrl(page.Path));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide Page Name And Theme", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide Page Name", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -22,20 +22,21 @@
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private async Task DeletePage(Page Page)
|
||||
private async Task DeletePage(Page page)
|
||||
{
|
||||
try
|
||||
{
|
||||
Page.IsDeleted = true;
|
||||
await PageService.UpdatePageAsync(Page);
|
||||
await logger.LogInformation("Page Deleted {Page}", Page);
|
||||
NavigationManager.NavigateTo(NavigateUrl("admin/pages", Reload.Site));
|
||||
page.IsDeleted = true;
|
||||
|
||||
await PageService.UpdatePageAsync(page);
|
||||
await logger.LogInformation("Page Deleted {Page}", page);
|
||||
NavigationManager.NavigateTo(NavigateUrl("admin/pages"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Page {Page} {Error}", Page, ex.Message);
|
||||
await logger.LogError(ex, "Error Deleting Page {Page} {Error}", page, ex.Message);
|
||||
AddModuleMessage("Error Deleting Page", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,66 +6,66 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="The name of this field">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Title: </label>
|
||||
<Label For="title" HelpText="The title of the field">Title: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@title" />
|
||||
<input id="title" class="form-control" @bind="@_title" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Description: </label>
|
||||
<Label For="description" HelpText="What the profile field is">Description: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@description" rows="5" />
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Category: </label>
|
||||
<Label For="category" HelpText="What larger category does this field belong to">Category: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@category" />
|
||||
<input id="category" class="form-control" @bind="@_category" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Order: </label>
|
||||
<Label For="order" HelpText="What place is this field in a larger category list">Order: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@vieworder" />
|
||||
<input id="order" class="form-control" @bind="@_vieworder" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Length: </label>
|
||||
<Label For="length" HelpText="What is the max amount of characters should this field accept">Length: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@maxlength" />
|
||||
<input id="length" class="form-control" @bind="@_maxlength" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Value: </label>
|
||||
<Label For="defaultVal" HelpText="What value do you want this field to start with">Default Value: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@defaultvalue" />
|
||||
<input id="defaultVal" class="form-control" @bind="@_defaultvalue" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Required? </label>
|
||||
<Label For="required" HelpText="Is a user required to input something into this field?">Required? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isrequired">
|
||||
<select id="required" class="form-control" @bind="@_isrequired">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -73,10 +73,10 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Private? </label>
|
||||
<Label For="private" HelpText="Is this field private?">Private? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isprivate">
|
||||
<select id="private" class="form-control" @bind="@_isprivate">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -87,19 +87,20 @@
|
|||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
public override string Actions { get { return "Add,Edit"; } }
|
||||
private int _profileid = -1;
|
||||
private string _name = string.Empty;
|
||||
private string _title = string.Empty;
|
||||
private string _description = string.Empty;
|
||||
private string _category = string.Empty;
|
||||
private string _vieworder = "0";
|
||||
private string _maxlength = "0";
|
||||
private string _defaultvalue = string.Empty;
|
||||
private string _isrequired = "False";
|
||||
private string _isprivate = "False";
|
||||
|
||||
int profileid = -1;
|
||||
string name = "";
|
||||
string title = "";
|
||||
string description = "";
|
||||
string category = "";
|
||||
string vieworder = "0";
|
||||
string maxlength = "0";
|
||||
string defaultvalue = "";
|
||||
string isrequired = "False";
|
||||
string isprivate = "False";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
public override string Actions => "Add,Edit";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -107,25 +108,25 @@
|
|||
{
|
||||
if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
profileid = Int32.Parse(PageState.QueryString["id"]);
|
||||
Profile profile = await ProfileService.GetProfileAsync(profileid);
|
||||
_profileid = Int32.Parse(PageState.QueryString["id"]);
|
||||
var profile = await ProfileService.GetProfileAsync(_profileid);
|
||||
if (profile != null)
|
||||
{
|
||||
name = profile.Name;
|
||||
title = profile.Title;
|
||||
description = profile.Description;
|
||||
category = profile.Category;
|
||||
vieworder = profile.ViewOrder.ToString();
|
||||
maxlength = profile.MaxLength.ToString();
|
||||
defaultvalue = profile.DefaultValue;
|
||||
isrequired = profile.IsRequired.ToString();
|
||||
isprivate = profile.IsPrivate.ToString();
|
||||
_name = profile.Name;
|
||||
_title = profile.Title;
|
||||
_description = profile.Description;
|
||||
_category = profile.Category;
|
||||
_vieworder = profile.ViewOrder.ToString();
|
||||
_maxlength = profile.MaxLength.ToString();
|
||||
_defaultvalue = profile.DefaultValue;
|
||||
_isrequired = profile.IsRequired.ToString();
|
||||
_isprivate = profile.IsPrivate.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Profile {ProfileId} {Error}", profileid, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Profile {ProfileId} {Error}", _profileid, ex.Message);
|
||||
AddModuleMessage("Error Loading Profile", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -135,30 +136,38 @@
|
|||
try
|
||||
{
|
||||
Profile profile;
|
||||
if (profileid != -1)
|
||||
if (_profileid != -1)
|
||||
{
|
||||
profile = await ProfileService.GetProfileAsync(profileid);
|
||||
profile = await ProfileService.GetProfileAsync(_profileid);
|
||||
}
|
||||
else
|
||||
{
|
||||
profile = new Profile();
|
||||
}
|
||||
profile.Name = name;
|
||||
profile.Title = title;
|
||||
profile.Description = description;
|
||||
profile.Category = category;
|
||||
profile.ViewOrder = int.Parse(vieworder);
|
||||
profile.MaxLength = int.Parse(maxlength);
|
||||
profile.DefaultValue = defaultvalue;
|
||||
profile.IsRequired = (isrequired == null ? false : Boolean.Parse(isrequired));
|
||||
profile.IsPrivate = (isprivate == null ? false : Boolean.Parse(isprivate));
|
||||
|
||||
profile.Name = _name;
|
||||
profile.Title = _title;
|
||||
profile.Description = _description;
|
||||
profile.Category = _category;
|
||||
profile.ViewOrder = int.Parse(_vieworder);
|
||||
profile.MaxLength = int.Parse(_maxlength);
|
||||
profile.DefaultValue = _defaultvalue;
|
||||
profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
|
||||
profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
|
||||
if (_profileid != -1)
|
||||
{
|
||||
profile = await ProfileService.UpdateProfileAsync(profile);
|
||||
}else
|
||||
{
|
||||
profile = await ProfileService.AddProfileAsync(profile);
|
||||
}
|
||||
|
||||
await logger.LogInformation("Profile Saved {Profile}", profile);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Profile {ProfleId} {Error}", profileid, ex.Message);
|
||||
await logger.LogError(ex, "Error Saving Profile {ProfleId} {Error}", _profileid, ex.Message);
|
||||
AddModuleMessage("Error Saving Profile", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@inherits ModuleBase
|
||||
@inject IProfileService ProfileService
|
||||
|
||||
@if (Profiles == null)
|
||||
@if (_profiles == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Security="SecurityAccessLevel.Admin" Text="Add Profile" />
|
||||
|
||||
<Pager Items="@Profiles">
|
||||
<Pager Items="@_profiles">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
|
@ -25,26 +25,26 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<Profile> _profiles;
|
||||
|
||||
List<Profile> Profiles;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
Profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
||||
_profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
||||
}
|
||||
|
||||
private async Task DeleteProfile(int ProfileId)
|
||||
private async Task DeleteProfile(int profileId)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ProfileService.DeleteProfileAsync(ProfileId);
|
||||
await logger.LogInformation("Profile Deleted {ProfileId}", ProfileId);
|
||||
await ProfileService.DeleteProfileAsync(profileId);
|
||||
await logger.LogInformation("Profile Deleted {ProfileId}", profileId);
|
||||
AddModuleMessage("Profile Deleted", MessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Profile {ProfileId} {Error}", ProfileId, ex.Message);
|
||||
await logger.LogError(ex, "Error Deleting Profile {ProfileId} {Error}", profileId, ex.Message);
|
||||
AddModuleMessage("Error Deleting Profile", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,76 +5,74 @@
|
|||
@inject IModuleService ModuleService
|
||||
@inject IPageService PageService
|
||||
|
||||
<TabControl>
|
||||
<TabPanel Text="Pages">
|
||||
@if (pages.Count == 0)
|
||||
<TabStrip>
|
||||
<TabPanel Name="Pages">
|
||||
@if (_pages == null)
|
||||
{
|
||||
<br/>
|
||||
<br />
|
||||
<p>No Deleted Pages</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Pager Items="@pages">
|
||||
<Pager Items="@_pages">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th>Name</th>
|
||||
<th>Deleted By</th>
|
||||
<th>Deleted On</th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><button @onclick="@(() => RestorePage(context))" class="btn btn-info" title="Restore">Restore</button></td>
|
||||
<td><ActionDialog Header="Delete Page" Message="@("Are You Sure You Wish To Permanently Delete The " + context.Name + " Page?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" /></td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.DeletedBy</td>
|
||||
<td>@context.DeletedOn</td>
|
||||
<td><button @onclick="@(() => RestorePage(context))" class="btn btn-info" title="Restore">Restore</button></td>
|
||||
<td><button @onclick="@(() => DeletePage(context.PageId))" class="btn btn-danger">Delete</button></td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Text="Modules">
|
||||
@if (pageModules.Count == 0)
|
||||
<TabPanel Name="Modules">
|
||||
@if (_modules == null)
|
||||
{
|
||||
<br/>
|
||||
<br />
|
||||
<p>No Deleted Modules</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Pager Items="@pageModules">
|
||||
<Pager Items="@_modules">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th>Page</th>
|
||||
<th>Module</th>
|
||||
<th>Deleted By</th>
|
||||
<th>Deleted On</th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><button @onclick="@(() => RestoreModule(context))" class="btn btn-info" title="Restore">Restore</button></td>
|
||||
<td><ActionDialog Header="Delete Module" Message="@("Are You Sure You Wish To Permanently Delete The " + context.Title + " Module?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" /></td>
|
||||
<td>@PageState.Pages.Find(item => item.PageId == context.PageId).Name</td>
|
||||
<td>@context.Title</td>
|
||||
<td>@context.DeletedBy</td>
|
||||
<td>@context.DeletedOn</td>
|
||||
<td><button @onclick="@(() => RestorePageModule(context))" class="btn btn-info" title="Restore">Restore</button></td>
|
||||
<td><button @onclick="@(() => DeletePageModule(context.PageModuleId, context.ModuleId))" class="btn btn-danger">Delete</button></td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
</TabPanel>
|
||||
</TabControl>
|
||||
</TabStrip>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<Page> _pages;
|
||||
private List<Module> _modules;
|
||||
|
||||
List<Page> pages { get; set; }
|
||||
List<PageModule> pageModules { get; set; }
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
pages = new List<Page>();
|
||||
pageModules = new List<PageModule>();
|
||||
await LoadEntities();
|
||||
await Load();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -83,92 +81,89 @@
|
|||
}
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
private async Task Load()
|
||||
{
|
||||
pages = PageState.Pages.Where(item => item.IsDeleted).ToList();
|
||||
_pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
||||
_pages = _pages.Where(item => item.IsDeleted).ToList();
|
||||
|
||||
_modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId);
|
||||
_modules = _modules.Where(item => item.IsDeleted).ToList();
|
||||
}
|
||||
|
||||
private async Task LoadEntities()
|
||||
{
|
||||
pageModules.Clear();
|
||||
foreach (var module in PageState.Modules.Where(item => item.IsDeleted))
|
||||
{
|
||||
var pageModule = await PageModuleService.GetPageModuleAsync(module.PageModuleId);
|
||||
pageModules.Add(pageModule);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RestorePage(Page Page)
|
||||
private async Task RestorePage(Page page)
|
||||
{
|
||||
try
|
||||
{
|
||||
Page.IsDeleted = false;
|
||||
await PageService.UpdatePageAsync(Page);
|
||||
await logger.LogInformation("Page Restored {Page}", Page);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
page.IsDeleted = false;
|
||||
await PageService.UpdatePageAsync(page);
|
||||
await logger.LogInformation("Page Restored {Page}", page);
|
||||
await Load();
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Restoring Deleted Page {Page} {Error}", Page, ex.Message);
|
||||
await logger.LogError(ex, "Error Restoring Deleted Page {Page} {Error}", page, ex.Message);
|
||||
AddModuleMessage("Error Restoring Deleted Page", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeletePage(int PageId)
|
||||
private async Task DeletePage(Page page)
|
||||
{
|
||||
try
|
||||
{
|
||||
var deletedPageModules = PageState.Modules.Where(item => item.PageId == PageId);
|
||||
await PageService.DeletePageAsync(PageId);
|
||||
foreach (var module in deletedPageModules)
|
||||
{
|
||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
||||
}
|
||||
await logger.LogInformation("Page Permanently Deleted {PageId}", PageId);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
await PageService.DeletePageAsync(page.PageId);
|
||||
await logger.LogInformation("Page Permanently Deleted {Page}", page);
|
||||
await Load();
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Permanently Deleting Page {PageId} {Error}", PageId, ex.Message);
|
||||
await logger.LogError(ex, "Error Permanently Deleting Page {Page} {Error}", page, ex.Message);
|
||||
AddModuleMessage(ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RestorePageModule(PageModule PageModule)
|
||||
private async Task RestoreModule(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
PageModule.IsDeleted = false;
|
||||
await PageModuleService.UpdatePageModuleAsync(PageModule);
|
||||
await LoadEntities();
|
||||
await logger.LogInformation("Page Module Restored {PageModule}", PageModule);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
var pagemodule = await PageModuleService.GetPageModuleAsync(module.PageModuleId);
|
||||
pagemodule.IsDeleted = false;
|
||||
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
||||
await logger.LogInformation("Module Restored {Module}", module);
|
||||
await Load();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Restoring Deleted Page Module {PageModule} {Error}", PageModule, ex.Message);
|
||||
AddModuleMessage("Error Restoring Deleted Page Module", MessageType.Error);
|
||||
await logger.LogError(ex, "Error Restoring Deleted Module {Module} {Error}", module, ex.Message);
|
||||
AddModuleMessage("Error Restoring Deleted Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeletePageModule(int PageModuleId, int ModuleId)
|
||||
private async Task DeleteModule(Module module)
|
||||
{
|
||||
try
|
||||
{
|
||||
await PageModuleService.DeletePageModuleAsync(PageModuleId);
|
||||
if (PageState.Modules.Count(item => item.ModuleId == ModuleId) == 1)
|
||||
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
||||
// check if there are any remaining module instances in the site
|
||||
_modules = await ModuleService.GetModulesAsync(PageState.Site.SiteId);
|
||||
|
||||
if (!_modules.Exists(item => item.ModuleId == module.ModuleId))
|
||||
{
|
||||
await ModuleService.DeleteModuleAsync(ModuleId);
|
||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
||||
}
|
||||
PageState.Modules.RemoveAt(PageState.Modules.FindIndex(item => item.ModuleId == ModuleId));
|
||||
await LoadEntities();
|
||||
await logger.LogInformation("Page Module Permanently Deleted {PageModuleId}", PageModuleId);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
|
||||
await logger.LogInformation("Module Permanently Deleted {Module}", module);
|
||||
await Load();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Permanently Deleting Page Module {PageModuleId} {Error}", PageModuleId, ex.Message);
|
||||
AddModuleMessage("Error Permanently Deleting Page Module", MessageType.Error);
|
||||
await logger.LogError(ex, "Error Permanently Deleting Module {Module} {Error}", module, ex.Message);
|
||||
AddModuleMessage("Error Permanently Deleting Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,71 +3,87 @@
|
|||
@inject NavigationManager NavigationManager
|
||||
@inject IUserService UserService
|
||||
|
||||
@if (Message != "")
|
||||
@if (PageState.Site.AllowRegistration)
|
||||
{
|
||||
<ModuleMessage Message="@Message" Type="MessageType.Info" />
|
||||
}
|
||||
<AuthorizeView>
|
||||
<Authorizing>
|
||||
<text>...</text>
|
||||
</Authorizing>
|
||||
<Authorized>
|
||||
<ModuleMessage Message="You Are Already Registered" Type="MessageType.Info" />
|
||||
</Authorized>
|
||||
<NotAuthorized>
|
||||
<ModuleMessage Message="Please Note That Registration Requires A Valid Email Address In Order To Verify Your Identity" Type="MessageType.Info" />
|
||||
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">Username: </label>
|
||||
<input type="text" class="form-control" placeholder="Username" @bind="@Username" />
|
||||
<input type="text" class="form-control" placeholder="Username" @bind="@_username" id="Username" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">Password: </label>
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@Password" />
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">Confirm Password: </label>
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@Confirm" />
|
||||
<label for="Confirm" class="control-label">Confirm Password: </label>
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">Email: </label>
|
||||
<input type="text" class="form-control" placeholder="Email" @bind="@Email" />
|
||||
<label for="Email" class="control-label">Email: </label>
|
||||
<input type="text" class="form-control" placeholder="Email" @bind="@_email" id="Email" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="DisplayName" class="control-label">Full Name: </label>
|
||||
<input type="text" class="form-control" placeholder="Full Name" @bind="@DisplayName" />
|
||||
<input type="text" class="form-control" placeholder="Full Name" @bind="@_displayName" id="DisplayName" />
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" @onclick="Register">Register</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</NotAuthorized>
|
||||
</AuthorizeView>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ModuleMessage Message="Registration is Disabled For This Site" Type="MessageType.Info" />
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } }
|
||||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private string _confirm = string.Empty;
|
||||
private string _email = string.Empty;
|
||||
private string _displayName = string.Empty;
|
||||
|
||||
string Message = "Please Note That Registration Requires A Valid Email Address In Order To Verify Your Identity";
|
||||
string Username = "";
|
||||
string Password = "";
|
||||
string Confirm = "";
|
||||
string Email = "";
|
||||
string DisplayName = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
private async Task Register()
|
||||
{
|
||||
try
|
||||
{
|
||||
Message = "";
|
||||
if (Username != "" && Password != "" && Confirm != "" && Email != "")
|
||||
bool _isEmailValid = Utilities.IsValidEmail(_email);
|
||||
|
||||
if (_username != "" && _password != "" && _confirm != "" && _isEmailValid)
|
||||
{
|
||||
if (Password == Confirm)
|
||||
if (_password == _confirm)
|
||||
{
|
||||
User user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user.DisplayName = (DisplayName == "" ? Username : DisplayName);
|
||||
user.Email = Email;
|
||||
user.Password = Password;
|
||||
var user = new User
|
||||
{
|
||||
SiteId = PageState.Site.SiteId,
|
||||
Username = _username,
|
||||
DisplayName = (_displayName == string.Empty ? _username : _displayName),
|
||||
Email = _email,
|
||||
Password = _password
|
||||
};
|
||||
user = await UserService.AddUserAsync(user);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
await logger.LogInformation("User Created {Username} {Email}", Username, Email);
|
||||
await logger.LogInformation("User Created {Username} {Email}", _username, _email);
|
||||
AddModuleMessage("User Account Created. Please Check Your Email For Verification Instructions.", MessageType.Info);
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Error Adding User {Username} {Email}", Username, Email);
|
||||
await logger.LogError("Error Adding User {Username} {Email}", _username, _email);
|
||||
AddModuleMessage("Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -83,13 +99,13 @@
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", Username, Email, ex.Message);
|
||||
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", _username, _email, ex.Message);
|
||||
AddModuleMessage("Error Adding User", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
NavigationManager.NavigateTo(NavigateUrl(""));
|
||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
||||
}
|
||||
}
|
|
@ -6,36 +6,36 @@
|
|||
<div class="container">
|
||||
<div class="form-group">
|
||||
<label for="Username" class="control-label">Username: </label>
|
||||
<input type="text" class="form-control" placeholder="Username" @bind="@Username" readonly />
|
||||
<input type="text" class="form-control" placeholder="Username" @bind="@_username" readonly id="Username"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">Password: </label>
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@Password" />
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="Password" class="control-label">Confirm Password: </label>
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@Confirm" />
|
||||
<label for="Confirm" class="control-label">Confirm Password: </label>
|
||||
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm"/>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary" @onclick="Reset">Reset Password</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } }
|
||||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private string _confirm = string.Empty;
|
||||
|
||||
string Username = "";
|
||||
string Password = "";
|
||||
string Confirm = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token"))
|
||||
{
|
||||
Username = PageState.QueryString["name"];
|
||||
_username = PageState.QueryString["name"];
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigationManager.NavigateTo(NavigateUrl(""));
|
||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,24 +43,26 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
if (Username != "" && Password != "" && Confirm != "")
|
||||
if (_username != string.Empty && _password != string.Empty && _confirm != string.Empty)
|
||||
{
|
||||
if (Password == Confirm)
|
||||
if (_password == _confirm)
|
||||
{
|
||||
User user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = Username;
|
||||
user.Password = Password;
|
||||
var user = new User
|
||||
{
|
||||
SiteId = PageState.Site.SiteId,
|
||||
Username = _username,
|
||||
Password = _password
|
||||
};
|
||||
user = await UserService.ResetPasswordAsync(user, PageState.QueryString["token"]);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
await logger.LogInformation("User Password Reset {Username}", Username);
|
||||
await logger.LogInformation("User Password Reset {Username}", _username);
|
||||
NavigationManager.NavigateTo(NavigateUrl("login"));
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Error Resetting User Password {Username}", Username);
|
||||
await logger.LogError("Error Resetting User Password {Username}", _username);
|
||||
AddModuleMessage("Error Resetting User Password. Please Ensure Password Meets Complexity Requirements.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -76,13 +78,13 @@
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Resetting User Password {Username} {Error}", Username, ex.Message);
|
||||
await logger.LogError(ex, "Error Resetting User Password {Username} {Error}", _username, ex.Message);
|
||||
AddModuleMessage("Error Resetting User Password", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void Cancel()
|
||||
{
|
||||
NavigationManager.NavigateTo(NavigateUrl(""));
|
||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,37 +6,26 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="Name Of The Role">Name:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Description: </label>
|
||||
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose">Description:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@description" rows="5" />
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Auto Assigned? </label>
|
||||
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role">Auto Assigned?</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isautoassigned">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">System Role? </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@issystem">
|
||||
<select id="isautoassigned" class="form-control" @bind="@_isautoassigned">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -47,21 +36,20 @@
|
|||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private string _name = string.Empty;
|
||||
private string _description = string.Empty;
|
||||
private string _isautoassigned = "False";
|
||||
|
||||
string name = "";
|
||||
string description = "";
|
||||
string isautoassigned = "False";
|
||||
string issystem = "False";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
private async Task SaveRole()
|
||||
{
|
||||
Role role = new Role();
|
||||
var role = new Role();
|
||||
role.SiteId = PageState.Page.SiteId;
|
||||
role.Name = name;
|
||||
role.Description = description;
|
||||
role.IsAutoAssigned = (isautoassigned == null ? false : Boolean.Parse(isautoassigned));
|
||||
role.IsSystem = (issystem == null ? false : Boolean.Parse(issystem));
|
||||
role.Name = _name;
|
||||
role.Description = _description;
|
||||
role.IsAutoAssigned = (_isautoassigned == null ? false : Boolean.Parse(_isautoassigned));
|
||||
role.IsSystem = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -6,37 +6,26 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="Name Of The Role">Name:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Description: </label>
|
||||
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose">Description:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@description" rows="5" />
|
||||
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Auto Assigned? </label>
|
||||
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role">Auto Assigned?</Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isautoassigned">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">System Role? </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@issystem">
|
||||
<select id="isautoassigned" class="form-control" @bind="@_isautoassigned">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
|
@ -47,42 +36,40 @@
|
|||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private int _roleid;
|
||||
private string _name = string.Empty;
|
||||
private string _description = string.Empty;
|
||||
private string _isautoassigned = "False";
|
||||
|
||||
int roleid;
|
||||
string name = "";
|
||||
string description = "";
|
||||
string isautoassigned = "False";
|
||||
string issystem = "False";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
roleid = Int32.Parse(PageState.QueryString["id"]);
|
||||
Role role = await RoleService.GetRoleAsync(roleid);
|
||||
_roleid = Int32.Parse(PageState.QueryString["id"]);
|
||||
var role = await RoleService.GetRoleAsync(_roleid);
|
||||
if (role != null)
|
||||
{
|
||||
name = role.Name;
|
||||
description = role.Description;
|
||||
isautoassigned = role.IsAutoAssigned.ToString();
|
||||
issystem = role.IsSystem.ToString();
|
||||
_name = role.Name;
|
||||
_description = role.Description;
|
||||
_isautoassigned = role.IsAutoAssigned.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Role {RoleId} {Error}", roleid, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Role {RoleId} {Error}", _roleid, ex.Message);
|
||||
AddModuleMessage("Error Loading Role", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveRole()
|
||||
{
|
||||
Role role = await RoleService.GetRoleAsync(roleid);
|
||||
role.Name = name;
|
||||
role.Description = description;
|
||||
role.IsAutoAssigned = (isautoassigned == null ? false : Boolean.Parse(isautoassigned));
|
||||
role.IsSystem = (issystem == null ? false : Boolean.Parse(issystem));
|
||||
var role = await RoleService.GetRoleAsync(_roleid);
|
||||
role.Name = _name;
|
||||
role.Description = _description;
|
||||
role.IsAutoAssigned = (_isautoassigned != null && Boolean.Parse(_isautoassigned));
|
||||
role.IsSystem = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
@inherits ModuleBase
|
||||
@inject IRoleService RoleService
|
||||
|
||||
@if (Roles == null)
|
||||
@if (_roles == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
|
@ -10,41 +10,43 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Role" />
|
||||
|
||||
<Pager Items="@Roles">
|
||||
<Pager Items="@_roles">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th>Name</th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.RoleId.ToString())" /></td>
|
||||
<td><ActionDialog Header="Delete Role" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Role?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteRole(context))" /></td>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.RoleId.ToString())" Disabled="@(context.IsSystem)" /></td>
|
||||
<td><ActionDialog Header="Delete Role" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Role?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteRole(context))" Disabled="@(context.IsSystem)" /></td>
|
||||
<td><ActionLink Action="Users" Parameters="@($"id=" + context.RoleId.ToString())" /></td>
|
||||
<td>@context.Name</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<Role> _roles;
|
||||
|
||||
List<Role> Roles;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
|
||||
_roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
|
||||
}
|
||||
|
||||
private async Task DeleteRole(Role Role)
|
||||
private async Task DeleteRole(Role role)
|
||||
{
|
||||
try
|
||||
{
|
||||
await RoleService.DeleteRoleAsync(Role.RoleId);
|
||||
await logger.LogInformation("Role Deleted {Role}", Role);
|
||||
await RoleService.DeleteRoleAsync(role.RoleId);
|
||||
await logger.LogInformation("Role Deleted {Role}", role);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Role {Role} {Error}", Role, ex.Message);
|
||||
await logger.LogError(ex, "Error Deleting Role {Role} {Error}", role, ex.Message);
|
||||
AddModuleMessage("Error Deleting Role", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
201
Oqtane.Client/Modules/Admin/Roles/Users.razor
Normal file
201
Oqtane.Client/Modules/Admin/Roles/Users.razor
Normal file
|
@ -0,0 +1,201 @@
|
|||
@namespace Oqtane.Modules.Admin.Roles
|
||||
@inherits ModuleBase
|
||||
@inject IRoleService RoleService
|
||||
@inject IUserRoleService UserRoleService
|
||||
|
||||
@if (userroles == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="role" HelpText="The role you are assigning users to">Role: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="role" class="form-control" @bind="@name" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="user" HelpText="Select a user">User: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="user" class="form-control" @bind="@userid">
|
||||
<option value="-1"><Select User></option>
|
||||
@foreach (UserRole userrole in users)
|
||||
{
|
||||
<option value="@(userrole.UserId)">@userrole.User.DisplayName</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="effectiveDate" HelpText="The date that this role assignment is active">Effective Date: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="effectiveDate" class="form-control" @bind="@effectivedate" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="expiryDate" HelpText="The date that this role assignment expires">Expiry Date: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="expiryDate" class="form-control" @bind="@expirydate" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveUserRole">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
<hr class="app-rule" />
|
||||
<p align="center">
|
||||
<Pager Items="@userroles">
|
||||
<Header>
|
||||
<th>Users</th>
|
||||
<th> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td>@context.User.DisplayName</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-danger" @onclick=@(async () => await DeleteUserRole(context.UserRoleId))>Delete</button>
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
</p>
|
||||
}
|
||||
|
||||
@code {
|
||||
private int roleid;
|
||||
private string name = string.Empty;
|
||||
private List<UserRole> users;
|
||||
private int userid = -1;
|
||||
private string effectivedate = string.Empty;
|
||||
private string expirydate = string.Empty;
|
||||
private List<UserRole> userroles;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
roleid = Int32.Parse(PageState.QueryString["id"]);
|
||||
Role role = await RoleService.GetRoleAsync(roleid);
|
||||
name = role.Name;
|
||||
users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
||||
users = users.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
||||
await GetUserRoles();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Users", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GetUserRoles()
|
||||
{
|
||||
try
|
||||
{
|
||||
userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
||||
userroles = userroles.Where(item => item.RoleId == roleid).ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading User Roles {RoleId} {Error}", roleid, ex.Message);
|
||||
AddModuleMessage("Error Loading User Roles", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveUserRole()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (userid != -1)
|
||||
{
|
||||
var userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault();
|
||||
if (userrole != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(effectivedate))
|
||||
{
|
||||
userrole.EffectiveDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
userrole.EffectiveDate = DateTime.Parse(effectivedate);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(expirydate))
|
||||
{
|
||||
userrole.ExpiryDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
userrole.ExpiryDate = DateTime.Parse(expirydate);
|
||||
}
|
||||
await UserRoleService.UpdateUserRoleAsync(userrole);
|
||||
}
|
||||
else
|
||||
{
|
||||
userrole = new UserRole();
|
||||
userrole.UserId = userid;
|
||||
userrole.RoleId = roleid;
|
||||
|
||||
if (string.IsNullOrEmpty(effectivedate))
|
||||
{
|
||||
userrole.EffectiveDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
userrole.EffectiveDate = DateTime.Parse(effectivedate);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(expirydate))
|
||||
{
|
||||
userrole.ExpiryDate = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
userrole.ExpiryDate = DateTime.Parse(expirydate);
|
||||
}
|
||||
|
||||
await UserRoleService.AddUserRoleAsync(userrole);
|
||||
}
|
||||
|
||||
await GetUserRoles();
|
||||
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
|
||||
AddModuleMessage("User Assigned To Role", MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Select A User", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving User Roles {RoleId} {Error}", roleid, ex.Message);
|
||||
AddModuleMessage("Error Saving User Roles", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteUserRole(int UserRoleId)
|
||||
{
|
||||
try
|
||||
{
|
||||
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
|
||||
await GetUserRoles();
|
||||
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
|
||||
AddModuleMessage("User Removed From Role", MessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message);
|
||||
AddModuleMessage("Error Removing User From Role", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
451
Oqtane.Client/Modules/Admin/Site/Index.razor
Normal file
451
Oqtane.Client/Modules/Admin/Site/Index.razor
Normal file
|
@ -0,0 +1,451 @@
|
|||
@namespace Oqtane.Modules.Admin.Site
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ISiteService SiteService
|
||||
@inject ITenantService TenantService
|
||||
@inject IAliasService AliasService
|
||||
@inject IThemeService ThemeService
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (_themes != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="name" HelpText="Enter the site name">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="tenant" HelpText="Enter the tenant for the site">Tenant: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="alias" HelpText="Enter the alias for the server">Aliases: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="logo" HelpText="Upload a logo for the site">Logo: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="favicon" HelpText="Select Your default icon">Favicon: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultTheme" HelpText="Select the sites default theme">Default Theme: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
{
|
||||
if (item.Key == _themetype)
|
||||
{
|
||||
<option value="@item.Key" selected>@item.Value</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@item.Key">@item.Value</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||
<option value=""><Select Layout></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
||||
{
|
||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||
<option value=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="allowRegister" HelpText="Do you want the users to be able to register for an account on the site">Allow User Registration? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="allowRegister" class="form-control" @bind="@_allowregistration">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="isDeleted" HelpText="Is this site deleted?">Is Deleted? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="isDeleted" class="form-control" @bind="@_isdeleted">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<Section Name="SMTP" Heading="SMTP Settings">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="host" HelpText="Enter the host name of the server">Host: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="host" class="form-control" @bind="@_smtphost" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="port" HelpText="Enter the port number for the server">Port: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="port" class="form-control" @bind="@_smtpport" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="enabledSSl" HelpText="Specifiy if SSL is enabled for your server">SSL Enabled: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="enabledSSl" class="form-control" @bind="@_smtpssl" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="username" HelpText="Enter the username for the server">Username: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="username" class="form-control" @bind="@_smtpusername" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="password" HelpText="Enter the password for the server">Password: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="password" type="password" class="form-control" @bind="@_smtppassword" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
<Section Name="PWA" Heading="Progressive Web Application Settings">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="isEnabled" HelpText="Select whether you would like this site to be available as a Progressive Web Application (PWA)">Is Enabled? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="isEnabled" class="form-control" @bind="@_pwaisenabled">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="appIcon" HelpText="Include an application icon for your PWA. It should be a PNG which is 192 X 192 pixels in dimension.">App Icon: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager FileId="@_pwaappiconfileid" Filter="png" @ref="_pwaappiconfilemanager" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="splashIcon" HelpText="Include a splash icon for your PWA. It should be a PNG which is 512 X 512 pixels in dimension.">Splash Icon: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager FileId="@_pwasplashiconfileid" Filter="png" @ref="_pwasplashiconfilemanager" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSite">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
|
||||
}
|
||||
|
||||
@code {
|
||||
private Dictionary<string, string> _themes;
|
||||
private Dictionary<string, string> _panelayouts;
|
||||
private Dictionary<string, string> _containers;
|
||||
private List<Theme> _themeList;
|
||||
private string _name = string.Empty;
|
||||
private List<Tenant> _tenantList;
|
||||
private string _tenant = string.Empty;
|
||||
private List<Alias> _aliasList;
|
||||
private string _urls = string.Empty;
|
||||
private int _logofileid = -1;
|
||||
private FileManager _logofilemanager;
|
||||
private int _faviconfileid = -1;
|
||||
private FileManager _faviconfilemanager;
|
||||
private string _themetype;
|
||||
private string _layouttype;
|
||||
private string _containertype;
|
||||
private string _allowregistration;
|
||||
private string _smtphost = string.Empty;
|
||||
private string _smtpport = string.Empty;
|
||||
private string _smtpssl = string.Empty;
|
||||
private string _smtpusername = string.Empty;
|
||||
private string _smtppassword = string.Empty;
|
||||
private string _pwaisenabled;
|
||||
private int _pwaappiconfileid = -1;
|
||||
private FileManager _pwaappiconfilemanager;
|
||||
private int _pwasplashiconfileid = -1;
|
||||
private FileManager _pwasplashiconfilemanager;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
private string _isdeleted;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_aliasList = await AliasService.GetAliasesAsync();
|
||||
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
_name = site.Name;
|
||||
_tenantList = await TenantService.GetTenantsAsync();
|
||||
_tenant = _tenantList.Find(item => item.TenantId == site.TenantId).Name;
|
||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
||||
{
|
||||
_urls += alias.Name + "\n";
|
||||
}
|
||||
if (site.LogoFileId != null)
|
||||
{
|
||||
_logofileid = site.LogoFileId.Value;
|
||||
}
|
||||
|
||||
if (site.FaviconFileId != null)
|
||||
{
|
||||
_faviconfileid = site.FaviconFileId.Value;
|
||||
}
|
||||
|
||||
_themetype = site.DefaultThemeType;
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
_layouttype = site.DefaultLayoutType;
|
||||
_containertype = site.DefaultContainerType;
|
||||
_allowregistration = site.AllowRegistration.ToString();
|
||||
|
||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
|
||||
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
|
||||
_smtpssl = SettingService.GetSetting(settings, "SMTPSSL", string.Empty);
|
||||
_smtpusername = SettingService.GetSetting(settings, "SMTPUsername", string.Empty);
|
||||
_smtppassword = SettingService.GetSetting(settings, "SMTPPassword", string.Empty);
|
||||
|
||||
_pwaisenabled = site.PwaIsEnabled.ToString();
|
||||
|
||||
if (site.PwaAppIconFileId != null)
|
||||
{
|
||||
_pwaappiconfileid = site.PwaAppIconFileId.Value;
|
||||
}
|
||||
|
||||
if (site.PwaSplashIconFileId != null)
|
||||
{
|
||||
_pwasplashiconfileid = site.PwaSplashIconFileId.Value;
|
||||
}
|
||||
|
||||
_pwaisenabled = site.PwaIsEnabled.ToString();
|
||||
if (site.PwaAppIconFileId != null)
|
||||
{
|
||||
_pwaappiconfileid = site.PwaAppIconFileId.Value;
|
||||
}
|
||||
if (site.PwaSplashIconFileId != null)
|
||||
{
|
||||
_pwasplashiconfileid = site.PwaSplashIconFileId.Value;
|
||||
}
|
||||
|
||||
_createdby = site.CreatedBy;
|
||||
_createdon = site.CreatedOn;
|
||||
_modifiedby = site.ModifiedBy;
|
||||
_modifiedon = site.ModifiedOn;
|
||||
_deletedby = site.DeletedBy;
|
||||
_deletedon = site.DeletedOn;
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
}
|
||||
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message);
|
||||
AddModuleMessage(ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async void ThemeChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != string.Empty)
|
||||
{
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
_panelayouts = new Dictionary<string, string>();
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveSite()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
var unique = true;
|
||||
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
|
||||
{
|
||||
unique = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (unique)
|
||||
{
|
||||
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
site.Name = _name;
|
||||
site.LogoFileId = null;
|
||||
var logofileid = _logofilemanager.GetFileId();
|
||||
if (logofileid != -1)
|
||||
{
|
||||
site.LogoFileId = logofileid;
|
||||
}
|
||||
|
||||
site.DefaultThemeType = _themetype;
|
||||
site.DefaultLayoutType = (_layouttype == null ? string.Empty : _layouttype);
|
||||
site.DefaultContainerType = _containertype;
|
||||
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
|
||||
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
||||
|
||||
site.PwaIsEnabled = (_pwaisenabled == null ? true : Boolean.Parse(_pwaisenabled));
|
||||
|
||||
var pwaappiconfileid = _pwaappiconfilemanager.GetFileId();
|
||||
if (pwaappiconfileid != -1)
|
||||
{
|
||||
site.PwaAppIconFileId = pwaappiconfileid;
|
||||
}
|
||||
|
||||
var pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId();
|
||||
if (pwasplashiconfileid != -1)
|
||||
{
|
||||
site.PwaSplashIconFileId = pwasplashiconfileid;
|
||||
}
|
||||
|
||||
site = await SiteService.UpdateSiteAsync(site);
|
||||
|
||||
_urls = _urls.Replace("\n", ",");
|
||||
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
||||
{
|
||||
if (!names.Contains(alias.Name))
|
||||
{
|
||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
if (!_aliasList.Exists(item => item.Name == name))
|
||||
{
|
||||
Alias alias = new Alias();
|
||||
alias.Name = name;
|
||||
alias.TenantId = site.TenantId;
|
||||
alias.SiteId = site.SiteId;
|
||||
await AliasService.AddAliasAsync(alias);
|
||||
}
|
||||
}
|
||||
|
||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
|
||||
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
|
||||
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
|
||||
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
|
||||
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
|
||||
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
||||
|
||||
await logger.LogInformation("Site Saved {Site}", site);
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("An Alias Specified Has Already Been Used For Another Site", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Site Name, Alias, And Default Theme/Container", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message);
|
||||
AddModuleMessage("Error Saving Site", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,9 +5,11 @@
|
|||
@inject IAliasService AliasService
|
||||
@inject ISiteService SiteService
|
||||
@inject IThemeService ThemeService
|
||||
@inject ISiteTemplateService SiteTemplateService
|
||||
@inject IUserService UserService
|
||||
@inject IInstallationService InstallationService
|
||||
|
||||
@if (tenants == null)
|
||||
@if (_tenants == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
|
@ -16,50 +18,28 @@ else
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Tenant: </label>
|
||||
<Label For="name" HelpText="Enter the name of the site">Site Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => TenantChanged(e))">
|
||||
<option value="-1"><Select Tenant></option>
|
||||
@foreach (Tenant tenant in tenants)
|
||||
{
|
||||
<option value="@tenant.TenantId">@tenant.Name</option>
|
||||
}
|
||||
</select>
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="alias" HelpText="Enter the alias for the server">Aliases: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Aliases: </label>
|
||||
<Label For="defaultTheme" HelpText="Select the default theme for the website">Default Theme: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@urls" rows="3" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Logo: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@logo" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Theme: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in themes)
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
{
|
||||
<option value="@item.Key">@item.Value</option>
|
||||
}
|
||||
|
@ -68,12 +48,12 @@ else
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Layout: </label>
|
||||
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@layouttype">
|
||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||
<option value=""><Select Layout></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
|
||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
||||
{
|
||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
||||
}
|
||||
|
@ -82,34 +62,133 @@ else
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Container: </label>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@containertype">
|
||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||
<option value=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string>container in containers)
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!isinitialized)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Host Username:</label>
|
||||
<Label For="siteTemplate" HelpText="Select the site template">Site Template: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@username" readonly />
|
||||
<select id="siteTemplate" class="form-control" @bind="@_sitetemplatetype">
|
||||
<option value=""><Select Site Template></option>
|
||||
@foreach (SiteTemplate siteTemplate in _siteTemplates)
|
||||
{
|
||||
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Host Password:</label>
|
||||
<Label For="tenant" HelpText="Select the tenant for the site">Tenant: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@password" />
|
||||
<select id="tenant" class="form-control" @onchange="(e => TenantChanged(e))">
|
||||
<option value="-"><Select Tenant></option>
|
||||
<option value="+"><Create New Tenant></option>
|
||||
@foreach (Tenant tenant in _tenants)
|
||||
{
|
||||
<option value="@tenant.TenantId">@tenant.Name</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (_tenantid == "+")
|
||||
{
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<hr class="app-rule" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="name" HelpText="Enter the name for the tenant">Tenant Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="name" class="form-control" @bind="@_tenantname" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="databaseType" HelpText="Select the database type for the tenant">Database Type: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="databaseType" class="custom-select" @bind="@_databasetype">
|
||||
<option value="LocalDB">Local Database</option>
|
||||
<option value="SQLServer">SQL Server</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="server" HelpText="Enter the server for the tenant">Server: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="server" type="text" class="form-control" @bind="@_server" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="database" HelpText="Enter the database for the tenant">Database: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="database" type="text" class="form-control" @bind="@_database" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="integratedSecurity" HelpText="Select if you want integrated security or not">Integrated Security: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="integratedSecurity" class="custom-select" @onchange="SetIntegratedSecurity">
|
||||
<option value="true" selected>True</option>
|
||||
<option value="false">False</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
@if (!_integratedsecurity)
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="username" HelpText="Enter the username for the integrated security">Database Username: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="username" type="text" class="form-control" @bind="@_username" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="password" HelpText="Enter the password for the integrated security">Database Password: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="password" type="password" class="form-control" @bind="@_password" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="hostUsername" HelpText="Enter the username of the host for this site">Host Username:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="hostUsername" class="form-control" @bind="@_hostusername" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="hostPassword" HelpText="Enter the password for the host of this site">Host Password:</Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="hostPassword" type="password" class="form-control" @bind="@_hostpassword" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
@ -119,154 +198,206 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private Dictionary<string, string> _themes = new Dictionary<string, string>();
|
||||
private Dictionary<string, string> _panelayouts = new Dictionary<string, string>();
|
||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
||||
private List<SiteTemplate> _siteTemplates;
|
||||
private List<Theme> _themeList;
|
||||
private List<Tenant> _tenants;
|
||||
private string _tenantid = "-";
|
||||
|
||||
Dictionary<string, string> themes = new Dictionary<string, string>();
|
||||
Dictionary<string, string> panelayouts = new Dictionary<string, string>();
|
||||
Dictionary<string, string> containers = new Dictionary<string, string>();
|
||||
private string _tenantname = string.Empty;
|
||||
private string _databasetype = "LocalDB";
|
||||
private string _server = "(LocalDb)\\MSSQLLocalDB";
|
||||
private string _database = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
|
||||
private string _username = string.Empty;
|
||||
private string _password = string.Empty;
|
||||
private bool _integratedsecurity = true;
|
||||
private string _hostusername = Constants.HostUser;
|
||||
private string _hostpassword = string.Empty;
|
||||
|
||||
List<Tenant> tenants;
|
||||
string tenantid = "-1";
|
||||
string name = "";
|
||||
string urls = "";
|
||||
string logo = "";
|
||||
string themetype = "";
|
||||
string layouttype = "";
|
||||
string containertype = "";
|
||||
bool isinitialized = true;
|
||||
string username = "";
|
||||
string password = "";
|
||||
private string _name = string.Empty;
|
||||
private string _urls = string.Empty;
|
||||
private string _themetype = string.Empty;
|
||||
private string _layouttype = string.Empty;
|
||||
private string _containertype = string.Empty;
|
||||
private string _sitetemplatetype = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
tenants = await TenantService.GetTenantsAsync();
|
||||
urls = PageState.Alias.Name;
|
||||
themes = ThemeService.GetThemeTypes(PageState.Themes);
|
||||
containers = ThemeService.GetContainerTypes(PageState.Themes);
|
||||
username = Constants.HostUser;
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_tenants = await TenantService.GetTenantsAsync();
|
||||
_urls = PageState.Alias.Name;
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
|
||||
}
|
||||
|
||||
private async void TenantChanged(ChangeEventArgs e)
|
||||
private void TenantChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
_tenantid = (string)e.Value;
|
||||
if (string.IsNullOrEmpty(_tenantname))
|
||||
{
|
||||
tenantid = (string)e.Value;
|
||||
if (tenantid != "-1")
|
||||
{
|
||||
Tenant tenant = tenants.Where(item => item.TenantId == int.Parse(tenantid)).FirstOrDefault();
|
||||
if (tenant != null)
|
||||
{
|
||||
isinitialized = tenant.IsInitialized;
|
||||
_tenantname = _name;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
private void SetIntegratedSecurity(ChangeEventArgs e)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Tenant {TenantId} {Error}", tenantid, ex.Message);
|
||||
AddModuleMessage("Error Loading Tenant", MessageType.Error);
|
||||
if (Convert.ToBoolean((string)e.Value))
|
||||
{
|
||||
_integratedsecurity = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_integratedsecurity = false;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async void ThemeChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
themetype = (string)e.Value;
|
||||
if (themetype != "")
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != string.Empty)
|
||||
{
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
panelayouts = new Dictionary<string, string>();
|
||||
_panelayouts = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveSite()
|
||||
{
|
||||
if (tenantid != "-1" && name != "" && urls != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype)) && !string.IsNullOrEmpty(containertype))
|
||||
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype) && !string.IsNullOrEmpty(_sitetemplatetype))
|
||||
{
|
||||
bool isvalid = true;
|
||||
var duplicates = new List<string>();
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (aliases.Exists(item => item.Name == name))
|
||||
{
|
||||
duplicates.Add(name);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isinitialized)
|
||||
if (duplicates.Count == 0)
|
||||
{
|
||||
User user = new User();
|
||||
InstallConfig config = new InstallConfig();
|
||||
|
||||
if (_tenantid == "+")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_tenantname) && _tenants.FirstOrDefault(item => item.Name == _tenantname) == null)
|
||||
{
|
||||
// validate host credentials
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = username;
|
||||
user.Password = password;
|
||||
user.Username = Constants.HostUser;
|
||||
user.Password = _hostpassword;
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
isvalid = user.IsAuthenticated;
|
||||
}
|
||||
|
||||
if (isvalid)
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
List<Alias> aliases = new List<Alias>();
|
||||
urls = urls.Replace("\n", ",");
|
||||
foreach (string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
if (!string.IsNullOrEmpty(_server) && !string.IsNullOrEmpty(_database))
|
||||
{
|
||||
Alias alias = new Alias();
|
||||
alias.Name = name;
|
||||
alias.TenantId = int.Parse(tenantid);
|
||||
alias.SiteId = -1;
|
||||
alias = await AliasService.AddAliasAsync(alias);
|
||||
aliases.Add(alias);
|
||||
}
|
||||
|
||||
Site site = new Site();
|
||||
site.TenantId = int.Parse(tenantid);
|
||||
site.Name = name;
|
||||
site.Logo = (logo == null ? "" : logo);
|
||||
site.DefaultThemeType = themetype;
|
||||
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
|
||||
site.DefaultContainerType = containertype;
|
||||
site = await SiteService.AddSiteAsync(site, aliases[0]);
|
||||
|
||||
foreach(Alias alias in aliases)
|
||||
var connectionString = string.Empty;
|
||||
if (_databasetype == "LocalDB")
|
||||
{
|
||||
alias.SiteId = site.SiteId;
|
||||
await AliasService.UpdateAliasAsync(alias);
|
||||
}
|
||||
|
||||
if (!isinitialized)
|
||||
{
|
||||
User user = new User();
|
||||
user.SiteId = site.SiteId;
|
||||
user.Username = username;
|
||||
user.Password = password;
|
||||
user.Email = PageState.User.Email;
|
||||
user.DisplayName = PageState.User.DisplayName;
|
||||
user = await UserService.AddUserAsync(user, aliases[0]);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
Tenant tenant = tenants.Where(item => item.TenantId == int.Parse(tenantid)).FirstOrDefault();
|
||||
tenant.IsInitialized = true;
|
||||
await TenantService.UpdateTenantAsync(tenant);
|
||||
}
|
||||
}
|
||||
await logger.LogInformation("Site Created {Site}", site);
|
||||
|
||||
Uri uri = new Uri(NavigationManager.Uri);
|
||||
NavigationManager.NavigateTo(uri.Scheme + "://" + aliases[0].Name, true);
|
||||
connectionString = "Data Source=" + _server + ";AttachDbFilename=|DataDirectory|\\" + _database + ".mdf;Initial Catalog=" + _database + ";Integrated Security=SSPI;";
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionString = "Data Source=" + _server + ";Initial Catalog=" + _database + ";";
|
||||
|
||||
if (_integratedsecurity)
|
||||
{
|
||||
connectionString += "Integrated Security=SSPI;";
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionString += "User ID=" + _username + ";Password=" + _password;
|
||||
}
|
||||
}
|
||||
|
||||
config.ConnectionString = connectionString;
|
||||
config.HostPassword = _hostpassword;
|
||||
config.HostEmail = user.Email;
|
||||
config.HostName = user.DisplayName;
|
||||
config.TenantName = _tenantname;
|
||||
config.IsNewTenant = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Specify A Server And Database", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Invalid Password Entered For Host {Username}", username);
|
||||
AddModuleMessage("Invalid Host Password", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, And Default Theme/Container", MessageType.Warning);
|
||||
AddModuleMessage("Tenant Name Is Missing Or Already Exists", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var tenant = _tenants.FirstOrDefault(item => item.TenantId == int.Parse(_tenantid));
|
||||
if (tenant != null)
|
||||
{
|
||||
config.TenantName = tenant.Name;
|
||||
config.ConnectionString= tenant.DBConnectionString;
|
||||
config.IsNewTenant = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(config.TenantName))
|
||||
{
|
||||
config.SiteName = _name;
|
||||
config.Aliases = _urls.Replace("\n", ",");
|
||||
config.DefaultTheme = _themetype;
|
||||
config.DefaultLayout = _layouttype;
|
||||
config.DefaultContainer = _containertype;
|
||||
config.SiteTemplate = _sitetemplatetype;
|
||||
|
||||
ShowProgressIndicator();
|
||||
|
||||
var installation = await InstallationService.Install(config);
|
||||
if (installation.Success)
|
||||
{
|
||||
var aliasname = config.Aliases.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||
var uri = new Uri(NavigationManager.Uri);
|
||||
NavigationManager.NavigateTo(uri.Scheme + "://" + aliasname, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Error Creating Site {Error}", installation.Message);
|
||||
AddModuleMessage(installation.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(string.Join(", ", duplicates.ToArray()) + " Already Used For Another Site", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, Default Theme/Container, And Site Template", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,51 +2,47 @@
|
|||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ISiteService SiteService
|
||||
@inject ITenantService TenantService
|
||||
@inject IAliasService AliasService
|
||||
@inject IThemeService ThemeService
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (themes == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
@if (_themes != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="Enter the name of the site">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
<input id="name" class="form-control" @bind="@_name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Aliases: </label>
|
||||
<Label For="tenant" HelpText="Enter the tenant for the site">Tenant: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@urls" rows="3" />
|
||||
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Logo: </label>
|
||||
<Label For="alias" HelpText="Enter the alias for the server">Aliases: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@logo" />
|
||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Theme: </label>
|
||||
<Label For="defaultTheme" HelpText="Select the default theme for the website">Default Theme: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in themes)
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
{
|
||||
if (item.Key == themetype)
|
||||
if (item.Key == _themetype)
|
||||
{
|
||||
<option value="@item.Key" selected>@item.Value</option>
|
||||
}
|
||||
|
@ -60,12 +56,12 @@ else
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Layout: </label>
|
||||
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@layouttype">
|
||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||
<option value=""><Select Layout></option>
|
||||
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
|
||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
||||
{
|
||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
||||
}
|
||||
|
@ -74,12 +70,12 @@ else
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Default Container: </label>
|
||||
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@containertype">
|
||||
<select id="defaultIdea" class="form-control" @bind="@_containertype">
|
||||
<option value=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string> container in containers)
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
}
|
||||
|
@ -88,146 +84,88 @@ else
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Is Deleted? </label>
|
||||
<Label For="isDeleted" HelpText="Has this site been deleted?">Is Deleted? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isdeleted">
|
||||
<select id="isDeleted" class="form-control" @bind="@_isdeleted">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<a data-toggle="collapse" class="app-link-unstyled" href="#SMTP" aria-expanded="false" aria-controls="SMTP">
|
||||
<h5>SMTP Settings</h5><hr class="app-rule" />
|
||||
</a>
|
||||
<div class="collapse" id="SMTP">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Host: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@smtphost" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Port: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@smtpport" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">SSL Enabled: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@smtpssl" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Username: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@smtpusername" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@smtppassword" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSite">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private Dictionary<string, string> _themes;
|
||||
private Dictionary<string, string> _panelayouts;
|
||||
private Dictionary<string, string> _containers;
|
||||
private Alias _alias;
|
||||
private List<Theme> _themeList;
|
||||
private string _name = string.Empty;
|
||||
private List<Tenant> _tenantList;
|
||||
private string _tenant = string.Empty;
|
||||
private List<Alias> _aliasList;
|
||||
private string _urls = string.Empty;
|
||||
private string _themetype;
|
||||
private string _layouttype;
|
||||
private string _containertype;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
private string _deletedby;
|
||||
private DateTime? _deletedon;
|
||||
private string _isdeleted;
|
||||
|
||||
Dictionary<string, string> themes = new Dictionary<string, string>();
|
||||
Dictionary<string, string> panelayouts = new Dictionary<string, string>();
|
||||
Dictionary<string, string> containers = new Dictionary<string, string>();
|
||||
|
||||
Alias Alias;
|
||||
int siteid;
|
||||
string name = "";
|
||||
List<Alias> aliases;
|
||||
string urls = "";
|
||||
string logo = "";
|
||||
string themetype;
|
||||
string layouttype;
|
||||
string containertype;
|
||||
|
||||
string smtphost = "";
|
||||
string smtpport = "";
|
||||
string smtpssl = "";
|
||||
string smtpusername = "";
|
||||
string smtppassword = "";
|
||||
|
||||
string createdby;
|
||||
DateTime createdon;
|
||||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
string deletedby;
|
||||
DateTime? deletedon;
|
||||
string isdeleted;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
themes = ThemeService.GetThemeTypes(PageState.Themes);
|
||||
containers = ThemeService.GetContainerTypes(PageState.Themes);
|
||||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_aliasList = await AliasService.GetAliasesAsync();
|
||||
|
||||
Alias = PageState.Aliases.Where(item => item.AliasId == Int32.Parse(PageState.QueryString["id"])).FirstOrDefault();
|
||||
siteid = Alias.SiteId;
|
||||
Site site = await SiteService.GetSiteAsync(siteid, Alias);
|
||||
_alias = _aliasList.Find(item => item.AliasId == Int32.Parse(PageState.QueryString["id"]));
|
||||
SiteService.SetAlias(_alias);
|
||||
var site = await SiteService.GetSiteAsync(_alias.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
name = site.Name;
|
||||
aliases = PageState.Aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList();
|
||||
foreach (Alias alias in aliases)
|
||||
_name = site.Name;
|
||||
_tenantList = await TenantService.GetTenantsAsync();
|
||||
_tenant = _tenantList.Find(item => item.TenantId == site.TenantId).Name;
|
||||
|
||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
||||
{
|
||||
urls += alias.Name + "\n";
|
||||
_urls += alias.Name + "\n";
|
||||
}
|
||||
logo = site.Logo;
|
||||
themetype = site.DefaultThemeType;
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
layouttype = site.DefaultLayoutType;
|
||||
containertype = site.DefaultContainerType;
|
||||
|
||||
Dictionary<string, string> settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||
smtphost = SettingService.GetSetting(settings, "SMTPHost", "");
|
||||
smtpport = SettingService.GetSetting(settings, "SMTPPort", "");
|
||||
smtpssl = SettingService.GetSetting(settings, "SMTPSSL", "");
|
||||
smtpusername = SettingService.GetSetting(settings, "SMTPUsername", "");
|
||||
smtppassword = SettingService.GetSetting(settings, "SMTPPassword", "");
|
||||
|
||||
createdby = site.CreatedBy;
|
||||
createdon = site.CreatedOn;
|
||||
modifiedby = site.ModifiedBy;
|
||||
modifiedon = site.ModifiedOn;
|
||||
deletedby = site.DeletedBy;
|
||||
deletedon = site.DeletedOn;
|
||||
isdeleted = site.IsDeleted.ToString();
|
||||
_themetype = site.DefaultThemeType;
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
_layouttype = site.DefaultLayoutType;
|
||||
_containertype = site.DefaultContainerType;
|
||||
_createdby = site.CreatedBy;
|
||||
_createdon = site.CreatedOn;
|
||||
_modifiedby = site.ModifiedBy;
|
||||
_modifiedon = site.ModifiedOn;
|
||||
_deletedby = site.DeletedBy;
|
||||
_deletedon = site.DeletedOn;
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
}
|
||||
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Site {SiteId} {Error}", siteid, ex.Message);
|
||||
await Log(_alias, LogLevel.Error, string.Empty, ex, "Error Loading Site {SiteId} {Error}", _alias.SiteId, ex.Message);
|
||||
AddModuleMessage(ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -236,20 +174,21 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
themetype = (string)e.Value;
|
||||
if (themetype != "")
|
||||
_themetype = (string)e.Value;
|
||||
if (_themetype != string.Empty)
|
||||
{
|
||||
panelayouts = ThemeService.GetPaneLayoutTypes(PageState.Themes, themetype);
|
||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
||||
}
|
||||
else
|
||||
{
|
||||
panelayouts = new Dictionary<string, string>();
|
||||
_panelayouts = new Dictionary<string, string>();
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", themetype, ex.Message);
|
||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
||||
AddModuleMessage("Error Loading Pane Layouts For Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
@ -258,52 +197,65 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
if (name != "" && urls != "" && !string.IsNullOrEmpty(themetype) && (panelayouts.Count == 0 || !string.IsNullOrEmpty(layouttype)) && !string.IsNullOrEmpty(containertype))
|
||||
if (_name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype))
|
||||
{
|
||||
Site site = await SiteService.GetSiteAsync(siteid, Alias);
|
||||
var unique = true;
|
||||
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (_aliasList.Exists(item => item.Name == name && item.SiteId != _alias.SiteId && item.TenantId != _alias.TenantId))
|
||||
{
|
||||
unique = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (unique)
|
||||
{
|
||||
SiteService.SetAlias(_alias);
|
||||
var site = await SiteService.GetSiteAsync(_alias.SiteId);
|
||||
if (site != null)
|
||||
{
|
||||
site.Name = name;
|
||||
site.Logo = (logo == null ? "" : logo);
|
||||
site.DefaultThemeType = themetype;
|
||||
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
|
||||
site.DefaultContainerType = containertype;
|
||||
site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
|
||||
site.Name = _name;
|
||||
site.LogoFileId = null;
|
||||
site.DefaultThemeType = _themetype;
|
||||
site.DefaultLayoutType = _layouttype ?? string.Empty;
|
||||
site.DefaultContainerType = _containertype;
|
||||
site.IsDeleted = (_isdeleted == null || Boolean.Parse(_isdeleted));
|
||||
|
||||
site = await SiteService.UpdateSiteAsync(site, Alias);
|
||||
site = await SiteService.UpdateSiteAsync(site);
|
||||
|
||||
urls = urls.Replace("\n", ",");
|
||||
string[] names = urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (Alias alias in aliases)
|
||||
_urls = _urls.Replace("\n", ",");
|
||||
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
||||
{
|
||||
if (!names.Contains(alias.Name))
|
||||
{
|
||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
if (!aliases.Exists(item => item.Name == name))
|
||||
if (!_aliasList.Exists(item => item.Name == name))
|
||||
{
|
||||
Alias alias = new Alias();
|
||||
alias.Name = name;
|
||||
alias.TenantId = site.TenantId;
|
||||
alias.SiteId = site.SiteId;
|
||||
Alias alias = new Alias
|
||||
{
|
||||
Name = name,
|
||||
TenantId = site.TenantId,
|
||||
SiteId = site.SiteId
|
||||
};
|
||||
await AliasService.AddAliasAsync(alias);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<string, string> settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||
SettingService.SetSetting(settings, "SMTPHost", smtphost);
|
||||
SettingService.SetSetting(settings, "SMTPPort", smtpport);
|
||||
SettingService.SetSetting(settings, "SMTPSSL", smtpssl);
|
||||
SettingService.SetSetting(settings, "SMTPUsername", smtpusername);
|
||||
SettingService.SetSetting(settings, "SMTPPassword", smtppassword);
|
||||
await SettingService.UpdateModuleSettingsAsync(settings, site.SiteId);
|
||||
await Log(_alias, LogLevel.Information,PermissionNames.Edit, null, "Site Saved {Site}", site);
|
||||
|
||||
await logger.LogInformation("Site Saved {Site}", site);
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Site));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("An Alias Specified Has Already Been Used For Another Site", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -313,8 +265,8 @@ else
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Site {SiteId} {Error}", siteid, ex.Message);
|
||||
await Log(_alias, LogLevel.Error, string.Empty, ex, "Error Saving Site {SiteId} {Error}", _alias.SiteId, ex.Message);
|
||||
AddModuleMessage("Error Saving Site", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@inject IAliasService AliasService
|
||||
@inject ISiteService SiteService
|
||||
|
||||
@if (sites == null)
|
||||
@if (_sites == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ else
|
|||
{
|
||||
<ActionLink Action="Add" Text="Add Site" />
|
||||
|
||||
<Pager Items="@sites">
|
||||
<Pager Items="@_sites">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
|
@ -20,44 +20,60 @@ else
|
|||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.AliasId.ToString())" /></td>
|
||||
<td><ActionDialog Header="Delete Site" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Site?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteSite(context))" /></td>
|
||||
<td><a href="@(scheme + context.Name)">@context.Name</a></td>
|
||||
<td><ActionDialog Header="Delete Site" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Site?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteSite(context))" /></td>
|
||||
<td><a href="@(_scheme + context.Name)">@context.Name</a></td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<Alias> _sites;
|
||||
private string _scheme;
|
||||
|
||||
List<Alias> sites;
|
||||
string scheme;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override void OnParametersSet()
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
Uri uri = new Uri(NavigationManager.Uri);
|
||||
scheme = uri.Scheme + "://";
|
||||
var uri = new Uri(NavigationManager.Uri);
|
||||
_scheme = uri.Scheme + "://";
|
||||
|
||||
sites = new List<Alias>();
|
||||
foreach (Alias alias in PageState.Aliases.OrderBy(item => item.Name))
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
_sites = new List<Alias>();
|
||||
foreach (Alias alias in aliases)
|
||||
{
|
||||
if (!sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
|
||||
if (!_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
|
||||
{
|
||||
sites.Add(alias);
|
||||
_sites.Add(alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteSite(Alias Alias)
|
||||
private async Task DeleteSite(Alias alias)
|
||||
{
|
||||
try
|
||||
{
|
||||
await SiteService.DeleteSiteAsync(Alias.SiteId, Alias);
|
||||
await logger.LogInformation("Sited Deleted {Alias}", Alias);
|
||||
StateHasChanged();
|
||||
if (alias.SiteId != PageState.Site.SiteId || alias.TenantId != PageState.Site.TenantId)
|
||||
{
|
||||
SiteService.SetAlias(alias);
|
||||
await SiteService.DeleteSiteAsync(alias.SiteId);
|
||||
await Log(alias, LogLevel.Information, "", null, "Site Deleted {SiteId}", alias.SiteId);
|
||||
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
foreach (Alias a in aliases.Where(item => item.SiteId == alias.SiteId && item.TenantId == alias.TenantId))
|
||||
{
|
||||
await AliasService.DeleteAliasAsync(a.AliasId);
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Can Not Delete The Current Site", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Site {Error}", ex.Message);
|
||||
await Log(alias, LogLevel.Error, "", ex, "Error Deleting Site {SiteId} {Error}", alias.SiteId, ex.Message);
|
||||
AddModuleMessage("Error Deleting Site", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
|
111
Oqtane.Client/Modules/Admin/Sql/Index.razor
Normal file
111
Oqtane.Client/Modules/Admin/Sql/Index.razor
Normal file
|
@ -0,0 +1,111 @@
|
|||
@namespace Oqtane.Modules.Admin.Sql
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ITenantService TenantService
|
||||
@inject ISqlService SqlService
|
||||
|
||||
@if (_tenants == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="tenant" HelpText="Select the tenant for the SQL server">Tenant: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="teneant" class="form-control" @bind="_tenantid">
|
||||
<option value="-1"><Select Tenant></option>
|
||||
@foreach (Tenant tenant in _tenants)
|
||||
{
|
||||
<option value="@tenant.TenantId">@tenant.Name</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="sqlQeury" HelpText="Enter the query for the SQL server">SQL Query: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="sqlQeury" class="form-control" @bind="@_sql" rows="5"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="Execute">Execute</button>
|
||||
<br /><br />
|
||||
@if (!string.IsNullOrEmpty(_results))
|
||||
{
|
||||
@((MarkupString)_results)
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private List<Tenant> _tenants;
|
||||
private string _tenantid = "-1";
|
||||
private string _sql = string.Empty;
|
||||
private string _results = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_tenants = await TenantService.GetTenantsAsync();
|
||||
}
|
||||
|
||||
private async Task Execute()
|
||||
{
|
||||
if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql))
|
||||
{
|
||||
var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql };
|
||||
sqlquery = await SqlService.ExecuteQueryAsync(sqlquery);
|
||||
_results = DisplayResults(sqlquery.Results);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Select A Tenant And Provide A SQL Query", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private string DisplayResults(List<Dictionary<string, string>> results)
|
||||
{
|
||||
var table = string.Empty;
|
||||
foreach (Dictionary<string, string> item in results)
|
||||
{
|
||||
if (table == string.Empty)
|
||||
{
|
||||
table = "<div class=\"table-responsive\">";
|
||||
table += "<table class=\"table table-bordered\"><thead><tr>";
|
||||
|
||||
foreach (KeyValuePair<string, string> kvp in item)
|
||||
{
|
||||
table += "<th scope=\"col\">" + kvp.Key + "</th>";
|
||||
}
|
||||
|
||||
table += "</tr></thead><tbody>";
|
||||
}
|
||||
|
||||
table += "<tr>";
|
||||
|
||||
foreach (KeyValuePair<string, string> kvp in item)
|
||||
{
|
||||
table += "<td>" + kvp.Value + "</td>";
|
||||
}
|
||||
|
||||
table += "</tr>";
|
||||
}
|
||||
|
||||
if (table != string.Empty)
|
||||
{
|
||||
table += "</tbody></table></div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
table = "No Results Returned";
|
||||
}
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
81
Oqtane.Client/Modules/Admin/SystemInfo/Index.razor
Normal file
81
Oqtane.Client/Modules/Admin/SystemInfo/Index.razor
Normal file
|
@ -0,0 +1,81 @@
|
|||
@namespace Oqtane.Modules.Admin.SystemInfo
|
||||
@inherits ModuleBase
|
||||
@inject ISystemService SystemService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="version" HelpText="Framework Version">Framework Version: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="version" class="form-control" @bind="@_version" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="runtime" HelpText="Blazor Runtime (Server or WebAssembly)">Blazor Runtime: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="runtime" class="form-control" @bind="@_runtime" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="clrversion" HelpText="Common Language Runtime Version">CLR Version: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="clrversion" class="form-control" @bind="@_clrversion" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="osversion" HelpText="Operating System Version">OS Version: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="osversion" class="form-control" @bind="@_osversion" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="serverpath" HelpText="Server Path">Server Path: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="serverpath" class="form-control" @bind="@_serverpath" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="servertime" HelpText="Server Time">Server Time: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="servertime" class="form-control" @bind="@_servertime" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<a class="btn btn-primary" href="swagger/index.html" target="_new">Access Framework API</a>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
private string _version = string.Empty;
|
||||
private string _runtime = string.Empty;
|
||||
private string _clrversion = string.Empty;
|
||||
private string _osversion = string.Empty;
|
||||
private string _serverpath = string.Empty;
|
||||
private string _servertime = string.Empty;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_version = Constants.Version;
|
||||
_runtime = PageState.Runtime.ToString();
|
||||
|
||||
Dictionary<string, string> systeminfo = await SystemService.GetSystemInfoAsync();
|
||||
if (systeminfo != null)
|
||||
{
|
||||
_clrversion = systeminfo["clrversion"];
|
||||
_osversion = systeminfo["osversion"];
|
||||
_serverpath = systeminfo["serverpath"];
|
||||
_servertime = systeminfo["servertime"];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
@namespace Oqtane.Modules.Admin.Tenants
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ITenantService TenantService
|
||||
@inject IInstallationService InstallationService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Connection String: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@connectionstring" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Schema: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@schema" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveTenant">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
|
||||
string name = "";
|
||||
string connectionstring = "";
|
||||
string schema = "";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<Tenant> tenants = await TenantService.GetTenantsAsync();
|
||||
connectionstring = tenants.FirstOrDefault().DBConnectionString;
|
||||
schema = tenants.FirstOrDefault().DBSchema;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Tenants {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Tenants", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveTenant()
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
|
||||
connectionstring = connectionstring.Replace("\\\\", "\\");
|
||||
GenericResponse response = await InstallationService.Install(connectionstring);
|
||||
if (response.Success)
|
||||
{
|
||||
Tenant tenant = new Tenant();
|
||||
tenant.Name = name;
|
||||
tenant.DBConnectionString = connectionstring;
|
||||
tenant.DBSchema = schema;
|
||||
tenant.IsInitialized = false;
|
||||
await TenantService.AddTenantAsync(tenant);
|
||||
await logger.LogInformation("Tenant Created {Tenant}", tenant);
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Error Creating Tenant {Error}", response.Message);
|
||||
AddModuleMessage(response.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,51 +6,50 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Name: </label>
|
||||
<Label For="name" HelpText="The name of the tenant">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@name" />
|
||||
@if (name == Constants.MasterTenant)
|
||||
{
|
||||
<input id="name" class="form-control" @bind="@name" readonly />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input id="name" class="form-control" @bind="@name" />
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Connection String: </label>
|
||||
<Label For="connectionstring" HelpText="The database connection string">Connection String: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@connectionstring" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Schema: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@schema" />
|
||||
<textarea id="connectionstring" class="form-control" @bind="@connectionstring" rows="3" readonly></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveTenant">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private int tenantid;
|
||||
private string name = string.Empty;
|
||||
private string connectionstring = string.Empty;
|
||||
private string schema = string.Empty;
|
||||
|
||||
int tenantid;
|
||||
string name = "";
|
||||
string connectionstring = "";
|
||||
string schema = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
tenantid = Int32.Parse(PageState.QueryString["id"]);
|
||||
Tenant tenant = await TenantService.GetTenantAsync(tenantid);
|
||||
var tenant = await TenantService.GetTenantAsync(tenantid);
|
||||
if (tenant != null)
|
||||
{
|
||||
name = tenant.Name;
|
||||
connectionstring = tenant.DBConnectionString;
|
||||
schema = tenant.DBSchema;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -65,12 +64,12 @@
|
|||
try
|
||||
{
|
||||
connectionstring = connectionstring.Replace("\\\\", "\\");
|
||||
Tenant tenant = await TenantService.GetTenantAsync(tenantid);
|
||||
var tenant = await TenantService.GetTenantAsync(tenantid);
|
||||
if (tenant != null)
|
||||
{
|
||||
tenant.Name = name;
|
||||
tenant.DBConnectionString = connectionstring;
|
||||
tenant.DBSchema = schema;
|
||||
|
||||
await TenantService.UpdateTenantAsync(tenant);
|
||||
await logger.LogInformation("Tenant Saved {TenantId}", tenantid);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@namespace Oqtane.Modules.Admin.Tenants
|
||||
@inherits ModuleBase
|
||||
@inject ITenantService TenantService
|
||||
@inject IAliasService AliasService
|
||||
|
||||
@if (tenants == null)
|
||||
{
|
||||
|
@ -8,8 +9,6 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Add Tenant" />
|
||||
|
||||
<Pager Items="@tenants">
|
||||
<Header>
|
||||
<th> </th>
|
||||
|
@ -18,7 +17,7 @@ else
|
|||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.TenantId.ToString())" /></td>
|
||||
<td><ActionDialog Header="Delete Tenant" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Tenant?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTenant(context))" /></td>
|
||||
<td><ActionDialog Header="Delete Tenant" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Tenant?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTenant(context))" Disabled="@(context.Name == Constants.MasterTenant)" /></td>
|
||||
<td>@context.Name</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
|
@ -26,9 +25,9 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<Tenant> tenants;
|
||||
|
||||
List<Tenant> tenants;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
|
@ -38,11 +37,27 @@ else
|
|||
private async Task DeleteTenant(Tenant Tenant)
|
||||
{
|
||||
try
|
||||
{
|
||||
string message = string.Empty;
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
foreach (var alias in aliases)
|
||||
{
|
||||
if (alias.TenantId == Tenant.TenantId)
|
||||
{
|
||||
message += ", " + alias.Name;
|
||||
}
|
||||
}
|
||||
if (string.IsNullOrEmpty(message))
|
||||
{
|
||||
await TenantService.DeleteTenantAsync(Tenant.TenantId);
|
||||
await logger.LogInformation("Tenant Deleted {Tenant}", Tenant);
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("Tenant Cannot Be Deleted Until The Following Sites Are Deleted: " + message.Substring(2), MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Tenant {Tenant} {Error}", Tenant, ex.Message);
|
||||
|
|
|
@ -5,24 +5,14 @@
|
|||
@inject IThemeService ThemeService
|
||||
@inject IPackageService PackageService
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Theme: </label>
|
||||
</td>
|
||||
<td>
|
||||
<FileUpload Filter=".nupkg" @ref="fileupload"></FileUpload>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="UploadTheme">Upload Theme</button>
|
||||
|
||||
@if (packages != null)
|
||||
@if (_packages != null)
|
||||
{
|
||||
<hr class="app-rule" />
|
||||
<div class="mx-auto text-center"><h2>Available Themes</h2></div>
|
||||
|
||||
<Pager Items="@packages">
|
||||
<TabStrip>
|
||||
@if (_packages.Count > 0)
|
||||
{
|
||||
<TabPanel Name="Download">
|
||||
<ModuleMessage Type="MessageType.Info" Message="Download one or more themes from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
|
||||
<Pager Items="@_packages">
|
||||
<Header>
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
|
@ -32,90 +22,83 @@
|
|||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>Download Theme</button>
|
||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>Download</button>
|
||||
</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
</TabPanel>
|
||||
}
|
||||
<TabPanel Name="Upload">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation.">Theme: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager Filter="nupkg" ShowFiles="false" Folder="Themes" UploadMultiple="@true" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
@if (uploaded)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick="InstallThemes">Install</button>
|
||||
}
|
||||
<button type="button" class="btn btn-success" @onclick="InstallThemes">Install</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<Package> _packages;
|
||||
|
||||
bool uploaded = false;
|
||||
List<Package> packages;
|
||||
FileUpload fileupload;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
List<Theme> themes = await ThemeService.GetThemesAsync();
|
||||
packages = await PackageService.GetPackagesAsync("theme");
|
||||
foreach(Package package in packages.ToArray())
|
||||
try
|
||||
{
|
||||
var themes = await ThemeService.GetThemesAsync();
|
||||
_packages = await PackageService.GetPackagesAsync("theme");
|
||||
|
||||
foreach (Package package in _packages.ToArray())
|
||||
{
|
||||
if (themes.Exists(item => Utilities.GetTypeName(item.ThemeName) == package.PackageId))
|
||||
{
|
||||
packages.Remove(package);
|
||||
_packages.Remove(package);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UploadTheme()
|
||||
{
|
||||
string[] files = await fileupload.GetFiles();
|
||||
if (files.Length > 0)
|
||||
{
|
||||
if (files[0].Contains(".Theme."))
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = await FileService.UploadFilesAsync("Themes", files, "");
|
||||
if (result == "")
|
||||
{
|
||||
await logger.LogInformation("Theme Uploaded {Package}", files[0]);
|
||||
AddModuleMessage("Theme Uploaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Theme Upload Failed For {Package}", result.Replace(",",", "));
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Theme Upload Failed {Package} {Error}", files[0], ex.Message);
|
||||
AddModuleMessage("Theme Upload Failed", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Invalid Theme Package {Package}", files[0]);
|
||||
AddModuleMessage("Invalid Theme Package", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Select A Theme To Upload", MessageType.Warning);
|
||||
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Packages", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task InstallThemes()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ThemeService.InstallThemesAsync();
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Installating Theme");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DownloadTheme(string packageid, string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(packageid, version, "Themes");
|
||||
AddModuleMessage("Theme Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
await logger.LogInformation("Theme {ThemeName} {Version} Downloaded Successfully", packageid, version);
|
||||
AddModuleMessage("Themes Downloaded Successfully. Click Install To Complete Installation.", MessageType.Success);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Module {ThemeName} {Version}", packageid, version);
|
||||
AddModuleMessage("Error Downloading Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,10 +39,10 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private List<Theme> themes;
|
||||
private List<Package> packages;
|
||||
|
||||
List<Theme> themes;
|
||||
List<Package> packages;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -52,12 +52,13 @@ else
|
|||
|
||||
private bool UpgradeAvailable(string themename, string version)
|
||||
{
|
||||
bool upgradeavailable = false;
|
||||
Package package = packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault();
|
||||
var upgradeavailable = false;
|
||||
var package = packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault();
|
||||
if (package != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||
}
|
||||
|
||||
return upgradeavailable;
|
||||
}
|
||||
|
||||
|
@ -66,13 +67,13 @@ else
|
|||
await PackageService.DownloadPackageAsync(themename, version, "Themes");
|
||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
||||
await ThemeService.InstallThemesAsync();
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
|
||||
private async Task DeleteTheme(Theme Theme)
|
||||
{
|
||||
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
||||
await logger.LogInformation("Theme Deleted {Theme}", Theme);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
}
|
|
@ -5,105 +5,66 @@
|
|||
@inject IPackageService PackageService
|
||||
@inject IInstallationService InstallationService
|
||||
|
||||
<table class="table table-borderless">
|
||||
@if (_package != null)
|
||||
{
|
||||
<TabStrip>
|
||||
<TabPanel Name="Download">
|
||||
@if (_upgradeavailable)
|
||||
{
|
||||
<ModuleMessage Type="MessageType.Info" Message="Select The Upgrade Button To Install a New Framework Version"></ModuleMessage>
|
||||
@("Framework") @_package.Version <button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Upgrade</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Upload">
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Framework: </label>
|
||||
<Label HelpText="Upload a framework package and select Install to complete the installation">Framework: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<FileUpload Filter=".nupkg" @ref="fileupload"></FileUpload>
|
||||
<FileManager Filter="nupkg" Folder="Framework" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@if (uploaded)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick="Upgrade">Upgrade</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button type="button" class="btn btn-primary" @onclick="UploadFile">Upload</button>
|
||||
}
|
||||
|
||||
@if (upgradeavailable)
|
||||
{
|
||||
<hr class="app-rule" />
|
||||
<div class="mx-auto text-center"><h2>Upgrade Available</h2></div>
|
||||
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Upgrade Framework</button>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="Upgrade">Install</button>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||
private Package _package;
|
||||
private bool _upgradeavailable = false;
|
||||
|
||||
bool uploaded = false;
|
||||
bool upgradeavailable = false;
|
||||
FileUpload fileupload;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
List<Package> packages = await PackageService.GetPackagesAsync("framework");
|
||||
Package package = packages.FirstOrDefault();
|
||||
if (package != null)
|
||||
_package = packages.FirstOrDefault();
|
||||
if (_package != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(Constants.Version)) > 0);
|
||||
}
|
||||
if (!upgradeavailable)
|
||||
{
|
||||
AddModuleMessage("Framework Is Up To Date", MessageType.Info);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UploadFile()
|
||||
{
|
||||
string[] files = await fileupload.GetFiles();
|
||||
if (files.Length > 0)
|
||||
{
|
||||
if (files[0].Contains(".Framework."))
|
||||
{
|
||||
try
|
||||
{
|
||||
string result = await FileService.UploadFilesAsync("Framework", files, "");
|
||||
if (result == "")
|
||||
{
|
||||
await logger.LogInformation("Framework Uploaded {Package}", files[0]);
|
||||
AddModuleMessage("Framework Uploaded Successfully. Click Upgrade To Complete Installation.", MessageType.Success);
|
||||
uploaded = true;
|
||||
StateHasChanged();
|
||||
_upgradeavailable = (Version.Parse(_package.Version).CompareTo(Version.Parse(Constants.Version)) > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogInformation("Framework Upload Failed For {Package}", result.Replace(",",", "));
|
||||
AddModuleMessage("Upload Failed For " + result.Replace(",",", ") + ". This Could Be Due To A Network Error Or Because A File Type Is Restricted.", MessageType.Error);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Framework Upload Failed {Package} {Error}", files[0], ex.Message);
|
||||
AddModuleMessage("Framework Upload Failed. " + ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("Invalid Framework Package {Package}", files[0]);
|
||||
AddModuleMessage("Invalid Framework Package", MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Select A Framework Package To Upload", MessageType.Warning);
|
||||
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Upgrade()
|
||||
{
|
||||
await InstallationService.Upgrade();
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
|
||||
private async Task Download(string packageid, string version)
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
||||
await InstallationService.Upgrade();
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Application));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
}
|
|
@ -9,10 +9,10 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">To: </label>
|
||||
<Label For="to" HelpText="Select the user it is going to">To: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@userid">
|
||||
<select id="to" class="form-control" @bind="@userid">
|
||||
<option value="-1"><Select User></option>
|
||||
@if (userroles != null)
|
||||
{
|
||||
|
@ -26,18 +26,18 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Subject: </label>
|
||||
<Label For="subject" HelpText="Enter the subject of the message">Subject: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@subject" />
|
||||
<input id="subject" class="form-control" @bind="@subject" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Message: </label>
|
||||
<Label For="message" HelpText="Enter the message">Message: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@body" rows="5" />
|
||||
<textarea id="message" class="form-control" @bind="@body" rows="5" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -46,13 +46,14 @@
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } }
|
||||
public override string Title { get { return "Send Notification"; } }
|
||||
private List<UserRole> userroles;
|
||||
private string userid = "-1";
|
||||
private string subject = "";
|
||||
private string body = "";
|
||||
|
||||
List<UserRole> userroles;
|
||||
string userid = "-1";
|
||||
string subject = "";
|
||||
string body = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||
|
||||
public override string Title => "Send Notification";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -71,7 +72,7 @@
|
|||
|
||||
private async Task Send()
|
||||
{
|
||||
Notification notification = new Notification();
|
||||
var notification = new Notification();
|
||||
try
|
||||
{
|
||||
notification.SiteId = PageState.Site.SiteId;
|
||||
|
@ -81,7 +82,7 @@
|
|||
notification.Subject = subject;
|
||||
notification.Body = body;
|
||||
notification.ParentId = null;
|
||||
notification.CreatedOn = DateTime.Now;
|
||||
notification.CreatedOn = DateTime.UtcNow;
|
||||
notification.IsDelivered = false;
|
||||
notification.DeliveredOn = null;
|
||||
|
||||
|
|
|
@ -6,27 +6,18 @@
|
|||
@inject ISettingService SettingService
|
||||
@inject INotificationService NotificationService
|
||||
|
||||
@if (PageState.User != null && profiles != null)
|
||||
@if (PageState.User != null && photofileid != -1)
|
||||
{
|
||||
<img src="@(ContentUrl(photofileid))" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="container-fluid">
|
||||
<div class="form-group">
|
||||
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-toggle="tab" href="#Profile" role="tab">
|
||||
Profile
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-toggle="tab" href="#Notifications" role="tab">
|
||||
Notifications
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="tab-content">
|
||||
<div id="Profile" class="tab-pane fade show active" role="tabpanel">
|
||||
<br />
|
||||
}
|
||||
<TabStrip>
|
||||
<TabPanel Name="Identity">
|
||||
@if (PageState.User != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
|
@ -68,7 +59,23 @@
|
|||
<input class="form-control" @bind="@displayname" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Photo: </label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager FileId="@photofileid" @ref="filemanager" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Profile">
|
||||
@if (profiles != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
@foreach (Profile profile in profiles)
|
||||
{
|
||||
var p = profile;
|
||||
|
@ -86,17 +93,18 @@
|
|||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="(e => ProfileChanged(e, p.Name))" />
|
||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
||||
</div>
|
||||
|
||||
<div id="Notifications" class="tab-pane fade" role="tabpanel">
|
||||
<br />
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Notifications">
|
||||
@if (notifications != null)
|
||||
{
|
||||
<ActionLink Action="Add" Text="Send Notification" Security="SecurityAccessLevel.View" EditMode="false" />
|
||||
<br /><br />
|
||||
@if (filter == "to")
|
||||
|
@ -118,7 +126,7 @@
|
|||
</Row>
|
||||
<Detail>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0,100) : context.Body)</td>
|
||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0, 100) : context.Body)</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
}
|
||||
|
@ -141,7 +149,7 @@
|
|||
</Row>
|
||||
<Detail>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0,100) : context.Body)</td>
|
||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0, 100) : context.Body)</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
}
|
||||
|
@ -150,25 +158,25 @@
|
|||
<option value="to">Inbox</option>
|
||||
<option value="from">Sent Items</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } }
|
||||
private string username = string.Empty;
|
||||
private string password = string.Empty;
|
||||
private string confirm = string.Empty;
|
||||
private string email = string.Empty;
|
||||
private string displayname = string.Empty;
|
||||
private FileManager filemanager;
|
||||
private int photofileid = -1;
|
||||
private List<Profile> profiles;
|
||||
private Dictionary<string, string> settings;
|
||||
private string category = string.Empty;
|
||||
private string filter = "to";
|
||||
private List<Notification> notifications;
|
||||
|
||||
string username = "";
|
||||
string password = "";
|
||||
string confirm = "";
|
||||
string email = "";
|
||||
string displayname = "";
|
||||
List<Profile> profiles;
|
||||
Dictionary<string, string> settings;
|
||||
string category = "";
|
||||
string filter = "to";
|
||||
List<Notification> notifications;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -179,8 +187,15 @@
|
|||
username = PageState.User.Username;
|
||||
email = PageState.User.Email;
|
||||
displayname = PageState.User.DisplayName;
|
||||
|
||||
if (PageState.User.PhotoFileId != null)
|
||||
{
|
||||
photofileid = PageState.User.PhotoFileId.Value;
|
||||
}
|
||||
|
||||
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
||||
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||
|
||||
await LoadNotificationsAsync();
|
||||
}
|
||||
else
|
||||
|
@ -202,28 +217,32 @@
|
|||
}
|
||||
|
||||
private string GetProfileValue(string SettingName, string DefaultValue)
|
||||
{
|
||||
return SettingService.GetSetting(settings, SettingName, DefaultValue);
|
||||
}
|
||||
=> SettingService.GetSetting(settings, SettingName, DefaultValue);
|
||||
|
||||
private async Task Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (password != "" && confirm != "" && email != "")
|
||||
if (username != string.Empty && email != string.Empty)
|
||||
{
|
||||
if (password == confirm)
|
||||
{
|
||||
User user = PageState.User;
|
||||
var user = PageState.User;
|
||||
user.Username = username;
|
||||
user.Password = password;
|
||||
user.Email = email;
|
||||
user.DisplayName = (displayname == "" ? username : displayname);
|
||||
user.DisplayName = (displayname == string.Empty ? username : displayname);
|
||||
user.PhotoFileId = null;
|
||||
photofileid = filemanager.GetFileId();
|
||||
|
||||
if (photofileid != -1)
|
||||
{
|
||||
user.PhotoFileId = photofileid;
|
||||
}
|
||||
|
||||
await UserService.UpdateUserAsync(user);
|
||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||
await logger.LogInformation("User Profile Saved");
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl(""));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -232,7 +251,7 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
|
||||
AddModuleMessage("You Must Provide A Username and Email Address", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -244,12 +263,12 @@
|
|||
|
||||
private void Cancel()
|
||||
{
|
||||
NavigationManager.NavigateTo(NavigateUrl(""));
|
||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
||||
}
|
||||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
{
|
||||
string value = (string)e.Value;
|
||||
var value = (string)e.Value;
|
||||
settings = SettingService.SetSetting(settings, SettingName, value);
|
||||
}
|
||||
|
||||
|
@ -266,6 +285,7 @@
|
|||
{
|
||||
await NotificationService.DeleteNotificationAsync(Notification.NotificationId);
|
||||
}
|
||||
|
||||
await logger.LogInformation("Notification Deleted {Notification}", Notification);
|
||||
await LoadNotificationsAsync();
|
||||
StateHasChanged();
|
||||
|
@ -280,6 +300,7 @@
|
|||
private async void FilterChanged(ChangeEventArgs e)
|
||||
{
|
||||
filter = (string)e.Value;
|
||||
|
||||
await LoadNotificationsAsync();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">@title: </label>
|
||||
<label class="control-label">@title: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" readonly @bind="userid">
|
||||
|
@ -26,7 +26,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Subject: </label>
|
||||
<label class="control-label">Subject: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@subject" />
|
||||
|
@ -36,7 +36,7 @@
|
|||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Date: </label>
|
||||
<label class="control-label">Date: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@createdon" />
|
||||
|
@ -45,14 +45,14 @@
|
|||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Message: </label>
|
||||
<label class="control-label">Message: </label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@body" rows="5" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@if (reply != "")
|
||||
@if (reply != string.Empty)
|
||||
{
|
||||
<button type="button" class="btn btn-primary" @onclick="Send">Send</button>
|
||||
}
|
||||
|
@ -70,17 +70,17 @@
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } }
|
||||
public override string Title { get { return "View Notification"; } }
|
||||
private int notificationid;
|
||||
private string title = string.Empty;
|
||||
private List<UserRole> userroles;
|
||||
private string userid = "-1";
|
||||
private string subject = string.Empty;
|
||||
private string createdon = string.Empty;
|
||||
private string body = string.Empty;
|
||||
private string reply = string.Empty;
|
||||
|
||||
int notificationid;
|
||||
string title = "";
|
||||
List<UserRole> userroles;
|
||||
string userid = "-1";
|
||||
string subject = "";
|
||||
string createdon = "";
|
||||
string body = "";
|
||||
string reply = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||
public override string Title => "View Notification";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -110,6 +110,7 @@
|
|||
userid = notification.ToUserId.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
subject = notification.Subject;
|
||||
createdon = notification.CreatedOn.ToString();
|
||||
body = notification.Body;
|
||||
|
@ -132,15 +133,15 @@
|
|||
|
||||
private async Task Send()
|
||||
{
|
||||
Notification notification = new Notification();
|
||||
var notification = new Notification();
|
||||
notification.SiteId = PageState.Site.SiteId;
|
||||
notification.FromUserId = PageState.User.UserId;
|
||||
notification.ToUserId = int.Parse(userid);
|
||||
notification.ToEmail = "";
|
||||
notification.ToEmail = string.Empty;
|
||||
notification.Subject = subject;
|
||||
notification.Body = body;
|
||||
notification.ParentId = notificationid;
|
||||
notification.CreatedOn = DateTime.Now;
|
||||
notification.CreatedOn = DateTime.UtcNow;
|
||||
notification.IsDelivered = false;
|
||||
notification.DeliveredOn = null;
|
||||
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
@inject IProfileService ProfileService
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (profiles != null)
|
||||
{
|
||||
<TabStrip>
|
||||
<TabPanel Name="Identity">
|
||||
@if (profiles != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Username: </label>
|
||||
<label class="control-label">Username: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@username" />
|
||||
|
@ -18,7 +20,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Password: </label>
|
||||
<label class="control-label">Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@password" />
|
||||
|
@ -26,7 +28,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Confirm Password: </label>
|
||||
<label class="control-label">Confirm Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@confirm" />
|
||||
|
@ -34,7 +36,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Email: </label>
|
||||
<label class="control-label">Email: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@email" />
|
||||
|
@ -42,13 +44,19 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Full Name: </label>
|
||||
<label class="control-label">Full Name: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@displayname" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Profile">
|
||||
@if (profiles != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
@foreach (Profile profile in profiles)
|
||||
{
|
||||
var p = profile;
|
||||
|
@ -66,26 +74,29 @@
|
|||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" maxlength="@p.MaxLength" placeholder="@p.Description" @onchange="(e => ProfileChanged(e, p.Name))" />
|
||||
<input class="form-control" maxlength="@p.MaxLength" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="SaveUser">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
}
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
<button type="button" class="btn btn-primary" @onclick="SaveUser">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private string username = string.Empty;
|
||||
private string password = string.Empty;
|
||||
private string confirm = string.Empty;
|
||||
private string email = string.Empty;
|
||||
private string displayname = string.Empty;
|
||||
private List<Profile> profiles;
|
||||
private Dictionary<string, string> settings;
|
||||
private string category = string.Empty;
|
||||
|
||||
string username = "";
|
||||
string password = "";
|
||||
string confirm = "";
|
||||
string email = "";
|
||||
string displayname = "";
|
||||
List<Profile> profiles;
|
||||
Dictionary<string, string> settings;
|
||||
string category = "";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -105,16 +116,17 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
if (username != "" && password != "" && confirm != "" && email != "")
|
||||
if (username != string.Empty && password != string.Empty && confirm != string.Empty && email != string.Empty)
|
||||
{
|
||||
if (password == confirm)
|
||||
{
|
||||
User user = new User();
|
||||
var user = new User();
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = username;
|
||||
user.Password = password;
|
||||
user.Email = email;
|
||||
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
||||
user.PhotoFileId = null;
|
||||
|
||||
user = await UserService.AddUserAsync(user);
|
||||
|
||||
|
@ -149,7 +161,7 @@
|
|||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
{
|
||||
string value = (string)e.Value;
|
||||
var value = (string)e.Value;
|
||||
settings = SettingService.SetSetting(settings, SettingName, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,12 +5,22 @@
|
|||
@inject IProfileService ProfileService
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (profiles != null)
|
||||
@if (PageState.User != null && photofileid != -1)
|
||||
{
|
||||
<img src="@(ContentUrl(photofileid))" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
||||
}
|
||||
else
|
||||
{
|
||||
<br />
|
||||
}
|
||||
<TabStrip>
|
||||
<TabPanel Name="Identity">
|
||||
@if (profiles != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Username: </label>
|
||||
<label class="control-label">Username: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@username" readonly />
|
||||
|
@ -18,7 +28,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Password: </label>
|
||||
<label class="control-label">Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@password" />
|
||||
|
@ -26,7 +36,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Confirm Password: </label>
|
||||
<label class="control-label">Confirm Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@confirm" />
|
||||
|
@ -34,7 +44,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Email: </label>
|
||||
<label class="control-label">Email: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@email" />
|
||||
|
@ -42,13 +52,38 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Full Name: </label>
|
||||
<label class="control-label">Full Name: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@displayname" />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Photo: </label>
|
||||
</td>
|
||||
<td>
|
||||
<FileManager FileId="@photofileid" @ref="filemanager" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Is Deleted? </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isdeleted">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Profile">
|
||||
@if (profiles != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
@foreach (Profile profile in profiles)
|
||||
{
|
||||
var p = profile;
|
||||
|
@ -66,48 +101,41 @@
|
|||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="(e => ProfileChanged(e, p.Name))" />
|
||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Is Deleted? </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@isdeleted">
|
||||
<option value="True">Yes</option>
|
||||
<option value="False">No</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-primary" @onclick="SaveUser">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
|
||||
}
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
|
||||
<button type="button" class="btn btn-primary" @onclick="SaveUser">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br /><br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private int userid;
|
||||
private string username = string.Empty;
|
||||
private string password = string.Empty;
|
||||
private string confirm = string.Empty;
|
||||
private string email = string.Empty;
|
||||
private string displayname = string.Empty;
|
||||
private FileManager filemanager;
|
||||
private int photofileid = -1;
|
||||
private List<Profile> profiles;
|
||||
private Dictionary<string, string> settings;
|
||||
private string category = string.Empty;
|
||||
private string createdby;
|
||||
private DateTime createdon;
|
||||
private string modifiedby;
|
||||
private DateTime modifiedon;
|
||||
private string deletedby;
|
||||
private DateTime? deletedon;
|
||||
private string isdeleted;
|
||||
|
||||
int userid;
|
||||
string username = "";
|
||||
string password = "";
|
||||
string confirm = "";
|
||||
string email = "";
|
||||
string displayname = "";
|
||||
List<Profile> profiles;
|
||||
Dictionary<string, string> settings;
|
||||
string category = "";
|
||||
string createdby;
|
||||
DateTime createdon;
|
||||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
string deletedby;
|
||||
DateTime? deletedon;
|
||||
string isdeleted;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -116,12 +144,18 @@
|
|||
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
||||
|
||||
userid = Int32.Parse(PageState.QueryString["id"]);
|
||||
User user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
if (user != null)
|
||||
{
|
||||
username = user.Username;
|
||||
email = user.Email;
|
||||
displayname = user.DisplayName;
|
||||
|
||||
if (user.PhotoFileId != null)
|
||||
{
|
||||
photofileid = user.PhotoFileId.Value;
|
||||
}
|
||||
|
||||
settings = await SettingService.GetUserSettingsAsync(user.UserId);
|
||||
createdby = user.CreatedBy;
|
||||
createdon = user.CreatedOn;
|
||||
|
@ -140,24 +174,30 @@
|
|||
}
|
||||
|
||||
private string GetProfileValue(string SettingName, string DefaultValue)
|
||||
{
|
||||
return SettingService.GetSetting(settings, SettingName, DefaultValue);
|
||||
}
|
||||
=> SettingService.GetSetting(settings, SettingName, DefaultValue);
|
||||
|
||||
private async Task SaveUser()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (username != "" && password != "" && confirm != "" && email != "")
|
||||
if (username != string.Empty && email != string.Empty)
|
||||
{
|
||||
if (password == confirm)
|
||||
{
|
||||
User user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
user.SiteId = PageState.Site.SiteId;
|
||||
user.Username = username;
|
||||
user.Password = password;
|
||||
user.Email = email;
|
||||
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
||||
user.PhotoFileId = null;
|
||||
photofileid = filemanager.GetFileId();
|
||||
|
||||
if (photofileid != -1)
|
||||
{
|
||||
user.PhotoFileId = photofileid;
|
||||
}
|
||||
|
||||
user.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
|
||||
|
||||
user = await UserService.UpdateUserAsync(user);
|
||||
|
@ -185,7 +225,7 @@
|
|||
|
||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||
{
|
||||
string value = (string)e.Value;
|
||||
var value = (string)e.Value;
|
||||
settings = SettingService.SetSetting(settings, SettingName, value);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private List<UserRole> userroles;
|
||||
|
||||
List<UserRole> userroles;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
User user = await UserService.GetUserAsync(UserRole.UserId, PageState.Site.SiteId);
|
||||
var user = await UserService.GetUserAsync(UserRole.UserId, PageState.Site.SiteId);
|
||||
if (user != null)
|
||||
{
|
||||
await UserService.DeleteUserAsync(user.UserId);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
@namespace Oqtane.Modules.Admin.Users
|
||||
@inherits ModuleBase
|
||||
@inject IRoleService RoleService
|
||||
@inject IUserService UserService
|
||||
@inject IUserRoleService UserRoleService
|
||||
|
||||
@if (userroles == null)
|
||||
|
@ -12,10 +13,18 @@ else
|
|||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Role: </label>
|
||||
<Label For="user" HelpText="The user you are assigning roles to">User: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" @bind="@roleid">
|
||||
<input id="user" class="form-control" @bind="@name" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="role" HelpText="Select a role">Role: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="role" class="form-control" @bind="@roleid">
|
||||
<option value="-1"><Select Role></option>
|
||||
@foreach (Role role in roles)
|
||||
{
|
||||
|
@ -26,18 +35,18 @@ else
|
|||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Effective Date: </label>
|
||||
<Label For="effectiveDate" HelpText="The date that this role assignment is active">Effective Date: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@effectivedate" />
|
||||
<input id="effectiveDate" class="form-control" @bind="@effectivedate" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Expiry Date: </label>
|
||||
<Label For="expiryDate" HelpText="The date that this role assignment expires">Expiry Date: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@expirydate" />
|
||||
<input id="expiryDate" class="form-control" @bind="@expirydate" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -48,13 +57,13 @@ else
|
|||
<p align="center">
|
||||
<Pager Items="@userroles">
|
||||
<Header>
|
||||
<th>Role</th>
|
||||
<th>Roles</th>
|
||||
<th> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td>@context.Role.Name</td>
|
||||
<td>
|
||||
@if (!context.Role.IsSystem)
|
||||
@if (context.Role.Name != Constants.RegisteredRole)
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick=@(async () => await DeleteUserRole(context.UserRoleId))>Delete</button>
|
||||
}
|
||||
|
@ -65,20 +74,23 @@ else
|
|||
}
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
|
||||
private int userid;
|
||||
private string name = string.Empty;
|
||||
private List<Role> roles;
|
||||
private int roleid = -1;
|
||||
private string effectivedate = string.Empty;
|
||||
private string expirydate = string.Empty;
|
||||
private List<UserRole> userroles;
|
||||
|
||||
int userid;
|
||||
List<Role> roles;
|
||||
int roleid = -1;
|
||||
string effectivedate = "";
|
||||
string expirydate = "";
|
||||
List<UserRole> userroles;
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
userid = Int32.Parse(PageState.QueryString["id"]);
|
||||
User user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
name = user.DisplayName;
|
||||
roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
|
||||
await GetUserRoles();
|
||||
}
|
||||
|
@ -109,7 +121,7 @@ else
|
|||
{
|
||||
if (roleid != -1)
|
||||
{
|
||||
UserRole userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault();
|
||||
var userrole = userroles.Where(item => item.UserId == userid && item.RoleId == roleid).FirstOrDefault();
|
||||
if (userrole != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(effectivedate))
|
||||
|
@ -120,6 +132,7 @@ else
|
|||
{
|
||||
userrole.EffectiveDate = DateTime.Parse(effectivedate);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(expirydate))
|
||||
{
|
||||
userrole.ExpiryDate = null;
|
||||
|
@ -135,6 +148,7 @@ else
|
|||
userrole = new UserRole();
|
||||
userrole.UserId = userid;
|
||||
userrole.RoleId = roleid;
|
||||
|
||||
if (string.IsNullOrEmpty(effectivedate))
|
||||
{
|
||||
userrole.EffectiveDate = null;
|
||||
|
@ -143,6 +157,7 @@ else
|
|||
{
|
||||
userrole.EffectiveDate = DateTime.Parse(effectivedate);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(expirydate))
|
||||
{
|
||||
userrole.ExpiryDate = null;
|
||||
|
@ -151,8 +166,10 @@ else
|
|||
{
|
||||
userrole.ExpiryDate = DateTime.Parse(expirydate);
|
||||
}
|
||||
|
||||
await UserRoleService.AddUserRoleAsync(userrole);
|
||||
}
|
||||
|
||||
await GetUserRoles();
|
||||
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
|
||||
AddModuleMessage("User Assigned To Role", MessageType.Success);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
|
||||
@if (visible)
|
||||
@attribute [OqtaneIgnore]
|
||||
@if (_visible)
|
||||
{
|
||||
<div class="app-admin-modal">
|
||||
<div class="modal" tabindex="-1" role="dialog">
|
||||
|
@ -17,7 +17,7 @@
|
|||
<div class="modal-footer">
|
||||
@if (!string.IsNullOrEmpty(Action))
|
||||
{
|
||||
<button type="button" class="@Class" @onclick="Confirm">@Action</button>
|
||||
<button type="button" class="@Class" @onclick="Confirm">@((MarkupString)_iconSpan) @Action</button>
|
||||
}
|
||||
<button type="button" class="btn btn-secondary" @onclick="DisplayModal">Cancel</button>
|
||||
</div>
|
||||
|
@ -26,12 +26,24 @@
|
|||
</div>
|
||||
</div>
|
||||
}
|
||||
@if (authorized)
|
||||
@if (_authorized)
|
||||
{
|
||||
<button class="@Class" @onclick="DisplayModal">@Text</button>
|
||||
if (Disabled)
|
||||
{
|
||||
<button class="@Class" disabled>@((MarkupString)_iconSpan) @Text</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="@Class" @onclick="DisplayModal">@((MarkupString)_iconSpan) @Text</button>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private bool _visible = false;
|
||||
private bool _editmode = true;
|
||||
private bool _authorized = false;
|
||||
private string _iconSpan = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Header { get; set; } // required
|
||||
|
||||
|
@ -50,15 +62,17 @@
|
|||
[Parameter]
|
||||
public string Class { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
||||
|
||||
[Parameter]
|
||||
public Action OnClick { get; set; } // required if an Action is specified - executes a method in the calling component
|
||||
|
||||
bool visible = false;
|
||||
bool editmode = true;
|
||||
bool authorized = false;
|
||||
[Parameter]
|
||||
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
|
@ -72,15 +86,21 @@
|
|||
}
|
||||
if (!string.IsNullOrEmpty(EditMode))
|
||||
{
|
||||
editmode = bool.Parse(EditMode);
|
||||
_editmode = bool.Parse(EditMode);
|
||||
}
|
||||
authorized = IsAuthorized();
|
||||
|
||||
if (!string.IsNullOrEmpty(IconName))
|
||||
{
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span> ";
|
||||
}
|
||||
|
||||
_authorized = IsAuthorized();
|
||||
}
|
||||
|
||||
private bool IsAuthorized()
|
||||
{
|
||||
bool authorized = false;
|
||||
if (PageState.EditMode || !editmode)
|
||||
if (PageState.EditMode || !_editmode)
|
||||
{
|
||||
SecurityAccessLevel security = SecurityAccessLevel.Host;
|
||||
if (Security == null)
|
||||
|
@ -89,8 +109,8 @@
|
|||
Type moduleType = Type.GetType(typename);
|
||||
if (moduleType != null)
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(moduleType);
|
||||
security = (SecurityAccessLevel)moduleType.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
|
||||
var moduleobject = Activator.CreateInstance(moduleType) as IModuleControl;
|
||||
security = moduleobject.SecurityAccessLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -107,10 +127,10 @@
|
|||
authorized = true;
|
||||
break;
|
||||
case SecurityAccessLevel.View:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, "View", ModuleState.Permissions);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User,PermissionNames.View, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Edit:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, "Edit", ModuleState.Permissions);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Admin:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole);
|
||||
|
@ -125,7 +145,7 @@
|
|||
|
||||
private void DisplayModal()
|
||||
{
|
||||
visible = !visible;
|
||||
_visible = !_visible;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,30 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inject IUserService UserService
|
||||
|
||||
@if (authorized)
|
||||
@if (_authorized)
|
||||
{
|
||||
<NavLink class="@classname" href="@url" style="@style">@text</NavLink>
|
||||
if (Disabled)
|
||||
{
|
||||
<button class="@_classname" style="@_style" disabled>@((MarkupString)_iconSpan) @_text</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<NavLink class="@_classname" href="@_url" style="@_style">@((MarkupString)_iconSpan) @_text</NavLink>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _text = string.Empty;
|
||||
private string _url = string.Empty;
|
||||
private string _parameters = string.Empty;
|
||||
private string _classname = "btn btn-primary";
|
||||
private string _style = string.Empty;
|
||||
private bool _editmode = true;
|
||||
private bool _authorized = false;
|
||||
private string _iconSpan = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Action { get; set; } // required
|
||||
|
||||
|
@ -26,63 +43,66 @@
|
|||
[Parameter]
|
||||
public string Style { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public bool Disabled { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
||||
|
||||
string text = "";
|
||||
string url = "";
|
||||
string parameters = "";
|
||||
string classname = "btn btn-primary";
|
||||
string style = "";
|
||||
bool editmode = true;
|
||||
bool authorized = false;
|
||||
[Parameter]
|
||||
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
text = Action;
|
||||
_text = Action;
|
||||
if (!string.IsNullOrEmpty(Text))
|
||||
{
|
||||
text = Text;
|
||||
_text = Text;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Parameters))
|
||||
{
|
||||
parameters = Parameters;
|
||||
_parameters = Parameters;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Class))
|
||||
{
|
||||
classname = Class;
|
||||
_classname = Class;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Style))
|
||||
{
|
||||
style = Style;
|
||||
_style = Style;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(EditMode))
|
||||
{
|
||||
editmode = bool.Parse(EditMode);
|
||||
_editmode = bool.Parse(EditMode);
|
||||
}
|
||||
|
||||
url = EditUrl(Action, parameters);
|
||||
authorized = IsAuthorized();
|
||||
if (!string.IsNullOrEmpty(IconName))
|
||||
{
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span> ";
|
||||
}
|
||||
|
||||
_url = EditUrl(Action, _parameters);
|
||||
_authorized = IsAuthorized();
|
||||
}
|
||||
|
||||
private bool IsAuthorized()
|
||||
{
|
||||
bool authorized = false;
|
||||
if (PageState.EditMode || !editmode)
|
||||
var authorized = false;
|
||||
if (PageState.EditMode || !_editmode)
|
||||
{
|
||||
SecurityAccessLevel security = SecurityAccessLevel.Host;
|
||||
var security = SecurityAccessLevel.Host;
|
||||
if (Security == null)
|
||||
{
|
||||
string typename = ModuleState.ModuleType.Replace(Utilities.GetTypeNameLastSegment(ModuleState.ModuleType, 0) + ",", Action + ",");
|
||||
Type moduleType = Type.GetType(typename);
|
||||
var typename = ModuleState.ModuleType.Replace(Utilities.GetTypeNameLastSegment(ModuleState.ModuleType, 0) + ",", Action + ",");
|
||||
var moduleType = Type.GetType(typename);
|
||||
if (moduleType != null)
|
||||
{
|
||||
var moduleobject = Activator.CreateInstance(moduleType);
|
||||
security = (SecurityAccessLevel)moduleType.GetProperty("SecurityAccessLevel").GetValue(moduleobject, null);
|
||||
var moduleobject = Activator.CreateInstance(moduleType) as IModuleControl;
|
||||
security = moduleobject.SecurityAccessLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -94,16 +114,17 @@
|
|||
{
|
||||
security = Security.Value;
|
||||
}
|
||||
|
||||
switch (security)
|
||||
{
|
||||
case SecurityAccessLevel.Anonymous:
|
||||
authorized = true;
|
||||
break;
|
||||
case SecurityAccessLevel.View:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, "View", ModuleState.Permissions);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Edit:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, "Edit", ModuleState.Permissions);
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions);
|
||||
break;
|
||||
case SecurityAccessLevel.Admin:
|
||||
authorized = UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole);
|
||||
|
@ -113,6 +134,7 @@
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return authorized;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (text != "")
|
||||
@if (_text != string.Empty)
|
||||
{
|
||||
@((MarkupString)@text)
|
||||
@((MarkupString)_text)
|
||||
}
|
||||
|
||||
@code {
|
||||
|
||||
private string _text = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string CreatedBy { get; set; }
|
||||
|
||||
|
@ -31,51 +35,58 @@
|
|||
[Parameter]
|
||||
public string Style { get; set; }
|
||||
|
||||
string text = "";
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
text = "";
|
||||
_text = string.Empty;
|
||||
if (!String.IsNullOrEmpty(CreatedBy) || CreatedOn != null)
|
||||
{
|
||||
text += "<p style=\"" + Style + "\">Created ";
|
||||
_text += "<p style=\"" + Style + "\">Created ";
|
||||
|
||||
if (!String.IsNullOrEmpty(CreatedBy))
|
||||
{
|
||||
text += " by <b>" + CreatedBy + "</b>";
|
||||
_text += " by <b>" + CreatedBy + "</b>";
|
||||
}
|
||||
|
||||
if (CreatedOn != null)
|
||||
{
|
||||
text += " on <b>" + CreatedOn.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
_text += " on <b>" + CreatedOn.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
}
|
||||
text += "</p>";
|
||||
|
||||
_text += "</p>";
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn != null)
|
||||
{
|
||||
text += "<p style=\"" + Style + "\">Last modified ";
|
||||
_text += "<p style=\"" + Style + "\">Last modified ";
|
||||
|
||||
if (!String.IsNullOrEmpty(ModifiedBy))
|
||||
{
|
||||
text += " by <b>" + ModifiedBy + "</b>";
|
||||
_text += " by <b>" + ModifiedBy + "</b>";
|
||||
}
|
||||
|
||||
if (ModifiedOn != null)
|
||||
{
|
||||
text += " on <b>" + ModifiedOn.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
_text += " on <b>" + ModifiedOn.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
}
|
||||
text += "</p>";
|
||||
|
||||
_text += "</p>";
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(DeletedBy) || DeletedOn.HasValue)
|
||||
{
|
||||
text += "<p style=\"" + Style + "\">Deleted ";
|
||||
_text += "<p style=\"" + Style + "\">Deleted ";
|
||||
|
||||
if (!String.IsNullOrEmpty(DeletedBy))
|
||||
{
|
||||
text += " by <b>" + DeletedBy + "</b>";
|
||||
_text += " by <b>" + DeletedBy + "</b>";
|
||||
}
|
||||
|
||||
if (DeletedOn != null)
|
||||
{
|
||||
text += " on <b>" + DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
_text += " on <b>" + DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss") + "</b>";
|
||||
}
|
||||
text += "</p>";
|
||||
|
||||
_text += "</p>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
335
Oqtane.Client/Modules/Controls/FileManager.razor
Normal file
335
Oqtane.Client/Modules/Controls/FileManager.razor
Normal file
|
@ -0,0 +1,335 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
|
||||
@attribute [OqtaneIgnore]
|
||||
@inject IFolderService FolderService
|
||||
@inject IFileService FileService
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
@if (_folders != null)
|
||||
{
|
||||
<div id="@Id" class="container-fluid px-0">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@if (ShowFolders || FolderId <= 0)
|
||||
{
|
||||
<div>
|
||||
<select class="form-control" @onchange="(e => FolderChanged(e))">
|
||||
@if (string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
<option value="-1"><Select Folder></option>
|
||||
}
|
||||
@foreach (Folder folder in _folders)
|
||||
{
|
||||
if (folder.FolderId == FolderId)
|
||||
{
|
||||
<option value="@(folder.FolderId)" selected>@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
@if (ShowFiles)
|
||||
{
|
||||
<div>
|
||||
<select class="form-control" @onchange="(e => FileChanged(e))">
|
||||
<option value="-1"><Select File></option>
|
||||
@foreach (File file in _files)
|
||||
{
|
||||
if (file.FileId == FileId)
|
||||
{
|
||||
<option value="@(file.FileId)" selected>@(file.Name)</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@(file.FileId)">@(file.Name)</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
}
|
||||
@if (ShowUpload && _haseditpermission)
|
||||
{
|
||||
<div>
|
||||
@if (UploadMultiple)
|
||||
{
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple/>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter"/>
|
||||
}
|
||||
<span id="@_progressinfoid"></span><progress id="@_progressbarid" style="width: 150px; visibility: hidden;"></progress>
|
||||
<span class="float-right">
|
||||
<button type="button" class="btn btn-success" @onclick="UploadFile">Upload</button>
|
||||
@if (_showfiles && GetFileId() != -1)
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick="DeleteFile">Delete</button>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
@((MarkupString) _message)
|
||||
</div>
|
||||
@if (_image != string.Empty)
|
||||
{
|
||||
<div class="col-auto">
|
||||
@((MarkupString) _image)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _id;
|
||||
private List<Folder> _folders;
|
||||
private List<File> _files = new List<File>();
|
||||
private bool _showfiles = true;
|
||||
private string _fileinputid = string.Empty;
|
||||
private string _progressinfoid = string.Empty;
|
||||
private string _progressbarid = string.Empty;
|
||||
private string _filter = "*";
|
||||
private bool _haseditpermission = false;
|
||||
private string _message = string.Empty;
|
||||
private string _image = string.Empty;
|
||||
private string _guid;
|
||||
|
||||
[Parameter]
|
||||
public string Id { get; set; } // optional - for setting the id of the FileManager component for accessibility
|
||||
|
||||
[Parameter]
|
||||
public string Folder { get; set; } // optional - for setting a specific folder by default
|
||||
|
||||
[Parameter]
|
||||
public int FolderId { get; set; } = -1; // optional - for setting a specific folderid by default
|
||||
|
||||
[Parameter]
|
||||
public bool ShowFiles { get; set; } = true; // optional - for indicating whether a list of files should be displayed - default is true
|
||||
|
||||
[Parameter]
|
||||
public bool ShowUpload { get; set; } = true; // optional - for indicating whether a Upload controls should be displayed - default is true
|
||||
|
||||
[Parameter]
|
||||
public bool ShowFolders { get; set; } = true; // optional - for indicating whether a list of folders should be displayed - default is true
|
||||
|
||||
[Parameter]
|
||||
public int FileId { get; set; } = -1; // optional - for setting a specific file by default
|
||||
|
||||
[Parameter]
|
||||
public string Filter { get; set; } // optional - comma delimited list of file types that can be selected or uploaded ie. "jpg,gif"
|
||||
|
||||
[Parameter]
|
||||
public bool UploadMultiple { get; set; } = false; // optional - enable multiple file uploads - default false
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(Id))
|
||||
{
|
||||
_id = Id;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
_folders = new List<Folder> {new Folder {FolderId = -1, Name = Folder}};
|
||||
FolderId = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
|
||||
}
|
||||
|
||||
if (FileId != -1)
|
||||
{
|
||||
File file = await FileService.GetFileAsync(FileId);
|
||||
if (file != null)
|
||||
{
|
||||
FolderId = file.FolderId;
|
||||
}
|
||||
else
|
||||
{
|
||||
FileId = -1; // file does not exist
|
||||
}
|
||||
}
|
||||
await SetImage();
|
||||
|
||||
if (!string.IsNullOrEmpty(Filter))
|
||||
{
|
||||
_filter = "." + Filter.Replace(",", ",.");
|
||||
}
|
||||
|
||||
await GetFiles();
|
||||
|
||||
// create unique id for component
|
||||
_guid = Guid.NewGuid().ToString("N");
|
||||
_fileinputid = _guid + "FileInput";
|
||||
_progressinfoid = _guid + "ProgressInfo";
|
||||
_progressbarid = _guid + "ProgressBar";
|
||||
}
|
||||
|
||||
private async Task GetFiles()
|
||||
{
|
||||
_haseditpermission = false;
|
||||
if (!string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
|
||||
_files = await FileService.GetFilesAsync(Folder);
|
||||
}
|
||||
else
|
||||
{
|
||||
Folder folder = _folders.FirstOrDefault(item => item.FolderId == FolderId);
|
||||
if (folder != null)
|
||||
{
|
||||
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, folder.Permissions);
|
||||
_files = await FileService.GetFilesAsync(FolderId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_haseditpermission = false;
|
||||
_files = new List<File>();
|
||||
}
|
||||
}
|
||||
if (_filter != "*")
|
||||
{
|
||||
List<File> filtered = new List<File>();
|
||||
foreach (File file in _files)
|
||||
{
|
||||
if (_filter.ToUpper().IndexOf("." + file.Extension.ToUpper()) != -1)
|
||||
{
|
||||
filtered.Add(file);
|
||||
}
|
||||
}
|
||||
_files = filtered;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FolderChanged(ChangeEventArgs e)
|
||||
{
|
||||
_message = string.Empty;
|
||||
try
|
||||
{
|
||||
FolderId = int.Parse((string) e.Value);
|
||||
await GetFiles();
|
||||
FileId = -1;
|
||||
_image = string.Empty;
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">Error Loading Files</div>";
|
||||
}
|
||||
}
|
||||
|
||||
private async Task FileChanged(ChangeEventArgs e)
|
||||
{
|
||||
_message = string.Empty;
|
||||
FileId = int.Parse((string) e.Value);
|
||||
|
||||
await SetImage();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task SetImage()
|
||||
{
|
||||
_image = string.Empty;
|
||||
if (FileId != -1)
|
||||
{
|
||||
File file = await FileService.GetFileAsync(FileId);
|
||||
if (file != null && file.ImageHeight != 0 && file.ImageWidth != 0)
|
||||
{
|
||||
var maxwidth = 200;
|
||||
var maxheight = 200;
|
||||
|
||||
var ratioX = (double) maxwidth / (double) file.ImageWidth;
|
||||
var ratioY = (double) maxheight / (double) file.ImageHeight;
|
||||
var ratio = ratioX < ratioY ? ratioX : ratioY;
|
||||
|
||||
_image = "<img src=\"" + ContentUrl(FileId) + "\" alt=\"" + file.Name +
|
||||
"\" width=\"" + Convert.ToInt32(file.ImageWidth * ratio).ToString() +
|
||||
"\" height=\"" + Convert.ToInt32(file.ImageHeight * ratio).ToString() + "\" />";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task UploadFile()
|
||||
{
|
||||
var interop = new Interop(JsRuntime);
|
||||
var upload = await interop.GetFiles(_fileinputid);
|
||||
if (upload.Length > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
string result;
|
||||
if (!string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
result = await FileService.UploadFilesAsync(Folder, upload, _guid);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await FileService.UploadFilesAsync(FolderId, upload, _guid);
|
||||
}
|
||||
|
||||
if (result == string.Empty)
|
||||
{
|
||||
await logger.LogInformation("File Upload Succeeded {Files}", upload);
|
||||
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Upload Succeeded</div>";
|
||||
await GetFiles();
|
||||
|
||||
if (upload.Length == 1)
|
||||
{
|
||||
var file = _files.Where(item => item.Name == upload[0]).FirstOrDefault();
|
||||
if (file != null)
|
||||
{
|
||||
FileId = file.FileId;
|
||||
await SetImage();
|
||||
}
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
await logger.LogError("File Upload Failed For {Files}", result.Replace(",", ", "));
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">File Upload Failed</div>";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "File Upload Failed {Error}", ex.Message);
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">File Upload Failed</div>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Have Not Selected A File To Upload</div>";
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteFile()
|
||||
{
|
||||
_message = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
await FileService.DeleteFileAsync(FileId);
|
||||
await logger.LogInformation("File Deleted {File}", FileId);
|
||||
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Deleted</div>";
|
||||
await GetFiles();
|
||||
FileId = -1;
|
||||
await SetImage();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting File {File} {Error}", FileId, ex.Message);
|
||||
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">Error Deleting File</div>";
|
||||
}
|
||||
}
|
||||
|
||||
public int GetFileId() => FileId;
|
||||
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inject IJSRuntime jsRuntime
|
||||
|
||||
@if (multiple)
|
||||
{
|
||||
<input type="file" id="@fileid" name="file" accept="@filter" value="@files" multiple />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="file" id="@fileid" name="file" accept="@filter" value="@files" />
|
||||
}
|
||||
<span id="@progressinfoid"></span> <progress id="@progressbarid" style="visibility: hidden;"></progress>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string Name { get; set; } // optional - can be used for managing multiple file upload controls on a page
|
||||
|
||||
[Parameter]
|
||||
public string Filter { get; set; } // optional - for restricting types of files that can be selected
|
||||
|
||||
[Parameter]
|
||||
public string Multiple { get; set; } // optional - enable multiple file uploads
|
||||
|
||||
string fileid = "";
|
||||
string progressinfoid = "";
|
||||
string progressbarid = "";
|
||||
string filter = "*";
|
||||
string files = "";
|
||||
bool multiple = false;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
fileid = Name + "FileInput";
|
||||
progressinfoid = Name + "ProgressInfo";
|
||||
progressbarid = Name + "ProgressBar";
|
||||
|
||||
if (!string.IsNullOrEmpty(Filter))
|
||||
{
|
||||
filter = Filter;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Multiple))
|
||||
{
|
||||
multiple = bool.Parse(Multiple);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<string[]> GetFiles()
|
||||
{
|
||||
var interop = new Interop(jsRuntime);
|
||||
string[] files = await interop.GetFiles(fileid);
|
||||
return files;
|
||||
}
|
||||
}
|
45
Oqtane.Client/Modules/Controls/Label.razor
Normal file
45
Oqtane.Client/Modules/Controls/Label.razor
Normal file
|
@ -0,0 +1,45 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (!string.IsNullOrEmpty(HelpText))
|
||||
{
|
||||
<span class="app-tooltip" data-tip="@((MarkupString)HelpText)">@((MarkupString)_openLabel)@ChildContent@((MarkupString)_closeLabel) <img src="images/help.png" /></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
@((MarkupString)_openLabel)@ChildContent@((MarkupString)_closeLabel)
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _openLabel = string.Empty;
|
||||
private string _closeLabel = "</label>";
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string For { get; set; } // optional - the id of the associated input control for accessibility
|
||||
|
||||
[Parameter]
|
||||
public string Class { get; set; } // optional - the class for the label ( ie. control-label )
|
||||
|
||||
[Parameter]
|
||||
public string HelpText { get; set; } // optional - tooltip for this label
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
_openLabel = "<label";
|
||||
if (!string.IsNullOrEmpty(For))
|
||||
{
|
||||
_openLabel += " for=\"" + For + "\"";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Class))
|
||||
{
|
||||
_openLabel += " class=\"" + Class + "\"";
|
||||
}
|
||||
|
||||
_openLabel += ">";
|
||||
}
|
||||
}
|
|
@ -1,38 +1,42 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (!string.IsNullOrEmpty(message))
|
||||
@if (!string.IsNullOrEmpty(_message))
|
||||
{
|
||||
<div class="@classname" role="alert">@message</div>
|
||||
<div class="@_classname" role="alert">@_message</div>
|
||||
<br />
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _message = string.Empty;
|
||||
private string _classname = "alert alert-danger";
|
||||
|
||||
[Parameter]
|
||||
public string Message { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public MessageType Type { get; set; }
|
||||
|
||||
string message = "";
|
||||
string classname = "alert alert-danger";
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
message = Message;
|
||||
classname = GetMessageType(Type);
|
||||
if (!string.IsNullOrEmpty(Message))
|
||||
{
|
||||
_message = Message;
|
||||
_classname = GetMessageType(Type);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetModuleMessage(string message, MessageType type)
|
||||
{
|
||||
this.message = message;
|
||||
classname = GetMessageType(type);
|
||||
_message = message;
|
||||
_classname = GetMessageType(type);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private string GetMessageType(MessageType type)
|
||||
{
|
||||
string classname = "";
|
||||
var classname = string.Empty;
|
||||
switch (type)
|
||||
{
|
||||
case MessageType.Success:
|
||||
|
@ -48,6 +52,7 @@
|
|||
classname = "alert alert-danger";
|
||||
break;
|
||||
}
|
||||
|
||||
return classname;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@typeparam TableItem
|
||||
|
||||
|
||||
<p>
|
||||
@if(Format == "Table")
|
||||
{
|
||||
|
@ -36,40 +38,40 @@
|
|||
</div>
|
||||
}
|
||||
<div class="mx-auto text-center">
|
||||
@if (Page > MaxPages)
|
||||
@if (_page > _maxPages)
|
||||
{
|
||||
<button class="btn btn-secondary" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></button>
|
||||
}
|
||||
@if (EndPage > 1)
|
||||
@if (_endPage > 1)
|
||||
{
|
||||
<button class="btn btn-secondary" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
|
||||
@for (int i = StartPage; i <= EndPage; i++)
|
||||
@for (int i = _startPage; i <= _endPage; i++)
|
||||
{
|
||||
var pager = i;
|
||||
<button class="btn @((pager == Page) ? "btn-primary" : "btn-link")" @onclick=@(async () => UpdateList(pager))>
|
||||
<button class="btn @((pager == _page) ? "btn-primary" : "btn-link")" @onclick=@(async () => UpdateList(pager))>
|
||||
@pager
|
||||
</button>
|
||||
}
|
||||
<button class="btn btn-secondary" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></button>
|
||||
}
|
||||
@if (EndPage < Pages)
|
||||
@if (_endPage < _pages)
|
||||
{
|
||||
<button class="btn btn-secondary" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></button>
|
||||
}
|
||||
@if (EndPage > 1)
|
||||
@if (_endPage > 1)
|
||||
{
|
||||
<span class="btn btn-link disabled">Page @Page of @Pages</span>
|
||||
<span class="btn btn-link disabled">Page @_page of @_pages</span>
|
||||
}
|
||||
</div>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
int Pages = 0;
|
||||
int Page = 1;
|
||||
int MaxItems;
|
||||
int MaxPages;
|
||||
int StartPage;
|
||||
int EndPage;
|
||||
private int _pages = 0;
|
||||
private int _page = 1;
|
||||
private int _maxItems;
|
||||
private int _maxPages;
|
||||
private int _startPage;
|
||||
private int _endPage;
|
||||
|
||||
[Parameter]
|
||||
public string Format { get; set; }
|
||||
|
@ -95,7 +97,7 @@
|
|||
[Parameter]
|
||||
public string Class { get; set; }
|
||||
|
||||
IEnumerable<TableItem> ItemList { get; set; }
|
||||
private IEnumerable<TableItem> ItemList { get; set; }
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
|
@ -103,6 +105,7 @@
|
|||
{
|
||||
Format = "Table";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(Class))
|
||||
{
|
||||
if (Format == "Table")
|
||||
|
@ -114,36 +117,39 @@
|
|||
Class = "container";
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(PageSize))
|
||||
{
|
||||
MaxItems = 10;
|
||||
_maxItems = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxItems = int.Parse(PageSize);
|
||||
_maxItems = int.Parse(PageSize);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(DisplayPages))
|
||||
{
|
||||
MaxPages = 5;
|
||||
_maxPages = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
MaxPages = int.Parse(DisplayPages);
|
||||
_maxPages = int.Parse(DisplayPages);
|
||||
}
|
||||
|
||||
if (Items != null)
|
||||
{
|
||||
ItemList = Items.Skip((Page - 1) * MaxItems).Take(MaxItems);
|
||||
Pages = (int)Math.Ceiling(Items.Count() / (decimal)MaxItems);
|
||||
ItemList = Items.Skip((_page - 1) * _maxItems).Take(_maxItems);
|
||||
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
||||
}
|
||||
|
||||
SetPagerSize("forward");
|
||||
}
|
||||
|
||||
public void UpdateList(int CurrentPage)
|
||||
public void UpdateList(int currentPage)
|
||||
{
|
||||
ItemList = Items.Skip((CurrentPage - 1) * MaxItems).Take(MaxItems);
|
||||
Page = CurrentPage;
|
||||
ItemList = Items.Skip((currentPage - 1) * _maxItems).Take(_maxItems);
|
||||
_page = currentPage;
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
|
@ -151,29 +157,30 @@
|
|||
{
|
||||
if (direction == "forward")
|
||||
{
|
||||
if (EndPage + 1 < Pages)
|
||||
if (_endPage + 1 < _pages)
|
||||
{
|
||||
StartPage = EndPage + 1;
|
||||
_startPage = _endPage + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
StartPage = 1;
|
||||
_startPage = 1;
|
||||
}
|
||||
|
||||
if (EndPage + MaxPages < Pages)
|
||||
if (_endPage + _maxPages < _pages)
|
||||
{
|
||||
EndPage = StartPage + MaxPages - 1;
|
||||
_endPage = _startPage + _maxPages - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
EndPage = Pages;
|
||||
_endPage = _pages;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
else if (direction == "back")
|
||||
{
|
||||
EndPage = StartPage - 1;
|
||||
StartPage = StartPage - MaxPages;
|
||||
_endPage = _startPage - 1;
|
||||
_startPage = _startPage - _maxPages;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,26 +188,27 @@
|
|||
{
|
||||
if (direction == "next")
|
||||
{
|
||||
if (Page < Pages)
|
||||
if (_page < _pages)
|
||||
{
|
||||
if (Page == EndPage)
|
||||
if (_page == _endPage)
|
||||
{
|
||||
SetPagerSize("forward");
|
||||
}
|
||||
Page += 1;
|
||||
_page += 1;
|
||||
}
|
||||
}
|
||||
else if (direction == "previous")
|
||||
{
|
||||
if (Page > 1)
|
||||
if (_page > 1)
|
||||
{
|
||||
if (Page == StartPage)
|
||||
if (_page == _startPage)
|
||||
{
|
||||
SetPagerSize("back");
|
||||
}
|
||||
Page -= 1;
|
||||
_page -= 1;
|
||||
}
|
||||
}
|
||||
UpdateList(Page);
|
||||
|
||||
UpdateList(_page);
|
||||
}
|
||||
}
|
|
@ -1,25 +1,26 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inject IRoleService RoleService
|
||||
@inject IUserService UserService
|
||||
|
||||
@if (roles != null)
|
||||
@if (_permissions != null)
|
||||
{
|
||||
<br />
|
||||
<table class="table">
|
||||
<table class="table" style="width: 50%; min-width: 250px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Role</th>
|
||||
@foreach (PermissionString permission in permissions)
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
<th style="text-align: center;">@permission.PermissionName @EntityName</th>
|
||||
<th style="text-align: center;">@permission.PermissionName</th>
|
||||
}
|
||||
</tr>
|
||||
@foreach (Role role in roles)
|
||||
@foreach (Role role in _roles)
|
||||
{
|
||||
<tr>
|
||||
<td>@role.Name</td>
|
||||
@foreach (PermissionString permission in permissions)
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
var p = permission;
|
||||
<td style="text-align: center;">
|
||||
|
@ -30,29 +31,29 @@
|
|||
}
|
||||
</tbody>
|
||||
</table>
|
||||
@if (@users.Count != 0)
|
||||
@if (_users.Count != 0)
|
||||
{
|
||||
<table class="table">
|
||||
<table class="table" style="width: 50%; min-width: 250px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
@foreach (PermissionString permission in permissions)
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
<th style="text-align: center;">@permission.PermissionName @EntityName</th>
|
||||
<th style="text-align: center;">@permission.PermissionName</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (User user in users)
|
||||
@foreach (User user in _users)
|
||||
{
|
||||
string userid = "[" + user.UserId.ToString() + "]";
|
||||
<tr>
|
||||
<td>@user.DisplayName</td>
|
||||
@foreach (PermissionString permission in permissions)
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
var p = permission;
|
||||
<td style="text-align: center;">
|
||||
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled=@GetPermissionDisabled(userid) OnChange="@(e => PermissionChanged(e, p.PermissionName, userid))" />
|
||||
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled=false OnChange="@(e => PermissionChanged(e, p.PermissionName, userid))" />
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
|
@ -60,20 +61,27 @@
|
|||
</tbody>
|
||||
</table>
|
||||
}
|
||||
<table class="table">
|
||||
<table class="table" style="width: 50%; min-width: 250px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align: right;"><label for="Username" class="control-label">User: </label></td>
|
||||
<td><input type="text" name="Username" class="form-control" placeholder="Enter Username" @bind="@username" /></td>
|
||||
<td><input type="text" name="Username" class="form-control" placeholder="Enter Username" @bind="@_username" /></td>
|
||||
<td style="text-align: left;"><button type="button" class="btn btn-primary" @onclick="AddUser">Add</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<ModuleMessage Type="MessageType.Error" Message="@message" />
|
||||
<ModuleMessage Type="MessageType.Error" Message="@_message" />
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _permissionnames = string.Empty;
|
||||
private List<Role> _roles;
|
||||
private List<PermissionString> _permissions;
|
||||
private List<User> _users = new List<User>();
|
||||
private string _username = string.Empty;
|
||||
private string _message = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string EntityName { get; set; }
|
||||
|
||||
|
@ -83,46 +91,49 @@
|
|||
[Parameter]
|
||||
public string Permissions { get; set; }
|
||||
|
||||
string permissionnames = "";
|
||||
List<Role> roles;
|
||||
List<PermissionString> permissions = new List<PermissionString>();
|
||||
List<User> users = new List<User>();
|
||||
string username = "";
|
||||
string message = "";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(PermissionNames))
|
||||
{
|
||||
permissionnames = "View,Edit";
|
||||
_permissionnames = Shared.PermissionNames.View + "," + Shared.PermissionNames.Edit;
|
||||
}
|
||||
else
|
||||
{
|
||||
permissionnames = PermissionNames;
|
||||
_permissionnames = PermissionNames;
|
||||
}
|
||||
roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
|
||||
roles.Insert(0, new Role { Name = Constants.AllUsersRole });
|
||||
|
||||
foreach (string permissionname in permissionnames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
|
||||
_roles.Insert(0, new Role { Name = Constants.AllUsersRole });
|
||||
|
||||
_permissions = new List<PermissionString>();
|
||||
|
||||
foreach (string permissionname in _permissionnames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
permissions.Add(new PermissionString { PermissionName = permissionname, Permissions = "" });
|
||||
// initialize with admin role
|
||||
_permissions.Add(new PermissionString { PermissionName = permissionname, Permissions = Constants.AdminRole });
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Permissions))
|
||||
{
|
||||
// populate permissions
|
||||
foreach (PermissionString permissionstring in UserSecurity.GetPermissionStrings(Permissions))
|
||||
{
|
||||
if (permissions.Find(item => item.PermissionName == permissionstring.PermissionName) != null)
|
||||
if (_permissions.Find(item => item.PermissionName == permissionstring.PermissionName) != null)
|
||||
{
|
||||
permissions[permissions.FindIndex(item => item.PermissionName == permissionstring.PermissionName)].Permissions = permissionstring.Permissions;
|
||||
_permissions[_permissions.FindIndex(item => item.PermissionName == permissionstring.PermissionName)].Permissions = permissionstring.Permissions;
|
||||
}
|
||||
|
||||
if (permissionstring.Permissions.Contains("["))
|
||||
{
|
||||
foreach (string user in permissionstring.Permissions.Split(new char[] { '[' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (user.Contains("]"))
|
||||
{
|
||||
int userid = int.Parse(user.Substring(0, user.IndexOf("]")));
|
||||
if (users.Where(item => item.UserId == userid).FirstOrDefault() == null)
|
||||
var userid = int.Parse(user.Substring(0, user.IndexOf("]")));
|
||||
if (_users.Where(item => item.UserId == userid).FirstOrDefault() == null)
|
||||
{
|
||||
users.Add(await UserService.GetUserAsync(userid, ModuleState.SiteId));
|
||||
_users.Add(await UserService.GetUserAsync(userid, ModuleState.SiteId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,15 +141,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
private bool? GetPermissionValue(string Permissions, string SecurityKey)
|
||||
private bool? GetPermissionValue(string permissions, string securityKey)
|
||||
{
|
||||
if ((";" + Permissions + ";").Contains(";" + "!" + SecurityKey + ";"))
|
||||
if ((";" + permissions + ";").Contains(";" + "!" + securityKey + ";"))
|
||||
{
|
||||
return false; // deny permission
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((";" + Permissions + ";").Contains(";" + SecurityKey + ";"))
|
||||
if ((";" + permissions + ";").Contains(";" + securityKey + ";"))
|
||||
{
|
||||
return true; // grant permission
|
||||
}
|
||||
|
@ -149,66 +160,76 @@
|
|||
}
|
||||
}
|
||||
|
||||
private bool GetPermissionDisabled(string RoleName)
|
||||
{
|
||||
if (RoleName == Constants.AdminRole)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private bool GetPermissionDisabled(string roleName)
|
||||
=> roleName == Constants.AdminRole
|
||||
? true
|
||||
: false;
|
||||
|
||||
private async Task AddUser()
|
||||
{
|
||||
if (users.Where(item => item.Username == username).FirstOrDefault() == null)
|
||||
if (_users.Where(item => item.Username == _username).FirstOrDefault() == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
User user = await UserService.GetUserAsync(username, ModuleState.SiteId);
|
||||
var user = await UserService.GetUserAsync(_username, ModuleState.SiteId);
|
||||
if (user != null)
|
||||
{
|
||||
users.Add(user);
|
||||
_users.Add(user);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
message = "Username Does Not Exist";
|
||||
_message = "Username Does Not Exist";
|
||||
}
|
||||
}
|
||||
username = "";
|
||||
}
|
||||
|
||||
private void PermissionChanged(bool? Value, string PermissionName, string SecurityId)
|
||||
_username = string.Empty;
|
||||
}
|
||||
|
||||
private void PermissionChanged(bool? value, string permissionName, string securityId)
|
||||
{
|
||||
bool? selected = Value;
|
||||
PermissionString permission = permissions.Find(item => item.PermissionName == PermissionName);
|
||||
var selected = value;
|
||||
var permission = _permissions.Find(item => item.PermissionName == permissionName);
|
||||
if (permission != null)
|
||||
{
|
||||
List<string> ids = permission.Permissions.Split(';').ToList();
|
||||
var ids = permission.Permissions.Split(';').ToList();
|
||||
|
||||
ids.Remove(SecurityId); // remove grant permission
|
||||
ids.Remove("!" + SecurityId); // remove deny permission
|
||||
ids.Remove(securityId); // remove grant permission
|
||||
ids.Remove("!" + securityId); // remove deny permission
|
||||
|
||||
switch (selected)
|
||||
{
|
||||
case true:
|
||||
ids.Add(SecurityId); // add grant permission
|
||||
ids.Add(securityId); // add grant permission
|
||||
break;
|
||||
case false:
|
||||
ids.Add("!" + SecurityId); // add deny permission
|
||||
ids.Add("!" + securityId); // add deny permission
|
||||
break;
|
||||
case null:
|
||||
break; // permission not specified
|
||||
}
|
||||
permissions[permissions.FindIndex(item => item.PermissionName == PermissionName)].Permissions = string.Join(";", ids.ToArray());
|
||||
|
||||
_permissions[_permissions.FindIndex(item => item.PermissionName == permissionName)].Permissions = string.Join(";", ids.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public string GetPermissions()
|
||||
{
|
||||
return UserSecurity.SetPermissionStrings(permissions);
|
||||
ValidatePermissions();
|
||||
return UserSecurity.SetPermissionStrings(_permissions);
|
||||
}
|
||||
|
||||
private void ValidatePermissions()
|
||||
{
|
||||
PermissionString permission;
|
||||
for (int i = 0; i < _permissions.Count; i++)
|
||||
{
|
||||
permission = _permissions[i];
|
||||
List<string> ids = permission.Permissions.Split(';').ToList();
|
||||
ids.Remove("!" + Constants.AllUsersRole); // remove deny all users
|
||||
ids.Remove("!" + Constants.RegisteredRole); // remove deny registered users
|
||||
permission.Permissions = string.Join(";", ids.ToArray());
|
||||
_permissions[i] = permission;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,91 +1,218 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@inject IJSRuntime JSRuntime
|
||||
@attribute [OqtaneIgnore]
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
<div @ref="@ToolBar">
|
||||
<div class="row" style="margin-bottom: 50px;">
|
||||
<div class="col">
|
||||
<TabStrip>
|
||||
<TabPanel Name="Rich" Heading="Rich Text Editor">
|
||||
@if (_filemanagervisible)
|
||||
{
|
||||
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
||||
@((MarkupString)_message)
|
||||
<br />
|
||||
}
|
||||
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||
<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">Synchronize Content</button>
|
||||
<button type="button" class="btn btn-primary" @onclick="InsertImage">Insert Image</button>
|
||||
@if (_filemanagervisible)
|
||||
{
|
||||
@((MarkupString)" ")
|
||||
<button type="button" class="btn btn-secondary" @onclick="CloseFileManager">Close</button>
|
||||
}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div @ref="@_toolBar">
|
||||
@if (ToolbarContent != null)
|
||||
{
|
||||
@ToolbarContent
|
||||
</div>
|
||||
<div @ref="@EditorElement">
|
||||
}
|
||||
else
|
||||
{
|
||||
<select class="ql-header">
|
||||
<option selected=""></option>
|
||||
<option value="1"></option>
|
||||
<option value="2"></option>
|
||||
<option value="3"></option>
|
||||
<option value="4"></option>
|
||||
<option value="5"></option>
|
||||
</select>
|
||||
<span class="ql-formats">
|
||||
<button class="ql-bold"></button>
|
||||
<button class="ql-italic"></button>
|
||||
<button class="ql-underline"></button>
|
||||
<button class="ql-strike"></button>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<select class="ql-color"></select>
|
||||
<select class="ql-background"></select>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<button class="ql-list" value="ordered"></button>
|
||||
<button class="ql-list" value="bullet"></button>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<button class="ql-link"></button>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
<div @ref="@_editorElement">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Raw" Heading="Raw HTML Editor">
|
||||
<div class="row justify-content-center" style="margin-bottom: 20px;">
|
||||
<button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">Synchronize Content</button>
|
||||
</div>
|
||||
@if (ReadOnly)
|
||||
{
|
||||
<textarea class="form-control" placeholder="@Placeholder" @bind="@_content" rows="10" readonly></textarea>
|
||||
}
|
||||
else
|
||||
{
|
||||
<textarea class="form-control" placeholder="@Placeholder" @bind="@_content" rows="10"></textarea>
|
||||
}
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private ElementReference _editorElement;
|
||||
private ElementReference _toolBar;
|
||||
private bool _filemanagervisible = false;
|
||||
private FileManager _fileManager;
|
||||
private string _content = string.Empty;
|
||||
private string _original = string.Empty;
|
||||
private string _message = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public string Content { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool ReadOnly { get; set; } = false;
|
||||
|
||||
[Parameter]
|
||||
public string Placeholder { get; set; } = "Enter Your Content...";
|
||||
|
||||
// parameters only applicable to rich text editor
|
||||
[Parameter]
|
||||
public RenderFragment ToolbarContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool ReadOnly { get; set; }
|
||||
= false;
|
||||
public string Theme { get; set; } = "snow";
|
||||
|
||||
[Parameter]
|
||||
public string Placeholder { get; set; }
|
||||
= "Compose an epic...";
|
||||
public string DebugLevel { get; set; } = "info";
|
||||
|
||||
[Parameter]
|
||||
public string Theme { get; set; }
|
||||
= "snow";
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_content = Content; // raw HTML
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public string DebugLevel { get; set; }
|
||||
= "info";
|
||||
|
||||
private ElementReference EditorElement;
|
||||
private ElementReference ToolBar;
|
||||
|
||||
protected override async Task
|
||||
OnAfterRenderAsync(bool firstRender)
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await RichTextEditorInterop.CreateEditor(
|
||||
JSRuntime,
|
||||
EditorElement,
|
||||
ToolBar,
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
|
||||
await interop.CreateEditor(
|
||||
_editorElement,
|
||||
_toolBar,
|
||||
ReadOnly,
|
||||
Placeholder,
|
||||
Theme,
|
||||
DebugLevel);
|
||||
|
||||
await interop.LoadEditorContent(_editorElement, Content);
|
||||
|
||||
// preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor )
|
||||
_original = await interop.GetHtml(_editorElement);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseFileManager()
|
||||
{
|
||||
_filemanagervisible = false;
|
||||
_message = string.Empty;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public async Task RefreshRichText()
|
||||
{
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
await interop.LoadEditorContent(_editorElement, _content);
|
||||
}
|
||||
|
||||
public async Task RefreshRawHtml()
|
||||
{
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
_content = await interop.GetHtml(_editorElement);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public async Task<string> GetHtml()
|
||||
{
|
||||
// get rich text content
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
string content = await interop.GetHtml(_editorElement);
|
||||
|
||||
if (_original != content)
|
||||
{
|
||||
// rich text content has changed - return it
|
||||
return content;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return raw html content
|
||||
return _content;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task InsertImage()
|
||||
{
|
||||
if (_filemanagervisible)
|
||||
{
|
||||
var fileid = _fileManager.GetFileId();
|
||||
if (fileid != -1)
|
||||
{
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
await interop.InsertImage(_editorElement, ContentUrl(fileid));
|
||||
_filemanagervisible = false;
|
||||
_message = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select An Image To Insert</div>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_filemanagervisible = true;
|
||||
_message = string.Empty;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
// other rich text editor methods which can be used by developers
|
||||
public async Task<string> GetText()
|
||||
{
|
||||
return await RichTextEditorInterop.GetText(
|
||||
JSRuntime,
|
||||
EditorElement);
|
||||
}
|
||||
|
||||
public async Task<string> GetHTML()
|
||||
{
|
||||
return await RichTextEditorInterop.GetHTML(
|
||||
JSRuntime,
|
||||
EditorElement);
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
return await interop.GetText(_editorElement);
|
||||
}
|
||||
|
||||
public async Task<string> GetContent()
|
||||
{
|
||||
return await RichTextEditorInterop.GetContent(
|
||||
JSRuntime,
|
||||
EditorElement);
|
||||
}
|
||||
|
||||
public async Task LoadContent(string Content)
|
||||
{
|
||||
await RichTextEditorInterop.LoadEditorContent(
|
||||
JSRuntime,
|
||||
EditorElement, Content);
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
return await interop.GetContent(_editorElement);
|
||||
}
|
||||
|
||||
public async Task EnableEditor(bool mode)
|
||||
{
|
||||
await RichTextEditorInterop.EnableEditor(
|
||||
JSRuntime,
|
||||
EditorElement, mode);
|
||||
}
|
||||
|
||||
public async Task InsertImage(string ImageURL)
|
||||
{
|
||||
await RichTextEditorInterop.InsertImage(
|
||||
JSRuntime,
|
||||
EditorElement, ImageURL);
|
||||
var interop = new RichTextEditorInterop(JsRuntime);
|
||||
await interop.EnableEditor(_editorElement, mode);
|
||||
}
|
||||
}
|
124
Oqtane.Client/Modules/Controls/RichTextEditorInterop.cs
Normal file
124
Oqtane.Client/Modules/Controls/RichTextEditorInterop.cs
Normal file
|
@ -0,0 +1,124 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Modules.Controls
|
||||
{
|
||||
public class RichTextEditorInterop
|
||||
{
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
|
||||
public RichTextEditorInterop(IJSRuntime jsRuntime)
|
||||
{
|
||||
_jsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public Task CreateEditor(
|
||||
ElementReference quillElement,
|
||||
ElementReference toolbar,
|
||||
bool readOnly,
|
||||
string placeholder,
|
||||
string theme,
|
||||
string debugLevel)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.createQuill",
|
||||
quillElement, toolbar, readOnly,
|
||||
placeholder, theme, debugLevel);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask<string> GetText(ElementReference quillElement)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"Oqtane.RichTextEditor.getQuillText",
|
||||
quillElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask<string> GetHtml(ElementReference quillElement)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"Oqtane.RichTextEditor.getQuillHTML",
|
||||
quillElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask<string> GetContent(ElementReference quillElement)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"Oqtane.RichTextEditor.getQuillContent",
|
||||
quillElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
public Task LoadEditorContent(ElementReference quillElement, string content)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.loadQuillContent",
|
||||
quillElement, content);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task EnableEditor(ElementReference quillElement, bool mode)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.enableQuillEditor", quillElement, mode);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task InsertImage(ElementReference quillElement, string imageUrl)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.insertQuillImage",
|
||||
quillElement, imageUrl);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
45
Oqtane.Client/Modules/Controls/Section.razor
Normal file
45
Oqtane.Client/Modules/Controls/Section.razor
Normal file
|
@ -0,0 +1,45 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
<div class="d-flex">
|
||||
<div>
|
||||
<a data-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name">
|
||||
<h5>@_heading</h5>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<a data-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name">
|
||||
<i class="oi oi-chevron-bottom"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<hr class="app-rule" />
|
||||
</div>
|
||||
<div class="collapse" id="@Name">
|
||||
@ChildContent
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private string _heading = string.Empty;
|
||||
private string _expanded = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Name { get; set; } // required - the name of the section
|
||||
|
||||
[Parameter]
|
||||
public string Heading { get; set; } // optional - will default to Name if not provided
|
||||
|
||||
[Parameter]
|
||||
public string Expanded { get; set; } // optional - will default to false if not provided
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_heading = (!string.IsNullOrEmpty(Heading)) ? Heading : Name;
|
||||
_expanded = (!string.IsNullOrEmpty(Expanded)) ? Expanded : "false";
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<div>
|
||||
@foreach (TabPanel tabPanel in TabPanels)
|
||||
{
|
||||
<button type="button"
|
||||
class="btn @GetButtonClass(tabPanel)"
|
||||
@onclick=@( () => ActivateTabPanel(tabPanel) )>
|
||||
@tabPanel.Text
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
@ChildContent
|
||||
</CascadingValue>
|
||||
|
||||
@code {
|
||||
// Next line is needed so we are able to add <TabPanel> components inside
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
public TabPanel ActiveTabPanel { get; set; }
|
||||
List<TabPanel> TabPanels = new List<TabPanel>();
|
||||
|
||||
internal void AddTabPanel(TabPanel tabPanel)
|
||||
{
|
||||
TabPanels.Add(tabPanel);
|
||||
if (TabPanels.Count == 1)
|
||||
ActiveTabPanel = tabPanel;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
string GetButtonClass(TabPanel tabPanel)
|
||||
{
|
||||
return tabPanel == ActiveTabPanel ? "btn-primary" : "btn-secondary";
|
||||
}
|
||||
|
||||
void ActivateTabPanel(TabPanel tabPanel)
|
||||
{
|
||||
ActiveTabPanel = tabPanel;
|
||||
}
|
||||
}
|
|
@ -1,27 +1,36 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (Parent.ActiveTabPanel == (TabPanel)(object)this)
|
||||
@if (Name == Parent.ActiveTab)
|
||||
{
|
||||
<div id="@Name" class="tab-pane fade show active" role="tabpanel">
|
||||
@ChildContent
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="@Name" class="tab-pane fade" role="tabpanel">
|
||||
@ChildContent
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
[CascadingParameter]
|
||||
private TabControl Parent { get; set; }
|
||||
private TabStrip Parent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Text { get; set; }
|
||||
public string Name { get; set; } // required - name of the TabPanel
|
||||
|
||||
[Parameter]
|
||||
public string Heading { get; set; } // optional - defaults to name if not specified
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (Parent == null)
|
||||
throw new ArgumentNullException(nameof(Parent), "TabPanel must exist within a TabControl");
|
||||
|
||||
base.OnInitialized();
|
||||
Parent.AddTabPanel((TabPanel)(object)this);
|
||||
Parent.AddTabPanel((TabPanel)this);
|
||||
}
|
||||
}
|
||||
|
|
66
Oqtane.Client/Modules/Controls/TabStrip.razor
Normal file
66
Oqtane.Client/Modules/Controls/TabStrip.razor
Normal file
|
@ -0,0 +1,66 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<div class="container-fluid">
|
||||
<div class="form-group">
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
@foreach (TabPanel tabPanel in _tabPanels)
|
||||
{
|
||||
<li class="nav-item">
|
||||
@if (tabPanel.Name == ActiveTab)
|
||||
{
|
||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab">
|
||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab">
|
||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||
</a>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<br />
|
||||
@ChildContent
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CascadingValue>
|
||||
|
||||
@code {
|
||||
private List<TabPanel> _tabPanels = new List<TabPanel>();
|
||||
|
||||
[Parameter]
|
||||
public RenderFragment ChildContent { get; set; } // contains the TabPanels
|
||||
|
||||
[Parameter]
|
||||
public string ActiveTab { get; set; } // optional - defaults to first TabPanel if not specified. Can also be set using a "tab=" querystring parameter.
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
if (PageState.QueryString.ContainsKey("tab"))
|
||||
{
|
||||
ActiveTab = PageState.QueryString["tab"];
|
||||
}
|
||||
}
|
||||
|
||||
internal void AddTabPanel(TabPanel tabPanel)
|
||||
{
|
||||
_tabPanels.Add(tabPanel);
|
||||
if (string.IsNullOrEmpty(ActiveTab))
|
||||
{
|
||||
ActiveTab = tabPanel.Name;
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private string DisplayHeading(string Name, string Heading)
|
||||
{
|
||||
return (string.IsNullOrEmpty(Heading)) ? Name : Heading;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
|
||||
<img src="@src" title="@title" disabled=@Disabled @onclick="SetValue" />
|
||||
<img src="@_src" title="@_title" @onclick="SetValue" />
|
||||
|
||||
@code {
|
||||
private bool? _value = null;
|
||||
private string _title;
|
||||
private string _src = string.Empty;
|
||||
|
||||
[Parameter]
|
||||
public bool? Value { get; set; }
|
||||
|
||||
|
@ -12,51 +16,52 @@
|
|||
[Parameter]
|
||||
public Action<bool?> OnChange { get; set; }
|
||||
|
||||
bool? value = null;
|
||||
string title;
|
||||
string src = "";
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
value = Value;
|
||||
_value = Value;
|
||||
SetImage();
|
||||
}
|
||||
|
||||
private void SetValue()
|
||||
{
|
||||
switch (value)
|
||||
if (!Disabled)
|
||||
{
|
||||
switch (_value)
|
||||
{
|
||||
case true:
|
||||
value = false;
|
||||
_value = false;
|
||||
break;
|
||||
case false:
|
||||
value = null;
|
||||
_value = null;
|
||||
break;
|
||||
case null:
|
||||
value = true;
|
||||
_value = true;
|
||||
break;
|
||||
}
|
||||
|
||||
SetImage();
|
||||
OnChange(value);
|
||||
OnChange(_value);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetImage()
|
||||
{
|
||||
switch (value)
|
||||
switch (_value)
|
||||
{
|
||||
case true:
|
||||
src = "images/checked.png";
|
||||
title = "Permission Granted";
|
||||
_src = "images/checked.png";
|
||||
_title = "Permission Granted";
|
||||
break;
|
||||
case false:
|
||||
src = "images/unchecked.png";
|
||||
title = "Permission Denied";
|
||||
_src = "images/unchecked.png";
|
||||
_title = "Permission Denied";
|
||||
break;
|
||||
case null:
|
||||
src = "images/null.png";
|
||||
title = "";
|
||||
_src = "images/null.png";
|
||||
_title = string.Empty;
|
||||
break;
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
@namespace Oqtane.Modules.Counter
|
||||
@inherits ModuleBase
|
||||
Current count: @currentCount
|
||||
<br />
|
||||
<button type="button" class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
@code {
|
||||
int currentCount = 0;
|
||||
|
||||
void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Oqtane.Modules.Counter
|
||||
{
|
||||
public class Module : IModule
|
||||
{
|
||||
public Dictionary<string, string> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<string, string> properties = new Dictionary<string, string>
|
||||
{
|
||||
{ "Name", "Counter" },
|
||||
{ "Description", "Increments a counter" },
|
||||
{ "Version", "1.0.0" }
|
||||
};
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,88 +3,63 @@
|
|||
@using Oqtane.Modules.Controls
|
||||
@namespace Oqtane.Modules.HtmlText
|
||||
@inherits ModuleBase
|
||||
@inject IHtmlTextService HtmlTextService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject HttpClient http
|
||||
@inject SiteState sitestate
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="Name" class="control-label">Content: </label>
|
||||
</td>
|
||||
<td>
|
||||
@if (!RichTextEditorMode)
|
||||
{
|
||||
<textarea class="form-control" @bind="@content" rows="5" />
|
||||
}
|
||||
else
|
||||
{
|
||||
<RichTextEditor @ref="@RichTextEditorHtml">
|
||||
<ToolbarContent>
|
||||
<select class="ql-header">
|
||||
<option selected=""></option>
|
||||
<option value="1"></option>
|
||||
<option value="2"></option>
|
||||
<option value="3"></option>
|
||||
<option value="4"></option>
|
||||
<option value="5"></option>
|
||||
</select>
|
||||
<span class="ql-formats">
|
||||
<button class="ql-bold"></button>
|
||||
<button class="ql-italic"></button>
|
||||
<button class="ql-underline"></button>
|
||||
<button class="ql-strike"></button>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<select class="ql-color"></select>
|
||||
<select class="ql-background"></select>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<button class="ql-list" value="ordered"></button>
|
||||
<button class="ql-list" value="bullet"></button>
|
||||
</span>
|
||||
<span class="ql-formats">
|
||||
<button class="ql-link"></button>
|
||||
</span>
|
||||
</ToolbarContent>
|
||||
</RichTextEditor>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@if (!RichTextEditorMode)
|
||||
@if (_content != null)
|
||||
{
|
||||
<button type="button" class="btn btn-secondary" @onclick="RichTextEditor">Rich Text Editor</button>
|
||||
<RichTextEditor Content="@_content" @ref="@RichTextEditorHtml"></RichTextEditor>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveContent">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
@if (!string.IsNullOrEmpty(_content))
|
||||
{
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
<button type="button" class="btn btn-secondary" @onclick="RawHTMLEditor">Raw HTML Editor</button>
|
||||
}
|
||||
<button type="button" class="btn btn-success" @onclick="SaveContent">Save</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Edit; } }
|
||||
public override string Title { get { return "Edit Html/Text"; } }
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||
|
||||
RichTextEditor RichTextEditorHtml;
|
||||
bool RichTextEditorMode = true;
|
||||
string content;
|
||||
string createdby;
|
||||
DateTime createdon;
|
||||
string modifiedby;
|
||||
DateTime modifiedon;
|
||||
public override string Title => "Edit Html/Text";
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
if (firstRender)
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
||||
// the following resources should be declared in the RichTextEditor component however the framework currently only supports resource management for modules and themes
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.bubble.css" },
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css" },
|
||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill1.3.6.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill-blot-formatter.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill-interop.js" }
|
||||
};
|
||||
|
||||
private RichTextEditor RichTextEditorHtml;
|
||||
private string _content = null;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await LoadText();
|
||||
var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||
if (htmltext != null)
|
||||
{
|
||||
_content = htmltext.Content;
|
||||
_content = _content.Replace(Constants.ContentUrl, "/" + PageState.Alias.AliasId.ToString() + Constants.ContentUrl);
|
||||
_createdby = htmltext.CreatedBy;
|
||||
_createdon = htmltext.CreatedOn;
|
||||
_modifiedby = htmltext.ModifiedBy;
|
||||
_modifiedon = htmltext.ModifiedOn;
|
||||
}
|
||||
else
|
||||
{
|
||||
_content = string.Empty;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -92,65 +67,30 @@ else
|
|||
AddModuleMessage(ex.Message, MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadText()
|
||||
{
|
||||
HtmlTextService htmltextservice = new HtmlTextService(http, sitestate, NavigationManager);
|
||||
HtmlTextInfo htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||
if (htmltext != null)
|
||||
{
|
||||
content = htmltext.Content;
|
||||
createdby = htmltext.CreatedBy;
|
||||
createdon = htmltext.CreatedOn;
|
||||
modifiedby = htmltext.ModifiedBy;
|
||||
modifiedon = htmltext.ModifiedOn;
|
||||
|
||||
if (RichTextEditorMode)
|
||||
{
|
||||
await RichTextEditorHtml.LoadContent(content);
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RichTextEditor()
|
||||
{
|
||||
RichTextEditorMode = true;
|
||||
await LoadText();
|
||||
}
|
||||
|
||||
private async Task RawHTMLEditor()
|
||||
{
|
||||
RichTextEditorMode = false;
|
||||
await LoadText();
|
||||
}
|
||||
|
||||
private async Task SaveContent()
|
||||
{
|
||||
if (RichTextEditorMode)
|
||||
{
|
||||
content = await this.RichTextEditorHtml.GetHTML();
|
||||
}
|
||||
string content = await RichTextEditorHtml.GetHtml();
|
||||
content = content.Replace("/" + PageState.Alias.AliasId.ToString() + Constants.ContentUrl, Constants.ContentUrl);
|
||||
|
||||
try
|
||||
{
|
||||
HtmlTextService htmltextservice = new HtmlTextService(http, sitestate, NavigationManager);
|
||||
HtmlTextInfo htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||
var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||
if (htmltext != null)
|
||||
{
|
||||
htmltext.Content = content;
|
||||
await htmltextservice.UpdateHtmlTextAsync(htmltext);
|
||||
await HtmlTextService.UpdateHtmlTextAsync(htmltext);
|
||||
}
|
||||
else
|
||||
{
|
||||
htmltext = new HtmlTextInfo();
|
||||
htmltext.ModuleId = ModuleState.ModuleId;
|
||||
htmltext.Content = content;
|
||||
await htmltextservice.AddHtmlTextAsync(htmltext);
|
||||
await HtmlTextService.AddHtmlTextAsync(htmltext);
|
||||
}
|
||||
|
||||
await logger.LogInformation("Html/Text Content Saved {HtmlText}", htmltext);
|
||||
NavigationManager.NavigateTo(NavigateUrl(Reload.Page));
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -1,29 +1,32 @@
|
|||
@using Oqtane.Modules.HtmlText.Services
|
||||
@using Oqtane.Modules.HtmlText.Models
|
||||
@namespace Oqtane.Modules.HtmlText
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject HttpClient http
|
||||
@inject SiteState sitestate
|
||||
@inject IHtmlTextService HtmlTextService
|
||||
|
||||
@((MarkupString)content)
|
||||
|
||||
<br />
|
||||
<ActionLink Action="Edit" />
|
||||
<br /><br />
|
||||
@if (PageState.EditMode)
|
||||
{
|
||||
<br /><ActionLink Action="Edit" /><br /><br />
|
||||
}
|
||||
|
||||
@code {
|
||||
string content;
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
|
||||
};
|
||||
|
||||
private string content = "";
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
HtmlTextService htmltextservice = new HtmlTextService(http, sitestate, NavigationManager);
|
||||
HtmlTextInfo htmltext = await htmltextservice.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||
var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||
if (htmltext != null)
|
||||
{
|
||||
content = htmltext.Content;
|
||||
content = content.Replace(Constants.ContentUrl, "/" + PageState.Alias.AliasId.ToString() + Constants.ContentUrl);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -1,22 +1,16 @@
|
|||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Modules.HtmlText
|
||||
{
|
||||
public class ModuleInfo : IModule
|
||||
{
|
||||
public Dictionary<string, string> Properties
|
||||
public ModuleDefinition ModuleDefinition => new ModuleDefinition
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<string, string> properties = new Dictionary<string, string>
|
||||
{
|
||||
{ "Name", "HtmlText" },
|
||||
{ "Description", "Renders HTML or Text" },
|
||||
{ "Version", "1.0.0" },
|
||||
{ "ServerAssemblyName", "Oqtane.Server" }
|
||||
Name = "HtmlText",
|
||||
Description = "Renders HTML or Text Content",
|
||||
Version = "1.0.0",
|
||||
ServerManagerType = "Oqtane.Modules.HtmlText.Manager.HtmlTextManager, Oqtane.Server",
|
||||
ReleaseVersions = "1.0.0"
|
||||
};
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,60 +1,43 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Oqtane.Services;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Modules.HtmlText.Models;
|
||||
using Oqtane.Services;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Modules.HtmlText.Services
|
||||
{
|
||||
public class HtmlTextService : ServiceBase, IHtmlTextService
|
||||
public class HtmlTextService : ServiceBase, IHtmlTextService, IService
|
||||
{
|
||||
private readonly HttpClient http;
|
||||
private readonly SiteState sitestate;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly SiteState _siteState;
|
||||
|
||||
public HtmlTextService(HttpClient http, SiteState sitestate, NavigationManager NavigationManager)
|
||||
public HtmlTextService(HttpClient http, SiteState siteState) : base(http)
|
||||
{
|
||||
this.http = http;
|
||||
this.sitestate = sitestate;
|
||||
this.NavigationManager = NavigationManager;
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private string apiurl
|
||||
private string ApiUrl => CreateApiUrl(_siteState.Alias, "HtmlText");
|
||||
|
||||
public async Task<HtmlTextInfo> GetHtmlTextAsync(int moduleId)
|
||||
{
|
||||
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "HtmlText"); }
|
||||
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
||||
return htmltext.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task<HtmlTextInfo> GetHtmlTextAsync(int ModuleId)
|
||||
public async Task AddHtmlTextAsync(HtmlTextInfo htmlText)
|
||||
{
|
||||
HtmlTextInfo htmltext;
|
||||
try
|
||||
{
|
||||
// exception handling is required because GetJsonAsync() returns an error if no content exists for the ModuleId ( https://github.com/aspnet/AspNetCore/issues/14041 )
|
||||
htmltext = await http.GetJsonAsync<HtmlTextInfo>(apiurl + "/" + ModuleId.ToString() + "?entityid=" + ModuleId.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
htmltext = null;
|
||||
}
|
||||
return htmltext;
|
||||
await PostJsonAsync($"{ApiUrl}?entityid={htmlText.ModuleId}", htmlText);
|
||||
}
|
||||
|
||||
public async Task AddHtmlTextAsync(HtmlTextInfo htmltext)
|
||||
public async Task UpdateHtmlTextAsync(HtmlTextInfo htmlText)
|
||||
{
|
||||
await http.PostJsonAsync(apiurl + "?entityid=" + htmltext.ModuleId.ToString(), htmltext);
|
||||
await PutJsonAsync($"{ApiUrl}/{htmlText.HtmlTextId}?entityid={htmlText.ModuleId}", htmlText);
|
||||
}
|
||||
|
||||
public async Task UpdateHtmlTextAsync(HtmlTextInfo htmltext)
|
||||
public async Task DeleteHtmlTextAsync(int moduleId)
|
||||
{
|
||||
await http.PutJsonAsync(apiurl + "/" + htmltext.HtmlTextId.ToString() + "?entityid=" + htmltext.ModuleId.ToString(), htmltext);
|
||||
await DeleteAsync($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
||||
}
|
||||
|
||||
public async Task DeleteHtmlTextAsync(int ModuleId)
|
||||
{
|
||||
await http.DeleteAsync(apiurl + "/" + ModuleId.ToString() + "?entityid=" + ModuleId.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
public interface IModule
|
||||
{
|
||||
Dictionary<string, string> Properties { get; }
|
||||
ModuleDefinition ModuleDefinition { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace Oqtane.Shared
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
public enum MessageType
|
||||
{
|
|
@ -2,20 +2,19 @@
|
|||
using Oqtane.Shared;
|
||||
using Oqtane.Models;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using Oqtane.Services;
|
||||
using System;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.UI;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
public class ModuleBase : ComponentBase, IModuleControl
|
||||
public abstract class ModuleBase : ComponentBase, IModuleControl
|
||||
{
|
||||
public Logger logger { get; set; }
|
||||
private Logger _logger;
|
||||
|
||||
public ModuleBase()
|
||||
{
|
||||
this.logger = new Logger(this);
|
||||
}
|
||||
protected Logger logger => _logger ?? (_logger = new Logger(this));
|
||||
|
||||
[Inject]
|
||||
protected ILogService LoggingService { get; set; }
|
||||
|
@ -29,13 +28,6 @@ namespace Oqtane.Modules
|
|||
[CascadingParameter]
|
||||
protected ModuleInstance ModuleInstance { get; set; }
|
||||
|
||||
protected ModuleDefinition ModuleDefinition
|
||||
{
|
||||
get
|
||||
{
|
||||
return PageState.ModuleDefinitions.Where(item => item.ModuleDefinitionName == ModuleState.ModuleDefinitionName).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// optional interface properties
|
||||
public virtual SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } set { } } // default security
|
||||
|
@ -46,11 +38,14 @@ namespace Oqtane.Modules
|
|||
|
||||
public virtual bool UseAdminContainer { get { return true; } }
|
||||
|
||||
public virtual List<Resource> Resources { get; set; }
|
||||
|
||||
|
||||
// path method
|
||||
|
||||
public string ModulePath()
|
||||
{
|
||||
return "Modules/" + this.GetType().Namespace + "/";
|
||||
return "Modules/" + GetType().Namespace + "/";
|
||||
}
|
||||
|
||||
// url methods
|
||||
|
@ -59,29 +54,14 @@ namespace Oqtane.Modules
|
|||
return NavigateUrl(PageState.Page.Path);
|
||||
}
|
||||
|
||||
public string NavigateUrl(Reload reload)
|
||||
{
|
||||
return NavigateUrl(PageState.Page.Path, reload);
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path)
|
||||
{
|
||||
return NavigateUrl(path, "", Reload.None);
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path, Reload reload)
|
||||
{
|
||||
return NavigateUrl(path, "", reload);
|
||||
return NavigateUrl(path, "");
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path, string parameters)
|
||||
{
|
||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters, Reload.None);
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path, string parameters, Reload reload)
|
||||
{
|
||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters, reload);
|
||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(string action)
|
||||
|
@ -94,14 +74,14 @@ namespace Oqtane.Modules
|
|||
return EditUrl(ModuleState.ModuleId, action, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(int moduleid, string action)
|
||||
public string EditUrl(int moduleId, string action)
|
||||
{
|
||||
return EditUrl(moduleid, action, "");
|
||||
return EditUrl(moduleId, action, "");
|
||||
}
|
||||
|
||||
public string EditUrl(int moduleid, string action, string parameters)
|
||||
public string EditUrl(int moduleId, string action, string parameters)
|
||||
{
|
||||
return EditUrl(PageState.Page.Path, moduleid, action, parameters);
|
||||
return EditUrl(PageState.Page.Path, moduleId, action, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(string path, int moduleid, string action, string parameters)
|
||||
|
@ -109,6 +89,11 @@ namespace Oqtane.Modules
|
|||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
||||
}
|
||||
|
||||
public string ContentUrl(int fileid)
|
||||
{
|
||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||
}
|
||||
|
||||
// user feedback methods
|
||||
public void AddModuleMessage(string message, MessageType type)
|
||||
{
|
||||
|
@ -126,107 +111,111 @@ namespace Oqtane.Modules
|
|||
}
|
||||
|
||||
// logging methods
|
||||
public async Task Log(LogLevel level, Exception exception, string message, params object[] args)
|
||||
public async Task Log(Alias alias, LogLevel level, string function, Exception exception, string message, params object[] args)
|
||||
{
|
||||
int PageId = PageState.Page.PageId;
|
||||
int ModuleId = ModuleState.ModuleId;
|
||||
int? UserId = null;
|
||||
int pageId = ModuleState.PageId;
|
||||
int moduleId = ModuleState.ModuleId;
|
||||
int? userId = null;
|
||||
if (PageState.User != null)
|
||||
{
|
||||
UserId = PageState.User.UserId;
|
||||
userId = PageState.User.UserId;
|
||||
}
|
||||
string category = this.GetType().AssemblyQualifiedName;
|
||||
string category = GetType().AssemblyQualifiedName;
|
||||
string feature = Utilities.GetTypeNameLastSegment(category, 1);
|
||||
LogFunction function;
|
||||
switch (PageState.Action)
|
||||
LogFunction logFunction;
|
||||
if (string.IsNullOrEmpty(function))
|
||||
{
|
||||
case "Add":
|
||||
function = LogFunction.Create;
|
||||
function = PageState.Action;
|
||||
}
|
||||
switch (function.ToLower())
|
||||
{
|
||||
case "add":
|
||||
logFunction = LogFunction.Create;
|
||||
break;
|
||||
case "Edit":
|
||||
function = LogFunction.Update;
|
||||
case "edit":
|
||||
logFunction = LogFunction.Update;
|
||||
break;
|
||||
case "Delete":
|
||||
function = LogFunction.Delete;
|
||||
case "delete":
|
||||
logFunction = LogFunction.Delete;
|
||||
break;
|
||||
default:
|
||||
function = LogFunction.Read;
|
||||
logFunction = LogFunction.Read;
|
||||
break;
|
||||
}
|
||||
if (feature == "Login")
|
||||
{
|
||||
function = LogFunction.Security;
|
||||
logFunction = LogFunction.Security;
|
||||
}
|
||||
await LoggingService.Log(PageId, ModuleId, UserId, category, feature, function, level, exception, message, args);
|
||||
await LoggingService.Log(alias, pageId, moduleId, userId, category, feature, logFunction, level, exception, message, args);
|
||||
}
|
||||
|
||||
public class Logger
|
||||
{
|
||||
private ModuleBase modulebase;
|
||||
private readonly ModuleBase _moduleBase;
|
||||
|
||||
public Logger(ModuleBase modulebase)
|
||||
public Logger(ModuleBase moduleBase)
|
||||
{
|
||||
this.modulebase = modulebase;
|
||||
_moduleBase = moduleBase;
|
||||
}
|
||||
|
||||
public async Task LogTrace(string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Trace, null, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Trace, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogTrace(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Trace, exception, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Trace, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogDebug(string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Debug, null, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Debug, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogDebug(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Debug, exception, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Debug, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogInformation(string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Information, null, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Information, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogInformation(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Information, exception, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Information, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogWarning(string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Warning, null, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Warning, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogWarning(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Warning, exception, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Warning, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogError(string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Error, null, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Error, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogError(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Error, exception, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Error, "", exception, message, args);
|
||||
}
|
||||
|
||||
public async Task LogCritical(string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Critical, null, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Critical, "", null, message, args);
|
||||
}
|
||||
|
||||
public async Task LogCritical(Exception exception, string message, params object[] args)
|
||||
{
|
||||
await modulebase.Log(LogLevel.Critical, exception, message, args);
|
||||
await _moduleBase.Log(null, LogLevel.Critical, "", exception, message, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
@using Oqtane.Modules.Weather.Services
|
||||
@namespace Oqtane.Modules.Weather
|
||||
@inherits ModuleBase
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@code {
|
||||
WeatherForecast[] forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
WeatherForecastService forecastservice = new WeatherForecastService();
|
||||
forecasts = await forecastservice.GetForecastAsync(DateTime.Now);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Oqtane.Modules.Weather
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
public int TemperatureC { get; set; }
|
||||
public int TemperatureF { get; set; }
|
||||
public string Summary { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Oqtane.Modules.Weather
|
||||
{
|
||||
public class Module : IModule
|
||||
{
|
||||
public Dictionary<string, string> Properties
|
||||
{
|
||||
get
|
||||
{
|
||||
Dictionary<string, string> properties = new Dictionary<string, string>
|
||||
{
|
||||
{ "Name", "Weather" },
|
||||
{ "Description", "Displays random weather using a service" },
|
||||
{ "Version", "1.0.0" }
|
||||
};
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Modules.Weather.Services
|
||||
{
|
||||
public interface IWeatherForecastService
|
||||
{
|
||||
Task<WeatherForecast[]> GetForecastAsync(DateTime startDate);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
using Oqtane.Modules;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Modules.Weather.Services
|
||||
{
|
||||
public class WeatherForecastService : IWeatherForecastService
|
||||
{
|
||||
private static string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
|
||||
{
|
||||
var rng = new Random();
|
||||
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = startDate.AddDays(index),
|
||||
TemperatureC = rng.Next(-20, 55),
|
||||
Summary = Summaries[rng.Next(Summaries.Length)]
|
||||
}).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,15 +3,10 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<BlazorLinkOnBuild>false</BlazorLinkOnBuild>
|
||||
<RestoreAdditionalProjectSources>
|
||||
https://dotnet.myget.org/F/aspnetcore-dev/api/v3/index.json;
|
||||
https://dotnet.myget.org/F/blazor-dev/api/v3/index.json;
|
||||
</RestoreAdditionalProjectSources>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<Configurations>Debug;Release;Wasm</Configurations>
|
||||
<Version>0.0.1</Version>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>1.0.0</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -21,21 +16,26 @@
|
|||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<PackageReleaseNotes>Not for production use.</PackageReleaseNotes>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Wasm|AnyCPU'">
|
||||
<DefineConstants>TRACE;WASM</DefineConstants>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor" Version="3.1.0-preview4.19579.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="3.1.0-preview4.19579.2" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.1.0-preview4.19579.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="3.1.0" />
|
||||
<Compile Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
<Content Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
<EmbeddedResource Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
<None Remove="Modules\Admin\ModuleCreator\Templates\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="3.1.4" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,24 +1,142 @@
|
|||
using Microsoft.AspNetCore.Blazor.Hosting;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Services;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Providers;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
|
||||
namespace Oqtane.Client
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
#if DEBUG || RELEASE
|
||||
public static void Main(string[] args)
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("app");
|
||||
HttpClient httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)};
|
||||
|
||||
#if WASM
|
||||
public static void Main(string[] args)
|
||||
builder.Services.AddSingleton(httpClient);
|
||||
builder.Services.AddOptions();
|
||||
|
||||
// register auth services
|
||||
builder.Services.AddAuthorizationCore();
|
||||
builder.Services.AddScoped<IdentityAuthenticationStateProvider>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<IdentityAuthenticationStateProvider>());
|
||||
|
||||
// register scoped core services
|
||||
builder.Services.AddScoped<SiteState>();
|
||||
builder.Services.AddScoped<IInstallationService, InstallationService>();
|
||||
builder.Services.AddScoped<IModuleDefinitionService, ModuleDefinitionService>();
|
||||
builder.Services.AddScoped<IThemeService, ThemeService>();
|
||||
builder.Services.AddScoped<IAliasService, AliasService>();
|
||||
builder.Services.AddScoped<ITenantService, TenantService>();
|
||||
builder.Services.AddScoped<ISiteService, SiteService>();
|
||||
builder.Services.AddScoped<IPageService, PageService>();
|
||||
builder.Services.AddScoped<IModuleService, ModuleService>();
|
||||
builder.Services.AddScoped<IPageModuleService, PageModuleService>();
|
||||
builder.Services.AddScoped<IUserService, UserService>();
|
||||
builder.Services.AddScoped<IProfileService, ProfileService>();
|
||||
builder.Services.AddScoped<IRoleService, RoleService>();
|
||||
builder.Services.AddScoped<IUserRoleService, UserRoleService>();
|
||||
builder.Services.AddScoped<ISettingService, SettingService>();
|
||||
builder.Services.AddScoped<IPackageService, PackageService>();
|
||||
builder.Services.AddScoped<ILogService, LogService>();
|
||||
builder.Services.AddScoped<IJobService, JobService>();
|
||||
builder.Services.AddScoped<IJobLogService, JobLogService>();
|
||||
builder.Services.AddScoped<INotificationService, NotificationService>();
|
||||
builder.Services.AddScoped<IFolderService, FolderService>();
|
||||
builder.Services.AddScoped<IFileService, FileService>();
|
||||
builder.Services.AddScoped<ISiteTemplateService, SiteTemplateService>();
|
||||
builder.Services.AddScoped<ISqlService, SqlService>();
|
||||
builder.Services.AddScoped<ISystemService, SystemService>();
|
||||
|
||||
await LoadClientAssemblies(httpClient);
|
||||
|
||||
// dynamically register module contexts and repository services
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
var implementationTypes = assembly.GetTypes()
|
||||
.Where(item => item.GetInterfaces().Contains(typeof(IService)));
|
||||
|
||||
foreach (Type implementationtype in implementationTypes)
|
||||
{
|
||||
Type servicetype = Type.GetType(implementationtype.AssemblyQualifiedName.Replace(implementationtype.Name, "I" + implementationtype.Name));
|
||||
if (servicetype != null)
|
||||
{
|
||||
builder.Services.AddScoped(servicetype, implementationtype); // traditional service interface
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.Services.AddScoped(implementationtype, implementationtype); // no interface defined for service
|
||||
}
|
||||
}
|
||||
|
||||
public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
|
||||
BlazorWebAssemblyHost.CreateDefaultBuilder()
|
||||
.UseBlazorStartup<Startup>();
|
||||
#endif
|
||||
assembly.GetInstances<IClientStartup>()
|
||||
.ToList()
|
||||
.ForEach(x => x.ConfigureServices(builder.Services));
|
||||
}
|
||||
|
||||
await builder.Build().RunAsync();
|
||||
}
|
||||
|
||||
private static async Task LoadClientAssemblies(HttpClient http)
|
||||
{
|
||||
// get list of loaded assemblies on the client
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies().Select(a => a.GetName().Name).ToList();
|
||||
|
||||
// get assemblies from server and load into client app domain
|
||||
var zip = await http.GetByteArrayAsync($"/~/api/Installation/load");
|
||||
|
||||
// asemblies and debug symbols are packaged in a zip file
|
||||
using (ZipArchive archive = new ZipArchive(new MemoryStream(zip)))
|
||||
{
|
||||
Dictionary<string, byte[]> dlls = new Dictionary<string, byte[]>();
|
||||
Dictionary<string, byte[]> pdbs = new Dictionary<string, byte[]>();
|
||||
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
if (!assemblies.Contains(Path.GetFileNameWithoutExtension(entry.Name)))
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
entry.Open().CopyTo(memoryStream);
|
||||
byte[] file = memoryStream.ToArray();
|
||||
switch (Path.GetExtension(entry.Name))
|
||||
{
|
||||
case ".dll":
|
||||
dlls.Add(entry.Name, file);
|
||||
break;
|
||||
case ".pdb":
|
||||
pdbs.Add(entry.Name, file);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in dlls)
|
||||
{
|
||||
if (pdbs.ContainsKey(item.Key))
|
||||
{
|
||||
Assembly.Load(item.Value, pdbs[item.Key]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assembly.Load(item.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
|
@ -13,23 +15,23 @@ namespace Oqtane.Providers
|
|||
{
|
||||
public class IdentityAuthenticationStateProvider : AuthenticationStateProvider
|
||||
{
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly SiteState sitestate;
|
||||
private readonly IServiceProvider provider;
|
||||
private readonly NavigationManager _navigationManager;
|
||||
private readonly SiteState _siteState;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public IdentityAuthenticationStateProvider(NavigationManager NavigationManager, SiteState sitestate, IServiceProvider provider)
|
||||
public IdentityAuthenticationStateProvider(NavigationManager navigationManager, SiteState siteState, IServiceProvider serviceProvider)
|
||||
{
|
||||
this.NavigationManager = NavigationManager;
|
||||
this.sitestate = sitestate;
|
||||
this.provider = provider;
|
||||
_navigationManager = navigationManager;
|
||||
_siteState = siteState;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public override async Task<AuthenticationState> GetAuthenticationStateAsync()
|
||||
{
|
||||
// get HttpClient lazily from IServiceProvider as you cannot use standard dependency injection due to the AuthenticationStateProvider being initialized prior to NavigationManager ( https://github.com/aspnet/AspNetCore/issues/11867 )
|
||||
var http = provider.GetRequiredService<HttpClient>();
|
||||
string apiurl = ServiceBase.CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "User") + "/authenticate";
|
||||
User user = await http.GetJsonAsync<User>(apiurl);
|
||||
var http = _serviceProvider.GetRequiredService<HttpClient>();
|
||||
string apiurl = "/~/api/User/authenticate";
|
||||
User user = await http.GetFromJsonAsync<User>(apiurl);
|
||||
|
||||
ClaimsIdentity identity = new ClaimsIdentity();
|
||||
if (user.IsAuthenticated)
|
||||
|
@ -37,7 +39,7 @@ namespace Oqtane.Providers
|
|||
identity = new ClaimsIdentity("Identity.Application");
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, user.Username));
|
||||
identity.AddClaim(new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()));
|
||||
foreach (string role in user.Roles.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
foreach (string role in user.Roles.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.Role, role));
|
||||
}
|
||||
|
|
|
@ -2,53 +2,54 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public class AliasService : ServiceBase, IAliasService
|
||||
{
|
||||
private readonly HttpClient http;
|
||||
private readonly SiteState sitestate;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
|
||||
public AliasService(HttpClient http, SiteState sitestate, NavigationManager NavigationManager)
|
||||
private readonly SiteState _siteState;
|
||||
|
||||
public AliasService(HttpClient http, SiteState siteState) : base(http)
|
||||
{
|
||||
this.http = http;
|
||||
this.sitestate = sitestate;
|
||||
this.NavigationManager = NavigationManager;
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private string apiurl
|
||||
{
|
||||
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "Alias"); }
|
||||
}
|
||||
private string Apiurl => CreateApiUrl(_siteState.Alias, "Alias");
|
||||
|
||||
public async Task<List<Alias>> GetAliasesAsync()
|
||||
{
|
||||
List<Alias> aliases = await http.GetJsonAsync<List<Alias>>(apiurl);
|
||||
List<Alias> aliases = await GetJsonAsync<List<Alias>>(Apiurl);
|
||||
return aliases.OrderBy(item => item.Name).ToList();
|
||||
}
|
||||
|
||||
public async Task<Alias> GetAliasAsync(int AliasId)
|
||||
public async Task<Alias> GetAliasAsync(int aliasId)
|
||||
{
|
||||
return await http.GetJsonAsync<Alias>(apiurl + "/" + AliasId.ToString());
|
||||
return await GetJsonAsync<Alias>($"{Apiurl}/{aliasId}");
|
||||
}
|
||||
|
||||
public async Task<Alias> GetAliasAsync(string name, DateTime lastSyncDate)
|
||||
{
|
||||
name = (string.IsNullOrEmpty(name)) ? "~" : name;
|
||||
return await GetJsonAsync<Alias>($"{Apiurl}/name/{WebUtility.UrlEncode(name)}?sync={lastSyncDate.ToString("yyyyMMddHHmmssfff")}");
|
||||
}
|
||||
|
||||
public async Task<Alias> AddAliasAsync(Alias alias)
|
||||
{
|
||||
return await http.PostJsonAsync<Alias>(apiurl, alias);
|
||||
return await PostJsonAsync<Alias>(Apiurl, alias);
|
||||
}
|
||||
|
||||
public async Task<Alias> UpdateAliasAsync(Alias alias)
|
||||
{
|
||||
return await http.PutJsonAsync<Alias>(apiurl + "/" + alias.AliasId.ToString(), alias);
|
||||
return await PutJsonAsync<Alias>($"{Apiurl}/{alias.AliasId}", alias);
|
||||
}
|
||||
public async Task DeleteAliasAsync(int AliasId)
|
||||
public async Task DeleteAliasAsync(int aliasId)
|
||||
{
|
||||
await http.DeleteAsync(apiurl + "/" + AliasId.ToString());
|
||||
await DeleteAsync($"{Apiurl}/{aliasId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,86 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.UI;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public class FileService : ServiceBase, IFileService
|
||||
{
|
||||
private readonly HttpClient http;
|
||||
private readonly SiteState sitestate;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly IJSRuntime jsRuntime;
|
||||
private readonly SiteState _siteState;
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
|
||||
public FileService(HttpClient http, SiteState sitestate, NavigationManager NavigationManager, IJSRuntime jsRuntime)
|
||||
public FileService(HttpClient http, SiteState siteState, IJSRuntime jsRuntime) : base(http)
|
||||
{
|
||||
this.http = http;
|
||||
this.sitestate = sitestate;
|
||||
this.NavigationManager = NavigationManager;
|
||||
this.jsRuntime = jsRuntime;
|
||||
_siteState = siteState;
|
||||
_jsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
private string apiurl
|
||||
private string Apiurl => CreateApiUrl(_siteState.Alias, "File");
|
||||
|
||||
public async Task<List<File>> GetFilesAsync(int folderId)
|
||||
{
|
||||
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "File"); }
|
||||
return await GetFilesAsync(folderId.ToString());
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetFilesAsync(string Folder)
|
||||
public async Task<List<File>> GetFilesAsync(string folder)
|
||||
{
|
||||
return await http.GetJsonAsync<List<string>>(apiurl + "?folder=" + Folder);
|
||||
return await GetJsonAsync<List<File>>($"{Apiurl}?folder={folder}");
|
||||
}
|
||||
|
||||
public async Task<string> UploadFilesAsync(string Folder, string[] Files, string FileUploadName)
|
||||
public async Task<List<File>> GetFilesAsync(int siteId, string folderPath)
|
||||
{
|
||||
if (!(folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar)))
|
||||
{
|
||||
folderPath = Utilities.PathCombine(folderPath,"\\");
|
||||
}
|
||||
|
||||
var path = WebUtility.UrlEncode(folderPath);
|
||||
|
||||
return await GetJsonAsync<List<File>>($"{Apiurl}/{siteId}/{path}");
|
||||
}
|
||||
|
||||
public async Task<File> GetFileAsync(int fileId)
|
||||
{
|
||||
return await GetJsonAsync<File>($"{Apiurl}/{fileId}");
|
||||
}
|
||||
|
||||
public async Task<File> AddFileAsync(File file)
|
||||
{
|
||||
return await PostJsonAsync<File>(Apiurl, file);
|
||||
}
|
||||
|
||||
public async Task<File> UpdateFileAsync(File file)
|
||||
{
|
||||
return await PutJsonAsync<File>($"{Apiurl}/{file.FileId}", file);
|
||||
}
|
||||
|
||||
public async Task DeleteFileAsync(int fileId)
|
||||
{
|
||||
await DeleteAsync($"{Apiurl}/{fileId}");
|
||||
}
|
||||
|
||||
public async Task<File> UploadFileAsync(string url, int folderId)
|
||||
{
|
||||
return await GetJsonAsync<File>($"{Apiurl}/upload?url={WebUtility.UrlEncode(url)}&folderid={folderId}");
|
||||
}
|
||||
|
||||
public async Task<string> UploadFilesAsync(int folderId, string[] files, string id)
|
||||
{
|
||||
return await UploadFilesAsync(folderId.ToString(), files, id);
|
||||
}
|
||||
|
||||
public async Task<string> UploadFilesAsync(string folder, string[] files, string id)
|
||||
{
|
||||
string result = "";
|
||||
|
||||
var interop = new Interop(jsRuntime);
|
||||
await interop.UploadFiles(apiurl + "/upload", Folder, FileUploadName);
|
||||
var interop = new Interop(_jsRuntime);
|
||||
await interop.UploadFiles($"{Apiurl}/upload", folder, id);
|
||||
|
||||
// uploading files is asynchronous so we need to wait for the upload to complete
|
||||
bool success = false;
|
||||
|
@ -48,21 +90,23 @@ namespace Oqtane.Services
|
|||
Thread.Sleep(2000); // wait 2 seconds
|
||||
result = "";
|
||||
|
||||
List<string> files = await GetFilesAsync(Folder);
|
||||
if (files.Count > 0)
|
||||
List<File> fileList = await GetFilesAsync(folder);
|
||||
if (fileList.Count > 0)
|
||||
{
|
||||
success = true;
|
||||
foreach (string file in Files)
|
||||
foreach (string file in files)
|
||||
{
|
||||
if (!files.Contains(file))
|
||||
if (!fileList.Exists(item => item.Name == file))
|
||||
{
|
||||
success = false;
|
||||
result += file + ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attempts += 1;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
result = result.Substring(0, result.Length - 1);
|
||||
|
@ -71,9 +115,9 @@ namespace Oqtane.Services
|
|||
return result;
|
||||
}
|
||||
|
||||
public async Task DeleteFileAsync(string Folder, string File)
|
||||
public async Task<byte[]> DownloadFileAsync(int fileId)
|
||||
{
|
||||
await http.DeleteAsync(apiurl + "?folder=" + Folder + "&file=" + File);
|
||||
return await GetByteArrayAsync($"{Apiurl}/download/{fileId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,91 +2,112 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Shared;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Net;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public class FolderService : ServiceBase, IFolderService
|
||||
{
|
||||
private readonly HttpClient http;
|
||||
private readonly SiteState sitestate;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly SiteState _siteState;
|
||||
|
||||
public FolderService(HttpClient http, SiteState sitestate, NavigationManager NavigationManager)
|
||||
public FolderService(HttpClient http, SiteState siteState) : base(http)
|
||||
{
|
||||
this.http = http;
|
||||
this.sitestate = sitestate;
|
||||
this.NavigationManager = NavigationManager;
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private string apiurl
|
||||
{
|
||||
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "Folder"); }
|
||||
}
|
||||
private string ApiUrl => CreateApiUrl(_siteState.Alias, "Folder");
|
||||
|
||||
public async Task<List<Folder>> GetFoldersAsync(int SiteId)
|
||||
public async Task<List<Folder>> GetFoldersAsync(int siteId)
|
||||
{
|
||||
List<Folder> folders = await http.GetJsonAsync<List<Folder>>(apiurl + "?siteid=" + SiteId.ToString());
|
||||
List<Folder> folders = await GetJsonAsync<List<Folder>>($"{ApiUrl}?siteid={siteId}");
|
||||
folders = GetFoldersHierarchy(folders);
|
||||
return folders;
|
||||
}
|
||||
|
||||
public async Task<Folder> GetFolderAsync(int FolderId)
|
||||
public async Task<Folder> GetFolderAsync(int folderId)
|
||||
{
|
||||
return await http.GetJsonAsync<Folder>(apiurl + "/" + FolderId.ToString());
|
||||
return await GetJsonAsync<Folder>($"{ApiUrl}/{folderId}");
|
||||
}
|
||||
|
||||
public async Task<Folder> AddFolderAsync(Folder Folder)
|
||||
public async Task<Folder> GetFolderAsync(int siteId, [NotNull] string folderPath)
|
||||
{
|
||||
return await http.PostJsonAsync<Folder>(apiurl, Folder);
|
||||
if (!(folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar)))
|
||||
{
|
||||
folderPath = Utilities.PathCombine(folderPath, "\\");
|
||||
}
|
||||
|
||||
public async Task<Folder> UpdateFolderAsync(Folder Folder)
|
||||
{
|
||||
return await http.PutJsonAsync<Folder>(apiurl + "/" + Folder.FolderId.ToString(), Folder);
|
||||
var path = WebUtility.UrlEncode(folderPath);
|
||||
|
||||
return await GetJsonAsync<Folder>($"{ApiUrl}/{siteId}/{path}");
|
||||
}
|
||||
|
||||
public async Task UpdateFolderOrderAsync(int SiteId, int FolderId, int? ParentId)
|
||||
public async Task<Folder> AddFolderAsync(Folder folder)
|
||||
{
|
||||
await http.PutJsonAsync(apiurl + "/?siteid=" + SiteId.ToString() + "&folderid=" + FolderId.ToString() + "&parentid=" + ((ParentId == null) ? "" : ParentId.ToString()), null);
|
||||
return await PostJsonAsync<Folder>(ApiUrl, folder);
|
||||
}
|
||||
|
||||
public async Task DeleteFolderAsync(int FolderId)
|
||||
public async Task<Folder> UpdateFolderAsync(Folder folder)
|
||||
{
|
||||
await http.DeleteAsync(apiurl + "/" + FolderId.ToString());
|
||||
return await PutJsonAsync<Folder>($"{ApiUrl}/{folder.FolderId}", folder);
|
||||
}
|
||||
|
||||
private static List<Folder> GetFoldersHierarchy(List<Folder> Folders)
|
||||
public async Task UpdateFolderOrderAsync(int siteId, int folderId, int? parentId)
|
||||
{
|
||||
var parent = parentId == null
|
||||
? string.Empty
|
||||
: parentId.ToString();
|
||||
await PutAsync($"{ApiUrl}/?siteid={siteId}&folderid={folderId}&parentid={parent}");
|
||||
}
|
||||
|
||||
public async Task DeleteFolderAsync(int folderId)
|
||||
{
|
||||
await DeleteAsync($"{ApiUrl}/{folderId}");
|
||||
}
|
||||
|
||||
private static List<Folder> GetFoldersHierarchy(List<Folder> folders)
|
||||
{
|
||||
List<Folder> hierarchy = new List<Folder>();
|
||||
Action<List<Folder>, Folder> GetPath = null;
|
||||
GetPath = (List<Folder> folders, Folder folder) =>
|
||||
Action<List<Folder>, Folder> getPath = null;
|
||||
var folders1 = folders;
|
||||
getPath = (folderList, folder) =>
|
||||
{
|
||||
IEnumerable<Folder> children;
|
||||
int level;
|
||||
if (folder == null)
|
||||
{
|
||||
level = -1;
|
||||
children = Folders.Where(item => item.ParentId == null);
|
||||
children = folders1.Where(item => item.ParentId == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
level = folder.Level;
|
||||
children = Folders.Where(item => item.ParentId == folder.FolderId);
|
||||
children = folders1.Where(item => item.ParentId == folder.FolderId);
|
||||
}
|
||||
|
||||
foreach (Folder child in children)
|
||||
{
|
||||
child.Level = level + 1;
|
||||
child.HasChildren = Folders.Where(item => item.ParentId == child.FolderId).Any();
|
||||
child.HasChildren = folders1.Any(item => item.ParentId == child.FolderId);
|
||||
hierarchy.Add(child);
|
||||
GetPath(folders, child);
|
||||
if (getPath != null) getPath(folderList, child);
|
||||
}
|
||||
};
|
||||
Folders = Folders.OrderBy(item => item.Order).ToList();
|
||||
GetPath(Folders, null);
|
||||
folders = folders.OrderBy(item => item.Order).ToList();
|
||||
getPath(folders, null);
|
||||
|
||||
// add any non-hierarchical items to the end of the list
|
||||
foreach (Folder folder in folders)
|
||||
{
|
||||
if (hierarchy.Find(item => item.FolderId == folder.FolderId) == null)
|
||||
{
|
||||
hierarchy.Add(folder);
|
||||
}
|
||||
}
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,29 @@
|
|||
using Oqtane.Models;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public class InstallationService : ServiceBase, IInstallationService
|
||||
{
|
||||
private readonly HttpClient http;
|
||||
private readonly SiteState sitestate;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
public InstallationService(HttpClient http):base(http) { }
|
||||
|
||||
public InstallationService(HttpClient http, SiteState sitestate, NavigationManager NavigationManager)
|
||||
private string ApiUrl => CreateApiUrl("Installation");
|
||||
|
||||
public async Task<Installation> IsInstalled()
|
||||
{
|
||||
this.http = http;
|
||||
this.sitestate = sitestate;
|
||||
this.NavigationManager = NavigationManager;
|
||||
return await GetJsonAsync<Installation>($"{ApiUrl}/installed");
|
||||
}
|
||||
|
||||
private string apiurl
|
||||
public async Task<Installation> Install(InstallConfig config)
|
||||
{
|
||||
get { return CreateApiUrl(sitestate.Alias, NavigationManager.Uri, "Installation"); }
|
||||
return await PostJsonAsync<InstallConfig,Installation>(ApiUrl, config);
|
||||
}
|
||||
|
||||
public async Task<GenericResponse> IsInstalled()
|
||||
public async Task<Installation> Upgrade()
|
||||
{
|
||||
return await http.GetJsonAsync<GenericResponse>(apiurl + "/installed");
|
||||
}
|
||||
|
||||
public async Task<GenericResponse> Install(string connectionstring)
|
||||
{
|
||||
return await http.PostJsonAsync<GenericResponse>(apiurl, connectionstring);
|
||||
}
|
||||
|
||||
public async Task<GenericResponse> Upgrade()
|
||||
{
|
||||
return await http.GetJsonAsync<GenericResponse>(apiurl + "/upgrade");
|
||||
return await GetJsonAsync<Installation>($"{ApiUrl}/upgrade");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Oqtane.Models;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -8,12 +9,14 @@ namespace Oqtane.Services
|
|||
{
|
||||
Task<List<Alias>> GetAliasesAsync();
|
||||
|
||||
Task<Alias> GetAliasAsync(int AliasId);
|
||||
Task<Alias> GetAliasAsync(int aliasId);
|
||||
|
||||
Task<Alias> AddAliasAsync(Alias Alias);
|
||||
Task<Alias> GetAliasAsync(string url, DateTime lastSyncDate);
|
||||
|
||||
Task<Alias> UpdateAliasAsync(Alias Alias);
|
||||
Task<Alias> AddAliasAsync(Alias alias);
|
||||
|
||||
Task DeleteAliasAsync(int AliasId);
|
||||
Task<Alias> UpdateAliasAsync(Alias alias);
|
||||
|
||||
Task DeleteAliasAsync(int aliasId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,17 @@ namespace Oqtane.Services
|
|||
{
|
||||
public interface IFileService
|
||||
{
|
||||
Task<List<string>> GetFilesAsync(string Folder);
|
||||
Task<string> UploadFilesAsync(string Folder, string[] Files, string FileUploadName);
|
||||
Task DeleteFileAsync(string Folder, string File);
|
||||
Task<List<File>> GetFilesAsync(int folderId);
|
||||
Task<List<File>> GetFilesAsync(string folder);
|
||||
Task<File> GetFileAsync(int fileId);
|
||||
Task<File> AddFileAsync(File file);
|
||||
Task<File> UpdateFileAsync(File file);
|
||||
Task DeleteFileAsync(int fileId);
|
||||
Task<File> UploadFileAsync(string url, int folderId);
|
||||
Task<string> UploadFilesAsync(int folderId, string[] files, string fileUploadName);
|
||||
Task<string> UploadFilesAsync(string folder, string[] files, string fileUploadName);
|
||||
Task<byte[]> DownloadFileAsync(int fileId);
|
||||
|
||||
Task<List<File>> GetFilesAsync(int siteId, string folderPath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
using Oqtane.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public interface IFolderService
|
||||
{
|
||||
Task<List<Folder>> GetFoldersAsync(int SiteId);
|
||||
Task<Folder> GetFolderAsync(int FolderId);
|
||||
Task<Folder> AddFolderAsync(Folder Folder);
|
||||
Task<Folder> UpdateFolderAsync(Folder Folder);
|
||||
Task UpdateFolderOrderAsync(int SiteId, int FolderId, int? ParentId);
|
||||
Task DeleteFolderAsync(int FolderId);
|
||||
Task<List<Folder>> GetFoldersAsync(int siteId);
|
||||
Task<Folder> GetFolderAsync(int folderId);
|
||||
Task<Folder> AddFolderAsync(Folder folder);
|
||||
Task<Folder> UpdateFolderAsync(Folder folder);
|
||||
Task UpdateFolderOrderAsync(int siteId, int folderId, int? parentId);
|
||||
Task DeleteFolderAsync(int folderId);
|
||||
Task<Folder> GetFolderAsync(int siteId, [NotNull]string folderPath);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
using Oqtane.Models;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public interface IInstallationService
|
||||
{
|
||||
Task<GenericResponse> IsInstalled();
|
||||
Task<GenericResponse> Install(string connectionstring);
|
||||
Task<GenericResponse> Upgrade();
|
||||
Task<Installation> IsInstalled();
|
||||
Task<Installation> Install(InstallConfig config);
|
||||
Task<Installation> Upgrade();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@ namespace Oqtane.Services
|
|||
{
|
||||
Task<List<JobLog>> GetJobLogsAsync();
|
||||
|
||||
Task<JobLog> GetJobLogAsync(int JobLogId);
|
||||
Task<JobLog> GetJobLogAsync(int jobLogId);
|
||||
|
||||
Task<JobLog> AddJobLogAsync(JobLog JobLog);
|
||||
Task<JobLog> AddJobLogAsync(JobLog jobLog);
|
||||
|
||||
Task<JobLog> UpdateJobLogAsync(JobLog JobLog);
|
||||
Task<JobLog> UpdateJobLogAsync(JobLog jobLog);
|
||||
|
||||
Task DeleteJobLogAsync(int JobLogId);
|
||||
Task DeleteJobLogAsync(int jobLogId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,16 +8,16 @@ namespace Oqtane.Services
|
|||
{
|
||||
Task<List<Job>> GetJobsAsync();
|
||||
|
||||
Task<Job> GetJobAsync(int JobId);
|
||||
Task<Job> GetJobAsync(int jobId);
|
||||
|
||||
Task<Job> AddJobAsync(Job Job);
|
||||
Task<Job> AddJobAsync(Job job);
|
||||
|
||||
Task<Job> UpdateJobAsync(Job Job);
|
||||
Task<Job> UpdateJobAsync(Job job);
|
||||
|
||||
Task DeleteJobAsync(int JobId);
|
||||
Task DeleteJobAsync(int jobId);
|
||||
|
||||
Task StartJobAsync(int JobId);
|
||||
Task StartJobAsync(int jobId);
|
||||
|
||||
Task StopJobAsync(int JobId);
|
||||
Task StopJobAsync(int jobId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,13 +3,15 @@ using Oqtane.Shared;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Enums;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public interface ILogService
|
||||
{
|
||||
Task<List<Log>> GetLogsAsync(int SiteId, string Level, string Function, int Rows);
|
||||
Task<Log> GetLogAsync(int LogId);
|
||||
Task Log(int? PageId, int? ModuleId, int? UserId, string category, string feature, LogFunction function, LogLevel level, Exception exception, string message, params object[] args);
|
||||
Task<List<Log>> GetLogsAsync(int siteId, string level, string function, int rows);
|
||||
Task<Log> GetLogAsync(int logId);
|
||||
Task Log(int? pageId, int? moduleId, int? userId, string category, string feature, LogFunction function, LogLevel level, Exception exception, string message, params object[] args);
|
||||
Task Log(Alias alias, int? pageId, int? moduleId, int? userId, string category, string feature, LogFunction function, LogLevel level, Exception exception, string message, params object[] args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Oqtane.Models;
|
||||
using Oqtane.UI;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -6,9 +7,11 @@ namespace Oqtane.Services
|
|||
{
|
||||
public interface IModuleDefinitionService
|
||||
{
|
||||
Task<List<ModuleDefinition>> GetModuleDefinitionsAsync(int SiteId);
|
||||
Task UpdateModuleDefinitionAsync(ModuleDefinition ModuleDefinition);
|
||||
Task<List<ModuleDefinition>> GetModuleDefinitionsAsync(int siteId);
|
||||
Task<ModuleDefinition> GetModuleDefinitionAsync(int moduleDefinitionId, int siteId);
|
||||
Task UpdateModuleDefinitionAsync(ModuleDefinition moduleDefinition);
|
||||
Task InstallModuleDefinitionsAsync();
|
||||
Task DeleteModuleDefinitionAsync(int ModuleDefinitionId, int SiteId);
|
||||
Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId);
|
||||
Task CreateModuleDefinitionAsync(ModuleDefinition moduleDefinition, int moduleId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,12 @@ namespace Oqtane.Services
|
|||
{
|
||||
public interface IModuleService
|
||||
{
|
||||
Task<List<Module>> GetModulesAsync(int SiteId);
|
||||
Task<Module> GetModuleAsync(int ModuleId);
|
||||
Task<Module> AddModuleAsync(Module Module);
|
||||
Task<Module> UpdateModuleAsync(Module Module);
|
||||
Task DeleteModuleAsync(int ModuleId);
|
||||
Task<bool> ImportModuleAsync(int ModuleId, string Content);
|
||||
Task<string> ExportModuleAsync(int ModuleId);
|
||||
Task<List<Module>> GetModulesAsync(int siteId);
|
||||
Task<Module> GetModuleAsync(int moduleId);
|
||||
Task<Module> AddModuleAsync(Module module);
|
||||
Task<Module> UpdateModuleAsync(Module module);
|
||||
Task DeleteModuleAsync(int moduleId);
|
||||
Task<bool> ImportModuleAsync(int moduleId, string content);
|
||||
Task<string> ExportModuleAsync(int moduleId);
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user