Merge pull request #1 from oqtane/master

update master branch
This commit is contained in:
Cody 2020-05-06 17:55:24 -07:00 committed by GitHub
commit 71f79bd90b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
382 changed files with 11719 additions and 9737 deletions

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ Oqtane.Server/appsettings.json
Oqtane.Server/Data/*.mdf
Oqtane.Server/Data/*.ldf
/Oqtane.Server/Properties/PublishProfiles/FolderProfile.pubxml

View File

@ -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

View File

@ -19,12 +19,13 @@
@code {
private bool _initialized;
private bool _installed;
private PageState PageState { get; set; }
protected override async Task OnParametersSetAsync()
{
var response = await InstallationService.IsInstalled();
_installed = response.Success;
var installation = await InstallationService.IsInstalled();
_installed = installation.Success;
_initialized = true;
}

View File

@ -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.FirstOrDefault(item => item.Path == "admin");
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
_pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList();
}
}

View File

@ -3,7 +3,7 @@
@inject IModuleService ModuleService
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Anonymous; } }
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
protected override async Task OnInitializedAsync()
{
@ -13,6 +13,7 @@
string message = "A Problem Was Encountered Loading Module " + module.ModuleDefinitionName;
AddModuleMessage(message, MessageType.Error);
}
await logger.LogCritical("Error Loading Module {Module}", module);
}
}

View File

@ -4,53 +4,38 @@
@inject IFileService FileService
@inject IFolderService FolderService
@if (_folders != null)
{
<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="#Upload" role="tab">
Upload Files
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#Download" role="tab">
Download Files
</a>
</li>
</ul>
<div class="tab-content">
<div id="Upload" class="tab-pane fade show active" role="tabpanel">
<TabStrip>
<TabPanel Name="Upload" Heading="Upload Files">
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Upload: </label>
<Label For="upload" HelpText="Upload the file you want">Upload: </Label>
</td>
<td>
<FileManager UploadMultiple="true" ShowFiles="false" FolderId="@_folderId.ToString()" />
</td>
</tr>
</table>
</div>
<div id="Download" class="tab-pane fade" role="tabpanel">
<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 class="control-label">Url: </label>
<Label For="url" HelpText="Enter the url of the file you wish to download">Url: </Label>
</td>
<td>
<input class="form-control" @bind="@url" />
<input id="url" class="form-control" @bind="@url" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Folder: </label>
<Label For="folder" HelpText="Select the folder to save the file in">Folder: </Label>
</td>
<td>
<select class="form-control" @bind="@_folderId">
<select id="folder" class="form-control" @bind="@_folderId">
<option value="-1">&lt;Select Folder&gt;</option>
@foreach (Folder folder in _folders)
{
@ -60,21 +45,18 @@
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="Download">Download</button>
</div>
</div>
</div>
</div>
<br />
<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;
string url = "";
List<Folder> _folders;
int _folderId = -1;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnInitializedAsync()
{
@ -90,7 +72,7 @@
{
try
{
if (url != "" && _folderId != -1)
if (url != string.Empty && _folderId != -1)
{
await FileService.UploadFileAsync(url, _folderId);
await logger.LogInformation("File Downloaded Successfully From Url {Url}", url);

View File

@ -8,10 +8,10 @@
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Parent: </label>
<Label For="parent" HelpText="Select the parent folder">Parent: </Label>
</td>
<td>
<select class="form-control" @bind="@_parentId">
<select id="parent" class="form-control" @bind="@_parentId">
@if (PageState.QueryString.ContainsKey("id"))
{
<option value="-1">&lt;No Parent&gt;</option>
@ -25,18 +25,16 @@
</tr>
<tr>
<td>
<label class="control-label">Name: </label>
<Label for="name" HelpText="Enter the file name">Name: </Label>
</td>
<td>
<input class="form-control" @bind="@_name" />
<input id="name" class="form-control" @bind="@_name" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Permissions: </label>
</td>
<td>
<PermissionGrid EntityName="Folder" PermissionNames="Browse,View,Edit" Permissions="@_permissions" @ref="_permissionGrid" />
<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>
@ -58,24 +56,25 @@
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
public override string Title { get { return "Folder Management"; } }
List<Folder> _folders;
int _folderId = -1;
string _name;
int _parentId = -1;
bool _isSystem;
string _permissions = "";
string _createdBy;
DateTime _createdOn;
string _modifiedBy;
DateTime _modifiedOn;
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;
#pragma warning disable 649
PermissionGrid _permissionGrid;
private PermissionGrid _permissionGrid;
#pragma warning restore 649
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
public override string Title => "Folder Management";
protected override async Task OnInitializedAsync()
{
try
@ -101,11 +100,7 @@
else
{
_parentId = _folders[0].FolderId;
List<PermissionString> permissionstrings = new List<PermissionString>();
permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.Browse, Permissions = Constants.AdminRole });
permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.View, Permissions = Constants.AdminRole });
permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.Edit, Permissions = Constants.AdminRole });
_permissions = UserSecurity.SetPermissionStrings(permissionstrings);
_permissions = string.Empty;
}
}
catch (Exception ex)
@ -119,7 +114,7 @@
{
try
{
if (_name != "" && _parentId != -1)
if (_name != string.Empty && _parentId != -1)
{
Folder folder;
if (_folderId != -1)
@ -132,6 +127,7 @@
}
folder.SiteId = PageState.Site.SiteId;
if (_parentId == -1)
{
folder.ParentId = null;
@ -140,6 +136,7 @@
{
folder.ParentId = _parentId;
}
folder.Name = _name;
folder.IsSystem = _isSystem;
folder.Permissions = _permissionGrid.GetPermissions();
@ -152,6 +149,7 @@
{
folder = await FolderService.AddFolderAsync(folder);
}
await FolderService.UpdateFolderOrderAsync(folder.SiteId, folder.FolderId, folder.ParentId);
await logger.LogInformation("Folder Saved {Folder}", folder);
NavigationManager.NavigateTo(NavigateUrl());

View File

@ -49,24 +49,23 @@
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
private List<Folder> _folders;
private int _folderId = -1;
private List<File> _files;
List<Folder> _folders;
int _folderId = -1;
List<File> _files;
Uri _uri;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnParametersSetAsync()
{
try
{
_folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
if (_folderId == -1 && _folders.Count > 0)
{
_folderId = _folders[0].FolderId;
await GetFiles();
}
_uri = new Uri(NavigationManager.Uri);
}
catch (Exception ex)
{

View File

@ -6,26 +6,26 @@
<table class="table table-borderless">
<tr>
<td>
<label 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 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 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 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,26 +47,26 @@
</tr>
<tr>
<td>
<label 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 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 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>
@ -74,28 +74,29 @@
<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();
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 == "")
if (_startDate == string.Empty)
{
job.StartDate = null;
}
@ -103,7 +104,8 @@
{
job.StartDate = DateTime.Parse(_startDate);
}
if (_endDate == "")
if (_endDate == string.Empty)
{
job.EndDate = null;
}
@ -111,6 +113,7 @@
{
job.EndDate = DateTime.Parse(_endDate);
}
job.RetentionHistory = int.Parse(_retentionHistory);
job.IsStarted = false;
job.IsExecuting = false;

View File

@ -6,26 +6,26 @@
<table class="table table-borderless">
<tr>
<td>
<label 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 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 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 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,26 +47,26 @@
</tr>
<tr>
<td>
<label 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 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 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>
@ -74,17 +74,17 @@
<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()
{
@ -99,8 +99,8 @@
_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() : "";
_startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty;
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
_retentionHistory = job.RetentionHistory.ToString();
}
}
@ -113,15 +113,16 @@
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);
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 == "")
if (_startDate == string.Empty)
{
job.StartDate = null;
}
@ -129,7 +130,8 @@
{
job.StartDate = DateTime.Parse(_startDate);
}
if (_endDate == "")
if (_endDate == string.Empty)
{
job.EndDate = null;
}
@ -137,6 +139,7 @@
{
job.EndDate = DateTime.Parse(_endDate);
}
job.RetentionHistory = int.Parse(_retentionHistory);
try

View File

@ -47,9 +47,9 @@ 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()
{
@ -58,7 +58,7 @@ else
private string DisplayStatus(bool isEnabled, bool isExecuting)
{
string status = "";
var status = string.Empty;
if (!isEnabled)
{
status = "Disabled";
@ -81,7 +81,7 @@ else
private string DisplayFrequency(int interval, string frequency)
{
string result = "Every " + interval.ToString() + " ";
var result = "Every " + interval.ToString() + " ";
switch (frequency)
{
case "m":
@ -97,10 +97,12 @@ else
result += "Month";
break;
}
if (interval > 1)
{
result += "s";
}
return result;
}

View File

@ -28,23 +28,25 @@ 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();
if (PageState.QueryString.ContainsKey("id"))
{
_jobLogs = _jobLogs.Where(item => item.JobId == Int32.Parse(PageState.QueryString["id"])).ToList();
}
_jobLogs = _jobLogs.OrderByDescending(item => item.JobLogId).ToList();
}
private string DisplayStatus(bool isExecuting, bool? succeeded)
{
string status = "";
var status = string.Empty;
if (isExecuting)
{
status = "Executing";
@ -60,6 +62,7 @@ else
status = "Failed";
}
}
return status;
}
}

View File

@ -5,7 +5,7 @@
@inject IUserService UserService
@inject IServiceProvider ServiceProvider
@if (_message != "")
@if (_message != string.Empty)
{
<ModuleMessage Message="@_message" Type="@_type" />
}
@ -14,7 +14,7 @@
<text>...</text>
</Authorizing>
<Authorized>
You are already logged in
<ModuleMessage Message="You Are Already Logged In" Type="MessageType.Info" />
</Authorized>
<NotAuthorized>
<div class="container">
@ -41,14 +41,14 @@
</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 = "";
string _message = "";
MessageType _type = MessageType.Info;
string _username = "";
string _password = "";
bool _remember = false;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
protected override async Task OnInitializedAsync()
{
@ -56,13 +56,15 @@
{
_returnUrl = PageState.QueryString["returnurl"];
}
if (PageState.QueryString.ContainsKey("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 = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]);
@ -81,15 +83,15 @@
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 = await UserService.LoginUserAsync(user, false, false);
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
@ -97,7 +99,7 @@
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);
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
}
else
{
@ -108,7 +110,7 @@
else
{
// client-side Blazor
User user = new User();
var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = _username;
user.Password = _password;
@ -116,6 +118,7 @@
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
}
@ -134,9 +137,9 @@
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);
@ -152,6 +155,7 @@
{
_message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again";
}
StateHasChanged();
}
}

View File

@ -10,156 +10,156 @@
<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>
<textarea id="message" class="form-control" @bind="@_message" rows="5" readonly></textarea>
</td>
</tr>
@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>
<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>
<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);
var log = await LogService.GetLogAsync(_logId);
if (log != null)
{
_logDate = log.LogDate.ToString(CultureInfo.CurrentCulture);
@ -167,30 +167,34 @@
_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;
}
}
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;
}
}
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;
}
}
_url = log.Url;
_template = log.MessageTemplate;
_message = log.Message;

View File

@ -71,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()
{
@ -139,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":
@ -163,7 +163,7 @@ else
classname = "table-secondary";
break;
default:
classname = "";
classname = string.Empty;
break;
}
return classname;

View File

@ -0,0 +1,80 @@
@namespace Oqtane.Modules.Admin.ModuleCreator
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IModuleDefinitionService ModuleDefinitionService
@inject IModuleService ModuleService
<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" @bind="@_template">
<option value="">&lt;Select Template&gt;</option>
<option value="internal">Internal</option>
<option value="external">External</option>
</select>
</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 = 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) && !string.IsNullOrEmpty(_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");
}
}
}

View 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"
};
}
}

View File

@ -0,0 +1,95 @@
@using Oqtane.Modules.Controls
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject HttpClient http
@inject SiteState sitestate
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Name: </label>
</td>
<td>
<input id="_name" class="form-control" @bind="@_name" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="Save">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
<br />
<br />
@if (PageState.Action == "Edit")
{
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
public override string Actions => "Add,Edit";
I[Module]Service [Module]Service;
int _id;
string _name;
string _createdby;
DateTime _createdon;
string _modifiedby;
DateTime _modifiedon;
protected override async Task OnInitializedAsync()
{
try
{
[Module]Service = new [Module]Service(http, sitestate);
if (PageState.Action == "Edit")
{
_id = Int32.Parse(PageState.QueryString["id"]);
[Module] [Module] = await [Module]Service.Get[Module]Async(_id);
if ([Module] != null)
{
_name = [Module].Name;
_createdby = [Module].CreatedBy;
_createdon = [Module].CreatedOn;
_modifiedby = [Module].ModifiedBy;
_modifiedon = [Module].ModifiedOn;
}
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading [Module] {[Module]Id} {Error}", _id, ex.Message);
AddModuleMessage("Error Loading [Module]", MessageType.Error);
}
}
private async Task Save()
{
try
{
if (PageState.Action == "Add")
{
[Module] [Module] = new [Module]();
[Module].ModuleId = ModuleState.ModuleId;
[Module].Name = _name;
[Module] = await [Module]Service.Add[Module]Async([Module]);
await logger.LogInformation("[Module] Added {[Module]}", [Module]);
}
else
{
[Module] [Module] = await [Module]Service.Get[Module]Async(_id);
[Module].Name = _name;
await [Module]Service.Update[Module]Async([Module]);
await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
}
NavigationManager.NavigateTo(NavigateUrl());
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving [Module] {Error}", ex.Message);
AddModuleMessage("Error Saving [Module]", MessageType.Error);
}
}
}

View File

@ -0,0 +1,106 @@
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject HttpClient http
@inject SiteState sitestate
@if (_[Module]s == null)
{
<p><em>Loading...</em></p>
}
else
{
<ActionLink Action="Add" Security="SecurityAccessLevel.Edit" Text="Add [Module]" />
<br />
<br />
@if (@_[Module]s.Count != 0)
{
<Pager Items="@_[Module]s" Format="Grid">
<Header>
<div class="col"><strong>[Module]s</strong></div>
</Header>
<Row>
<div class="col">
<ActionLink Action="Edit" Parameters="@($"id=" + context.[Module]Id.ToString())" />
<ActionDialog Header="Delete [Module]" Message="@("Are You Sure You Wish To Delete The " + context.Name + " [Module]?")" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" />
@context.Name
</div>
</Row>
</Pager>
}
else
{
<p>No [Module]s To Display</p>
}
}
<!-- The content below is for informational purposes only and can be safely removed -->
<hr />
[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br />
[RootPath]Client\<br />
- [Owner].[Module]s.Module.Client.csproj - client project<br />
- _Imports.razor - global imports for module components<br />
- Edit.razor - component for adding or editing content<br />
- Index.razor - main component for your module **the content you are reading is in this file**<br />
- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module<br />
- Settings.razor - component for managing module settings<br />
- Services\I[Module]Service.cs - interface for defining service API methods<br />
- Services\[Module]Service.cs - implements service API interface methods<br /><br />
[RootPath]Package\<br />
- [Owner].[Module]s.Module.nuspec - nuget manifest for packaging module<br />
- [Owner].[Module]s.Module.Package.csproj - packaging project<br />
- debug.cmd - copies assemblies to Oqtane bin folder when in Debug mode<br />
- release.cmd - creates nuget package and deploys to Oqtane wwwroot/modules folder when in Release mode<br /><br />
[RootPath]Server\<br />
- [Owner].[Module]s.Module.Server.csproj - server project<br />
- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern<br />
- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content<br />
- Repository\I[Module]Repository.cs - interface for defining repository methods<br />
- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core<br />
- Repository\[Module]Context.cs - provides a DB Context for data access<br />
- Scripts\[Owner].[Module].1.0.0.sql - database schema definition script<br /><br />
- Scripts\[Owner].[Module].Uninstall.sql - database uninstall script<br /><br />
[RootPath]Shared\<br />
- [Owner].[Module]s.Module.Shared.csproj - shared project<br />
- Models\[Module].cs - model definition<br /><br />
<!-- The content above is for informational purposes only and can be safely removed -->
@code {
I[Module]Service [Module]Service;
List<[Module]> _[Module]s;
protected override async Task OnInitializedAsync()
{
try
{
[Module]Service = new [Module]Service(http, sitestate);
_[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading [Module] {Error}", ex.Message);
AddModuleMessage("Error Loading [Module]", MessageType.Error);
}
}
private async Task Delete([Module] [Module])
{
try
{
await [Module]Service.Delete[Module]Async([Module].[Module]Id);
await logger.LogInformation("[Module] Deleted {[Module]}", [Module]);
_[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting [Module] {[Module]} {Error}", [Module], ex.Message);
AddModuleMessage("Error Deleting [Module]", MessageType.Error);
}
}
}

View File

@ -0,0 +1,18 @@
using Oqtane.Models;
using Oqtane.Modules;
namespace [Owner].[Module]s.Modules
{
public class ModuleInfo : IModule
{
public ModuleDefinition ModuleDefinition => new ModuleDefinition
{
Name = "[Module]",
Description = "[Module]",
Version = "1.0.0",
Dependencies = "[Owner].[Module]s.Module.Shared",
ServerManagerType = "[ServerManagerType]",
ReleaseVersions = "1.0.0"
};
}
}

View File

@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Services
{
public interface I[Module]Service
{
Task<List<[Module]>> Get[Module]sAsync(int ModuleId);
Task<[Module]> Get[Module]Async(int [Module]Id);
Task<[Module]> Add[Module]Async([Module] [Module]);
Task<[Module]> Update[Module]Async([Module] [Module]);
Task Delete[Module]Async(int [Module]Id);
}
}

View File

@ -0,0 +1,49 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Oqtane.Modules;
using Oqtane.Services;
using Oqtane.Shared;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Services
{
public class [Module]Service : ServiceBase, I[Module]Service, IService
{
private readonly SiteState _siteState;
public [Module]Service(HttpClient http, SiteState siteState) : base(http)
{
_siteState = siteState;
}
private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]");
public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId)
{
List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>($"{Apiurl}?moduleid={ModuleId}");
return [Module]s.OrderBy(item => item.Name).ToList();
}
public async Task<[Module]> Get[Module]Async(int [Module]Id)
{
return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}");
}
public async Task<[Module]> Add[Module]Async([Module] [Module])
{
return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]);
}
public async Task<[Module]> Update[Module]Async([Module] [Module])
{
return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]);
}
public async Task Delete[Module]Async(int [Module]Id)
{
await DeleteAsync($"{Apiurl}/{[Module]Id}");
}
}
}

View File

@ -0,0 +1,47 @@
@namespace [Owner].[Module]s.Modules
@inherits ModuleBase
@inject ISettingService SettingService
<table class="table table-borderless">
<tr>
<td>
<label for="Setting" class="control-label">Setting: </label>
</td>
<td>
<input type="text" class="form-control" @bind="_value" />
</td>
</tr>
</table>
@code {
public override string Title => "[Module] Settings";
string _value;
protected override async Task OnInitializedAsync()
{
try
{
Dictionary<string, string> settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
_value = SettingService.GetSetting(settings, "SettingName", "");
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
}
}
public async Task UpdateSettings()
{
try
{
Dictionary<string, string> settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
SettingService.SetSetting(settings, "SettingName", _value);
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
}
}
}

View File

@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
<Version>1.0.0</Version>
<Authors>[Owner]</Authors>
<Company>[Owner]</Company>
<Description>[Description]</Description>
<Product>[Owner].[Module]s.Module</Product>
<Copyright>[Owner]</Copyright>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.0-rc1.20223.4" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0-rc1.20223.4" PrivateAssets="all" />
<PackageReference Include="System.Net.Http.Json" Version="3.2.0-rc1.20217.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\[Owner].[Module]s.Module.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Oqtane.Client">
<HintPath>..\..\[RootFolder]\Oqtane.Client\bin\Debug\netstandard2.1\Oqtane.Client.dll</HintPath>
</Reference>
<Reference Include="Oqtane.Shared">
<HintPath>..\..\[RootFolder]\Oqtane.Client\bin\Debug\netstandard2.1\Oqtane.Shared.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup>
<!-- there may be other elements here -->
<BlazorWebAssemblyEnableLinking>false</BlazorWebAssemblyEnableLinking>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,18 @@
@using System
@using System.Linq
@using System.Collections.Generic
@using System.Net.Http
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.JSInterop
@using Oqtane.Models
@using Oqtane.Modules
@using Oqtane.Modules.Controls
@using Oqtane.Providers
@using Oqtane.Security
@using Oqtane.Services
@using Oqtane.Shared
@using Oqtane.Themes
@using Oqtane.Themes.Controls

View File

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Client\[Owner].[Module]s.Module.Client.csproj" />
<ProjectReference Include="..\Server\[Owner].[Module]s.Module.Server.csproj" />
<ProjectReference Include="..\Shared\[Owner].[Module]s.Module.Shared.csproj" />
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="IF $(ConfigurationName) == Debug (debug.cmd)" />
<Exec Command="IF $(ConfigurationName) == Release (release.cmd)" />
</Target>
</Project>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>[Owner].[Module]s.Module</id>
<version>1.0.0</version>
<authors>[Owner]</authors>
<owners>[Owner]</owners>
<title>[Module]s</title>
<description>[Module]s</description>
<copyright>[Owner]</copyright>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<license type="expression">MIT</license>
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
<tags>oqtane module</tags>
<releaseNotes></releaseNotes>
<summary></summary>
<dependencies>
<dependency id="Oqtane.Framework" version="[FrameworkVersion]" />
</dependencies>
</metadata>
<files>
<file src="..\Client\bin\Release\netstandard2.1\[Owner].[Module]s.Module.Client.dll" target="lib" />
<file src="..\Client\bin\Release\netstandard2.1\[Owner].[Module]s.Module.Client.pdb" target="lib" />
<file src="..\Server\bin\Release\netcoreapp3.1\[Owner].[Module]s.Module.Server.dll" target="lib" />
<file src="..\Server\bin\Release\netcoreapp3.1\[Owner].[Module]s.Module.Server.pdb" target="lib" />
<file src="..\Shared\bin\Release\netstandard2.1\[Owner].[Module]s.Module.Shared.dll" target="lib" />
<file src="..\Shared\bin\Release\netstandard2.1\[Owner].[Module]s.Module.Shared.pdb" target="lib" />
<file src="..\wwwroot\**\*.*" target="wwwroot" />
</files>
</package>

View File

@ -0,0 +1,6 @@
XCOPY "..\Client\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Client.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y
XCOPY "..\Client\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Client.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y
XCOPY "..\Server\bin\Debug\netcoreapp3.1\[Owner].[Module]s.Module.Server.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y
XCOPY "..\Server\bin\Debug\netcoreapp3.1\[Owner].[Module]s.Module.Server.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y
XCOPY "..\Shared\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Shared.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y
XCOPY "..\Shared\bin\Debug\netstandard2.1\[Owner].[Module]s.Module.Shared.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\" /Y

View File

@ -0,0 +1,2 @@
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack [Owner].[Module]s.Module.nuspec
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Modules\" /Y

View File

@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic;
using Oqtane.Shared;
using Oqtane.Enums;
using Oqtane.Infrastructure;
using [Owner].[Module]s.Models;
using [Owner].[Module]s.Repository;
namespace [Owner].[Module]s.Controllers
{
[Route("{site}/api/[controller]")]
public class [Module]Controller : Controller
{
private readonly I[Module]Repository _[Module]s;
private readonly ILogManager _logger;
public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger)
{
_[Module]s = [Module]s;
_logger = logger;
}
// GET: api/<controller>?moduleid=x
[HttpGet]
[Authorize(Roles = Constants.RegisteredRole)]
public IEnumerable<[Module]> Get(string moduleid)
{
return _[Module]s.Get[Module]s(int.Parse(moduleid));
}
// GET api/<controller>/5
[HttpGet("{id}")]
[Authorize(Roles = Constants.RegisteredRole)]
public [Module] Get(int id)
{
return _[Module]s.Get[Module](id);
}
// POST api/<controller>
[HttpPost]
[Authorize(Roles = Constants.AdminRole)]
public [Module] Post([FromBody] [Module] [Module])
{
if (ModelState.IsValid)
{
[Module] = _[Module]s.Add[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]);
}
return [Module];
}
// PUT api/<controller>/5
[HttpPut("{id}")]
[Authorize(Roles = Constants.AdminRole)]
public [Module] Put(int id, [FromBody] [Module] [Module])
{
if (ModelState.IsValid)
{
[Module] = _[Module]s.Update[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]);
}
return [Module];
}
// DELETE api/<controller>/5
[HttpDelete("{id}")]
[Authorize(Roles = Constants.AdminRole)]
public void Delete(int id)
{
_[Module]s.Delete[Module](id);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id);
}
}
}

View File

@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Oqtane.Modules;
using Oqtane.Models;
using Oqtane.Infrastructure;
using Oqtane.Repository;
using [Owner].[Module]s.Models;
using [Owner].[Module]s.Repository;
namespace [Owner].[Module]s.Manager
{
public class [Module]Manager : IInstallable, IPortable
{
private I[Module]Repository _[Module]s;
private ISqlRepository _sql;
public [Module]Manager(I[Module]Repository [Module]s, ISqlRepository sql)
{
_[Module]s = [Module]s;
_sql = sql;
}
public bool Install(Tenant tenant, string version)
{
return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module]." + version + ".sql");
}
public bool Uninstall(Tenant tenant)
{
return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module].Uninstall.sql");
}
public string ExportModule(Module module)
{
string content = "";
List<[Module]> [Module]s = _[Module]s.Get[Module]s(module.ModuleId).ToList();
if ([Module]s != null)
{
content = JsonSerializer.Serialize([Module]s);
}
return content;
}
public void ImportModule(Module module, string content, string version)
{
List<[Module]> [Module]s = null;
if (!string.IsNullOrEmpty(content))
{
[Module]s = JsonSerializer.Deserialize<List<[Module]>>(content);
}
if ([Module]s != null)
{
foreach([Module] [Module] in [Module]s)
{
[Module] _[Module] = new [Module]();
_[Module].ModuleId = module.ModuleId;
_[Module].Name = [Module].Name;
_[Module]s.Add[Module](_[Module]);
}
}
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Repository
{
public interface I[Module]Repository
{
IEnumerable<[Module]> Get[Module]s(int ModuleId);
[Module] Get[Module](int [Module]Id);
[Module] Add[Module]([Module] [Module]);
[Module] Update[Module]([Module] [Module]);
void Delete[Module](int [Module]Id);
}
}

View File

@ -0,0 +1,18 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Http;
using Oqtane.Modules;
using Oqtane.Repository;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Repository
{
public class [Module]Context : DBContextBase, IService
{
public virtual DbSet<[Module]> [Module] { get; set; }
public [Module]Context(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor)
{
// ContextBase handles multi-tenant database connections
}
}
}

View File

@ -0,0 +1,49 @@
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Collections.Generic;
using Oqtane.Modules;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Repository
{
public class [Module]Repository : I[Module]Repository, IService
{
private readonly [Module]Context _db;
public [Module]Repository([Module]Context context)
{
_db = context;
}
public IEnumerable<[Module]> Get[Module]s(int ModuleId)
{
return _db.[Module].Where(item => item.ModuleId == ModuleId);
}
public [Module] Get[Module](int [Module]Id)
{
return _db.[Module].Find([Module]Id);
}
public [Module] Add[Module]([Module] [Module])
{
_db.[Module].Add([Module]);
_db.SaveChanges();
return [Module];
}
public [Module] Update[Module]([Module] [Module])
{
_db.Entry([Module]).State = EntityState.Modified;
_db.SaveChanges();
return [Module];
}
public void Delete[Module](int [Module]Id)
{
[Module] [Module] = _db.[Module].Find([Module]Id);
_db.[Module].Remove([Module]);
_db.SaveChanges();
}
}
}

View File

@ -0,0 +1,26 @@
/*
Create [Owner][Module] table
*/
CREATE TABLE [dbo].[[Owner][Module]](
[[Module]Id] [int] IDENTITY(1,1) NOT NULL,
[ModuleId] [int] NOT NULL,
[Name] [nvarchar](256) NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,
[ModifiedOn] [datetime] NOT NULL,
CONSTRAINT [PK_[Owner][Module]] PRIMARY KEY CLUSTERED
(
[[Module]Id] ASC
)
)
GO
/*
Create foreign key relationships
*/
ALTER TABLE [dbo].[[Owner][Module]] WITH CHECK ADD CONSTRAINT [FK_[Owner][Module]_Module] FOREIGN KEY([ModuleId])
REFERENCES [dbo].Module ([ModuleId])
ON DELETE CASCADE
GO

