2
.deployment
Normal file
2
.deployment
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[config]
|
||||||
|
project = Oqtane.Server/Oqtane.Server.csproj
|
111
Oqtane.Client/Modules/Admin/Files/Details.razor
Normal file
111
Oqtane.Client/Modules/Admin/Files/Details.razor
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Files
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject IFileService FileService
|
||||||
|
@inject IFolderService FolderService
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
|
@if (_folders != null)
|
||||||
|
{
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label for="name" HelpText="The name of the file">Name: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="name" class="form-control" @bind="@_name" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="parent" HelpText="The folder where the file is located">Folder: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select id="parent" class="form-control" @bind="@_folderId">
|
||||||
|
@foreach (Folder folder in _folders)
|
||||||
|
{
|
||||||
|
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label for="size" HelpText="The size of the file (in bytes)">Size: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="size" class="form-control" @bind="@_size" readonly />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<button type="button" class="btn btn-success" @onclick="SaveFile">Save</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private int _fileId = -1;
|
||||||
|
private string _name;
|
||||||
|
private List<Folder> _folders;
|
||||||
|
private int _folderId = -1;
|
||||||
|
private int _size;
|
||||||
|
private string _createdBy;
|
||||||
|
private DateTime _createdOn;
|
||||||
|
private string _modifiedBy;
|
||||||
|
private DateTime _modifiedOn;
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
|
public override string Title => "File Management";
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
|
||||||
|
_fileId = Int32.Parse(PageState.QueryString["id"]);
|
||||||
|
File file = await FileService.GetFileAsync(_fileId);
|
||||||
|
if (file != null)
|
||||||
|
{
|
||||||
|
_name = file.Name;
|
||||||
|
_folderId = file.FolderId;
|
||||||
|
_size = file.Size;
|
||||||
|
_createdBy = file.CreatedBy;
|
||||||
|
_createdOn = file.CreatedOn;
|
||||||
|
_modifiedBy = file.ModifiedBy;
|
||||||
|
_modifiedOn = file.ModifiedOn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading File {FileId} {Error}", _fileId, ex.Message);
|
||||||
|
AddModuleMessage("Error Loading File", MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveFile()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_name.IsPathOrFileValid())
|
||||||
|
{
|
||||||
|
File file = await FileService.GetFileAsync(_fileId);
|
||||||
|
file.Name = _name;
|
||||||
|
file.FolderId = _folderId;
|
||||||
|
file = await FileService.UpdateFileAsync(file);
|
||||||
|
await logger.LogInformation("File Saved {File}", file);
|
||||||
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage("File Name Not Valid", MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Saving File {FileId} {Error}", _fileId, ex.Message);
|
||||||
|
AddModuleMessage("Error Saving File", MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -174,17 +174,33 @@
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message);
|
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message);
|
||||||
AddModuleMessage("Error Saving Module", MessageType.Error);
|
AddModuleMessage("Error Saving Folder", MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteFolder()
|
private async Task DeleteFolder()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
bool isparent = false;
|
||||||
|
foreach (Folder folder in _folders)
|
||||||
|
{
|
||||||
|
if (folder.ParentId == _folderId)
|
||||||
|
{
|
||||||
|
isparent = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isparent)
|
||||||
{
|
{
|
||||||
await FolderService.DeleteFolderAsync(_folderId);
|
await FolderService.DeleteFolderAsync(_folderId);
|
||||||
await logger.LogInformation("Folder Deleted {Folder}", _folderId);
|
await logger.LogInformation("Folder Deleted {Folder}", _folderId);
|
||||||
AddModuleMessage("Folder Deleted", MessageType.Success);
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage("Folder Has Child Folders And Cannot Be Deleted", MessageType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -28,13 +28,15 @@
|
|||||||
</table>
|
</table>
|
||||||
<Pager Items="@_files">
|
<Pager Items="@_files">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Modified</th>
|
<th>Modified</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Size</th>
|
<th>Size</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
<td><ActionLink Action="Details" Text="Edit" Parameters="@($"id=" + context.FileId.ToString())" /></td>
|
||||||
<td><ActionDialog Header="Delete File" Message="@("Are You Sure You Wish To Delete " + context.Name + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" /></td>
|
<td><ActionDialog Header="Delete File" Message="@("Are You Sure You Wish To Delete " + context.Name + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" /></td>
|
||||||
<td><a href="@(ContentUrl(context.FileId))" target="_new">@context.Name</a></td>
|
<td><a href="@(ContentUrl(context.FileId))" target="_new">@context.Name</a></td>
|
||||||
<td>@context.ModifiedOn</td>
|
<td>@context.ModifiedOn</td>
|
||||||
|
@ -63,10 +63,18 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="retention-log" HelpText="What items do you want in the retention log">Retention Log (Items): </Label>
|
<Label For="retention" HelpText="Number of log entries to retain for this job">Retention Log (Items): </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input id="retention-log" class="form-control" @bind="@_retentionHistory" />
|
<input id="retention" class="form-control" @bind="@_retentionHistory" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="next" HelpText="Next execution for this job.">Next Execution: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="next" class="form-control" @bind="@_nextExecution" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -83,6 +91,7 @@
|
|||||||
private string _startDate = string.Empty;
|
private string _startDate = string.Empty;
|
||||||
private string _endDate = string.Empty;
|
private string _endDate = string.Empty;
|
||||||
private string _retentionHistory = string.Empty;
|
private string _retentionHistory = string.Empty;
|
||||||
|
private string _nextExecution = string.Empty;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
@ -102,6 +111,7 @@
|
|||||||
_startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty;
|
_startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty;
|
||||||
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
|
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
|
||||||
_retentionHistory = job.RetentionHistory.ToString();
|
_retentionHistory = job.RetentionHistory.ToString();
|
||||||
|
_nextExecution = job.NextExecution.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -140,6 +150,15 @@
|
|||||||
job.EndDate = DateTime.Parse(_endDate);
|
job.EndDate = DateTime.Parse(_endDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_nextExecution == string.Empty)
|
||||||
|
{
|
||||||
|
job.NextExecution = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job.NextExecution = DateTime.Parse(_nextExecution);
|
||||||
|
}
|
||||||
|
|
||||||
job.RetentionHistory = int.Parse(_retentionHistory);
|
job.RetentionHistory = int.Parse(_retentionHistory);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -15,14 +15,14 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_jobs">
|
<Pager Items="@_jobs">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Frequency</th>
|
<th>Frequency</th>
|
||||||
<th>Next Execution</th>
|
<th>Next Execution</th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.JobId.ToString())" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.JobId.ToString())" /></td>
|
||||||
|
@ -22,7 +22,7 @@ else
|
|||||||
<td>@context.FinishDate</td>
|
<td>@context.FinishDate</td>
|
||||||
</Row>
|
</Row>
|
||||||
<Detail>
|
<Detail>
|
||||||
<td colspan="4">@context.Notes</td>
|
<td colspan="4">@((MarkupString)context.Notes)</td>
|
||||||
</Detail>
|
</Detail>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ else
|
|||||||
{
|
{
|
||||||
<Pager Items="@_logs">
|
<Pager Items="@_logs">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Date</th>
|
<th>Date</th>
|
||||||
<th>Level</th>
|
<th>Level</th>
|
||||||
<th>Feature</th>
|
<th>Feature</th>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<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>
|
<Label For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation.">Module Name: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input id="module" class="form-control" @bind="@_module" />
|
<input id="module" class="form-control" @bind="@_module" />
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<Header>
|
<Header>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Version</th>
|
<th>Version</th>
|
||||||
<th></th>
|
<th style="width: 1px"></th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
{
|
{
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -75,12 +75,20 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="license" HelpText="The license of the module">License: </Label>
|
<Label For="license" HelpText="The module license terms">License: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="runtimes" HelpText="The Blazor runtimes which this module supports">Runtimes: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</Section>
|
</Section>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
@ -110,6 +118,7 @@
|
|||||||
private string _url = "";
|
private string _url = "";
|
||||||
private string _contact = "";
|
private string _contact = "";
|
||||||
private string _license = "";
|
private string _license = "";
|
||||||
|
private string _runtimes = "";
|
||||||
private string _permissions;
|
private string _permissions;
|
||||||
private string _createdby;
|
private string _createdby;
|
||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
@ -139,6 +148,7 @@
|
|||||||
_url = moduleDefinition.Url;
|
_url = moduleDefinition.Url;
|
||||||
_contact = moduleDefinition.Contact;
|
_contact = moduleDefinition.Contact;
|
||||||
_license = moduleDefinition.License;
|
_license = moduleDefinition.License;
|
||||||
|
_runtimes = moduleDefinition.Runtimes;
|
||||||
_permissions = moduleDefinition.Permissions;
|
_permissions = moduleDefinition.Permissions;
|
||||||
_createdby = moduleDefinition.CreatedBy;
|
_createdby = moduleDefinition.CreatedBy;
|
||||||
_createdon = moduleDefinition.CreatedOn;
|
_createdon = moduleDefinition.CreatedOn;
|
||||||
|
@ -14,11 +14,11 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_moduleDefinitions">
|
<Pager Items="@_moduleDefinitions">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Version</th>
|
<th>Version</th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" /></td>
|
||||||
@ -86,7 +86,7 @@ else
|
|||||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -102,7 +102,7 @@ else
|
|||||||
{
|
{
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -31,9 +31,15 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
||||||
StateHasChanged();
|
if (success)
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
{
|
||||||
|
AddModuleMessage("Content Imported Successfully", MessageType.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage("A Problem Was Encountered Importing Content. Please Ensure The Content Is Formatted Correctly For The Module.", MessageType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -162,17 +162,6 @@
|
|||||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||||
@ -217,7 +206,6 @@
|
|||||||
private string _isnavigation = "True";
|
private string _isnavigation = "True";
|
||||||
private string _url;
|
private string _url;
|
||||||
private string _ispersonalizable = "False";
|
private string _ispersonalizable = "False";
|
||||||
private string _mode = "view";
|
|
||||||
private string _themetype = "-";
|
private string _themetype = "-";
|
||||||
private string _layouttype = "-";
|
private string _layouttype = "-";
|
||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
@ -346,6 +334,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!PagePathIsUnique(page.Path, page.SiteId, _pageList))
|
||||||
|
{
|
||||||
|
AddModuleMessage($"A page with path {_path} already exists for the selected parent page. The page path needs to be unique for the selected parent.", MessageType.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Page child;
|
Page child;
|
||||||
switch (_insert)
|
switch (_insert)
|
||||||
{
|
{
|
||||||
@ -367,7 +361,6 @@
|
|||||||
|
|
||||||
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
||||||
page.Url = _url;
|
page.Url = _url;
|
||||||
page.EditMode = (_mode == "edit" ? true : false);
|
|
||||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||||
{
|
{
|
||||||
@ -407,4 +400,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool PagePathIsUnique(string pagePath, int siteId, List<Page> existingPages)
|
||||||
|
{
|
||||||
|
return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,17 +173,6 @@
|
|||||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</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>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||||
@ -235,7 +224,6 @@
|
|||||||
private string _isnavigation;
|
private string _isnavigation;
|
||||||
private string _url;
|
private string _url;
|
||||||
private string _ispersonalizable;
|
private string _ispersonalizable;
|
||||||
private string _mode;
|
|
||||||
private string _themetype = "-";
|
private string _themetype = "-";
|
||||||
private string _layouttype = "-";
|
private string _layouttype = "-";
|
||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
@ -290,7 +278,6 @@
|
|||||||
_isnavigation = page.IsNavigation.ToString();
|
_isnavigation = page.IsNavigation.ToString();
|
||||||
_url = page.Url;
|
_url = page.Url;
|
||||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||||
_mode = (page.EditMode) ? "edit" : "view";
|
|
||||||
_themetype = page.ThemeType;
|
_themetype = page.ThemeType;
|
||||||
if (_themetype == PageState.Site.DefaultThemeType)
|
if (_themetype == PageState.Site.DefaultThemeType)
|
||||||
{
|
{
|
||||||
@ -433,6 +420,13 @@
|
|||||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!PagePathIsUnique(page.Path, page.SiteId, page.PageId, _pageList))
|
||||||
|
{
|
||||||
|
AddModuleMessage($"A page with path {_path} already exists for the selected parent page. The page path needs to be unique for the selected parent.", MessageType.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_insert != "=")
|
if (_insert != "=")
|
||||||
{
|
{
|
||||||
Page child;
|
Page child;
|
||||||
@ -456,7 +450,6 @@
|
|||||||
}
|
}
|
||||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||||
page.Url = _url;
|
page.Url = _url;
|
||||||
page.EditMode = (_mode == "edit");
|
|
||||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||||
{
|
{
|
||||||
@ -512,4 +505,9 @@
|
|||||||
AddModuleMessage("Error Saving Page", MessageType.Error);
|
AddModuleMessage("Error Saving Page", MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool PagePathIsUnique(string pagePath, int siteId, int pageId, List<Page> existingPages)
|
||||||
|
{
|
||||||
|
return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath && page.PageId != pageId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)">
|
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -145,6 +145,7 @@
|
|||||||
profile = new Profile();
|
profile = new Profile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
profile.SiteId = PageState.Site.SiteId;
|
||||||
profile.Name = _name;
|
profile.Name = _name;
|
||||||
profile.Title = _title;
|
profile.Title = _title;
|
||||||
profile.Description = _description;
|
profile.Description = _description;
|
||||||
|
@ -12,8 +12,8 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_profiles">
|
<Pager Items="@_profiles">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
{
|
{
|
||||||
<Pager Items="@_pages">
|
<Pager Items="@_pages">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Deleted By</th>
|
<th>Deleted By</th>
|
||||||
<th>Deleted On</th>
|
<th>Deleted On</th>
|
||||||
@ -42,8 +42,8 @@
|
|||||||
{
|
{
|
||||||
<Pager Items="@_modules">
|
<Pager Items="@_modules">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Page</th>
|
<th>Page</th>
|
||||||
<th>Module</th>
|
<th>Module</th>
|
||||||
<th>Deleted By</th>
|
<th>Deleted By</th>
|
||||||
|
@ -12,9 +12,9 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_roles">
|
<Pager Items="@_roles">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
@inject ISettingService SettingService
|
@inject ISettingService SettingService
|
||||||
|
|
||||||
@if (_themes != null)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
@ -211,6 +211,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
@ -318,6 +319,8 @@
|
|||||||
_deletedby = site.DeletedBy;
|
_deletedby = site.DeletedBy;
|
||||||
_deletedon = site.DeletedOn;
|
_deletedon = site.DeletedOn;
|
||||||
_isdeleted = site.IsDeleted.ToString();
|
_isdeleted = site.IsDeleted.ToString();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
@inject IAliasService AliasService
|
@inject IAliasService AliasService
|
||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
|
|
||||||
@if (_themes != null)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
@ -106,6 +106,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
@ -163,6 +164,8 @@
|
|||||||
_deletedby = site.DeletedBy;
|
_deletedby = site.DeletedBy;
|
||||||
_deletedon = site.DeletedOn;
|
_deletedon = site.DeletedOn;
|
||||||
_isdeleted = site.IsDeleted.ToString();
|
_isdeleted = site.IsDeleted.ToString();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -14,8 +14,8 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_sites">
|
<Pager Items="@_sites">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -11,8 +11,8 @@ else
|
|||||||
{
|
{
|
||||||
<Pager Items="@tenants">
|
<Pager Items="@tenants">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<Header>
|
<Header>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Version</th>
|
<th>Version</th>
|
||||||
<th></th>
|
<th style="width: 1px;"></th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
{
|
{
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await ThemeService.InstallThemesAsync();
|
await ThemeService.InstallThemesAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -15,10 +15,10 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_themes">
|
<Pager Items="@_themes">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th scope="col">Name</th>
|
||||||
<th>Version</th>
|
<th scope="col">Version</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
@ -37,6 +37,7 @@ else
|
|||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.ThemeName, context.Version))>Upgrade</button>
|
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.ThemeName, context.Version))>Upgrade</button>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
|
<td></td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
@ -86,7 +87,7 @@ else
|
|||||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await ThemeService.InstallThemesAsync();
|
await ThemeService.InstallThemesAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -102,7 +103,7 @@ else
|
|||||||
{
|
{
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
@if (_upgradeavailable)
|
@if (_upgradeavailable)
|
||||||
{
|
{
|
||||||
<ModuleMessage Type="MessageType.Info" Message="Select The Upgrade Button To Install a New Framework Version"></ModuleMessage>
|
<ModuleMessage Type="MessageType.Info" Message="Select The Upgrade Button To Install a New Framework Version"></ModuleMessage>
|
||||||
@("Framework") @_package.Version <button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Upgrade</button>
|
<button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>Upgrade To @_package.Version</button>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -26,7 +26,7 @@
|
|||||||
<Label HelpText="Upload a framework package and select Install to complete the installation">Framework: </Label>
|
<Label HelpText="Upload a framework package and select Install to complete the installation">Framework: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<FileManager Filter="nupkg" Folder="Framework" />
|
<FileManager Filter="nupkg" ShowFiles="false" Folder="Framework" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -71,7 +71,7 @@
|
|||||||
{
|
{
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await InstallationService.Upgrade();
|
await InstallationService.Upgrade();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -88,7 +88,7 @@
|
|||||||
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
||||||
ShowProgressIndicator();
|
ShowProgressIndicator();
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.RedirectBrowser(NavigateUrl(), 3);
|
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||||
await InstallationService.Upgrade();
|
await InstallationService.Upgrade();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
notification.CreatedOn = DateTime.UtcNow;
|
notification.CreatedOn = DateTime.UtcNow;
|
||||||
notification.IsDelivered = false;
|
notification.IsDelivered = false;
|
||||||
notification.DeliveredOn = null;
|
notification.DeliveredOn = null;
|
||||||
|
notification.SendOn = DateTime.UtcNow;
|
||||||
notification = await NotificationService.AddNotificationAsync(notification);
|
notification = await NotificationService.AddNotificationAsync(notification);
|
||||||
await logger.LogInformation("Notification Created {Notification}", notification);
|
await logger.LogInformation("Notification Created {Notification}", notification);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
@ -32,7 +32,7 @@ else
|
|||||||
<label for="Name" class="control-label">Password: </label>
|
<label for="Name" class="control-label">Password: </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="password" class="form-control" @bind="@password" />
|
<input type="password" class="form-control" @bind="@password" autocomplete="new-password" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -40,7 +40,7 @@ else
|
|||||||
<label for="Name" class="control-label">Confirm Password: </label>
|
<label for="Name" class="control-label">Confirm Password: </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="password" class="form-control" @bind="@confirm" />
|
<input type="password" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -79,6 +79,8 @@ else
|
|||||||
@foreach (Profile profile in profiles)
|
@foreach (Profile profile in profiles)
|
||||||
{
|
{
|
||||||
var p = profile;
|
var p = profile;
|
||||||
|
if (!p.IsPrivate || UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole))
|
||||||
|
{
|
||||||
if (p.Category != category)
|
if (p.Category != category)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
@ -90,13 +92,21 @@ else
|
|||||||
}
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
@if (p.IsRequired)
|
||||||
|
{
|
||||||
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</table>
|
</table>
|
||||||
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
<button type="button" class="btn btn-primary" @onclick="Save">Save</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
<button type="button" class="btn btn-secondary" @onclick="Cancel">Cancel</button>
|
||||||
@ -111,8 +121,8 @@ else
|
|||||||
{
|
{
|
||||||
<Pager Items="@notifications">
|
<Pager Items="@notifications">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>From</th>
|
<th>From</th>
|
||||||
<th>Subject</th>
|
<th>Subject</th>
|
||||||
<th>Received</th>
|
<th>Received</th>
|
||||||
@ -241,7 +251,7 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (username != string.Empty && email != string.Empty)
|
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
||||||
{
|
{
|
||||||
if (password == confirm)
|
if (password == confirm)
|
||||||
{
|
{
|
||||||
@ -261,6 +271,7 @@ else
|
|||||||
await UserService.UpdateUserAsync(user);
|
await UserService.UpdateUserAsync(user);
|
||||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||||
await logger.LogInformation("User Profile Saved");
|
await logger.LogInformation("User Profile Saved");
|
||||||
|
AddModuleMessage("User Profile Updated Successfully", MessageType.Success);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -269,7 +280,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage("You Must Provide A Username and Email Address", MessageType.Warning);
|
AddModuleMessage("You Must Provide A Username and Email Address As Well As All Required Profile Information", MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -279,6 +290,26 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ValidateProfiles()
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
foreach (Profile profile in profiles)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
|
{
|
||||||
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
|
}
|
||||||
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, Constants.AdminRole))
|
||||||
|
{
|
||||||
|
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
||||||
|
@ -192,6 +192,7 @@
|
|||||||
notification.CreatedOn = DateTime.UtcNow;
|
notification.CreatedOn = DateTime.UtcNow;
|
||||||
notification.IsDelivered = false;
|
notification.IsDelivered = false;
|
||||||
notification.DeliveredOn = null;
|
notification.DeliveredOn = null;
|
||||||
|
notification.SendOn = DateTime.UtcNow;
|
||||||
notification = await NotificationService.AddNotificationAsync(notification);
|
notification = await NotificationService.AddNotificationAsync(notification);
|
||||||
await logger.LogInformation("Notification Created {Notification}", notification);
|
await logger.LogInformation("Notification Created {Notification}", notification);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
@ -71,10 +71,17 @@
|
|||||||
}
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input class="form-control" maxlength="@p.MaxLength" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
@if (p.IsRequired)
|
||||||
|
{
|
||||||
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@ -112,11 +119,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetProfileValue(string SettingName, string DefaultValue)
|
||||||
|
=> SettingService.GetSetting(settings, SettingName, DefaultValue);
|
||||||
|
|
||||||
private async Task SaveUser()
|
private async Task SaveUser()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (username != string.Empty && password != string.Empty && confirm != string.Empty && email != string.Empty)
|
if (username != string.Empty && password != string.Empty && confirm != string.Empty && email != string.Empty && ValidateProfiles())
|
||||||
{
|
{
|
||||||
if (password == confirm)
|
if (password == confirm)
|
||||||
{
|
{
|
||||||
@ -149,7 +159,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
|
AddModuleMessage("You Must Provide A Username, Password, Email Address And All Required Profile Information", MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -159,6 +169,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ValidateProfiles()
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
foreach (Profile profile in profiles)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
|
{
|
||||||
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
|
}
|
||||||
|
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
{
|
{
|
||||||
var value = (string)e.Value;
|
var value = (string)e.Value;
|
||||||
|
@ -98,10 +98,17 @@ else
|
|||||||
}
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="@p.Name" class="control-label">@p.Title: </label>
|
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" placeholder="@p.Description" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
@if (p.IsRequired)
|
||||||
|
{
|
||||||
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
|
}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@ -180,7 +187,7 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (username != string.Empty && email != string.Empty)
|
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
||||||
{
|
{
|
||||||
if (password == confirm)
|
if (password == confirm)
|
||||||
{
|
{
|
||||||
@ -213,7 +220,7 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage("You Must Provide A Username, Password, and Email Address", MessageType.Warning);
|
AddModuleMessage("You Must Provide A Username, Password, Email Address, And All Required Profile Information", MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -223,6 +230,23 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ValidateProfiles()
|
||||||
|
{
|
||||||
|
bool valid = true;
|
||||||
|
foreach (Profile profile in profiles)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
|
{
|
||||||
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
|
}
|
||||||
|
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
{
|
{
|
||||||
var value = (string)e.Value;
|
var value = (string)e.Value;
|
||||||
|
@ -20,9 +20,9 @@ else
|
|||||||
|
|
||||||
<Pager Items="@userroles">
|
<Pager Items="@userroles">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@if (_visible)
|
@if (_visible)
|
||||||
{
|
{
|
||||||
<div class="app-admin-modal">
|
<div class="app-admin-modal">
|
||||||
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private bool _visible = false;
|
private bool _visible = false;
|
||||||
private bool _editmode = true;
|
private bool _editmode = false;
|
||||||
private bool _authorized = false;
|
private bool _authorized = false;
|
||||||
private string _iconSpan = string.Empty;
|
private string _iconSpan = string.Empty;
|
||||||
|
|
||||||
@ -66,7 +66,7 @@
|
|||||||
public bool Disabled { get; set; } // optional
|
public bool Disabled { get; set; } // optional
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
public string EditMode { get; set; } // optional - specifies if an authorized user must be in edit mode to see the action - default is false
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Action OnClick { get; set; } // required if an Action is specified - executes a method in the calling component
|
public Action OnClick { get; set; } // required if an Action is specified - executes a method in the calling component
|
||||||
@ -84,6 +84,7 @@
|
|||||||
{
|
{
|
||||||
Class = "btn btn-success";
|
Class = "btn btn-success";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(EditMode))
|
if (!string.IsNullOrEmpty(EditMode))
|
||||||
{
|
{
|
||||||
_editmode = bool.Parse(EditMode);
|
_editmode = bool.Parse(EditMode);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
|
||||||
@if (_authorized)
|
@if (_authorized)
|
||||||
@ -21,7 +20,7 @@
|
|||||||
private string _parameters = string.Empty;
|
private string _parameters = string.Empty;
|
||||||
private string _classname = "btn btn-primary";
|
private string _classname = "btn btn-primary";
|
||||||
private string _style = string.Empty;
|
private string _style = string.Empty;
|
||||||
private bool _editmode = true;
|
private bool _editmode = false;
|
||||||
private bool _authorized = false;
|
private bool _authorized = false;
|
||||||
private string _iconSpan = string.Empty;
|
private string _iconSpan = string.Empty;
|
||||||
|
|
||||||
@ -47,7 +46,7 @@
|
|||||||
public bool Disabled { get; set; } // optional
|
public bool Disabled { get; set; } // optional
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
public string EditMode { get; set; } // optional - specifies if an authorized user must be in edit mode to see the action - default is false.
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
public string IconName { get; set; } // optional - specifies an icon for the link - default is no icon
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
@if (_text != string.Empty)
|
@if (_text != string.Empty)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
|
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@inject IFolderService FolderService
|
@inject IFolderService FolderService
|
||||||
@inject IFileService FileService
|
@inject IFileService FileService
|
||||||
|
|
||||||
@ -65,7 +63,7 @@
|
|||||||
<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">
|
<span class="float-right">
|
||||||
<button type="button" class="btn btn-success" @onclick="UploadFile">Upload</button>
|
<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>
|
<button type="button" class="btn btn-danger" @onclick="DeleteFile">Delete</button>
|
||||||
}
|
}
|
||||||
@ -88,7 +86,6 @@
|
|||||||
private string _id;
|
private string _id;
|
||||||
private List<Folder> _folders;
|
private List<Folder> _folders;
|
||||||
private List<File> _files = new List<File>();
|
private List<File> _files = new List<File>();
|
||||||
private bool _showfiles = true;
|
|
||||||
private string _fileinputid = string.Empty;
|
private string _fileinputid = string.Empty;
|
||||||
private string _progressinfoid = string.Empty;
|
private string _progressinfoid = string.Empty;
|
||||||
private string _progressbarid = string.Empty;
|
private string _progressbarid = string.Empty;
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(HelpText))
|
@if (!string.IsNullOrEmpty(HelpText))
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,16 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(_message))
|
@if (!string.IsNullOrEmpty(_message))
|
||||||
{
|
{
|
||||||
<div class="@_classname" role="alert">@_message</div>
|
<div class="@_classname" role="alert">
|
||||||
|
@_message
|
||||||
|
@if (Type == MessageType.Error && UserSecurity.IsAuthorized(PageState.User, Constants.HostRole))
|
||||||
|
{
|
||||||
|
@((MarkupString)" ")<NavLink href="@NavigateUrl("admin/log")">View Details</NavLink>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
<br />
|
<br />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@typeparam TableItem
|
@typeparam TableItem
|
||||||
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
@if (Format == "Table")
|
@if (Format == "Table")
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@inject IRoleService RoleService
|
@inject IRoleService RoleService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
|
||||||
@ -10,10 +9,10 @@
|
|||||||
<table class="table" style="width: 50%; min-width: 250px;">
|
<table class="table" style="width: 50%; min-width: 250px;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Role</th>
|
<th scope="col">Role</th>
|
||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (PermissionString permission in _permissions)
|
||||||
{
|
{
|
||||||
<th style="text-align: center;">@permission.PermissionName</th>
|
<th style="text-align: center; width: 1px;">@permission.PermissionName</th>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
@foreach (Role role in _roles)
|
@foreach (Role role in _roles)
|
||||||
@ -36,10 +35,10 @@
|
|||||||
<table class="table" style="width: 50%; min-width: 250px;">
|
<table class="table" style="width: 50%; min-width: 250px;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>User</th>
|
<th scope="col">User</th>
|
||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (PermissionString permission in _permissions)
|
||||||
{
|
{
|
||||||
<th style="text-align: center;">@permission.PermissionName</th>
|
<th style="text-align: center; width: 1px;">@permission.PermissionName</th>
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -52,7 +51,7 @@
|
|||||||
@foreach (PermissionString permission in _permissions)
|
@foreach (PermissionString permission in _permissions)
|
||||||
{
|
{
|
||||||
var p = permission;
|
var p = permission;
|
||||||
<td style="text-align: center;">
|
<td style="text-align: center; width: 1px;">
|
||||||
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled=false OnChange="@(e => PermissionChanged(e, p.PermissionName, userid))" />
|
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled=false OnChange="@(e => PermissionChanged(e, p.PermissionName, userid))" />
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
@ -64,9 +63,10 @@
|
|||||||
<table class="table" style="width: 50%; min-width: 250px;">
|
<table class="table" style="width: 50%; min-width: 250px;">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="text-align: right;"><label for="Username" class="control-label">User: </label></td>
|
<td class="input-group">
|
||||||
<td><input type="text" name="Username" class="form-control" placeholder="Enter Username" @bind="@_username" /></td>
|
<input type="text" name="Username" class="form-control" placeholder="Enter Username" @bind="@_username" />
|
||||||
<td style="text-align: left;"><button type="button" class="btn btn-primary" @onclick="AddUser">Add</button></td>
|
<button type="button" class="btn btn-primary" @onclick="AddUser">Add</button>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
<div class="row" style="margin-bottom: 50px;">
|
<div class="row" style="margin-bottom: 50px;">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div>
|
<div>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
@if (Name == Parent.ActiveTab)
|
@if (Name == Parent.ActiveTab)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
<CascadingValue Value="this">
|
<CascadingValue Value="this">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
|
@inherits ModuleControlBase
|
||||||
|
|
||||||
<img src="@_src" title="@_title" @onclick="SetValue" />
|
<img src="@_src" title="@_title" @onclick="SetValue" />
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
@if (PageState.EditMode)
|
@if (PageState.EditMode)
|
||||||
{
|
{
|
||||||
<br /><ActionLink Action="Edit" /><br /><br />
|
<br /><ActionLink Action="Edit" EditMode="true" /><br /><br />
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
@ -21,23 +21,23 @@ namespace Oqtane.Modules.HtmlText.Services
|
|||||||
|
|
||||||
public async Task<HtmlTextInfo> GetHtmlTextAsync(int moduleId)
|
public async Task<HtmlTextInfo> GetHtmlTextAsync(int moduleId)
|
||||||
{
|
{
|
||||||
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", moduleId));
|
||||||
return htmltext.FirstOrDefault();
|
return htmltext.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AddHtmlTextAsync(HtmlTextInfo htmlText)
|
public async Task AddHtmlTextAsync(HtmlTextInfo htmlText)
|
||||||
{
|
{
|
||||||
await PostJsonAsync($"{ApiUrl}?entityid={htmlText.ModuleId}", htmlText);
|
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", htmlText.ModuleId), htmlText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateHtmlTextAsync(HtmlTextInfo htmlText)
|
public async Task UpdateHtmlTextAsync(HtmlTextInfo htmlText)
|
||||||
{
|
{
|
||||||
await PutJsonAsync($"{ApiUrl}/{htmlText.HtmlTextId}?entityid={htmlText.ModuleId}", htmlText);
|
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", htmlText.ModuleId), htmlText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteHtmlTextAsync(int moduleId)
|
public async Task DeleteHtmlTextAsync(int moduleId)
|
||||||
{
|
{
|
||||||
await DeleteAsync($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", moduleId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,54 @@ namespace Oqtane.Modules
|
|||||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
||||||
|
{
|
||||||
|
var urlParameters = new Dictionary<string, string>();
|
||||||
|
string[] templateSegments;
|
||||||
|
var parameters = PageState.UrlParameters.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
var parameterId = 0;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(parametersTemplate))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
urlParameters.TryAdd("parameter" + i, parameters[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
templateSegments = parametersTemplate.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
if (parameters.Length == templateSegments.Length)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < parameters.Length; i++)
|
||||||
|
{
|
||||||
|
if (parameters.Length > i)
|
||||||
|
{
|
||||||
|
if (templateSegments[i] == parameters[i])
|
||||||
|
{
|
||||||
|
urlParameters.TryAdd("parameter" + parameterId, parameters[i]);
|
||||||
|
parameterId++;
|
||||||
|
}
|
||||||
|
else if (templateSegments[i].StartsWith("{") && templateSegments[i].EndsWith("}"))
|
||||||
|
{
|
||||||
|
var key = templateSegments[i].Replace("{", "");
|
||||||
|
key = key.Replace("}", "");
|
||||||
|
urlParameters.TryAdd(key, parameters[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = parameters.Length;
|
||||||
|
urlParameters.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlParameters;
|
||||||
|
}
|
||||||
|
|
||||||
// user feedback methods
|
// user feedback methods
|
||||||
public void AddModuleMessage(string message, MessageType type)
|
public void AddModuleMessage(string message, MessageType type)
|
||||||
{
|
{
|
||||||
@ -154,12 +202,15 @@ namespace Oqtane.Modules
|
|||||||
case "add":
|
case "add":
|
||||||
logFunction = LogFunction.Create;
|
logFunction = LogFunction.Create;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "edit":
|
case "edit":
|
||||||
logFunction = LogFunction.Update;
|
logFunction = LogFunction.Update;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "delete":
|
case "delete":
|
||||||
logFunction = LogFunction.Delete;
|
logFunction = LogFunction.Delete;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logFunction = LogFunction.Read;
|
logFunction = LogFunction.Read;
|
||||||
break;
|
break;
|
||||||
|
10
Oqtane.Client/Modules/ModuleControlBase.cs
Normal file
10
Oqtane.Client/Modules/ModuleControlBase.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
namespace Oqtane.Modules
|
||||||
|
{
|
||||||
|
[OqtaneIgnore]
|
||||||
|
public abstract class ModuleControlBase : ModuleBase
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -6,7 +6,7 @@
|
|||||||
<LangVersion>7.3</LangVersion>
|
<LangVersion>7.3</LangVersion>
|
||||||
<RazorLangVersion>3.0</RazorLangVersion>
|
<RazorLangVersion>3.0</RazorLangVersion>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Version>1.0.0</Version>
|
<Version>1.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<PackageReleaseNotes>Not for production use.</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</PackageReleaseNotes>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -170,6 +170,19 @@ namespace Oqtane.Services
|
|||||||
// can be used to override the default alias
|
// can be used to override the default alias
|
||||||
public Alias Alias { get; set; }
|
public Alias Alias { get; set; }
|
||||||
|
|
||||||
|
// add entityid parameter to url for custom authorization policy
|
||||||
|
public string CreateAuthorizationPolicyUrl(string url, int entityId)
|
||||||
|
{
|
||||||
|
if (url.Contains("?"))
|
||||||
|
{
|
||||||
|
return url + "&entityid=" + entityId.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return url + "?entityid=" + entityId.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Obsolete("This method is obsolete. Use CreateApiUrl(Alias alias, string serviceName) instead.", false)]
|
[Obsolete("This method is obsolete. Use CreateApiUrl(Alias alias, string serviceName) instead.", false)]
|
||||||
public string CreateApiUrl(Alias alias, string absoluteUri, string serviceName)
|
public string CreateApiUrl(Alias alias, string absoluteUri, string serviceName)
|
||||||
{
|
{
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
using Oqtane.Models;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Reflection;
|
using Oqtane.Models;
|
||||||
using System;
|
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
public class ThemeService : ServiceBase, IThemeService
|
public class ThemeService : ServiceBase, IThemeService
|
||||||
{
|
{
|
||||||
private readonly HttpClient _http;
|
private readonly SiteState _siteState;
|
||||||
|
|
||||||
public ThemeService(HttpClient http) : base(http)
|
public ThemeService(HttpClient http, SiteState siteState) : base(http)
|
||||||
{
|
{
|
||||||
_http = http;
|
_siteState = siteState;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string Apiurl => CreateApiUrl("Theme");
|
private string ApiUrl => CreateApiUrl(_siteState.Alias, "Theme");
|
||||||
|
|
||||||
public async Task<List<Theme>> GetThemesAsync()
|
public async Task<List<Theme>> GetThemesAsync()
|
||||||
{
|
{
|
||||||
List<Theme> themes = await GetJsonAsync<List<Theme>>(Apiurl);
|
List<Theme> themes = await GetJsonAsync<List<Theme>>(ApiUrl);
|
||||||
return themes.OrderBy(item => item.Name).ToList();
|
return themes.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,12 +43,12 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public async Task InstallThemesAsync()
|
public async Task InstallThemesAsync()
|
||||||
{
|
{
|
||||||
await GetJsonAsync<List<string>>($"{Apiurl}/install");
|
await GetJsonAsync<List<string>>($"{ApiUrl}/install");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteThemeAsync(string themeName)
|
public async Task DeleteThemeAsync(string themeName)
|
||||||
{
|
{
|
||||||
await DeleteAsync($"{Apiurl}/{themeName}");
|
await DeleteAsync($"{ApiUrl}/{themeName}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Themes.BlazorTheme
|
@namespace Oqtane.Themes.BlazorTheme
|
||||||
@inherits ThemeBase
|
@inherits ThemeBase
|
||||||
@implements IThemeControl
|
|
||||||
|
|
||||||
<div class="breadcrumbs">
|
<div class="breadcrumbs">
|
||||||
<Breadcrumbs />
|
<Breadcrumbs />
|
||||||
@ -31,11 +30,11 @@
|
|||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css", Integrity = "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css", Integrity = "sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.3.1.slim.min.js", Integrity = "sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.5.1.slim.min.js", Integrity = "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", Integrity = "sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js", Integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js", Integrity = "sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM", CrossOrigin = "anonymous" }
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -7,5 +7,6 @@ namespace Oqtane.Themes
|
|||||||
{
|
{
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected Module ModuleState { get; set; }
|
protected Module ModuleState { get; set; }
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits ThemeControlBase
|
@inherits ThemeControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
@if (BreadCrumbPages.Any())
|
@if (BreadCrumbPages.Any())
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits ThemeControlBase
|
@inherits ThemeControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IModuleDefinitionService ModuleDefinitionService
|
@inject IModuleDefinitionService ModuleDefinitionService
|
||||||
@ -127,10 +126,13 @@
|
|||||||
@foreach (var moduledefinition in _moduleDefinitions)
|
@foreach (var moduledefinition in _moduleDefinitions)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
|
||||||
|
{
|
||||||
|
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
||||||
{
|
{
|
||||||
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</select>
|
</select>
|
||||||
@((MarkupString) Description)
|
@((MarkupString) Description)
|
||||||
}
|
}
|
||||||
@ -196,14 +198,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
|
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
|
||||||
{
|
|
||||||
@if (PageState.Page.EditMode)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn @ButtonClass active" aria-pressed="true" autocomplete="off">
|
|
||||||
<span class="oi oi-pencil"></span>
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (PageState.EditMode)
|
if (PageState.EditMode)
|
||||||
{
|
{
|
||||||
@ -218,7 +212,6 @@
|
|||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits LoginBase
|
@inherits LoginBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
<span class="app-login">
|
<span class="app-login">
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits ThemeControlBase
|
@inherits ThemeControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
@if (PageState.Site.LogoFileId != null)
|
@if (PageState.Site.LogoFileId != null)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits MenuBase
|
@inherits MenuBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@if (MenuPages.Any())
|
@if (MenuPages.Any())
|
||||||
{
|
{
|
||||||
<span class="app-menu-toggler">
|
<span class="app-menu-toggler">
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits MenuBase
|
@inherits MenuBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@if (MenuPages.Any())
|
@if (MenuPages.Any())
|
||||||
{
|
{
|
||||||
<span class="app-menu-toggler">
|
<span class="app-menu-toggler">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
@inherits ModuleActionsBase
|
@inherits ModuleActionsBase
|
||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
|
|
||||||
@if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
||||||
{
|
{
|
||||||
<div class="app-moduleactions">
|
<div class="app-moduleactions">
|
||||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
||||||
@ -15,7 +15,18 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">@action.Name</a>
|
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">
|
||||||
|
@if (string.IsNullOrEmpty(action.Icon))
|
||||||
|
{
|
||||||
|
@((MarkupString) " ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span class="oi oi-@action.Icon" aria-hidden="true"></span>
|
||||||
|
}
|
||||||
|
|
||||||
|
@action.Name
|
||||||
|
</a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,7 +19,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
[Inject] public IPageModuleService PageModuleService { get; set; }
|
[Inject] public IPageModuleService PageModuleService { get; set; }
|
||||||
[Inject] public IModuleService ModuleService { get; set; }
|
[Inject] public IModuleService ModuleService { get; set; }
|
||||||
|
|
||||||
protected List<ActionViewModel> Actions;
|
public List<ActionViewModel> Actions;
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
@ -31,51 +31,52 @@ namespace Oqtane.Themes.Controls
|
|||||||
var actionList = new List<ActionViewModel>();
|
var actionList = new List<ActionViewModel>();
|
||||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions))
|
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions))
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel {Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)});
|
actionList.Add(new ActionViewModel {Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)});
|
||||||
|
|
||||||
if (UserSecurity.GetPermissionStrings(ModuleState.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(Constants.AllUsersRole))
|
if (UserSecurity.GetPermissionStrings(ModuleState.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(Constants.AllUsersRole))
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel { Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) });
|
actionList.Add(new ActionViewModel {Icon=Icons.CircleX, Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel { Name = "Publish Module", Action = async (s, m) => await Publish(s, m) });
|
actionList.Add(new ActionViewModel {Icon=Icons.CircleCheck, Name = "Publish Module", Action = async (s, m) => await Publish(s, m) });
|
||||||
}
|
}
|
||||||
actionList.Add(new ActionViewModel { Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) });
|
actionList.Add(new ActionViewModel {Icon=Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) });
|
||||||
|
|
||||||
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel { Name = "" });
|
actionList.Add(new ActionViewModel { Name = "" });
|
||||||
actionList.Add(new ActionViewModel {Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import")});
|
actionList.Add(new ActionViewModel {Icon=Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import")});
|
||||||
actionList.Add(new ActionViewModel {Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")});
|
actionList.Add(new ActionViewModel {Icon = Icons.CloudDownload, Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")});
|
||||||
}
|
}
|
||||||
|
|
||||||
actionList.Add(new ActionViewModel {Name = ""});
|
actionList.Add(new ActionViewModel {Name = ""});
|
||||||
|
|
||||||
if (ModuleState.PaneModuleIndex > 0)
|
if (ModuleState.PaneModuleIndex > 0)
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel {Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)});
|
actionList.Add(new ActionViewModel {Icon = Icons.DataTransferUpload ,Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModuleState.PaneModuleIndex > 0)
|
if (ModuleState.PaneModuleIndex > 0)
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel {Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)});
|
actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickTop, Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel {Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)});
|
actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickBottom, Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel {Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
actionList.Add(new ActionViewModel {Icon = Icons.DataTransferDownload, Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (string pane in PageState.Page.Panes)
|
foreach (string pane in PageState.Page.Panes)
|
||||||
{
|
{
|
||||||
if (pane != ModuleState.Pane)
|
if (pane != ModuleState.Pane)
|
||||||
{
|
{
|
||||||
actionList.Add(new ActionViewModel {Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
actionList.Add(new ActionViewModel {Icon = Icons.AccountLogin, Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,8 +203,8 @@ namespace Oqtane.Themes.Controls
|
|||||||
|
|
||||||
public class ActionViewModel
|
public class ActionViewModel
|
||||||
{
|
{
|
||||||
|
public string Icon { get; set; }
|
||||||
public string Name { set; get; }
|
public string Name { set; get; }
|
||||||
|
|
||||||
public Func<string, PageModule, Task<string>> Action { set; get; }
|
public Func<string, PageModule, Task<string>> Action { set; get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits ThemeControlBase
|
@inherits ThemeControlBase
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
<span class="app-profile">
|
<span class="app-profile">
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{
|
{
|
||||||
public interface IContainerControl
|
public interface IContainerControl
|
||||||
{
|
{
|
||||||
string Name { get; } // friendly name for a container
|
|
||||||
string Thumbnail { get; } // screen shot of a container - assumed to be in the ThemePath() folder
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
{
|
{
|
||||||
public interface ILayoutControl
|
public interface ILayoutControl
|
||||||
{
|
{
|
||||||
string Name { get; } // friendly name for a layout
|
|
||||||
string Thumbnail { get; } // screen shot of a layout - assumed to be in the ThemePath() folder
|
|
||||||
string Panes { get; } // identifies all panes in a theme ( delimited by "," or ";" )
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
@namespace Oqtane.Themes.OqtaneTheme
|
@namespace Oqtane.Themes.OqtaneTheme
|
||||||
@inherits ThemeBase
|
@inherits ThemeBase
|
||||||
@implements IThemeControl
|
|
||||||
|
|
||||||
<main role="main">
|
<main role="main">
|
||||||
<nav class="navbar navbar-expand-md navbar-dark bg-primary fixed-top">
|
<nav class="navbar navbar-expand-md navbar-dark bg-primary fixed-top">
|
||||||
@ -24,10 +23,10 @@
|
|||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css", Integrity = "sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/cyborg/bootstrap.min.css", Integrity = "sha384-GKugkVcT8wqoh3M8z1lqHbU+g6j498/ZT/zuXbepz7Dc09/otQZxTimkEMTkRWHP", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.3.1.slim.min.js", Integrity = "sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.5.1.slim.min.js", Integrity = "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", Integrity = "sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js", Integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js", Integrity = "sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM", CrossOrigin = "anonymous" }
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Oqtane.Themes
|
namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
public abstract class ThemeBase : ComponentBase
|
public abstract class ThemeBase : ComponentBase, IThemeControl
|
||||||
{
|
{
|
||||||
[Inject]
|
[Inject]
|
||||||
protected IJSRuntime JSRuntime { get; set; }
|
protected IJSRuntime JSRuntime { get; set; }
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
namespace Oqtane.Themes
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
|
[OqtaneIgnore]
|
||||||
public abstract class ThemeControlBase : ThemeBase
|
public abstract class ThemeControlBase : ThemeBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
{
|
{
|
||||||
_moduleState = Module; // passed in from Pane component
|
_moduleState = Module; // passed in from Pane component
|
||||||
string container = _moduleState.ContainerType;
|
string container = _moduleState.ContainerType;
|
||||||
if (PageState.ModuleId != -1 && PageState.Action != "" && _moduleState.UseAdminContainer)
|
if (PageState.ModuleId != -1 && _moduleState.UseAdminContainer)
|
||||||
{
|
{
|
||||||
container = Constants.DefaultAdminContainer;
|
container = Constants.DefaultAdminContainer;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace Oqtane.UI
|
|||||||
public List<Module> Modules { get; set; }
|
public List<Module> Modules { get; set; }
|
||||||
public Uri Uri { get; set; }
|
public Uri Uri { get; set; }
|
||||||
public Dictionary<string, string> QueryString { get; set; }
|
public Dictionary<string, string> QueryString { get; set; }
|
||||||
|
public string UrlParameters { get; set; }
|
||||||
public int ModuleId { get; set; }
|
public int ModuleId { get; set; }
|
||||||
public string Action { get; set; }
|
public string Action { get; set; }
|
||||||
public bool EditMode { get; set; }
|
public bool EditMode { get; set; }
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.UI
|
@using Microsoft.AspNetCore.Components.Rendering
|
||||||
|
@namespace Oqtane.UI
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IModuleService ModuleService
|
@inject IModuleService ModuleService
|
||||||
@inject IModuleDefinitionService ModuleDefinitionService
|
@inject IModuleDefinitionService ModuleDefinitionService
|
||||||
@ -25,7 +26,7 @@
|
|||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane)
|
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane)
|
||||||
{
|
{
|
||||||
_paneadminborder = "app-pane-admin-border";
|
_paneadminborder = "app-pane-admin-border";
|
||||||
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
||||||
@ -38,12 +39,12 @@
|
|||||||
|
|
||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
if (PageState.ModuleId != -1 && PageState.Action != "")
|
if (PageState.ModuleId != -1 && PageState.Action != Constants.DefaultAction)
|
||||||
{
|
{
|
||||||
if (Name.ToLower() == Constants.AdminPane.ToLower())
|
if (Name.ToLower() == Constants.AdminPane.ToLower())
|
||||||
{
|
{
|
||||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||||
if (module != null)
|
if (module != null && !module.IsDeleted)
|
||||||
{
|
{
|
||||||
var typename = module.ModuleType;
|
var typename = module.ModuleType;
|
||||||
// check for core module actions component
|
// check for core module actions component
|
||||||
@ -88,10 +89,7 @@
|
|||||||
{
|
{
|
||||||
module.Title = module.ControlTitle;
|
module.Title = module.ControlTitle;
|
||||||
}
|
}
|
||||||
|
CreateComponent(builder, module);
|
||||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
|
||||||
builder.AddAttribute(1, "Module", module);
|
|
||||||
builder.CloseComponent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -106,14 +104,12 @@
|
|||||||
if (PageState.ModuleId != -1)
|
if (PageState.ModuleId != -1)
|
||||||
{
|
{
|
||||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||||
if (module != null && module.Pane.ToLower() == Name.ToLower())
|
if (module != null && module.Pane.ToLower() == Name.ToLower() && !module.IsDeleted)
|
||||||
{
|
{
|
||||||
// check if user is authorized to view module
|
// check if user is authorized to view module
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||||
{
|
{
|
||||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
CreateComponent(builder, module);
|
||||||
builder.AddAttribute(1, "Module", module);
|
|
||||||
builder.CloseComponent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,14 +120,19 @@
|
|||||||
// check if user is authorized to view module
|
// check if user is authorized to view module
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||||
{
|
{
|
||||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
CreateComponent(builder, module);
|
||||||
builder.AddAttribute(1, "Module", module);
|
|
||||||
builder.SetKey(module.PageModuleId);
|
|
||||||
builder.CloseComponent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CreateComponent(RenderTreeBuilder builder, Module module)
|
||||||
|
{
|
||||||
|
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||||
|
builder.AddAttribute(1, "Module", module);
|
||||||
|
builder.SetKey(module.PageModuleId);
|
||||||
|
builder.CloseComponent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,8 @@
|
|||||||
User user = null;
|
User user = null;
|
||||||
List<Module> modules;
|
List<Module> modules;
|
||||||
var moduleid = -1;
|
var moduleid = -1;
|
||||||
var action = "";
|
var action = string.Empty;
|
||||||
|
var urlparameters = string.Empty;
|
||||||
var editmode = false;
|
var editmode = false;
|
||||||
var reload = Reload.None;
|
var reload = Reload.None;
|
||||||
var lastsyncdate = DateTime.UtcNow;
|
var lastsyncdate = DateTime.UtcNow;
|
||||||
@ -179,23 +180,62 @@
|
|||||||
// extract admin route elements from path
|
// extract admin route elements from path
|
||||||
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
int result;
|
int result;
|
||||||
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
|
||||||
if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result))
|
int modIdPos = 0;
|
||||||
|
int actionPos = 0;
|
||||||
|
int urlParametersPos = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < segments.Length; i++)
|
||||||
{
|
{
|
||||||
action = segments[segments.Length - 1];
|
|
||||||
moduleid = result;
|
if (segments[i] == Constants.UrlParametersDelimiter)
|
||||||
path = path.Replace(moduleid.ToString() + "/" + action + "/", "");
|
{
|
||||||
|
urlParametersPos = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i >= urlParametersPos && urlParametersPos != 0)
|
||||||
|
{
|
||||||
|
urlparameters += "/" + segments[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segments[i] == Constants.ModuleDelimiter)
|
||||||
|
{
|
||||||
|
modIdPos = i + 1;
|
||||||
|
actionPos = modIdPos + 1;
|
||||||
|
if (actionPos > segments.Length - 1)
|
||||||
|
{
|
||||||
|
action = Constants.DefaultAction;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// check if path has moduleid specification ie. pagename/moduleid/
|
action = segments[actionPos];
|
||||||
if (segments.Length >= 1 && int.TryParse(segments[segments.Length - 1], out result))
|
|
||||||
{
|
|
||||||
moduleid = result;
|
|
||||||
path = path.Replace(moduleid.ToString() + "/", "");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
||||||
|
if (modIdPos > 0)
|
||||||
|
{
|
||||||
|
int.TryParse(segments[modIdPos], out result);
|
||||||
|
moduleid = result;
|
||||||
|
if (actionPos > segments.Length - 1)
|
||||||
|
{
|
||||||
|
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/", "");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos] + "/", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (urlParametersPos > 0)
|
||||||
|
{
|
||||||
|
path = path.Replace(segments[urlParametersPos - 1] + urlparameters + "/", "");
|
||||||
|
}
|
||||||
|
|
||||||
// remove trailing slash so it can be used as a key for Pages
|
// remove trailing slash so it can be used as a key for Pages
|
||||||
if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1);
|
if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1);
|
||||||
|
|
||||||
@ -220,17 +260,14 @@
|
|||||||
{
|
{
|
||||||
page = pages.Where(item => item.Path == path).FirstOrDefault();
|
page = pages.Where(item => item.Path == path).FirstOrDefault();
|
||||||
reload = Reload.Page;
|
reload = Reload.Page;
|
||||||
if (page != null)
|
editmode = false;
|
||||||
{
|
|
||||||
editmode = page.EditMode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page != null)
|
if (page != null)
|
||||||
{
|
{
|
||||||
if (PageState == null)
|
if (PageState == null)
|
||||||
{
|
{
|
||||||
editmode = page.EditMode;
|
editmode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if user is authorized to view page
|
// check if user is authorized to view page
|
||||||
@ -263,6 +300,7 @@
|
|||||||
Modules = modules,
|
Modules = modules,
|
||||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||||
QueryString = querystring,
|
QueryString = querystring,
|
||||||
|
UrlParameters = urlparameters,
|
||||||
ModuleId = moduleid,
|
ModuleId = moduleid,
|
||||||
Action = action,
|
Action = action,
|
||||||
EditMode = editmode,
|
EditMode = editmode,
|
||||||
@ -360,6 +398,13 @@
|
|||||||
|
|
||||||
string panes = "";
|
string panes = "";
|
||||||
Type themetype = Type.GetType(page.ThemeType);
|
Type themetype = Type.GetType(page.ThemeType);
|
||||||
|
if (themetype == null)
|
||||||
|
{
|
||||||
|
// fallback
|
||||||
|
page.ThemeType = Constants.DefaultTheme;
|
||||||
|
page.LayoutType = Constants.DefaultLayout;
|
||||||
|
themetype = Type.GetType(Constants.DefaultTheme);
|
||||||
|
}
|
||||||
if (themetype != null)
|
if (themetype != null)
|
||||||
{
|
{
|
||||||
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
||||||
@ -375,7 +420,7 @@
|
|||||||
Type layouttype = Type.GetType(page.LayoutType);
|
Type layouttype = Type.GetType(page.LayoutType);
|
||||||
if (layouttype != null)
|
if (layouttype != null)
|
||||||
{
|
{
|
||||||
var layoutobject = Activator.CreateInstance(layouttype) as ILayoutControl;
|
var layoutobject = Activator.CreateInstance(layouttype) as IThemeControl;
|
||||||
if (layoutobject != null)
|
if (layoutobject != null)
|
||||||
{
|
{
|
||||||
panes = layoutobject.Panes;
|
panes = layoutobject.Panes;
|
||||||
@ -401,7 +446,7 @@
|
|||||||
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
||||||
{
|
{
|
||||||
var typename = string.Empty;
|
var typename = string.Empty;
|
||||||
if (module.ModuleDefinition != null)
|
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))
|
||||||
{
|
{
|
||||||
typename = module.ModuleDefinition.ControlTypeTemplate;
|
typename = module.ModuleDefinition.ControlTypeTemplate;
|
||||||
}
|
}
|
||||||
|
@ -54,11 +54,6 @@
|
|||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
var themeType = Type.GetType(PageState.Page.ThemeType);
|
var themeType = Type.GetType(PageState.Page.ThemeType);
|
||||||
if (themeType == null)
|
|
||||||
{
|
|
||||||
// fallback
|
|
||||||
themeType = Type.GetType(Constants.DefaultTheme);
|
|
||||||
}
|
|
||||||
builder.OpenComponent(0, themeType);
|
builder.OpenComponent(0, themeType);
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
};
|
};
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Client</id>
|
<id>Oqtane.Client</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
<releaseNotes>Initial Release</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||||
<summary>A modular application framework for Blazor</summary>
|
<summary>A modular application framework for Blazor</summary>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Framework</id>
|
<id>Oqtane.Framework</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -13,16 +13,11 @@
|
|||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
<tags>oqtane framework</tags>
|
<tags>oqtane framework</tags>
|
||||||
<releaseNotes>Initial Release</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||||
<summary>A modular application framework for Blazor</summary>
|
<summary>A modular application framework for Blazor</summary>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib\netcoreapp3.1" />
|
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\*.*" target="lib\netcoreapp3.1" />
|
||||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.pdb" target="lib\netcoreapp3.1" />
|
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\wwwroot\**\*.*" target="wwwroot" />
|
||||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib\netcoreapp3.1" />
|
|
||||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.pdb" target="lib\netcoreapp3.1" />
|
|
||||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib\netcoreapp3.1" />
|
|
||||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.pdb" target="lib\netcoreapp3.1" />
|
|
||||||
<file src="..\Oqtane.Server\wwwroot\**\*.*" target="wwwroot" />
|
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Server</id>
|
<id>Oqtane.Server</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
<releaseNotes>Initial Release</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||||
<summary>A modular application framework for Blazor</summary>
|
<summary>A modular application framework for Blazor</summary>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Shared</id>
|
<id>Oqtane.Shared</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
<releaseNotes>Initial Release</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||||
<summary>A modular application framework for Blazor</summary>
|
<summary>A modular application framework for Blazor</summary>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
1
Oqtane.Package/install.ps1
Normal file
1
Oqtane.Package/install.ps1
Normal file
@ -0,0 +1 @@
|
|||||||
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.1.0.3.Install.zip" -Force
|
Binary file not shown.
@ -1,5 +1,18 @@
|
|||||||
DEL "*.nupkg"
|
del "*.nupkg"
|
||||||
dotnet clean -c Release ..\Oqtane.sln
|
dotnet clean -c Release ..\Oqtane.sln
|
||||||
dotnet build -c Release ..\Oqtane.sln
|
dotnet build -c Release ..\Oqtane.sln
|
||||||
dotnet pack -o .\ -c Release ..\Oqtane.sln
|
nuget.exe pack Oqtane.Client.nuspec
|
||||||
|
nuget.exe pack Oqtane.Server.nuspec
|
||||||
|
nuget.exe pack Oqtane.Shared.nuspec
|
||||||
|
del /F/Q/S "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish" > NUL
|
||||||
|
rmdir /Q/S "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish"
|
||||||
|
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
|
||||||
|
del "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\appsettings.json"
|
||||||
|
ren "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\appsettings.release.json" "appsettings.json"
|
||||||
|
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
||||||
|
del "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\appsettings.json"
|
||||||
|
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
|
||||||
|
del "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\Oqtane.Upgrade.*"
|
||||||
nuget.exe pack Oqtane.Framework.nuspec
|
nuget.exe pack Oqtane.Framework.nuspec
|
||||||
|
|
||||||
|
|
||||||
|
1
Oqtane.Package/upgrade.ps1
Normal file
1
Oqtane.Package/upgrade.ps1
Normal file
@ -0,0 +1 @@
|
|||||||
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.1.0.3.Upgrade.zip" -Force
|
@ -1,4 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -135,8 +135,20 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = Constants.RegisteredRole)]
|
[Authorize(Roles = Constants.RegisteredRole)]
|
||||||
public Models.File Put(int id, [FromBody] Models.File file)
|
public Models.File Put(int id, [FromBody] Models.File file)
|
||||||
{
|
{
|
||||||
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, file.Folder.FolderId, PermissionNames.Edit))
|
if (ModelState.IsValid && _userPermissions.IsAuthorized(User, EntityNames.Folder, file.FolderId, PermissionNames.Edit))
|
||||||
{
|
{
|
||||||
|
file.Folder = _folders.GetFolder(file.FolderId);
|
||||||
|
Models.File _file = _files.GetFile(id, false);
|
||||||
|
if (_file.Name != file.Name || _file.FolderId != file.FolderId)
|
||||||
|
{
|
||||||
|
string folderpath = GetFolderPath(file.Folder);
|
||||||
|
if (!Directory.Exists(folderpath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(folderpath);
|
||||||
|
}
|
||||||
|
System.IO.File.Move(Path.Combine(GetFolderPath(_file.Folder), _file.Name), Path.Combine(folderpath, file.Name));
|
||||||
|
}
|
||||||
|
file.Extension = Path.GetExtension(file.Name).ToLower().Replace(".", "");
|
||||||
file = _files.UpdateFile(file);
|
file = _files.UpdateFile(file);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", file);
|
_logger.Log(LogLevel.Information, this, LogFunction.Update, "File Updated {File}", file);
|
||||||
}
|
}
|
||||||
@ -483,7 +495,7 @@ namespace Oqtane.Controllers
|
|||||||
string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
||||||
foreach (string folder in folders)
|
foreach (string folder in folders)
|
||||||
{
|
{
|
||||||
path = Utilities.PathCombine(path, folder, "\\");
|
path = Utilities.PathCombine(path, folder, Path.DirectorySeparatorChar.ToString());
|
||||||
if (!Directory.Exists(path))
|
if (!Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(path);
|
Directory.CreateDirectory(path);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
@ -10,20 +11,25 @@ using Oqtane.Extensions;
|
|||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
[Route("{alias}/api/[controller]")]
|
[Route("{alias}/api/[controller]")]
|
||||||
public class FolderController : Controller
|
public class FolderController : Controller
|
||||||
{
|
{
|
||||||
|
private readonly IWebHostEnvironment _environment;
|
||||||
private readonly IFolderRepository _folders;
|
private readonly IFolderRepository _folders;
|
||||||
private readonly IUserPermissions _userPermissions;
|
private readonly IUserPermissions _userPermissions;
|
||||||
|
private readonly ITenantResolver _tenants;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
|
|
||||||
public FolderController(IFolderRepository folders, IUserPermissions userPermissions, ILogManager logger)
|
public FolderController(IWebHostEnvironment environment, IFolderRepository folders, IUserPermissions userPermissions, ITenantResolver tenants, ILogManager logger)
|
||||||
{
|
{
|
||||||
|
_environment = environment;
|
||||||
_folders = folders;
|
_folders = folders;
|
||||||
_userPermissions = userPermissions;
|
_userPermissions = userPermissions;
|
||||||
|
_tenants = tenants;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +118,7 @@ namespace Oqtane.Controllers
|
|||||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||||
}
|
}
|
||||||
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
folder.Path = Utilities.PathCombine(folder.Path, Path.DirectorySeparatorChar.ToString());
|
||||||
folder = _folders.AddFolder(folder);
|
folder = _folders.AddFolder(folder);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
|
||||||
}
|
}
|
||||||
@ -142,12 +148,19 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
if (folder.IsPathValid())
|
if (folder.IsPathValid())
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(folder.Path) && folder.ParentId != null)
|
if (folder.ParentId != null)
|
||||||
{
|
{
|
||||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||||
}
|
}
|
||||||
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
folder.Path = Utilities.PathCombine(folder.Path, Path.DirectorySeparatorChar.ToString());
|
||||||
|
|
||||||
|
Models.Folder _folder = _folders.GetFolder(id, false);
|
||||||
|
if (_folder.Path != folder.Path && Directory.Exists(GetFolderPath(_folder)))
|
||||||
|
{
|
||||||
|
Directory.Move(GetFolderPath(_folder), GetFolderPath(folder));
|
||||||
|
}
|
||||||
|
|
||||||
folder = _folders.UpdateFolder(folder);
|
folder = _folders.UpdateFolder(folder);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
|
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
|
||||||
}
|
}
|
||||||
@ -210,5 +223,10 @@ namespace Oqtane.Controllers
|
|||||||
HttpContext.Response.StatusCode = 401;
|
HttpContext.Response.StatusCode = 401;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetFolderPath(Folder folder)
|
||||||
|
{
|
||||||
|
return Utilities.PathCombine(_environment.ContentRootPath, "Content", "Tenants", _tenants.GetTenant().TenantId.ToString(), "Sites", folder.SiteId.ToString(), folder.Path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ namespace Oqtane.Controllers
|
|||||||
var pages = _pages.GetPages(module.SiteId).ToList();
|
var pages = _pages.GetPages(module.SiteId).ToList();
|
||||||
foreach (Page page in pages)
|
foreach (Page page in pages)
|
||||||
{
|
{
|
||||||
if (page.PageId != pageModule.PageId && !page.EditMode)
|
if (page.PageId != pageModule.PageId && !page.Path.StartsWith("admin/"))
|
||||||
{
|
{
|
||||||
_pageModules.AddPageModule(new PageModule { PageId = page.PageId, ModuleId = pageModule.ModuleId, Title = pageModule.Title, Pane = pageModule.Pane, Order = pageModule.Order, ContainerType = pageModule.ContainerType });
|
_pageModules.AddPageModule(new PageModule { PageId = page.PageId, ModuleId = pageModule.ModuleId, Title = pageModule.Title, Pane = pageModule.Pane, Order = pageModule.Order, ContainerType = pageModule.ContainerType });
|
||||||
}
|
}
|
||||||
|
21
Oqtane.Server/Controllers/ModuleControllerBase.cs
Normal file
21
Oqtane.Server/Controllers/ModuleControllerBase.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Oqtane.Infrastructure;
|
||||||
|
|
||||||
|
namespace Oqtane.Controllers
|
||||||
|
{
|
||||||
|
public class ModuleControllerBase : Controller
|
||||||
|
{
|
||||||
|
protected readonly ILogManager _logger;
|
||||||
|
protected int _entityId = -1; // passed as a querystring parameter for policy authorization and used for validation
|
||||||
|
|
||||||
|
public ModuleControllerBase(ILogManager logger, IHttpContextAccessor accessor)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
if (accessor.HttpContext.Request.Query.ContainsKey("entityid"))
|
||||||
|
{
|
||||||
|
_entityId = int.Parse(accessor.HttpContext.Request.Query["entityid"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -94,8 +94,8 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = Constants.HostRole)]
|
[Authorize(Roles = Constants.HostRole)]
|
||||||
public void InstallModules()
|
public void InstallModules()
|
||||||
{
|
{
|
||||||
_installationManager.InstallPackages("Modules", true);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Modules Installed");
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Modules Installed");
|
||||||
|
_installationManager.InstallPackages("Modules", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DELETE api/<controller>/5?siteid=x
|
// DELETE api/<controller>/5?siteid=x
|
||||||
@ -170,19 +170,19 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
string rootPath;
|
string rootPath;
|
||||||
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
|
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
|
||||||
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,"\\");
|
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,Path.DirectorySeparatorChar.ToString());
|
||||||
|
|
||||||
if (moduleDefinition.Template == "internal")
|
if (moduleDefinition.Template == "internal")
|
||||||
{
|
{
|
||||||
rootPath = Utilities.PathCombine(rootFolder.FullName,"\\");
|
rootPath = Utilities.PathCombine(rootFolder.FullName,Path.DirectorySeparatorChar.ToString());
|
||||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + "s, Oqtane.Client";
|
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", Oqtane.Client";
|
||||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
|
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name + "s","\\");
|
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName , moduleDefinition.Owner + "." + moduleDefinition.Name,Path.DirectorySeparatorChar.ToString());
|
||||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + "s, " + moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Client.Oqtane";
|
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane";
|
||||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Server.Oqtane";
|
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane";
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition);
|
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition);
|
||||||
@ -196,8 +196,8 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
// add embedded resources to project
|
// add embedded resources to project
|
||||||
List<string> resources = new List<string>();
|
List<string> resources = new List<string>();
|
||||||
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name + "s", "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + "s.1.0.0.sql"));
|
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".1.0.0.sql"));
|
||||||
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name + "s", "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + "s.Uninstall.sql"));
|
resources.Add(Utilities.PathCombine("Modules", moduleDefinition.Owner + "." + moduleDefinition.Name, "Scripts", moduleDefinition.Owner + "." + moduleDefinition.Name + ".Uninstall.sql"));
|
||||||
EmbedResourceFiles(Utilities.PathCombine(rootPath, "Oqtane.Server", "Oqtane.Server.csproj"), resources);
|
EmbedResourceFiles(Utilities.PathCombine(rootPath, "Oqtane.Server", "Oqtane.Server.csproj"), resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ namespace Oqtane.Controllers
|
|||||||
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, page.SiteId);
|
_syncManager.AddSyncEvent(_tenants.GetTenant().TenantId, EntityNames.Site, page.SiteId);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", page);
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Page Added {Page}", page);
|
||||||
|
|
||||||
if (!page.EditMode)
|
if (!page.Path.StartsWith("admin/"))
|
||||||
{
|
{
|
||||||
var modules = _modules.GetModules(page.SiteId).Where(item => item.AllPages).ToList();
|
var modules = _modules.GetModules(page.SiteId).Where(item => item.AllPages).ToList();
|
||||||
foreach (Module module in modules)
|
foreach (Module module in modules)
|
||||||
@ -163,7 +163,6 @@ namespace Oqtane.Controllers
|
|||||||
page.Order = 0;
|
page.Order = 0;
|
||||||
page.IsNavigation = false;
|
page.IsNavigation = false;
|
||||||
page.Url = "";
|
page.Url = "";
|
||||||
page.EditMode = false;
|
|
||||||
page.ThemeType = parent.ThemeType;
|
page.ThemeType = parent.ThemeType;
|
||||||
page.LayoutType = parent.LayoutType;
|
page.LayoutType = parent.LayoutType;
|
||||||
page.DefaultContainerType = parent.DefaultContainerType;
|
page.DefaultContainerType = parent.DefaultContainerType;
|
||||||
|
@ -43,8 +43,8 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = Constants.HostRole)]
|
[Authorize(Roles = Constants.HostRole)]
|
||||||
public void InstallThemes()
|
public void InstallThemes()
|
||||||
{
|
{
|
||||||
_installationManager.InstallPackages("Themes", true);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Themes Installed");
|
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Themes Installed");
|
||||||
|
_installationManager.InstallPackages("Themes", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// DELETE api/<controller>/xxx
|
// DELETE api/<controller>/xxx
|
||||||
|
@ -9,6 +9,7 @@ using System.Linq;
|
|||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
@ -148,7 +149,7 @@ namespace Oqtane.Controllers
|
|||||||
notification.SiteId = user.SiteId;
|
notification.SiteId = user.SiteId;
|
||||||
notification.FromUserId = null;
|
notification.FromUserId = null;
|
||||||
notification.ToUserId = newUser.UserId;
|
notification.ToUserId = newUser.UserId;
|
||||||
notification.ToEmail = "";
|
notification.ToEmail = newUser.Email;
|
||||||
notification.Subject = "User Account Verification";
|
notification.Subject = "User Account Verification";
|
||||||
string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
|
string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
|
||||||
string url = HttpContext.Request.Scheme + "://" + _tenants.GetAlias().Name + "/login?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
string url = HttpContext.Request.Scheme + "://" + _tenants.GetAlias().Name + "/login?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||||
@ -157,6 +158,7 @@ namespace Oqtane.Controllers
|
|||||||
notification.CreatedOn = DateTime.UtcNow;
|
notification.CreatedOn = DateTime.UtcNow;
|
||||||
notification.IsDelivered = false;
|
notification.IsDelivered = false;
|
||||||
notification.DeliveredOn = null;
|
notification.DeliveredOn = null;
|
||||||
|
notification.SendOn = DateTime.UtcNow;
|
||||||
_notifications.AddNotification(notification);
|
_notifications.AddNotification(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +175,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add folder for user
|
// add folder for user
|
||||||
Folder folder = _folders.GetFolder(user.SiteId, Utilities.PathCombine("Users","\\"));
|
Folder folder = _folders.GetFolder(user.SiteId, Utilities.PathCombine("Users",Path.DirectorySeparatorChar.ToString()));
|
||||||
if (folder != null)
|
if (folder != null)
|
||||||
{
|
{
|
||||||
_folders.AddFolder(new Folder
|
_folders.AddFolder(new Folder
|
||||||
@ -181,7 +183,7 @@ namespace Oqtane.Controllers
|
|||||||
SiteId = folder.SiteId,
|
SiteId = folder.SiteId,
|
||||||
ParentId = folder.FolderId,
|
ParentId = folder.FolderId,
|
||||||
Name = "My Folder",
|
Name = "My Folder",
|
||||||
Path = Utilities.PathCombine(folder.Path, newUser.UserId.ToString(),"\\"),
|
Path = Utilities.PathCombine(folder.Path, newUser.UserId.ToString(),Path.DirectorySeparatorChar.ToString()),
|
||||||
Order = 1,
|
Order = 1,
|
||||||
IsSystem = true,
|
IsSystem = true,
|
||||||
Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"[" + newUser.UserId.ToString() + "]\"},{\"PermissionName\":\"View\",\"Permissions\":\"All Users\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"[" +
|
Permissions = "[{\"PermissionName\":\"Browse\",\"Permissions\":\"[" + newUser.UserId.ToString() + "]\"},{\"PermissionName\":\"View\",\"Permissions\":\"All Users\"},{\"PermissionName\":\"Edit\",\"Permissions\":\"[" +
|
||||||
@ -385,6 +387,7 @@ namespace Oqtane.Controllers
|
|||||||
notification.CreatedOn = DateTime.UtcNow;
|
notification.CreatedOn = DateTime.UtcNow;
|
||||||
notification.IsDelivered = false;
|
notification.IsDelivered = false;
|
||||||
notification.DeliveredOn = null;
|
notification.DeliveredOn = null;
|
||||||
|
notification.SendOn = DateTime.UtcNow;
|
||||||
_notifications.AddNotification(notification);
|
_notifications.AddNotification(notification);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset Notification Sent For {Username}", user.Username);
|
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset Notification Sent For {Username}", user.Username);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Oqtane.Extensions;
|
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Modules;
|
using Oqtane.Modules;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.UI;
|
using Oqtane.UI;
|
||||||
|
|
||||||
// ReSharper disable once CheckNamespace
|
// ReSharper disable once CheckNamespace
|
||||||
@ -72,14 +69,15 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void LoadAssemblies()
|
private static void LoadAssemblies()
|
||||||
{
|
{
|
||||||
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
||||||
if (assemblyPath == null) return;
|
if (assemblyPath == null) return;
|
||||||
|
|
||||||
var assembliesFolder = new DirectoryInfo(assemblyPath);
|
AssemblyLoadContext.Default.Resolving += ResolveDependencies;
|
||||||
|
|
||||||
|
var assembliesFolder = new DirectoryInfo(assemblyPath);
|
||||||
|
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||||
|
|
||||||
// iterate through Oqtane assemblies in /bin ( filter is narrow to optimize loading process )
|
// iterate through Oqtane assemblies in /bin ( filter is narrow to optimize loading process )
|
||||||
foreach (var dll in assembliesFolder.EnumerateFiles($"*.dll", SearchOption.TopDirectoryOnly).Where(f => f.IsOqtaneAssembly()))
|
foreach (var dll in assembliesFolder.EnumerateFiles($"*.dll", SearchOption.TopDirectoryOnly).Where(f => f.IsOqtaneAssembly()))
|
||||||
@ -95,7 +93,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
|
||||||
if (!assemblies.Any(a => AssemblyName.ReferenceMatchesDefinition(assemblyName, a.GetName())))
|
if (!assemblies.Any(a => AssemblyName.ReferenceMatchesDefinition(assemblyName, a.GetName())))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -121,5 +118,19 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Assembly ResolveDependencies(AssemblyLoadContext context, AssemblyName name)
|
||||||
|
{
|
||||||
|
var assemblyPath = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location) + "\\" + name.Name + ".dll";
|
||||||
|
if (File.Exists(assemblyPath))
|
||||||
|
{
|
||||||
|
return context.LoadFromStream(new MemoryStream(File.ReadAllBytes(assemblyPath)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,8 @@ namespace Oqtane.Infrastructure
|
|||||||
if (!string.IsNullOrEmpty(moduledefinition.ReleaseVersions) && !string.IsNullOrEmpty(moduledefinition.ServerManagerType))
|
if (!string.IsNullOrEmpty(moduledefinition.ReleaseVersions) && !string.IsNullOrEmpty(moduledefinition.ServerManagerType))
|
||||||
{
|
{
|
||||||
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
|
Type moduletype = Type.GetType(moduledefinition.ServerManagerType);
|
||||||
|
if (moduletype != null)
|
||||||
|
{
|
||||||
string[] versions = moduledefinition.ReleaseVersions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
string[] versions = moduledefinition.ReleaseVersions.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
using (var db = new InstallationContext(NormalizeConnectionString(_config.GetConnectionString(SettingKeys.ConnectionStringKey))))
|
||||||
{
|
{
|
||||||
@ -387,6 +388,7 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(result.Message))
|
if (string.IsNullOrEmpty(result.Message))
|
||||||
{
|
{
|
||||||
@ -461,7 +463,7 @@ namespace Oqtane.Infrastructure
|
|||||||
userroles.AddUserRole(userRole);
|
userroles.AddUserRole(userRole);
|
||||||
|
|
||||||
// add user folder
|
// add user folder
|
||||||
var folder = folders.GetFolder(user.SiteId, Utilities.PathCombine("Users", "\\"));
|
var folder = folders.GetFolder(user.SiteId, Utilities.PathCombine("Users", Path.DirectorySeparatorChar.ToString()));
|
||||||
if (folder != null)
|
if (folder != null)
|
||||||
{
|
{
|
||||||
folders.AddFolder(new Folder
|
folders.AddFolder(new Folder
|
||||||
@ -469,7 +471,7 @@ namespace Oqtane.Infrastructure
|
|||||||
SiteId = folder.SiteId,
|
SiteId = folder.SiteId,
|
||||||
ParentId = folder.FolderId,
|
ParentId = folder.FolderId,
|
||||||
Name = "My Folder",
|
Name = "My Folder",
|
||||||
Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), "\\"),
|
Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
|
||||||
Order = 1,
|
Order = 1,
|
||||||
IsSystem = true,
|
IsSystem = true,
|
||||||
Permissions = new List<Permission>
|
Permissions = new List<Permission>
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
using System.Reflection;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using Microsoft.Extensions.Hosting;
|
using System.Reflection;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Oqtane.Shared;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Infrastructure
|
namespace Oqtane.Infrastructure
|
||||||
{
|
{
|
||||||
@ -88,7 +88,7 @@ namespace Oqtane.Infrastructure
|
|||||||
// deploy to appropriate locations
|
// deploy to appropriate locations
|
||||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||||
{
|
{
|
||||||
string foldername = Path.GetDirectoryName(entry.FullName).Split('\\')[0];
|
string foldername = Path.GetDirectoryName(entry.FullName).Split(Path.DirectorySeparatorChar)[0];
|
||||||
string filename = Path.GetFileName(entry.FullName);
|
string filename = Path.GetFileName(entry.FullName);
|
||||||
|
|
||||||
switch (foldername)
|
switch (foldername)
|
||||||
@ -98,7 +98,12 @@ namespace Oqtane.Infrastructure
|
|||||||
ExtractFile(entry, filename);
|
ExtractFile(entry, filename);
|
||||||
break;
|
break;
|
||||||
case "wwwroot":
|
case "wwwroot":
|
||||||
filename = Path.Combine(webRootPath, Utilities.PathCombine(entry.FullName.Replace("wwwroot/", "").Split('/')));
|
filename = Path.Combine(webRootPath.Replace(Path.DirectorySeparatorChar + "wwwroot", ""), Utilities.PathCombine(entry.FullName.Split('/')));
|
||||||
|
ExtractFile(entry, filename);
|
||||||
|
break;
|
||||||
|
case "runtimes":
|
||||||
|
var destSubFolder = Path.GetDirectoryName(entry.FullName);
|
||||||
|
filename = Path.Combine(binFolder, destSubFolder, filename);
|
||||||
ExtractFile(entry, filename);
|
ExtractFile(entry, filename);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -121,8 +126,16 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(filename));
|
Directory.CreateDirectory(Path.GetDirectoryName(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
entry.ExtractToFile(filename, true);
|
entry.ExtractToFile(filename, true);
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// an error occurred extracting the file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpgradeFramework()
|
public void UpgradeFramework()
|
||||||
{
|
{
|
||||||
@ -163,12 +176,13 @@ namespace Oqtane.Infrastructure
|
|||||||
packageversion = node.InnerText;
|
packageversion = node.InnerText;
|
||||||
}
|
}
|
||||||
reader.Close();
|
reader.Close();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure package version is higher than current framework version
|
// ensure package version is greater than or equal to current framework version
|
||||||
if (packageversion != "" && Version.Parse(Constants.Version).CompareTo(Version.Parse(packageversion)) < 0)
|
if (packageversion != "" && Version.Parse(Constants.Version).CompareTo(Version.Parse(packageversion)) <= 0)
|
||||||
{
|
{
|
||||||
FinishUpgrade();
|
FinishUpgrade();
|
||||||
}
|
}
|
||||||
@ -179,28 +193,26 @@ namespace Oqtane.Infrastructure
|
|||||||
private void FinishUpgrade()
|
private void FinishUpgrade()
|
||||||
{
|
{
|
||||||
// check if upgrade application exists
|
// check if upgrade application exists
|
||||||
|
string Upgrader = "Oqtane.Upgrade.dll";
|
||||||
string folder = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
string folder = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
||||||
if (folder == null || !File.Exists(Path.Combine(folder, "Oqtane.Upgrade.exe"))) return;
|
if (folder == null || !File.Exists(Path.Combine(folder, Upgrader))) return;
|
||||||
|
|
||||||
// run upgrade application
|
// run upgrade application
|
||||||
var process = new Process
|
using (var process = new Process())
|
||||||
{
|
{
|
||||||
StartInfo =
|
process.StartInfo = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = Path.Combine(folder, "Oqtane.Upgrade.exe"),
|
WorkingDirectory = folder,
|
||||||
Arguments = "\"" + _environment.ContentRootPath + "\" \"" + _environment.WebRootPath + "\"",
|
FileName = "dotnet",
|
||||||
ErrorDialog = false,
|
Arguments = Path.Combine(folder, Upgrader) + " \"" + _environment.ContentRootPath + "\" \"" + _environment.WebRootPath + "\"",
|
||||||
UseShellExecute = false,
|
UseShellExecute = false,
|
||||||
|
ErrorDialog = false,
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true,
|
||||||
RedirectStandardOutput = false,
|
RedirectStandardOutput = false,
|
||||||
RedirectStandardError = false
|
RedirectStandardError = false
|
||||||
}
|
|
||||||
};
|
};
|
||||||
process.Start();
|
process.Start();
|
||||||
process.Dispose();
|
};
|
||||||
|
|
||||||
// stop application so upgrade application can proceed
|
|
||||||
RestartApplication();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RestartApplication()
|
public void RestartApplication()
|
||||||
|
@ -27,6 +27,8 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
protected async Task ExecuteAsync(CancellationToken stoppingToken)
|
protected async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||||
{
|
{
|
||||||
|
await Task.Yield(); // required so that this method does not block startup
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
while (!stoppingToken.IsCancellationRequested)
|
while (!stoppingToken.IsCancellationRequested)
|
||||||
@ -41,21 +43,26 @@ namespace Oqtane.Infrastructure
|
|||||||
Job job = jobs.GetJobs().Where(item => item.JobType == jobType).FirstOrDefault();
|
Job job = jobs.GetJobs().Where(item => item.JobType == jobType).FirstOrDefault();
|
||||||
if (job != null && job.IsEnabled && !job.IsExecuting)
|
if (job != null && job.IsEnabled && !job.IsExecuting)
|
||||||
{
|
{
|
||||||
// set next execution date
|
// get next execution date
|
||||||
|
DateTime NextExecution;
|
||||||
if (job.NextExecution == null)
|
if (job.NextExecution == null)
|
||||||
{
|
{
|
||||||
if (job.StartDate != null)
|
if (job.StartDate != null)
|
||||||
{
|
{
|
||||||
job.NextExecution = job.StartDate;
|
NextExecution = job.StartDate.Value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
job.NextExecution = DateTime.UtcNow;
|
NextExecution = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NextExecution = job.NextExecution.Value;
|
||||||
|
}
|
||||||
|
|
||||||
// determine if the job should be run
|
// determine if the job should be run
|
||||||
if (job.NextExecution <= DateTime.UtcNow && (job.EndDate == null || job.EndDate >= DateTime.UtcNow))
|
if (NextExecution <= DateTime.UtcNow && (job.EndDate == null || job.EndDate >= DateTime.UtcNow))
|
||||||
{
|
{
|
||||||
IJobLogRepository jobLogs = scope.ServiceProvider.GetRequiredService<IJobLogRepository>();
|
IJobLogRepository jobLogs = scope.ServiceProvider.GetRequiredService<IJobLogRepository>();
|
||||||
|
|
||||||
@ -89,7 +96,7 @@ namespace Oqtane.Infrastructure
|
|||||||
jobLogs.UpdateJobLog(log);
|
jobLogs.UpdateJobLog(log);
|
||||||
|
|
||||||
// update the job
|
// update the job
|
||||||
job.NextExecution = CalculateNextExecution(job.NextExecution.Value, job.Frequency, job.Interval);
|
job.NextExecution = CalculateNextExecution(NextExecution, job.Frequency, job.Interval);
|
||||||
job.IsExecuting = false;
|
job.IsExecuting = false;
|
||||||
jobs.UpdateJob(job);
|
jobs.UpdateJob(job);
|
||||||
|
|
||||||
|
@ -20,11 +20,15 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
string log = "";
|
string log = "";
|
||||||
|
|
||||||
// iterate through aliases in this installation
|
// iterate through tenants in this installation
|
||||||
|
List<int> tenants = new List<int>();
|
||||||
var aliasRepository = provider.GetRequiredService<IAliasRepository>();
|
var aliasRepository = provider.GetRequiredService<IAliasRepository>();
|
||||||
List<Alias> aliases = aliasRepository.GetAliases().ToList();
|
List<Alias> aliases = aliasRepository.GetAliases().ToList();
|
||||||
foreach (Alias alias in aliases)
|
foreach (Alias alias in aliases)
|
||||||
{
|
{
|
||||||
|
if (tenants.Contains(alias.TenantId)) continue;
|
||||||
|
tenants.Add(alias.TenantId);
|
||||||
|
|
||||||
// use the SiteState to set the Alias explicitly so the tenant can be resolved
|
// use the SiteState to set the Alias explicitly so the tenant can be resolved
|
||||||
var siteState = provider.GetRequiredService<SiteState>();
|
var siteState = provider.GetRequiredService<SiteState>();
|
||||||
siteState.Alias = alias;
|
siteState.Alias = alias;
|
||||||
@ -34,11 +38,11 @@ namespace Oqtane.Infrastructure
|
|||||||
var settingRepository = provider.GetRequiredService<ISettingRepository>();
|
var settingRepository = provider.GetRequiredService<ISettingRepository>();
|
||||||
var notificationRepository = provider.GetRequiredService<INotificationRepository>();
|
var notificationRepository = provider.GetRequiredService<INotificationRepository>();
|
||||||
|
|
||||||
// iterate through sites
|
// iterate through sites for this tenant
|
||||||
List<Site> sites = siteRepository.GetSites().ToList();
|
List<Site> sites = siteRepository.GetSites().ToList();
|
||||||
foreach (Site site in sites)
|
foreach (Site site in sites)
|
||||||
{
|
{
|
||||||
log += "Processing Notifications For Site: " + site.Name + "\n\n";
|
log += "Processing Notifications For Site: " + site.Name + "<br />";
|
||||||
|
|
||||||
// get site settings
|
// get site settings
|
||||||
List<Setting> sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList();
|
List<Setting> sitesettings = settingRepository.GetSettings(EntityNames.Site, site.SiteId).ToList();
|
||||||
@ -101,14 +105,14 @@ namespace Oqtane.Infrastructure
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// error
|
// error
|
||||||
log += ex.Message + "\n\n";
|
log += ex.Message + "<br />";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log += "Notifications Delivered: " + sent + "\n\n";
|
log += "Notifications Delivered: " + sent + "<br />";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log += "SMTP Not Configured" + "\n\n";
|
log += "SMTP Not Configured" + "<br />";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +120,6 @@ namespace Oqtane.Infrastructure
|
|||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Dictionary<string, string> GetSettings(List<Setting> settings)
|
private Dictionary<string, string> GetSettings(List<Setting> settings)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> dictionary = new Dictionary<string, string>();
|
Dictionary<string, string> dictionary = new Dictionary<string, string>();
|
||||||
|
@ -42,7 +42,6 @@ namespace Oqtane.SiteTemplates
|
|||||||
Icon = "home",
|
Icon = "home",
|
||||||
IsNavigation = true,
|
IsNavigation = true,
|
||||||
IsPersonalizable = false,
|
IsPersonalizable = false,
|
||||||
EditMode = false,
|
|
||||||
PagePermissions = new List<Permission> {
|
PagePermissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
||||||
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
||||||
@ -89,7 +88,6 @@ namespace Oqtane.SiteTemplates
|
|||||||
Icon = "lock-locked",
|
Icon = "lock-locked",
|
||||||
IsNavigation = true,
|
IsNavigation = true,
|
||||||
IsPersonalizable = false,
|
IsPersonalizable = false,
|
||||||
EditMode = false,
|
|
||||||
PagePermissions = new List<Permission> {
|
PagePermissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, Constants.RegisteredRole, true),
|
new Permission(PermissionNames.View, Constants.RegisteredRole, true),
|
||||||
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
||||||
@ -114,7 +112,6 @@ namespace Oqtane.SiteTemplates
|
|||||||
Icon = "target",
|
Icon = "target",
|
||||||
IsNavigation = true,
|
IsNavigation = true,
|
||||||
IsPersonalizable = true,
|
IsPersonalizable = true,
|
||||||
EditMode = false,
|
|
||||||
PagePermissions = new List<Permission> {
|
PagePermissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
||||||
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
||||||
@ -134,7 +131,7 @@ namespace Oqtane.SiteTemplates
|
|||||||
|
|
||||||
if (System.IO.File.Exists(Path.Combine(_environment.WebRootPath, "images", "logo-white.png")))
|
if (System.IO.File.Exists(Path.Combine(_environment.WebRootPath, "images", "logo-white.png")))
|
||||||
{
|
{
|
||||||
string folderpath = Utilities.PathCombine(_environment.ContentRootPath, "Content", "Tenants", site.TenantId.ToString(), "Sites", site.SiteId.ToString(),"\\");
|
string folderpath = Utilities.PathCombine(_environment.ContentRootPath, "Content", "Tenants", site.TenantId.ToString(), "Sites", site.SiteId.ToString(), Path.DirectorySeparatorChar.ToString());
|
||||||
System.IO.Directory.CreateDirectory(folderpath);
|
System.IO.Directory.CreateDirectory(folderpath);
|
||||||
if (!System.IO.File.Exists(Path.Combine(folderpath, "logo-white.png")))
|
if (!System.IO.File.Exists(Path.Combine(folderpath, "logo-white.png")))
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,6 @@ namespace Oqtane.SiteTemplates
|
|||||||
Icon = "home",
|
Icon = "home",
|
||||||
IsNavigation = true,
|
IsNavigation = true,
|
||||||
IsPersonalizable = false,
|
IsPersonalizable = false,
|
||||||
EditMode = false,
|
|
||||||
PagePermissions = new List<Permission> {
|
PagePermissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
new Permission(PermissionNames.View, Constants.AllUsersRole, true),
|
||||||
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
new Permission(PermissionNames.View, Constants.AdminRole, true),
|
||||||
|
@ -8,24 +8,18 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
|
using Oqtane.Controllers;
|
||||||
|
|
||||||
namespace Oqtane.Modules.HtmlText.Controllers
|
namespace Oqtane.Modules.HtmlText.Controllers
|
||||||
{
|
{
|
||||||
[Route("{alias}/api/[controller]")]
|
[Route("{alias}/api/[controller]")]
|
||||||
public class HtmlTextController : Controller
|
public class HtmlTextController : ModuleControllerBase
|
||||||
{
|
{
|
||||||
private readonly IHtmlTextRepository _htmlText;
|
private readonly IHtmlTextRepository _htmlText;
|
||||||
private readonly ILogManager _logger;
|
|
||||||
private int _entityId = -1; // passed as a querystring parameter for authorization and used for validation
|
|
||||||
|
|
||||||
public HtmlTextController(IHtmlTextRepository htmlText, ILogManager logger, IHttpContextAccessor httpContextAccessor)
|
public HtmlTextController(IHtmlTextRepository htmlText, ILogManager logger, IHttpContextAccessor accessor) : base(logger, accessor)
|
||||||
{
|
{
|
||||||
_htmlText = htmlText;
|
_htmlText = htmlText;
|
||||||
_logger = logger;
|
|
||||||
if (httpContextAccessor.HttpContext.Request.Query.ContainsKey("entityid"))
|
|
||||||
{
|
|
||||||
_entityId = int.Parse(httpContextAccessor.HttpContext.Request.Query["entityid"]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/5
|
// GET api/<controller>/5
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<LangVersion>7.3</LangVersion>
|
<LangVersion>7.3</LangVersion>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Version>1.0.0</Version>
|
<Version>1.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<PackageReleaseNotes>Not for production use.</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</PackageReleaseNotes>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -31,6 +31,8 @@
|
|||||||
<EmbeddedResource Include="Scripts\Tenant.00.09.01.00.sql" />
|
<EmbeddedResource Include="Scripts\Tenant.00.09.01.00.sql" />
|
||||||
<EmbeddedResource Include="Scripts\Tenant.00.09.02.00.sql" />
|
<EmbeddedResource Include="Scripts\Tenant.00.09.02.00.sql" />
|
||||||
<EmbeddedResource Include="Scripts\Tenant.01.00.01.00.sql" />
|
<EmbeddedResource Include="Scripts\Tenant.01.00.01.00.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Tenant.01.00.01.01.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Tenant.01.00.02.01.sql" />
|
||||||
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" />
|
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.1.0.0.sql" />
|
||||||
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" />
|
<EmbeddedResource Include="Modules\HtmlText\Scripts\HtmlText.Uninstall.sql" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -48,4 +50,14 @@
|
|||||||
<ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" />
|
<ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" />
|
||||||
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
<ItemGroup>
|
||||||
|
<UpgradeFiles Include="$(ProjectDir)bin\Release\netcoreapp3.1\Oqtane.Upgrade.deps.json" />
|
||||||
|
<UpgradeFiles Include="$(ProjectDir)bin\Release\netcoreapp3.1\Oqtane.Upgrade.dll" />
|
||||||
|
<UpgradeFiles Include="$(ProjectDir)bin\Release\netcoreapp3.1\Oqtane.Upgrade.pdb" />
|
||||||
|
<UpgradeFiles Include="$(ProjectDir)bin\Release\netcoreapp3.1\Oqtane.Upgrade.runtimeconfig.json" />
|
||||||
|
<TemplateFiles Include="$(ProjectDir)wwwroot\Modules\Templates\**\*.*" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Target Name="AddPayloadsFolder" AfterTargets="Publish">
|
||||||
|
<Copy SourceFiles="@(UpgradeFiles)" DestinationFiles="@(UpgradeFiles->'$(PublishDir)%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||||
|
<Copy SourceFiles="@(TemplateFiles)" DestinationFiles="@(TemplateFiles->'$(PublishDir)wwwroot\Modules\Templates\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="false" />
|
||||||
|
</Target></Project>
|
||||||
|
@ -45,7 +45,21 @@ namespace Oqtane.Repository
|
|||||||
|
|
||||||
public File GetFile(int fileId)
|
public File GetFile(int fileId)
|
||||||
{
|
{
|
||||||
File file = _db.File.Where(item => item.FileId == fileId).Include(item => item.Folder).FirstOrDefault();
|
return GetFile(fileId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public File GetFile(int fileId, bool tracking)
|
||||||
|
{
|
||||||
|
File file;
|
||||||
|
if (tracking)
|
||||||
|
{
|
||||||
|
file = _db.File.Where(item => item.FileId == fileId).Include(item => item.Folder).FirstOrDefault();
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file = _db.File.AsNoTracking().Where(item => item.FileId == fileId).Include(item => item.Folder).FirstOrDefault();
|
||||||
|
}
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
IEnumerable<Permission> permissions = _permissions.GetPermissions(EntityNames.Folder, file.FolderId).ToList();
|
IEnumerable<Permission> permissions = _permissions.GetPermissions(EntityNames.Folder, file.FolderId).ToList();
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user