View File

@ -0,0 +1,6 @@
/*
Remove [Owner][Module] table
*/
DROP TABLE [dbo].[[Owner][Module]]
GO

View File

@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>7.3</LangVersion>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<Version>1.0.0</Version>
<Product>[Owner].[Module]s.Module</Product>
<Authors>[Owner]</Authors>
<Company>[Owner]</Company>
<Description>[Description]</Description>
<Copyright>[Owner]</Copyright>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Scripts\[Owner].[Module].1.0.0.sql" />
<EmbeddedResource Include="Scripts\[Owner].[Module].Uninstall.sql" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.0-rc1.20223.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\[Owner].[Module]s.Module.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="Oqtane.Server">
<HintPath>..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\Oqtane.Server.dll</HintPath>
</Reference>
<Reference Include="Oqtane.Shared">
<HintPath>..\..\[RootFolder]\Oqtane.Server\bin\Debug\netcoreapp3.1\Oqtane.Shared.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Oqtane.Models;
namespace [Owner].[Module]s.Models
{
[Table("[Owner][Module]")]
public class [Module] : IAuditable
{
public int [Module]Id { get; set; }
public int ModuleId { get; set; }
public string Name { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string ModifiedBy { get; set; }
public DateTime ModifiedOn { get; set; }
}
}

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>7.3</LangVersion>
<Version>1.0.0</Version>
<Product>[Owner].[Module].Module</Product>
<Authors>[Owner]</Authors>
<Company>[Owner]</Company>
<Description>[Description]</Description>
<Copyright>[Owner]</Copyright>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="Oqtane.Shared">
<HintPath>..\..\[RootFolder]\Oqtane.Shared\bin\Debug\netstandard2.1\Oqtane.Shared.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@ -0,0 +1,52 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28621.142
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Module]s.Module.Client", "Client\[Owner].[Module]s.Module.Client.csproj", "{AA8E58A1-CD09-4208-BF66-A8BB341FD669}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Module]s.Module.Server", "Server\[Owner].[Module]s.Module.Server.csproj", "{04B05448-788F-433D-92C0-FED35122D45A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "[Owner].[Module]s.Module.Shared", "Shared\[Owner].[Module]s.Module.Shared.csproj", "{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "[Owner].[Module]s.Module.Package", "Package\[Owner].[Module]s.Module.Package.csproj", "{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Wasm|Any CPU = Wasm|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Release|Any CPU.Build.0 = Release|Any CPU
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Wasm|Any CPU.ActiveCfg = Release|Any CPU
{AA8E58A1-CD09-4208-BF66-A8BB341FD669}.Wasm|Any CPU.Build.0 = Release|Any CPU
{04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04B05448-788F-433D-92C0-FED35122D45A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04B05448-788F-433D-92C0-FED35122D45A}.Release|Any CPU.Build.0 = Release|Any CPU
{04B05448-788F-433D-92C0-FED35122D45A}.Wasm|Any CPU.ActiveCfg = Release|Any CPU
{04B05448-788F-433D-92C0-FED35122D45A}.Wasm|Any CPU.Build.0 = Release|Any CPU
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Release|Any CPU.Build.0 = Release|Any CPU
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Wasm|Any CPU.ActiveCfg = Release|Any CPU
{18D73F73-D7BE-4388-85BA-FBD9AC96FCA2}.Wasm|Any CPU.Build.0 = Release|Any CPU
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Release|Any CPU.Build.0 = Release|Any CPU
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Wasm|Any CPU.ActiveCfg = Debug|Any CPU
{C5CE512D-CBB7-4545-AF0F-9B6591A0C3A7}.Wasm|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1D016F15-46FE-4726-8DFD-2E4FD4DC7668}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1 @@
This is the location where static resources such as images or style sheets should be located

View File

@ -0,0 +1,95 @@
@using Oqtane.Modules.Controls
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject HttpClient http
@inject SiteState sitestate
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Name: </label>
</td>
<td>
<input id="_name" class="form-control" @bind="@_name" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="Save">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
<br />
<br />
@if (PageState.Action == "Edit")
{
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
public override string Actions => "Add,Edit";
I[Module]Service [Module]Service;
int _id;
string _name;
string _createdby;
DateTime _createdon;
string _modifiedby;
DateTime _modifiedon;
protected override async Task OnInitializedAsync()
{
try
{
[Module]Service = new [Module]Service(http, sitestate);
if (PageState.Action == "Edit")
{
_id = Int32.Parse(PageState.QueryString["id"]);
[Module] [Module] = await [Module]Service.Get[Module]Async(_id);
if ([Module] != null)
{
_name = [Module].Name;
_createdby = [Module].CreatedBy;
_createdon = [Module].CreatedOn;
_modifiedby = [Module].ModifiedBy;
_modifiedon = [Module].ModifiedOn;
}
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading [Module] {[Module]Id} {Error}", _id, ex.Message);
AddModuleMessage("Error Loading [Module]", MessageType.Error);
}
}
private async Task Save()
{
try
{
if (PageState.Action == "Add")
{
[Module] [Module] = new [Module]();
[Module].ModuleId = ModuleState.ModuleId;
[Module].Name = _name;
[Module] = await [Module]Service.Add[Module]Async([Module]);
await logger.LogInformation("[Module] Added {[Module]}", [Module]);
}
else
{
[Module] [Module] = await [Module]Service.Get[Module]Async(_id);
[Module].Name = _name;
await [Module]Service.Update[Module]Async([Module]);
await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
}
NavigationManager.NavigateTo(NavigateUrl());
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving [Module] {Error}", ex.Message);
AddModuleMessage("Error Saving [Module]", MessageType.Error);
}
}
}

View File

@ -0,0 +1,97 @@
@using [Owner].[Module]s.Services
@using [Owner].[Module]s.Models
@namespace [Owner].[Module]s.Modules
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject HttpClient http
@inject SiteState sitestate
@if (_[Module]s == null)
{
<p><em>Loading...</em></p>
}
else
{
<ActionLink Action="Add" Security="SecurityAccessLevel.Edit" Text="Add [Module]" />
<br />
<br />
@if (@_[Module]s.Count != 0)
{
<Pager Items="@_[Module]s" Format="Grid">
<Header>
<div class="col"><strong>[Module]s</strong></div>
</Header>
<Row>
<div class="col">
<ActionLink Action="Edit" Parameters="@($"id=" + context.[Module]Id.ToString())" />
<ActionDialog Header="Delete [Module]" Message="@("Are You Sure You Wish To Delete The " + context.Name + " [Module]?")" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" />
@context.Name
</div>
</Row>
</Pager>
}
else
{
<p>No [Module]s To Display</p>
}
}
<!-- The content below is for informational purposes only and can be safely removed -->
<hr />
[Module] Module Created Successfully. Use Edit Mode To Add A [Module]. You Can Access The Files At The Following Locations:<br /><br />
[RootPath]Oqtane.Client\Modules\[Module]\<br />
- Edit.razor - component for adding or editing content<br />
- Index.razor - main component for your module **the content you are reading is in this file**<br />
- ModuleInfo.cs - implements IModule interface to provide configuration settings for your module<br />
- Settings.razor - component for managing module settings<br />
- Services\I[Module]Service.cs - interface for defining service API methods<br />
- Services\[Module]Service.cs - implements service API interface methods<br /><br />
[RootPath]Oqtane.Server\Modules\[Module]\<br />
- Controllers\[Module]Controller.cs - API methods implemented using a REST pattern<br />
- Manager\[Module]Manager.cs - implements optional module interfaces for features such as import/export of content<br />
- Repository\I[Module]Repository.cs - interface for defining repository methods<br />
- Repository\[Module]Respository.cs - implements repository interface methods for data access using EF Core<br />
- Repository\[Module]Context.cs - provides a DB Context for data access<br />
- Scripts\[Owner].[Module].1.0.0.sql - database schema definition script<br /><br />
- Scripts\[Owner].[Module].Uninstall.sql - database uninstall script<br /><br />
[RootPath]Oqtane.Shared\Modules\[Module]\<br />
- Models\[Module].cs - model definition<br /><br />
<!-- The content above is for informational purposes only and can be safely removed -->
@code {
I[Module]Service [Module]Service;
List<[Module]> _[Module]s;
protected override async Task OnInitializedAsync()
{
try
{
[Module]Service = new [Module]Service(http, sitestate);
_[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading [Module] {Error}", ex.Message);
AddModuleMessage("Error Loading [Module]", MessageType.Error);
}
}
private async Task Delete([Module] [Module])
{
try
{
await [Module]Service.Delete[Module]Async([Module].[Module]Id);
await logger.LogInformation("[Module] Deleted {[Module]}", [Module]);
_[Module]s = await [Module]Service.Get[Module]sAsync(ModuleState.ModuleId);
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting [Module] {[Module]} {Error}", [Module], ex.Message);
AddModuleMessage("Error Deleting [Module]", MessageType.Error);
}
}
}

View File

@ -0,0 +1,18 @@
using Oqtane.Models;
using Oqtane.Modules;
namespace [Owner].[Module]s.Modules
{
public class ModuleInfo : IModule
{
public ModuleDefinition ModuleDefinition => new ModuleDefinition
{
Name = "[Module]",
Description = "[Module]",
Version = "1.0.0",
Dependencies = "[Owner].[Module]s.Module.Shared",
ServerManagerType = "[ServerManagerType]",
ReleaseVersions = "1.0.0"
};
}
}

View File

@ -0,0 +1,19 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Services
{
public interface I[Module]Service
{
Task<List<[Module]>> Get[Module]sAsync(int ModuleId);
Task<[Module]> Get[Module]Async(int [Module]Id);
Task<[Module]> Add[Module]Async([Module] [Module]);
Task<[Module]> Update[Module]Async([Module] [Module]);
Task Delete[Module]Async(int [Module]Id);
}
}

View File

@ -0,0 +1,49 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Oqtane.Modules;
using Oqtane.Services;
using Oqtane.Shared;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Services
{
public class [Module]Service : ServiceBase, I[Module]Service, IService
{
private readonly SiteState _siteState;
public [Module]Service(HttpClient http, SiteState siteState) : base(http)
{
_siteState = siteState;
}
private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]");
public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId)
{
List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>($"{Apiurl}?moduleid={ModuleId}");
return [Module]s.OrderBy(item => item.Name).ToList();
}
public async Task<[Module]> Get[Module]Async(int [Module]Id)
{
return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}");
}
public async Task<[Module]> Add[Module]Async([Module] [Module])
{
return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]);
}
public async Task<[Module]> Update[Module]Async([Module] [Module])
{
return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]);
}
public async Task Delete[Module]Async(int [Module]Id)
{
await DeleteAsync($"{Apiurl}/{[Module]Id}");
}
}
}

View File

@ -0,0 +1,47 @@
@namespace [Owner].[Module]s.Modules
@inherits ModuleBase
@inject ISettingService SettingService
<table class="table table-borderless">
<tr>
<td>
<label for="Setting" class="control-label">Setting: </label>
</td>
<td>
<input type="text" class="form-control" @bind="_value" />
</td>
</tr>
</table>
@code {
public override string Title => "[Module] Settings";
string _value;
protected override async Task OnInitializedAsync()
{
try
{
Dictionary<string, string> settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
_value = SettingService.GetSetting(settings, "SettingName", "");
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
}
}
public async Task UpdateSettings()
{
try
{
Dictionary<string, string> settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
SettingService.SetSetting(settings, "SettingName", _value);
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
}
catch (Exception ex)
{
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
}
}
}

View File

@ -0,0 +1,75 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using System.Collections.Generic;
using Oqtane.Shared;
using Oqtane.Enums;
using Oqtane.Infrastructure;
using [Owner].[Module]s.Models;
using [Owner].[Module]s.Repository;
namespace [Owner].[Module]s.Controllers
{
[Route("{site}/api/[controller]")]
public class [Module]Controller : Controller
{
private readonly I[Module]Repository _[Module]s;
private readonly ILogManager _logger;
public [Module]Controller(I[Module]Repository [Module]s, ILogManager logger)
{
_[Module]s = [Module]s;
_logger = logger;
}
// GET: api/<controller>?moduleid=x
[HttpGet]
[Authorize(Roles = Constants.RegisteredRole)]
public IEnumerable<[Module]> Get(string moduleid)
{
return _[Module]s.Get[Module]s(int.Parse(moduleid));
}
// GET api/<controller>/5
[HttpGet("{id}")]
[Authorize(Roles = Constants.RegisteredRole)]
public [Module] Get(int id)
{
return _[Module]s.Get[Module](id);
}
// POST api/<controller>
[HttpPost]
[Authorize(Roles = Constants.AdminRole)]
public [Module] Post([FromBody] [Module] [Module])
{
if (ModelState.IsValid)
{
[Module] = _[Module]s.Add[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "[Module] Added {[Module]}", [Module]);
}
return [Module];
}
// PUT api/<controller>/5
[HttpPut("{id}")]
[Authorize(Roles = Constants.AdminRole)]
public [Module] Put(int id, [FromBody] [Module] [Module])
{
if (ModelState.IsValid)
{
[Module] = _[Module]s.Update[Module]([Module]);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "[Module] Updated {[Module]}", [Module]);
}
return [Module];
}
// DELETE api/<controller>/5
[HttpDelete("{id}")]
[Authorize(Roles = Constants.AdminRole)]
public void Delete(int id)
{
_[Module]s.Delete[Module](id);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "[Module] Deleted {[Module]Id}", id);
}
}
}

View File

@ -0,0 +1,64 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using Oqtane.Modules;
using Oqtane.Models;
using Oqtane.Infrastructure;
using Oqtane.Repository;
using [Owner].[Module]s.Models;
using [Owner].[Module]s.Repository;
namespace [Owner].[Module]s.Manager
{
public class [Module]Manager : IInstallable, IPortable
{
private I[Module]Repository _[Module]s;
private ISqlRepository _sql;
public [Module]Manager(I[Module]Repository [Module]s, ISqlRepository sql)
{
_[Module]s = [Module]s;
_sql = sql;
}
public bool Install(Tenant tenant, string version)
{
return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module]." + version + ".sql");
}
public bool Uninstall(Tenant tenant)
{
return _sql.ExecuteScript(tenant, GetType().Assembly, "[Owner].[Module].Uninstall.sql");
}
public string ExportModule(Module module)
{
string content = "";
List<[Module]> [Module]s = _[Module]s.Get[Module]s(module.ModuleId).ToList();
if ([Module]s != null)
{
content = JsonSerializer.Serialize([Module]s);
}
return content;
}
public void ImportModule(Module module, string content, string version)
{
List<[Module]> [Module]s = null;
if (!string.IsNullOrEmpty(content))
{
[Module]s = JsonSerializer.Deserialize<List<[Module]>>(content);
}
if ([Module]s != null)
{
foreach([Module] [Module] in [Module]s)
{
[Module] _[Module] = new [Module]();
_[Module].ModuleId = module.ModuleId;
_[Module].Name = [Module].Name;
_[Module]s.Add[Module](_[Module]);
}
}
}
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Repository
{
public interface I[Module]Repository
{
IEnumerable<[Module]> Get[Module]s(int ModuleId);
[Module] Get[Module](int [Module]Id);
[Module] Add[Module]([Module] [Module]);
[Module] Update[Module]([Module] [Module]);
void Delete[Module](int [Module]Id);
}
}

View File

@ -0,0 +1,18 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Http;
using Oqtane.Modules;
using Oqtane.Repository;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Repository
{
public class [Module]Context : DBContextBase, IService
{
public virtual DbSet<[Module]> [Module] { get; set; }
public [Module]Context(ITenantResolver tenantResolver, IHttpContextAccessor accessor) : base(tenantResolver, accessor)
{
// ContextBase handles multi-tenant database connections
}
}
}

View File

@ -0,0 +1,49 @@
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Collections.Generic;
using Oqtane.Modules;
using [Owner].[Module]s.Models;
namespace [Owner].[Module]s.Repository
{
public class [Module]Repository : I[Module]Repository, IService
{
private readonly [Module]Context _db;
public [Module]Repository([Module]Context context)
{
_db = context;
}
public IEnumerable<[Module]> Get[Module]s(int ModuleId)
{
return _db.[Module].Where(item => item.ModuleId == ModuleId);
}
public [Module] Get[Module](int [Module]Id)
{
return _db.[Module].Find([Module]Id);
}
public [Module] Add[Module]([Module] [Module])
{
_db.[Module].Add([Module]);
_db.SaveChanges();
return [Module];
}
public [Module] Update[Module]([Module] [Module])
{
_db.Entry([Module]).State = EntityState.Modified;
_db.SaveChanges();
return [Module];
}
public void Delete[Module](int [Module]Id)
{
[Module] [Module] = _db.[Module].Find([Module]Id);
_db.[Module].Remove([Module]);
_db.SaveChanges();
}
}
}

View File

@ -0,0 +1,26 @@
/*
Create [Owner][Module] table
*/
CREATE TABLE [dbo].[[Owner][Module]](
[[Module]Id] [int] IDENTITY(1,1) NOT NULL,
[ModuleId] [int] NOT NULL,
[Name] [nvarchar](256) NOT NULL,
[CreatedBy] [nvarchar](256) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[ModifiedBy] [nvarchar](256) NOT NULL,
[ModifiedOn] [datetime] NOT NULL,
CONSTRAINT [PK_[Owner][Module]] PRIMARY KEY CLUSTERED
(
[[Module]Id] ASC
)
)
GO
/*
Create foreign key relationships
*/
ALTER TABLE [dbo].[[Owner][Module]] WITH CHECK ADD CONSTRAINT [FK_[Owner][Module]_Module] FOREIGN KEY([ModuleId])
REFERENCES [dbo].Module ([ModuleId])
ON DELETE CASCADE
GO

View File

@ -0,0 +1,6 @@
/*
Remove [Owner][Module] table
*/
DROP TABLE [dbo].[[Owner][Module]]
GO

View File

@ -0,0 +1,19 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Oqtane.Models;
namespace [Owner].[Module]s.Models
{
[Table("[Owner][Module]")]
public class [Module] : IAuditable
{
public int [Module]Id { get; set; }
public int ModuleId { get; set; }
public string Name { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public string ModifiedBy { get; set; }
public DateTime ModifiedOn { get; set; }
}
}

View File

@ -5,22 +5,13 @@
@inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Module: </label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Modules" />
</td>
</tr>
</table>
@if (_packages != null)
{
<hr class="app-rule" />
<div class="mx-auto text-center"><h2>Available Modules</h2></div>
<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>
@ -31,27 +22,42 @@
<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>
<button type="button" class="btn btn-success" @onclick="InstallModules">Install</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
private List<Package> _packages;
List<Package> _packages;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override async Task OnInitializedAsync()
{
try
{
List<ModuleDefinition> moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
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))
@ -80,18 +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);
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);
}
}

View File

@ -3,54 +3,142 @@
@inject IModuleDefinitionService ModuleDefinitionService
@inject NavigationManager NavigationManager
<TabStrip>
<TabPanel Name="Definition">
<table class="table table-borderless">
<tr>
<td>
<label 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 class="control-label">Permissions: </label>
<Label For="description" HelpText="The description of the module">Description: </Label>
</td>
<td>
<PermissionGrid EntityName="ModuleDefinition" PermissionNames=PermissionNames.Utilize Permissions="@_permissions" @ref="_permissionGrid" />
<textarea id="description" class="form-control" @bind="@_description" rows="2"></textarea>
</td>
</tr>
<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 />
<br /><br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
int _moduleDefinitionId;
string _name;
string _permissions;
string _createdby;
DateTime _createdon;
string _modifiedby;
DateTime _modifiedon;
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;
#pragma warning disable 649
PermissionGrid _permissionGrid;
private PermissionGrid _permissionGrid;
#pragma warning restore 649
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnInitializedAsync()
{
try
{
_moduleDefinitionId = Int32.Parse(PageState.QueryString["id"]);
ModuleDefinition moduleDefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
var moduleDefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
if (moduleDefinition != null)
{
_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;
@ -69,7 +157,19 @@
{
try
{
ModuleDefinition moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
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);

View File

@ -41,10 +41,10 @@ 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()
{
@ -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;
}

View File

@ -7,10 +7,10 @@
<tbody>
<tr>
<td>
<label 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>
<textarea id="content" class="form-control" @bind="@_content" rows="5"></textarea>
</td>
</tr>
</tbody>
@ -20,10 +20,11 @@
@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()
{

View File

@ -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>
<textarea id="content" class="form-control" @bind="@_content" rows="5"></textarea>
</td>
</tr>
</tbody>
@ -20,15 +20,14 @@
@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
{

View File

@ -5,22 +5,25 @@
@inject IModuleService ModuleService
@inject IPageModuleService PageModuleService
<TabStrip>
<TabPanel Name="Settings" Heading="Module Settings">
@if (_containers != null)
{
<table class="table table-borderless">
<tbody>
<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">
<select id="container" class="form-control" @bind="@_containerType">
<option value="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in _containers)
{
@ -31,51 +34,61 @@
</tr>
<tr>
<td>
<label for="Name" class="control-label">Permissions: </label>
<Label For="page" HelpText="The page that the module is on">Page: </Label>
</td>
<td>
<PermissionGrid EntityName="Module" PermissionNames="@_permissionNames" Permissions="@_permissions" @ref="_permissionGrid" />
</td>
</tr>
<tr>
<td>
<label for="Page" class="control-label">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>
}
</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 _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";
#pragma warning disable 649
PermissionGrid _permissionGrid;
#pragma warning restore 649
RenderFragment DynamicComponent { get; set; }
object _settings;
private RenderFragment DynamicComponent { get; set; }
protected override async Task OnInitializedAsync()
{
@ -86,36 +99,47 @@
_permissionNames = ModuleState.ModuleDefinition.PermissionNames;
_pageId = ModuleState.PageId.ToString();
_settingsModuleType = Type.GetType(ModuleState.ModuleType);
if (_settingsModuleType != null)
{
var moduleobject = Activator.CreateInstance(_settingsModuleType);
_settingstitle = (string)_settingsModuleType.GetProperty("Title").GetValue(moduleobject, null);
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;
var module = ModuleState;
module.Permissions = _permissionGrid.GetPermissions();
await ModuleService.UpdateModuleAsync(module);
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
pagemodule.PageId = int.Parse(_pageId);
pagemodule.Title = _title;
pagemodule.ContainerType = _containerType;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
Type moduleType = Type.GetType(ModuleState.ModuleType);
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
}
}
NavigationManager.NavigateTo(NavigateUrl());
}

View File

@ -4,33 +4,27 @@
@inject IPageService PageService
@inject IThemeService ThemeService
@if (Themes != null)
<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">&lt;Site Root&gt;</option>
@foreach (Page page in pages)
@foreach (Page page in _pageList)
{
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
}
@ -39,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">&lt;Select Page&gt;</option>
@foreach (Page page in children)
@foreach (Page page in _children)
{
<option value="@(page.PageId)">@(page.Name)</option>
}
@ -65,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>
@ -76,21 +70,87 @@
</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="-">&lt;Select Theme&gt;</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="-">&lt;Select Layout&gt;</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="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>
@ -98,95 +158,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="">&lt;Select Theme&gt;</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="">&lt;Select Layout&gt;</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 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 _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<Theme> Themes;
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 = "";
PermissionGrid permissiongrid;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnInitializedAsync()
{
try
{
Themes = await ThemeService.GetThemesAsync();
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(Themes);
themetype = PageState.Site.DefaultThemeType;
_themetype = PageState.Site.DefaultThemeType;
_layouttype = PageState.Site.DefaultLayoutType;
panelayouts = ThemeService.GetPaneLayoutTypes(Themes, themetype);
layouttype = PageState.Site.DefaultLayoutType;
_themes = ThemeService.GetThemeTypes(_themeList);
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
List<PermissionString> permissionstrings = new List<PermissionString>();
permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.View, Permissions = Constants.AdminRole });
permissionstrings.Add(new PermissionString { PermissionName = PermissionNames.Edit, Permissions = Constants.AdminRole });
permissions = UserSecurity.SetPermissionStrings(permissionstrings);
_permissions = string.Empty;
}
catch (Exception ex)
{
@ -199,20 +235,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);
}
}
@ -221,20 +270,20 @@
{
try
{
themetype = (string)e.Value;
if (themetype != "")
_themetype = (string)e.Value;
if (_themetype != "-")
{
panelayouts = ThemeService.GetPaneLayoutTypes(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);
}
}
@ -244,71 +293,77 @@
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();
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
page.Url = _url;
page.EditMode = (_mode == "edit" ? true : false);
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty;
if (page.ThemeType == PageState.Site.DefaultThemeType)
{
page.ThemeType = "";
page.ThemeType = string.Empty;
}
if (page.LayoutType == PageState.Site.DefaultLayoutType)
{
page.LayoutType = "";
page.LayoutType = string.Empty;
}
page.IsPersonalizable = (ispersonalizable == null ? false : Boolean.Parse(ispersonalizable));
page.Icon = (_icon == null ? string.Empty : _icon);
page.Permissions = _permissionGrid.GetPermissions();
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
page.UserId = null;
page = await PageService.AddPageAsync(page);

View File

@ -4,35 +4,29 @@
@inject IPageService PageService
@inject IThemeService ThemeService
@if (Themes != null)
<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">&lt;Site Root&gt;</option>
@foreach (Page page in pages)
@foreach (Page page in _pageList)
{
if (page.PageId.ToString() == parentid)
if (page.PageId.ToString() == _parentid)
{
<option value="@(page.PageId)" selected>@(new string('-', page.Level * 2))@(page.Name)</option>
}
@ -46,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="=">&lt;Maintain Current Location&gt;</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">&lt;Select Page&gt;</option>
@foreach (Page page in children)
@foreach (Page page in _children)
{
<option value="@(page.PageId)">@(page.Name)</option>
}
@ -76,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>
@ -87,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="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in themes)
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in _themes)
{
if (item.Key == themetype)
if (item.Key == _themetype)
{
<option value="@item.Key" selected>@item.Value</option>
}
@ -130,122 +129,170 @@
</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="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
<select id="Layout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Select Layout&gt;</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="Icon" HelpText="Optionally provide an icon for this page which will be displayed in the site navigation">Icon: </Label>
</td>
<td>
<input class="form-control" @bind="@icon" />
<input id="Icon" class="form-control" @bind="@_icon" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">Permissions: </label>
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
</td>
<td>
<PermissionGrid EntityName="Page" Permissions="@permissions" @ref="permissiongrid" />
<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 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 _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<Theme> Themes;
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
{
Themes = await ThemeService.GetThemesAsync();
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(Themes);
_themes = ThemeService.GetThemeTypes(_themeList);
PageId = Int32.Parse(PageState.QueryString["id"]);
Page page = PageState.Pages.FirstOrDefault(item => item.PageId == PageId);
_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(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;
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_layouttype = page.LayoutType;
if (_themetype == PageState.Site.DefaultThemeType)
{
_themetype = "-";
}
if (_layouttype == PageState.Site.DefaultLayoutType)
{
_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;
}
}
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);
}
}
@ -254,28 +301,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);
}
}
@ -284,20 +344,20 @@
{
try
{
themetype = (string)e.Value;
if (themetype != "")
_themetype = (string)e.Value;
if (_themetype != "-")
{
panelayouts = ThemeService.GetPaneLayoutTypes(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);
}
}
@ -307,52 +367,54 @@
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();
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.ParentId = Int32.Parse(_parentid);
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
if (parent.Path == "")
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.FirstOrDefault(item => item.PageId == childid);
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
if (child != null) page.Order = child.Order - 1;
break;
case ">":
child = PageState.Pages.FirstOrDefault(item => item.PageId == childid);
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
if (child != null) page.Order = child.Order + 1;
break;
case ">>":
@ -360,37 +422,37 @@
break;
}
}
page.IsNavigation = (isnavigation == null ? true : Boolean.Parse(isnavigation));
page.EditMode = (mode == "edit" ? true : false);
page.ThemeType = themetype;
page.LayoutType = layouttype ?? "";
page.Icon = icon ?? "";
page.Permissions = permissiongrid.GetPermissions();
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
page.Url = _url;
page.EditMode = (_mode == "edit");
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
page.LayoutType = (_layouttype != "-") ? _layouttype : string.Empty;
if (page.ThemeType == PageState.Site.DefaultThemeType)
{
page.ThemeType = "";
page.ThemeType = string.Empty;
}
if (page.LayoutType == PageState.Site.DefaultLayoutType)
{
page.LayoutType = "";
page.LayoutType = string.Empty;
}
page.IsPersonalizable = (ispersonalizable != null && Boolean.Parse(ispersonalizable));
page.Icon = _icon ?? string.Empty;
page.Permissions = _permissionGrid.GetPermissions();
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
page.UserId = null;
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)))
{
@ -404,7 +466,7 @@
}
else
{
AddModuleMessage("You Must Provide Page Name And Theme", MessageType.Warning);
AddModuleMessage("You Must Provide Page Name", MessageType.Warning);
}
}
catch (Exception ex)

View File

@ -22,13 +22,14 @@
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
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"));

View File

@ -6,66 +6,66 @@
<table class="table table-borderless">
<tr>
<td>
<label 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 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 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>
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
</td>
</tr>
<tr>
<td>
<label 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 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 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 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 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 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()
{
@ -108,7 +109,7 @@
if (PageState.QueryString.ContainsKey("id"))
{
_profileid = Int32.Parse(PageState.QueryString["id"]);
Profile profile = await ProfileService.GetProfileAsync(_profileid);
var profile = await ProfileService.GetProfileAsync(_profileid);
if (profile != null)
{
_name = profile.Name;
@ -143,6 +144,7 @@
{
profile = new Profile();
}
profile.Name = _name;
profile.Title = _title;
profile.Description = _description;
@ -152,7 +154,14 @@
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());
}

View File

@ -25,9 +25,9 @@ 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()
{

View File

@ -5,24 +5,8 @@
@inject IModuleService ModuleService
@inject IPageService PageService
<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="#Pages" role="tab">
Pages
</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#Modules" role="tab">
Modules
</a>
</li>
</ul>
<div class="tab-content">
<div id="Pages" class="tab-pane fade show active" role="tabpanel">
<TabStrip>
<TabPanel Name="Pages">
@if (_pages == null)
{
<br />
@ -47,8 +31,8 @@
</Row>
</Pager>
}
</div>
<div id="Modules" class="tab-pane fade" role="tabpanel">
</TabPanel>
<TabPanel Name="Modules">
@if (_modules == null)
{
<br />
@ -75,16 +59,14 @@
</Row>
</Pager>
}
</div>
</div>
</div>
</div>
</TabPanel>
</TabStrip>
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Admin; } }
private List<Page> _pages;
private List<Module> _modules;
List<Page> _pages;
List<Module> _modules;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnInitializedAsync()
{
@ -147,7 +129,7 @@
{
try
{
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(module.PageModuleId);
var pagemodule = await PageModuleService.GetPageModuleAsync(module.PageModuleId);
pagemodule.IsDeleted = false;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await logger.LogInformation("Module Restored {Module}", module);
@ -168,10 +150,12 @@
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(module.ModuleId);
}
await logger.LogInformation("Module Permanently Deleted {Module}", module);
await Load();
StateHasChanged();

View File

@ -3,10 +3,17 @@
@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="form-group">
@ -32,31 +39,38 @@
<button type="button" class="btn btn-primary" @onclick="Register">Register</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
</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)
{
User user = new User
var user = new User
{
SiteId = PageState.Site.SiteId,
Username = _username,
DisplayName = (_displayName == "" ? _username : _displayName),
DisplayName = (_displayName == string.Empty ? _username : _displayName),
Email = _email,
Password = _password
};
@ -92,6 +106,6 @@
private void Cancel()
{
NavigationManager.NavigateTo(NavigateUrl(""));
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
}
}

View File

@ -21,11 +21,11 @@
</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()
{
@ -35,7 +35,7 @@
}
else
{
NavigationManager.NavigateTo(NavigateUrl(""));
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
}
}
@ -43,11 +43,11 @@
{
try
{
if (_username != "" && _password != "" && _confirm != "")
if (_username != string.Empty && _password != string.Empty && _confirm != string.Empty)
{
if (_password == _confirm)
{
User user = new User
var user = new User
{
SiteId = PageState.Site.SiteId,
Username = _username,
@ -85,6 +85,6 @@
private void Cancel()
{
NavigationManager.NavigateTo(NavigateUrl(""));
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
}
}

View File

@ -6,37 +6,26 @@
<table class="table table-borderless">
<tr>
<td>
<label 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 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>
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
</td>
</tr>
<tr>
<td>
<label 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 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
{

View File

@ -6,37 +6,26 @@
<table class="table table-borderless">
<tr>
<td>
<label 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 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>
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
</td>
</tr>
<tr>
<td>
<label 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 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,26 +36,24 @@
<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);
var role = await RoleService.GetRoleAsync(_roleid);
if (role != null)
{
_name = role.Name;
_description = role.Description;
_isautoassigned = role.IsAutoAssigned.ToString();
_issystem = role.IsSystem.ToString();
}
}
catch (Exception ex)
@ -78,11 +65,11 @@
private async Task SaveRole()
{
Role role = await RoleService.GetRoleAsync(_roleid);
var role = await RoleService.GetRoleAsync(_roleid);
role.Name = _name;
role.Description = _description;
role.IsAutoAssigned = (_isautoassigned != null && Boolean.Parse(_isautoassigned));
role.IsSystem = (_issystem != null && Boolean.Parse(_issystem));
role.IsSystem = false;
try
{

View File

@ -12,22 +12,24 @@ else
<Pager Items="@_roles">
<Header>
<th>&nbsp;</th>
<th>&nbsp;</th>
<th>&nbsp;</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()
{

View 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">&lt;Select User&gt;</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>&nbsp;</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);
}
}
}

View File

@ -7,51 +7,59 @@
@inject IThemeService ThemeService
@inject ISettingService SettingService
@if (themes != null)
@if (_themes != null)
{
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Name: </label>
<Label For="name" HelpText="Enter the site name">Name: </Label>
</td>
<td>
<input class="form-control" @bind="@name" />
<input id="name" class="form-control" @bind="@_name" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Tenant: </label>
<Label For="tenant" HelpText="Enter the tenant for the site">Tenant: </Label>
</td>
<td>
<input class="form-control" @bind="@tenant" readonly />
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
</td>
</tr>
<tr>
<td>
<label class="control-label">Aliases: </label>
<Label For="alias" HelpText="Enter the alias for the server">Aliases: </Label>
</td>
<td>
<textarea class="form-control" @bind="@urls" rows="3"></textarea>
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
</td>
</tr>
<tr>
<td>
<label class="control-label">Logo: </label>
<Label For="logo" HelpText="Upload a logo for the site">Logo: </Label>
</td>
<td>
<FileManager FileId="@logofileid.ToString()" @ref="filemanager" />
<FileManager FileId="@_logofileid.ToString()" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Default Theme: </label>
<Label For="favicon" HelpText="Select Your default icon">Favicon: </Label>
</td>
<td>
<select class="form-control" @onchange="(e => ThemeChanged(e))">
<FileManager FileId="@_faviconfileid.ToString()" 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="">&lt;Select Theme&gt;</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>
}
@ -65,12 +73,12 @@
</tr>
<tr>
<td>
<label class="control-label">Default Layout: </label>
<Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label>
</td>
<td>
<select class="form-control" @bind="@layouttype">
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
<option value="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
@ -79,12 +87,12 @@
</tr>
<tr>
<td>
<label 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="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in containers)
@foreach (KeyValuePair<string, string> container in _containers)
{
<option value="@container.Key">@container.Value</option>
}
@ -93,10 +101,21 @@
</tr>
<tr>
<td>
<label class="control-label">Is Deleted? </label>
<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 class="form-control" @bind="@isdeleted">
<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>
@ -104,137 +123,200 @@
</tr>
</table>
<a data-toggle="collapse" class="app-link-unstyled" href="#SMTP" aria-expanded="false" aria-controls="SMTP">
<h5><i class="oi oi-chevron-bottom"></i>&nbsp;SMTP Settings</h5><hr class="app-rule" />
</a>
<div class="collapse" id="SMTP">
<Section Name="SMTP" Heading="SMTP Settings">
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Host: </label>
<Label For="host" HelpText="Enter the host name of the server">Host: </Label>
</td>
<td>
<input class="form-control" @bind="@smtphost" />
<input id="host" class="form-control" @bind="@_smtphost" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Port: </label>
<Label For="port" HelpText="Enter the port number for the server">Port: </Label>
</td>
<td>
<input class="form-control" @bind="@smtpport" />
<input id="port" class="form-control" @bind="@_smtpport" />
</td>
</tr>
<tr>
<td>
<label class="control-label">SSL Enabled: </label>
<Label For="enabledSSl" HelpText="Specifiy if SSL is enabled for your server">SSL Enabled: </Label>
</td>
<td>
<input class="form-control" @bind="@smtpssl" />
<input id="enabledSSl" class="form-control" @bind="@_smtpssl" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Username: </label>
<Label For="username" HelpText="Enter the username for the server">Username: </Label>
</td>
<td>
<input class="form-control" @bind="@smtpusername" />
<input id="username" class="form-control" @bind="@_smtpusername" />
</td>
</tr>
<tr>
<td>
<label class="control-label">Password: </label>
<Label For="password" HelpText="Enter the password for the server">Password: </Label>
</td>
<td>
<input type="password" class="form-control" @bind="@smtppassword" />
<input id="password" type="password" class="form-control" @bind="@_smtppassword" />
</td>
</tr>
</table>
</div>
</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.ToString()" 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.ToString()" 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>
<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;
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;
Dictionary<string, string> themes;
Dictionary<string, string> panelayouts;
Dictionary<string, string> containers;
List<Theme> Themes;
string name = "";
List<Tenant> tenants;
string tenant = "";
List<Alias> aliases;
string urls = "";
int logofileid = -1;
FileManager filemanager;
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.Admin;
protected override async Task OnInitializedAsync()
{
try
{
Themes = await ThemeService.GetThemesAsync();
aliases = await AliasService.GetAliasesAsync();
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId, PageState.Alias);
_themeList = await ThemeService.GetThemesAsync();
_aliasList = await AliasService.GetAliasesAsync();
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null)
{
name = site.Name;
tenants = await TenantService.GetTenantsAsync();
tenant = tenants.Find(item => item.TenantId == site.TenantId).Name;
foreach (Alias alias in aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
_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";
}
if (site.LogoFileId != null)
{
logofileid = site.LogoFileId.Value;
}
themetype = site.DefaultThemeType;
panelayouts = ThemeService.GetPaneLayoutTypes(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();
_logofileid = site.LogoFileId.Value;
}
themes = ThemeService.GetThemeTypes(Themes);
containers = ThemeService.GetContainerTypes(Themes);
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)
{
@ -247,20 +329,20 @@
{
try
{
themetype = (string)e.Value;
if (themetype != "")
_themetype = (string)e.Value;
if (_themetype != string.Empty)
{
panelayouts = ThemeService.GetPaneLayoutTypes(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);
}
}
@ -269,47 +351,65 @@
{
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))
{
bool unique = true;
foreach (string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
var unique = true;
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
if (aliases.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
{
unique = false;
}
}
if (unique)
{
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId, PageState.Alias);
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null)
{
site.Name = name;
site.Name = _name;
site.LogoFileId = null;
int logofileid = filemanager.GetFileId();
var logofileid = _logofilemanager.GetFileId();
if (logofileid != -1)
{
site.LogoFileId = logofileid;
}
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site.DefaultContainerType = containertype;
site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
site = await SiteService.UpdateSiteAsync(site, PageState.Alias);
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));
urls = urls.Replace("\n", ",");
string[] names = urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (Alias alias in aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
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 (!aliases.Exists(item => item.Name == name))
if (!_aliasList.Exists(item => item.Name == name))
{
Alias alias = new Alias();
alias.Name = name;
@ -319,12 +419,12 @@
}
}
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);
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);

View File

@ -5,7 +5,9 @@
@inject IAliasService AliasService
@inject ISiteService SiteService
@inject IThemeService ThemeService
@inject ISiteTemplateService SiteTemplateService
@inject IUserService UserService
@inject IInstallationService InstallationService
@if (_tenants == null)
{
@ -16,40 +18,26 @@ else
<table class="table table-borderless">
<tr>
<td>
<label 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">&lt;Select Tenant&gt;</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 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 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"></textarea>
</td>
</tr>
<tr>
<td>
<label 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="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in _themes)
{
@ -60,10 +48,10 @@ else
</tr>
<tr>
<td>
<label 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="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
{
@ -74,10 +62,10 @@ else
</tr>
<tr>
<td>
<label 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="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in _containers)
{
@ -86,22 +74,121 @@ else
</select>
</td>
</tr>
@if (!_isinitialized)
{
<tr>
<td>
<label 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="">&lt;Select Site Template&gt;</option>
@foreach (SiteTemplate siteTemplate in _siteTemplates)
{
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option>
}
</select>
</td>
</tr>
<tr>
<td>
<label 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="-">&lt;Select Tenant&gt;</option>
<option value="+">&lt;Create New Tenant&gt;</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>
}
@ -111,23 +198,32 @@ 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<Theme> _themeList;
List<Tenant> _tenants;
string _tenantid = "-1";
string _name = "";
string _urls = "";
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()
{
@ -136,29 +232,30 @@ else
_urls = PageState.Alias.Name;
_themes = ThemeService.GetThemeTypes(_themeList);
_containers = ThemeService.GetContainerTypes(_themeList);
_username = Constants.HostUser;
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
}
private async void TenantChanged(ChangeEventArgs e)
{
try
private void TenantChanged(ChangeEventArgs e)
{
_tenantid = (string)e.Value;
if (_tenantid != "-1")
if (string.IsNullOrEmpty(_tenantname))
{
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)
@ -166,7 +263,7 @@ else
try
{
_themetype = (string)e.Value;
if (_themetype != "")
if (_themetype != string.Empty)
{
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
}
@ -174,6 +271,7 @@ else
{
_panelayouts = new Dictionary<string, string>();
}
StateHasChanged();
}
catch (Exception ex)
@ -185,99 +283,121 @@ else
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 unique = true;
List<Alias> aliases = await AliasService.GetAliasesAsync();
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))
{
unique = false;
duplicates.Add(name);
}
}
if (unique)
{
bool isvalid = true;
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)
{
ShowProgressIndicator();
aliases = new List<Alias>();
_urls = _urls.Replace("\n", ",");
foreach (string name in _urls.Split(new[] { ',' }, 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.LogoFileId = null;
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.FirstOrDefault(item => item.TenantId == int.Parse(_tenantid));
tenant.IsInitialized = true;
await TenantService.UpdateTenantAsync(tenant);
}
}
await Log(aliases[0], LogLevel.Information, "", null, "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("An Alias Specified Has Already Been Used For Another Site", MessageType.Warning);
AddModuleMessage("Tenant Name Is Missing Or Already Exists", MessageType.Error);
}
}
else
{
AddModuleMessage("You Must Provide A Tenant, Site Name, Alias, And Default Theme/Container", MessageType.Warning);
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);
}
}
}

View File

@ -6,43 +6,43 @@
@inject IAliasService AliasService
@inject IThemeService ThemeService
@if (themes != null)
@if (_themes != null)
{
<table class="table table-borderless">
<tr>
<td>
<label 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 class="control-label">Tenant: </label>
<Label For="tenant" HelpText="Enter the tenant for the site">Tenant: </Label>
</td>
<td>
<input class="form-control" @bind="@tenant" readonly />
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
</td>
</tr>
<tr>
<td>
<label class="control-label">Aliases: </label>
<Label For="alias" HelpText="Enter the alias for the server">Aliases: </Label>
</td>
<td>
<textarea class="form-control" @bind="@urls" rows="3" />
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" />
</td>
</tr>
<tr>
<td>
<label 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="">&lt;Select Theme&gt;</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>
}
@ -56,12 +56,12 @@
</tr>
<tr>
<td>
<label 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="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in panelayouts)
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
@ -70,12 +70,12 @@
</tr>
<tr>
<td>
<label 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="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in containers)
@foreach (KeyValuePair<string, string> container in _containers)
{
<option value="@container.Key">@container.Value</option>
}
@ -84,10 +84,10 @@
</tr>
<tr>
<td>
<label 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>
@ -99,73 +99,73 @@
<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;
Dictionary<string, string> panelayouts;
Dictionary<string, string> containers;
Alias Alias;
List<Theme> Themes;
string name = "";
List<Tenant> tenants;
string tenant = "";
List<Alias> aliases;
string urls = "";
string themetype;
string layouttype;
string containertype;
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 = await ThemeService.GetThemesAsync();
aliases = await AliasService.GetAliasesAsync();
_themeList = await ThemeService.GetThemesAsync();
_aliasList = await AliasService.GetAliasesAsync();
Alias = aliases.Find(item => item.AliasId == Int32.Parse(PageState.QueryString["id"]));
Site site = await SiteService.GetSiteAsync(Alias.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;
tenants = await TenantService.GetTenantsAsync();
tenant = tenants.Find(item => item.TenantId == site.TenantId).Name;
foreach (Alias alias in aliases.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
_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";
}
themetype = site.DefaultThemeType;
panelayouts = ThemeService.GetPaneLayoutTypes(Themes, 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();
_urls += alias.Name + "\n";
}
themes = ThemeService.GetThemeTypes(Themes);
containers = ThemeService.GetContainerTypes(Themes);
_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 Log(Alias, LogLevel.Error, "", ex, "Error Loading Site {SiteId} {Error}", Alias.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);
}
}
@ -174,20 +174,21 @@
{
try
{
themetype = (string)e.Value;
if (themetype != "")
_themetype = (string)e.Value;
if (_themetype != string.Empty)
{
panelayouts = ThemeService.GetPaneLayoutTypes(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);
}
}
@ -196,52 +197,58 @@
{
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))
{
bool unique = true;
foreach (string name in urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
var unique = true;
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
if (aliases.Exists(item => item.Name == name && item.SiteId != Alias.SiteId && item.TenantId != Alias.TenantId))
if (_aliasList.Exists(item => item.Name == name && item.SiteId != _alias.SiteId && item.TenantId != _alias.TenantId))
{
unique = false;
}
}
if (unique)
{
Site site = await SiteService.GetSiteAsync(Alias.SiteId, Alias);
SiteService.SetAlias(_alias);
var site = await SiteService.GetSiteAsync(_alias.SiteId);
if (site != null)
{
site.Name = name;
site.Name = _name;
site.LogoFileId = null;
site.DefaultThemeType = themetype;
site.DefaultLayoutType = (layouttype == null ? "" : layouttype);
site.DefaultContainerType = containertype;
site.IsDeleted = (isdeleted == null ? true : Boolean.Parse(isdeleted));
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.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
_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);
}
}
await Log(Alias, LogLevel.Information,PermissionNames.Edit, null, "Site Saved {Site}", site);
await Log(_alias, LogLevel.Information,PermissionNames.Edit, null, "Site Saved {Site}", site);
NavigationManager.NavigateTo(NavigateUrl());
}
@ -258,7 +265,7 @@
}
catch (Exception ex)
{
await Log(Alias, LogLevel.Error, "", ex, "Error Saving Site {SiteId} {Error}", Alias.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);
}
}

View File

@ -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>&nbsp;</th>
<th>&nbsp;</th>
@ -21,46 +21,49 @@ else
<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.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteSite(context))" /></td>
<td><a href="@(scheme + context.Name)">@context.Name</a></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 async Task OnParametersSetAsync()
{
Uri uri = new Uri(NavigationManager.Uri);
scheme = uri.Scheme + "://";
var uri = new Uri(NavigationManager.Uri);
_scheme = uri.Scheme + "://";
List<Alias> aliases = await AliasService.GetAliasesAsync();
sites = new List<Alias>();
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
{
if (Alias.SiteId != PageState.Site.SiteId || Alias.TenantId != PageState.Site.TenantId)
if (alias.SiteId != PageState.Site.SiteId || alias.TenantId != PageState.Site.TenantId)
{
await SiteService.DeleteSiteAsync(Alias.SiteId, Alias);
await Log(Alias, LogLevel.Information, "", null, "Site Deleted {SiteId}", Alias.SiteId);
List<Alias> aliases = await AliasService.GetAliasesAsync();
foreach (Alias alias in aliases.Where(item => item.SiteId == Alias.SiteId && item.TenantId == Alias.TenantId).ToList())
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(alias.AliasId);
await AliasService.DeleteAliasAsync(a.AliasId);
}
NavigationManager.NavigateTo(NavigateUrl());
}
else
@ -70,7 +73,7 @@ else
}
catch (Exception ex)
{
await Log(Alias, LogLevel.Error, "", ex, "Error Deleting Site {SiteId} {Error}", Alias.SiteId, ex.Message);
await Log(alias, LogLevel.Error, "", ex, "Error Deleting Site {SiteId} {Error}", alias.SiteId, ex.Message);
AddModuleMessage("Error Deleting Site", MessageType.Error);
}
}

View 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">&lt;Select Tenant&gt;</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;
}
}

View 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" disabled />
</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" disabled />
</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" disabled />
</td>
</tr>
<tr>
<td>
<Label For="osversion" HelpText="Operating System Version">OS Version: </Label>
</td>
<td>
<input id="osversion" class="form-control" @bind="@_osversion" disabled />
</td>
</tr>
<tr>
<td>
<Label For="serverpath" HelpText="Server Path">Server Path: </Label>
</td>
<td>
<input id="serverpath" class="form-control" @bind="@_serverpath" disabled />
</td>
</tr>
<tr>
<td>
<Label For="servertime" HelpText="Server Time">Server Time: </Label>
</td>
<td>
<input id="servertime" class="form-control" @bind="@_servertime" disabled />
</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"];
}
}
}

View File

@ -1,154 +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 class="control-label">Name: </label>
</td>
<td>
<input class="form-control" @bind="@name" />
</td>
</tr>
<tr>
<td>
<label for="Title" class="control-label">Database Type: </label>
</td>
<td>
<select class="custom-select" @bind="@type">
<option value="LocalDB">Local Database</option>
<option value="SQLServer">SQL Server</option>
</select>
</td>
</tr>
<tr>
<td>
<label for="Title" class="control-label">Server: </label>
</td>
<td>
<input type="text" class="form-control" @bind="@server" />
</td>
</tr>
<tr>
<td>
<label for="Title" class="control-label">Database: </label>
</td>
<td>
<input type="text" class="form-control" @bind="@database" />
</td>
</tr>
<tr>
<td>
<label for="Title" class="control-label">Integrated Security: </label>
</td>
<td>
<select class="custom-select" @onchange="SetIntegratedSecurity">
<option value="true" selected>True</option>
<option value="false">False</option>
</select>
</td>
</tr>
<tr style="@integratedsecurity">
<td>
<label for="Title" class="control-label">Username: </label>
</td>
<td>
<input type="text" class="form-control" @bind="@username" />
</td>
</tr>
<tr style="@integratedsecurity">
<td>
<label for="Title" class="control-label">Password: </label>
</td>
<td>
<input type="password" class="form-control" @bind="@password" />
</td>
</tr>
<tr>
<td>
<label 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 type = "LocalDB";
string server = "(LocalDb)\\MSSQLLocalDB";
string database = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
string username = "";
string password = "";
string schema = "";
string integratedsecurity = "display: none;";
private void SetIntegratedSecurity(ChangeEventArgs e)
{
if (Convert.ToBoolean((string)e.Value))
{
integratedsecurity = "display: none;";
}
else
{
integratedsecurity = "";
}
}
private async Task SaveTenant()
{
if (!string.IsNullOrEmpty(name))
{
ShowProgressIndicator();
string connectionstring = "";
if (type == "LocalDB")
{
connectionstring = "Data Source=" + server + ";AttachDbFilename=|DataDirectory|\\" + database + ".mdf;Initial Catalog=" + database + ";Integrated Security=SSPI;";
}
else
{
connectionstring = "Data Source=" + server + ";Initial Catalog=" + database + ";";
if (integratedsecurity == "display: none;")
{
connectionstring += "Integrated Security=SSPI;";
}
else
{
connectionstring += "User ID=" + username + ";Password=" + password;
}
}
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);
}
}
else
{
AddModuleMessage("You Must Provide A Name For The Tenant", MessageType.Warning);
}
}
}

View File

@ -6,51 +6,50 @@
<table class="table table-borderless">
<tr>
<td>
<label 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 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 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);

View File

@ -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>&nbsp;</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);

View File

@ -5,23 +5,14 @@
@inject IThemeService ThemeService
@inject IPackageService PackageService
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Theme: </label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Themes" />
</td>
</tr>
</table>
@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>
@ -31,43 +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>
<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;
List<Package> packages;
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);
}
}
}
catch (Exception ex)
{
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());
}
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);
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);
}
}
}

View File

@ -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;
}

View File

@ -5,42 +5,55 @@
@inject IPackageService PackageService
@inject IInstallationService InstallationService
@if (_package != null)
{
<TabStrip>
<TabPanel Name="Download">
@if (_upgradeavailable)
{
<ModuleMessage Type="MessageType.Info" Message="Download a new version of the framework. Once you are ready click Install to complete the installation."></ModuleMessage>
@("Framework") @_package.Version <button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Download</button>
}
else
{
<ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage>
}
</TabPanel>
@if (_upgradeavailable)
{
<TabPanel Name="Upload">
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">Framework: </label>
<Label HelpText="Upload a new framework package. Once it is uploaded click Install to complete the installation.">Framework: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Framework" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="Upgrade">Upgrade</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>
</TabPanel>
}
</TabStrip>
}
@code {
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
private Package _package;
private bool _upgradeavailable = false;
bool upgradeavailable = false;
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);
_upgradeavailable = (Version.Parse(_package.Version).CompareTo(Version.Parse(Constants.Version)) > 0);
}
if (!upgradeavailable)
else
{
AddModuleMessage("Framework Is Up To Date", MessageType.Info);
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
}
}

View File

@ -9,10 +9,10 @@
<table class="table table-borderless">
<tr>
<td>
<label 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">&lt;Select User&gt;</option>
@if (userroles != null)
{
@ -26,18 +26,18 @@
</tr>
<tr>
<td>
<label 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 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;

View File

@ -6,27 +6,7 @@
@inject ISettingService SettingService
@inject INotificationService NotificationService
@if (PageState.User != null && profiles != null)
{
<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">
@if (photofileid != -1)
@if (PageState.User != null && photofileid != -1)
{
<img src="@(ContentUrl(photofileid))" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
@ -34,6 +14,10 @@
{
<br />
}
<TabStrip>
<TabPanel Name="Identity">
@if (PageState.User != null)
{
<table class="table table-borderless">
<tr>
<td>
@ -83,7 +67,15 @@
<FileManager FileId="@photofileid.ToString()" @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;
@ -108,10 +100,11 @@
</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")
@ -165,27 +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 = "";
FileManager filemanager;
int photofileid = -1;
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()
{
@ -196,12 +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
@ -223,29 +217,29 @@
}
private string GetProfileValue(string SettingName, string DefaultValue)
{
return SettingService.GetSetting(settings, SettingName, DefaultValue);
}
=> SettingService.GetSetting(settings, SettingName, DefaultValue);
private async Task Save()
{
try
{
if (username != "" && 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");
@ -269,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);
}
@ -291,6 +285,7 @@
{
await NotificationService.DeleteNotificationAsync(Notification.NotificationId);
}
await logger.LogInformation("Notification Deleted {Notification}", Notification);
await LoadNotificationsAsync();
StateHasChanged();
@ -305,6 +300,7 @@
private async void FilterChanged(ChangeEventArgs e)
{
filter = (string)e.Value;
await LoadNotificationsAsync();
StateHasChanged();
}

View File

@ -52,7 +52,7 @@
</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,11 +133,11 @@
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;

View File

@ -5,6 +5,8 @@
@inject IProfileService ProfileService
@inject ISettingService SettingService
<TabStrip>
<TabPanel Name="Identity">
@if (profiles != null)
{
<table class="table table-borderless">
@ -48,7 +50,13 @@
<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;
@ -71,21 +79,24 @@
</tr>
}
</table>
}
</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,11 +116,11 @@
{
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;
@ -150,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);
}

View File

@ -5,9 +5,7 @@
@inject IProfileService ProfileService
@inject ISettingService SettingService
@if (profiles != null)
{
@if (photofileid != -1)
@if (PageState.User != null && photofileid != -1)
{
<img src="@(ContentUrl(photofileid))" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
@ -15,6 +13,10 @@
{
<br />
}
<TabStrip>
<TabPanel Name="Identity">
@if (profiles != null)
{
<table class="table table-borderless">
<tr>
<td>
@ -64,7 +66,24 @@
<FileManager FileId="@photofileid.ToString()" @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;
@ -86,46 +105,37 @@
</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>
</TabStrip>
<button type="button" class="btn btn-primary" @onclick="SaveUser">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
<br />
<br />
<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 = "";
FileManager filemanager;
int photofileid = -1;
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()
{
@ -134,16 +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;
@ -162,19 +174,17 @@
}
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;
@ -182,10 +192,12 @@
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);
@ -213,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);
}

View File

@ -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);

View File

@ -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 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">&lt;Select Role&gt;</option>
@foreach (Role role in roles)
{
@ -26,18 +35,18 @@ else
</tr>
<tr>
<td>
<label 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 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>&nbsp;</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);

View File

@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Controls
@inherits ModuleBase
@if (visible)
@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,19 +26,24 @@
</div>
</div>
}
@if (authorized)
@if (_authorized)
{
if (Disabled)
{
<button class="@Class" disabled @onclick="DisplayModal">@Text</button>
<button class="@Class" disabled>@((MarkupString)_iconSpan) @Text</button>
}
else
{
<button class="@Class" @onclick="DisplayModal">@Text</button>
<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
@ -66,9 +71,8 @@
[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()
{
@ -82,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>&nbsp;";
}
_authorized = IsAuthorized();
}
private bool IsAuthorized()
{
bool authorized = false;
if (PageState.EditMode || !editmode)
if (PageState.EditMode || !_editmode)
{
SecurityAccessLevel security = SecurityAccessLevel.Host;
if (Security == null)
@ -135,7 +145,7 @@
private void DisplayModal()
{
visible = !visible;
_visible = !_visible;
StateHasChanged();
}

View File

@ -2,19 +2,28 @@
@inherits ModuleBase
@inject IUserService UserService
@if (authorized)
@if (_authorized)
{
if (Disabled)
{
<NavLink class="@classname" href="@url" style="@style" disabled>@text</NavLink>
<button class="@_classname" style="@_style" disabled>@((MarkupString)_iconSpan) @_text</button>
}
else
{
<NavLink class="@classname" href="@url" style="@style">@text</NavLink>
<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
@ -39,56 +48,56 @@
[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>&nbsp;";
}
_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);
@ -104,6 +113,7 @@
{
security = Security.Value;
}
switch (security)
{
case SecurityAccessLevel.Anonymous:
@ -123,6 +133,7 @@
break;
}
}
return authorized;
}
}

View File

@ -1,12 +1,15 @@
@namespace Oqtane.Modules.Controls
@inherits ModuleBase
@if (text != "")
@if (_text != string.Empty)
{
@((MarkupString)@text)
@((MarkupString)_text)
}
@code {
private string _text = string.Empty;
[Parameter]
public string CreatedBy { get; set; }
@ -31,51 +34,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>";
}
}
}

View File

@ -2,11 +2,11 @@
@inherits ModuleBase
@inject IFolderService FolderService
@inject IFileService FileService
@inject IJSRuntime jsRuntime
@inject IJSRuntime JsRuntime
@if (folders != null)
@if (_folders != null)
{
<div class="container-fluid px-0">
<div id="@Id" class="container-fluid px-0">
<div class="row">
<div class="col">
<div>
@ -15,9 +15,9 @@
{
<option value="-1">&lt;Select Folder&gt;</option>
}
@foreach (Folder folder in folders)
@foreach (Folder folder in _folders)
{
if (folder.FolderId == folderid)
if (folder.FolderId == _folderid)
{
<option value="@(folder.FolderId)" selected>@(new string('-', folder.Level * 2))@(folder.Name)</option>
}
@ -28,14 +28,14 @@
}
</select>
</div>
@if (showfiles)
@if (_showfiles)
{
<div>
<select class="form-control" @onchange="(e => FileChanged(e))">
<option value="-1">&lt;Select File&gt;</option>
@foreach (File file in files)
@foreach (File file in _files)
{
if (file.FileId == fileid)
if (file.FileId == _fileid)
{
<option value="@(file.FileId)" selected>@(file.Name)</option>
}
@ -47,33 +47,33 @@
</select>
</div>
}
@if (haseditpermission)
@if (_haseditpermission)
{
<div>
@if (uploadmultiple)
@if (_uploadmultiple)
{
<input type="file" id="@fileinputid" name="file" accept="@filter" multiple />
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple />
}
else
{
<input type="file" id="@fileinputid" name="file" accept="@filter" />
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
}
<span id="@progressinfoid"></span><progress id="@progressbarid" style="width: 150px; visibility: hidden;"></progress>
<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)
@if (_showfiles && GetFileId() != -1)
{
<button type="button" class="btn btn-danger" @onclick="DeleteFile">Delete</button>
}
</span>
</div>
@((MarkupString)@message)
@((MarkupString)_message)
}
</div>
@if (@image != "")
@if (_image != string.Empty)
{
<div class="col-auto">
@((MarkupString)@image)
@((MarkupString)_image)
</div>
}
</div>
@ -81,6 +81,25 @@
}
@code {
private string _id;
private List<Folder> _folders;
private int _folderid = -1;
private List<File> _files = new List<File>();
private int _fileid = -1;
private bool _showfiles = true;
private string _fileinputid = string.Empty;
private string _progressinfoid = string.Empty;
private string _progressbarid = string.Empty;
private string _filter = "*";
private bool _uploadmultiple = false;
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
@ -99,153 +118,147 @@
[Parameter]
public string UploadMultiple { get; set; } // optional - enable multiple file uploads - default false
string id;
List<Folder> folders;
int folderid = -1;
List<File> files = new List<File>();
int fileid = -1;
bool showfiles = true;
string fileinputid = "";
string progressinfoid = "";
string progressbarid = "";
string filter = "*";
bool uploadmultiple = false;
bool haseditpermission = false;
string message = "";
string image = "";
protected override async Task OnInitializedAsync()
{
if (!string.IsNullOrEmpty(Id))
{
_id = Id;
}
if (!string.IsNullOrEmpty(Folder))
{
folders = new List<Folder>();
folders.Add(new Folder { FolderId = -1, Name = Folder });
folderid = -1;
_folders = new List<Folder> {new Folder {FolderId = -1, Name = Folder}};
_folderid = -1;
}
else
{
folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
if (!string.IsNullOrEmpty(FolderId))
{
folderid = int.Parse(FolderId);
_folderid = int.Parse(FolderId);
}
}
if (!string.IsNullOrEmpty(FileId))
{
fileid = int.Parse(FileId);
await SetImage();
if (fileid != -1)
_fileid = int.Parse(FileId);
if (_fileid != -1)
{
File file = await FileService.GetFileAsync(int.Parse(FileId));
if (file != null)
{
folderid = file.FolderId;
_folderid = file.FolderId;
}
else
{
_fileid = -1; // file does not exist
}
}
await SetImage();
}
if (!string.IsNullOrEmpty(ShowFiles))
{
showfiles = bool.Parse(ShowFiles);
_showfiles = bool.Parse(ShowFiles);
}
if (!string.IsNullOrEmpty(Filter))
{
filter = "." + Filter.Replace(",",",.");
_filter = "." + Filter.Replace(",",",.");
}
await GetFiles();
// create unique id for component
id = Guid.NewGuid().ToString("N");
fileinputid = id + "FileInput";
progressinfoid = id + "ProgressInfo";
progressbarid = id + "ProgressBar";
_guid = Guid.NewGuid().ToString("N");
_fileinputid = _guid + "FileInput";
_progressinfoid = _guid + "ProgressInfo";
_progressbarid = _guid + "ProgressBar";
if (!string.IsNullOrEmpty(UploadMultiple))
{
uploadmultiple = bool.Parse(UploadMultiple);
_uploadmultiple = bool.Parse(UploadMultiple);
}
}
private async Task GetFiles()
{
haseditpermission = false;
_haseditpermission = false;
if (!string.IsNullOrEmpty(Folder))
{
haseditpermission = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
files = await FileService.GetFilesAsync(Folder);
_haseditpermission = UserSecurity.IsAuthorized(PageState.User, Constants.HostRole);
_files = await FileService.GetFilesAsync(Folder);
}
else
{
Folder folder = folders.Where(item => item.FolderId == folderid).FirstOrDefault();
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);
_haseditpermission = UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, folder.Permissions);
_files = await FileService.GetFilesAsync(_folderid);
}
else
{
haseditpermission = false;
files = new List<File>();
_haseditpermission = false;
_files = new List<File>();
}
}
if (filter != "*")
if (_filter != "*")
{
List<File> filtered = new List<File>();
foreach (File file in files)
foreach (File file in _files)
{
if (filter.ToUpper().IndexOf("." + file.Extension.ToUpper()) != -1)
if (_filter.ToUpper().IndexOf("." + file.Extension.ToUpper()) != -1)
{
filtered.Add(file);
}
}
files = filtered;
_files = filtered;
}
}
private async Task FolderChanged(ChangeEventArgs e)
{
message = "";
_message = string.Empty;
try
{
folderid = int.Parse((string)e.Value);
_folderid = int.Parse((string)e.Value);
await GetFiles();
fileid = -1;
image = "";
_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>";
_message = "<br /><div class=\"alert alert-danger\" role=\"alert\">Error Loading Files</div>";
}
}
private async Task FileChanged(ChangeEventArgs e)
{
message = "";
fileid = int.Parse((string)e.Value);
_message = string.Empty;
_fileid = int.Parse((string)e.Value);
await SetImage();
StateHasChanged();
}
private async Task SetImage()
{
image = "";
if (fileid != -1)
_image = string.Empty;
if (_fileid != -1)
{
File file = await FileService.GetFileAsync(fileid);
if (file.ImageHeight != 0 && file.ImageWidth != 0)
File file = await FileService.GetFileAsync(_fileid);
if (file != null && file.ImageHeight != 0 && file.ImageWidth != 0)
{
int maxwidth = 200;
int maxheight = 200;
var maxwidth = 200;
var maxheight = 200;
double ratioX = (double)maxwidth / (double)file.ImageWidth;
double ratioY = (double)maxheight / (double)file.ImageHeight;
double ratio = ratioX < ratioY ? ratioX : ratioY;
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 +
_image = "<img src=\"" + ContentUrl(_fileid) + "\" alt=\"" + file.Name +
"\" width=\"" + Convert.ToInt32(file.ImageWidth * ratio).ToString() +
"\" height=\"" + Convert.ToInt32(file.ImageHeight * ratio).ToString() + "\" />";
}
@ -254,8 +267,8 @@
private async Task UploadFile()
{
var interop = new Interop(jsRuntime);
string[] upload = await interop.GetFiles(fileinputid);
var interop = new Interop(JsRuntime);
var upload = await interop.GetFiles(_fileinputid);
if (upload.Length > 0)
{
try
@ -263,23 +276,25 @@
string result;
if (!string.IsNullOrEmpty(Folder))
{
result = await FileService.UploadFilesAsync(Folder, upload, id);
result = await FileService.UploadFilesAsync(Folder, upload, _guid);
}
else
{
result = await FileService.UploadFilesAsync(folderid, upload, id);
result = await FileService.UploadFilesAsync(_folderid, upload, _guid);
}
if (result == "")
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>";
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">File Upload Succeeded</div>";
await GetFiles();
if (upload.Length == 1)
{
File file = files.Where(item => item.Name == upload[0]).FirstOrDefault();
var file = _files.Where(item => item.Name == upload[0]).FirstOrDefault();
if (file != null)
{
fileid = file.FileId;
_fileid = file.FileId;
await SetImage();
}
}
@ -288,44 +303,42 @@
else
{
await logger.LogError("File Upload Failed For {Files}", result.Replace(",", ", "));
message = "<br /><div class=\"alert alert-danger\" role=\"alert\">File Upload Failed</div>";
_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>";
_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>";
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Have Not Selected A File To Upload</div>";
}
}
private async Task DeleteFile()
{
message = "";
_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 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;
_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>";
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()
{
return fileid;
}
public int GetFileId() => _fileid;
}

View File

@ -0,0 +1,44 @@
@namespace Oqtane.Modules.Controls
@inherits ModuleBase
@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 += ">";
}
}

View File

@ -8,15 +8,15 @@
}
@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()
{
if (!string.IsNullOrEmpty(Message))
@ -35,7 +35,7 @@
private string GetMessageType(MessageType type)
{
string classname = "";
var classname = string.Empty;
switch (type)
{
case MessageType.Success:
@ -51,6 +51,7 @@
classname = "alert alert-danger";
break;
}
return classname;
}
}

View File

@ -36,40 +36,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 +95,7 @@
[Parameter]
public string Class { get; set; }
IEnumerable<TableItem> ItemList { get; set; }
private IEnumerable<TableItem> ItemList { get; set; }
protected override void OnParametersSet()
{
@ -103,6 +103,7 @@
{
Format = "Table";
}
if (string.IsNullOrEmpty(Class))
{
if (Format == "Table")
@ -114,36 +115,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 +155,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 +186,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);
}
}

View File

@ -3,23 +3,23 @@
@inject IRoleService RoleService
@inject IUserService UserService
@if (permissions != 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,25 +30,25 @@
}
</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;">
@ -60,20 +60,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,49 +90,48 @@
[Parameter]
public string Permissions { get; set; }
string permissionnames = "";
List<Role> roles;
List<PermissionString> permissions;
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 });
_permissions = new List<PermissionString>();
foreach (string permissionname in _permissionnames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
// initialize with admin role
_permissions.Add(new PermissionString { PermissionName = permissionname, Permissions = Constants.AdminRole });
}
roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
roles.Insert(0, new Role { Name = Constants.AllUsersRole });
if (!string.IsNullOrEmpty(Permissions))
{
permissions = new List<PermissionString>();
foreach (string permissionname in permissionnames.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
permissions.Add(new PermissionString { PermissionName = permissionname, 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));
}
}
}
@ -134,15 +140,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
}
@ -153,81 +159,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()
{
ValidatePermissions();
return UserSecurity.SetPermissionStrings(permissions);
return UserSecurity.SetPermissionStrings(_permissions);
}
private void ValidatePermissions()
{
PermissionString permission;
for (int i = 0; i < permissions.Count; i++)
for (int i = 0; i < _permissions.Count; i++)
{
permission = permissions[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;
_permissions[i] = permission;
}
}
}

Some files were not shown because too many files have changed in this diff Show More