Compare commits
184 Commits
Author | SHA1 | Date | |
---|---|---|---|
9ea5da525b | |||
fa15a5e44b | |||
35d037bbf4 | |||
e8387103f1 | |||
16965fd027 | |||
f81ef89c61 | |||
6034a161e7 | |||
ff23865711 | |||
3ac4116a84 | |||
65df0549fd | |||
04ffb079ea | |||
99d99ca6ad | |||
0659fc53b7 | |||
2febd81b4a | |||
0f814bfefe | |||
120066fce1 | |||
f4ca525bb5 | |||
5dced08f7a | |||
882412b8ff | |||
563345638a | |||
20b83c8809 | |||
7d89670930 | |||
40571bfb6e | |||
5a7a47ef27 | |||
ee5553ad8a | |||
ab8a1e7324 | |||
9e633d2d6d | |||
975e7217a5 | |||
95053d8671 | |||
61498862b5 | |||
a57e25d3d3 | |||
7cd18b1fe1 | |||
0636227284 | |||
d4d12b6f41 | |||
7c24bae753 | |||
06480d9a7e | |||
71b3b695fc | |||
db6d5d2b64 | |||
7d7e8e9e66 | |||
354382a580 | |||
288cad3d3f | |||
597a935cac | |||
1e4b2404c4 | |||
048d8f1b87 | |||
ec416a7fef | |||
c8630d7b05 | |||
42696eacbd | |||
b668a5d0ae | |||
4285603563 | |||
1c0d24ac25 | |||
4e6b4a20ef | |||
ea89cc1a64 | |||
79622819aa | |||
88e3a9adc3 | |||
f0c95c46c9 | |||
1a0e8f7e19 | |||
b5d4f8b176 | |||
8053cc0af6 | |||
134f21e29c | |||
a67330dbbb | |||
06820b9b63 | |||
f5d47a0308 | |||
937ae32a9e | |||
5124dea72c | |||
2ceeb25d0e | |||
e2732d83bd | |||
3e56e9cc04 | |||
836c4505b9 | |||
ef5ae77060 | |||
86b7fe193f | |||
3503f20255 | |||
51b69e05fb | |||
095a95a3a9 | |||
8d17153686 | |||
6efbeeb2b4 | |||
af1aab5b8d | |||
f854b948ce | |||
7b9cd39cb7 | |||
6f6f2b77d7 | |||
ed2822ac7c | |||
41348b285d | |||
5b0da056b4 | |||
2d079bdc06 | |||
aed71fbf96 | |||
4ebdf5721c | |||
99cad13890 | |||
4edb3f32f0 | |||
01a3b7ed95 | |||
c79199357e | |||
e24c6fc235 | |||
cdc4de432a | |||
5544d2bed3 | |||
aa4b00c900 | |||
c4f1d37421 | |||
c6b22d660b | |||
ec11587b28 | |||
1b7ca45d4a | |||
01491b063d | |||
4142cc63e7 | |||
20dc749d05 | |||
4144be5323 | |||
27a3ac8d1c | |||
f45cb8b069 | |||
0cc325ee95 | |||
7d21cfefc1 | |||
652d46f64a | |||
be4813d9c0 | |||
fe92d3d74f | |||
833ea9461a | |||
47a917a3df | |||
cb484665ca | |||
64b0c2f128 | |||
6402723d2a | |||
b1a007491f | |||
17ef268594 | |||
58d97dd731 | |||
ee3a4d1624 | |||
f9035f8fdf | |||
3a5b6954e3 | |||
1794d54a3f | |||
7d251b20cc | |||
0f09df13b5 | |||
73763f1623 | |||
1b2c7772ef | |||
3b2583a1bd | |||
f7470e3c5b | |||
19f8b3d429 | |||
fd249a7734 | |||
d5f3b7513d | |||
2a3b7caa9f | |||
612a820dac | |||
e80f42f1d9 | |||
8b5004c628 | |||
151e37c470 | |||
e935451d93 | |||
b0af00aa47 | |||
cbbac26881 | |||
f2230dd530 | |||
963148c639 | |||
215e52e42e | |||
945d7870c0 | |||
cc40733cff | |||
795f591da2 | |||
4cab49e022 | |||
3b685fe571 | |||
97df673609 | |||
cbcec0481a | |||
2f272ef4b6 | |||
a4ed06f2fc | |||
3339690e2a | |||
e4b37c17d8 | |||
f1f07f45c6 | |||
068803615b | |||
ddbb08ea75 | |||
6ac2b64d7d | |||
93497eb776 | |||
e1b0dbcdf7 | |||
c2ddd248e4 | |||
a4ec456205 | |||
23764d1ae4 | |||
f77a8a964f | |||
c089b90659 | |||
32cd34b090 | |||
d8fca5de20 | |||
2f8a15fb89 | |||
1495a5c017 | |||
61b1b710db | |||
24579dc4d0 | |||
066ef44773 | |||
1355233b92 | |||
dc55c5b3ec | |||
ed3f07ff61 | |||
028485b653 | |||
b43d191536 | |||
43dfad38c9 | |||
6f1e930474 | |||
1d52de53a6 | |||
3aec68d9fa | |||
4dc24f4c78 | |||
a73e088abc | |||
b61446a50a | |||
31773abb01 | |||
85c491224d | |||
71f79bd90b |
@ -28,7 +28,7 @@
|
|||||||
</table>
|
</table>
|
||||||
<Pager Items="@_files">
|
<Pager Items="@_files">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Modified</th>
|
<th>Modified</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
|
@ -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>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Login
|
@namespace Oqtane.Modules.Admin.Login
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IJSRuntime JsRuntime
|
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IServiceProvider ServiceProvider
|
@inject IServiceProvider ServiceProvider
|
||||||
|
|
||||||
@ -96,7 +95,7 @@
|
|||||||
{
|
{
|
||||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||||
// complete the login on the server so that the cookies are set correctly on SignalR
|
// complete the login on the server so that the cookies are set correctly on SignalR
|
||||||
var interop = new Interop(JsRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
||||||
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||||
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
|
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
|
||||||
|
@ -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>
|
||||||
|
@ -1 +0,0 @@
|
|||||||
This is the location where static resources for third party libraries should be located ( the third party library assemblies will be included in the /lib folder ). They should be placed in subfolders which match the naming convention of the third party library. When the module package is deployed the static resource subfolders will be extracted under the web root.
|
|
@ -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>
|
||||||
@ -77,8 +77,10 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -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>
|
||||||
@ -54,21 +54,27 @@ else
|
|||||||
_packages = await PackageService.GetPackagesAsync("module");
|
_packages = await PackageService.GetPackagesAsync("module");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (_moduleDefinitions == null)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Loading Modules {Error}", ex.Message);
|
await logger.LogError(ex, "Error Loading Modules {Error}", ex.Message);
|
||||||
AddModuleMessage("Error Loading Modules", MessageType.Error);
|
AddModuleMessage("Error Loading Modules", MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool UpgradeAvailable(string moduledefinitionname, string version)
|
private bool UpgradeAvailable(string moduledefinitionname, string version)
|
||||||
{
|
{
|
||||||
var upgradeavailable = false;
|
var upgradeavailable = false;
|
||||||
|
if (_packages != null)
|
||||||
|
{
|
||||||
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault();
|
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault();
|
||||||
if (package != null)
|
if (package != null)
|
||||||
{
|
{
|
||||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return upgradeavailable;
|
return upgradeavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,9 +83,11 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
|
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
|
||||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", moduledefinitionname, version);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
|
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -92,9 +100,10 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||||
await logger.LogInformation("Module Deleted {ModuleDefinition}", moduleDefinition);
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="container" class="form-control" @bind="@_containerType">
|
<select id="container" class="form-control" @bind="@_containerType">
|
||||||
<option value="-"><Inherit From Page Or Site></option>
|
<option value="-"><Inherit From Page Or Site></option>
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
@ -63,7 +63,7 @@
|
|||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions">
|
<TabPanel Name="Permissions">
|
||||||
@if (_containers != null)
|
@if (_permissions != null)
|
||||||
{
|
{
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
@ -85,12 +85,12 @@
|
|||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private Dictionary<string, string> _containers;
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _title;
|
private string _title;
|
||||||
private string _containerType;
|
private string _containerType;
|
||||||
private string _allPages = "false";
|
private string _allPages = "false";
|
||||||
private string _permissionNames = "";
|
private string _permissionNames = "";
|
||||||
private string _permissions;
|
private string _permissions = null;
|
||||||
private string _pageId;
|
private string _pageId;
|
||||||
private PermissionGrid _permissionGrid;
|
private PermissionGrid _permissionGrid;
|
||||||
private Type _settingsModuleType;
|
private Type _settingsModuleType;
|
||||||
@ -105,7 +105,7 @@
|
|||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_title = ModuleState.Title;
|
_title = ModuleState.Title;
|
||||||
_containers = ThemeService.GetContainerTypes(await ThemeService.GetThemesAsync());
|
_containers = ThemeService.GetContainerControls(await ThemeService.GetThemesAsync(), PageState.Page.ThemeType);
|
||||||
_containerType = ModuleState.ContainerType;
|
_containerType = ModuleState.ContainerType;
|
||||||
if (!string.IsNullOrEmpty(PageState.Page.DefaultContainerType) && _containerType == PageState.Page.DefaultContainerType)
|
if (!string.IsNullOrEmpty(PageState.Page.DefaultContainerType) && _containerType == PageState.Page.DefaultContainerType)
|
||||||
{
|
{
|
||||||
|
@ -102,20 +102,22 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||||
<option value="-"><Inherit From Site></option>
|
<option value="-"><Inherit From Site></option>
|
||||||
@foreach (KeyValuePair<string, string> item in _themes)
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
if (item.Key == _themetype)
|
if (theme.TypeName == _themetype)
|
||||||
{
|
{
|
||||||
<option value="@item.Key" selected>@item.Value</option>
|
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@item.Key">@item.Value</option>
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if (_layouts.Count > 0)
|
||||||
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
|
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
|
||||||
@ -123,20 +125,21 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="Layout" class="form-control" @bind="@_layouttype">
|
<select id="Layout" class="form-control" @bind="@_layouttype">
|
||||||
<option value="-"><Inherit From Site></option>
|
<option value="-"><Inherit From Site></option>
|
||||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
@foreach (var layout in _layouts)
|
||||||
{
|
{
|
||||||
if (panelayout.Key == _layouttype)
|
if (layout.TypeName == _layouttype)
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key" selected>@panelayout.Value</option>
|
<option value="@(layout.TypeName)" selected>@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
|
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
|
||||||
@ -144,9 +147,9 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||||
<option value="-"><Inherit From Site></option>
|
<option value="-"><Inherit From Site></option>
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
@ -199,10 +202,10 @@
|
|||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private Dictionary<string, string> _themes;
|
|
||||||
private Dictionary<string, string> _panelayouts;
|
|
||||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private List<Page> _pageList;
|
private List<Page> _pageList;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _title;
|
private string _title;
|
||||||
@ -232,10 +235,7 @@
|
|||||||
_pageList = PageState.Pages;
|
_pageList = PageState.Pages;
|
||||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||||
|
|
||||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
_themes = ThemeService.GetThemeControls(_themeList);
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
|
||||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
|
||||||
|
|
||||||
_permissions = string.Empty;
|
_permissions = string.Empty;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -287,12 +287,16 @@
|
|||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
if (_themetype != "-")
|
if (_themetype != "-")
|
||||||
{
|
{
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_panelayouts = new Dictionary<string, string>();
|
_layouts = new List<ThemeControl>();
|
||||||
|
_containers = new List<ThemeControl>();
|
||||||
}
|
}
|
||||||
|
_layouttype = "-";
|
||||||
|
_containertype = "-";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -307,7 +311,7 @@
|
|||||||
Page page = null;
|
Page page = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)))
|
if (_name != string.Empty && !string.IsNullOrEmpty(_themetype) && (_layouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)))
|
||||||
{
|
{
|
||||||
page = new Page();
|
page = new Page();
|
||||||
page.SiteId = PageState.Page.SiteId;
|
page.SiteId = PageState.Page.SiteId;
|
||||||
|
@ -113,20 +113,22 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||||
<option value="-"><Inherit From Site></option>
|
<option value="-"><Inherit From Site></option>
|
||||||
@foreach (KeyValuePair<string, string> item in _themes)
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
if (item.Key == _themetype)
|
if (theme.TypeName == _themetype)
|
||||||
{
|
{
|
||||||
<option value="@item.Key" selected>@item.Value</option>
|
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@item.Key">@item.Value</option>
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if (_layouts.Count > 0)
|
||||||
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
|
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
|
||||||
@ -134,20 +136,21 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="Layout" class="form-control" @bind="@_layouttype">
|
<select id="Layout" class="form-control" @bind="@_layouttype">
|
||||||
<option value="-"><Inherit From Site></option>
|
<option value="-"><Inherit From Site></option>
|
||||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
@foreach (var layout in _layouts)
|
||||||
{
|
{
|
||||||
if (panelayout.Key == _layouttype)
|
if (layout.TypeName == _layouttype)
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key" selected>@panelayout.Value</option>
|
<option value="@(layout.TypeName)" selected>@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
|
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
|
||||||
@ -155,9 +158,9 @@
|
|||||||
<td>
|
<td>
|
||||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||||
<option value="-"><Inherit From Site></option>
|
<option value="-"><Inherit From Site></option>
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
@ -199,6 +202,8 @@
|
|||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions">
|
<TabPanel Name="Permissions">
|
||||||
|
@if (_permissions != null)
|
||||||
|
{
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@ -206,16 +211,17 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
<button type="button" class="btn btn-success" @onclick="SavePage">Save</button>
|
<button type="button" class="btn btn-success" @onclick="SavePage">Save</button>
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private Dictionary<string, string> _themes;
|
|
||||||
private Dictionary<string, string> _panelayouts;
|
|
||||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private List<Page> _pageList;
|
private List<Page> _pageList;
|
||||||
private int _pageId;
|
private int _pageId;
|
||||||
private string _name;
|
private string _name;
|
||||||
@ -234,7 +240,7 @@
|
|||||||
private string _layouttype = "-";
|
private string _layouttype = "-";
|
||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
private string _icon;
|
private string _icon;
|
||||||
private string _permissions;
|
private string _permissions = null;
|
||||||
private string _createdby;
|
private string _createdby;
|
||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
private string _modifiedby;
|
private string _modifiedby;
|
||||||
@ -252,12 +258,11 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themeList = await ThemeService.GetThemesAsync();
|
|
||||||
_pageList = PageState.Pages;
|
_pageList = PageState.Pages;
|
||||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||||
|
|
||||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
_themeList = await ThemeService.GetThemesAsync();
|
||||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
_themes = ThemeService.GetThemeControls(_themeList);
|
||||||
|
|
||||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||||
var page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
var page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
||||||
@ -291,12 +296,13 @@
|
|||||||
{
|
{
|
||||||
_themetype = "-";
|
_themetype = "-";
|
||||||
}
|
}
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, page.ThemeType);
|
||||||
_layouttype = page.LayoutType;
|
_layouttype = page.LayoutType;
|
||||||
if (_layouttype == PageState.Site.DefaultLayoutType)
|
if (_layouttype == PageState.Site.DefaultLayoutType)
|
||||||
{
|
{
|
||||||
_layouttype = "-";
|
_layouttype = "-";
|
||||||
}
|
}
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, page.ThemeType);
|
||||||
_containertype = page.DefaultContainerType;
|
_containertype = page.DefaultContainerType;
|
||||||
if (string.IsNullOrEmpty(_containertype))
|
if (string.IsNullOrEmpty(_containertype))
|
||||||
{
|
{
|
||||||
@ -369,12 +375,16 @@
|
|||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
if (_themetype != "-")
|
if (_themetype != "-")
|
||||||
{
|
{
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_panelayouts = new Dictionary<string, string>();
|
_layouts = new List<ThemeControl>();
|
||||||
|
_containers = new List<ThemeControl>();
|
||||||
}
|
}
|
||||||
|
_layouttype = "-";
|
||||||
|
_containertype = "-";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -56,45 +56,48 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||||
<option value=""><Select Theme></option>
|
<option value="-"><Select Theme></option>
|
||||||
@foreach (KeyValuePair<string, string> item in _themes)
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
if (item.Key == _themetype)
|
if (theme.TypeName == _themetype)
|
||||||
{
|
{
|
||||||
<option value="@item.Key" selected>@item.Value</option>
|
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@item.Key">@item.Value</option>
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if (_layouts.Count > 0)
|
||||||
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label>
|
<Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||||
<option value=""><Select Layout></option>
|
<option value="-"><Select Layout></option>
|
||||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
@foreach (var layout in _layouts)
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||||
<option value=""><Select Container></option>
|
<option value="-"><Select Container></option>
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
@ -208,10 +211,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private Dictionary<string, string> _themes;
|
|
||||||
private Dictionary<string, string> _panelayouts;
|
|
||||||
private Dictionary<string, string> _containers;
|
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private List<Tenant> _tenantList;
|
private List<Tenant> _tenantList;
|
||||||
private string _tenant = string.Empty;
|
private string _tenant = string.Empty;
|
||||||
@ -221,9 +224,9 @@
|
|||||||
private FileManager _logofilemanager;
|
private FileManager _logofilemanager;
|
||||||
private int _faviconfileid = -1;
|
private int _faviconfileid = -1;
|
||||||
private FileManager _faviconfilemanager;
|
private FileManager _faviconfilemanager;
|
||||||
private string _themetype;
|
private string _themetype = "-";
|
||||||
private string _layouttype;
|
private string _layouttype = "-";
|
||||||
private string _containertype;
|
private string _containertype = "-";
|
||||||
private string _allowregistration;
|
private string _allowregistration;
|
||||||
private string _smtphost = string.Empty;
|
private string _smtphost = string.Empty;
|
||||||
private string _smtpport = string.Empty;
|
private string _smtpport = string.Empty;
|
||||||
@ -271,9 +274,11 @@
|
|||||||
_faviconfileid = site.FaviconFileId.Value;
|
_faviconfileid = site.FaviconFileId.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_themes = ThemeService.GetThemeControls(_themeList);
|
||||||
_themetype = site.DefaultThemeType;
|
_themetype = site.DefaultThemeType;
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
_layouttype = site.DefaultLayoutType;
|
_layouttype = site.DefaultLayoutType;
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
_containertype = site.DefaultContainerType;
|
_containertype = site.DefaultContainerType;
|
||||||
_allowregistration = site.AllowRegistration.ToString();
|
_allowregistration = site.AllowRegistration.ToString();
|
||||||
|
|
||||||
@ -314,9 +319,6 @@
|
|||||||
_deletedon = site.DeletedOn;
|
_deletedon = site.DeletedOn;
|
||||||
_isdeleted = site.IsDeleted.ToString();
|
_isdeleted = site.IsDeleted.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
|
||||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -330,14 +332,18 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
if (_themetype != string.Empty)
|
if (_themetype != "-")
|
||||||
{
|
{
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_panelayouts = new Dictionary<string, string>();
|
_layouts = new List<ThemeControl>();
|
||||||
|
_containers = new List<ThemeControl>();
|
||||||
}
|
}
|
||||||
|
_layouttype = "-";
|
||||||
|
_containertype = "-";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -351,7 +357,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype))
|
if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && (_layouts.Count == 0 || _layouttype != "-") && _containertype != "-")
|
||||||
{
|
{
|
||||||
var unique = true;
|
var unique = true;
|
||||||
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
@ -376,7 +382,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
site.DefaultThemeType = _themetype;
|
site.DefaultThemeType = _themetype;
|
||||||
site.DefaultLayoutType = (_layouttype == null ? string.Empty : _layouttype);
|
site.DefaultLayoutType = (_layouttype == "-" ? string.Empty : _layouttype);
|
||||||
site.DefaultContainerType = _containertype;
|
site.DefaultContainerType = _containertype;
|
||||||
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
|
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
|
||||||
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
||||||
|
@ -38,38 +38,41 @@ else
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||||
<option value=""><Select Theme></option>
|
<option value="-"><Select Theme></option>
|
||||||
@foreach (KeyValuePair<string, string> item in _themes)
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
<option value="@item.Key">@item.Value</option>
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if (_layouts.Count > 0)
|
||||||
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
|
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||||
<option value=""><Select Layout></option>
|
<option value="-"><Select Layout></option>
|
||||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
@foreach (var layout in _layouts)
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
<select id="defaultContainer" class="form-control" @bind="@_containertype">
|
||||||
<option value=""><Select Container></option>
|
<option value="-"><Select Container></option>
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
@ -80,7 +83,7 @@ else
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="siteTemplate" class="form-control" @bind="@_sitetemplatetype">
|
<select id="siteTemplate" class="form-control" @bind="@_sitetemplatetype">
|
||||||
<option value=""><Select Site Template></option>
|
<option value="-"><Select Site Template></option>
|
||||||
@foreach (SiteTemplate siteTemplate in _siteTemplates)
|
@foreach (SiteTemplate siteTemplate in _siteTemplates)
|
||||||
{
|
{
|
||||||
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option>
|
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option>
|
||||||
@ -198,11 +201,11 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private Dictionary<string, string> _themes = new Dictionary<string, string>();
|
|
||||||
private Dictionary<string, string> _panelayouts = new Dictionary<string, string>();
|
|
||||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
|
||||||
private List<SiteTemplate> _siteTemplates;
|
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
|
private List<SiteTemplate> _siteTemplates;
|
||||||
private List<Tenant> _tenants;
|
private List<Tenant> _tenants;
|
||||||
private string _tenantid = "-";
|
private string _tenantid = "-";
|
||||||
|
|
||||||
@ -218,20 +221,19 @@ else
|
|||||||
|
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private string _urls = string.Empty;
|
private string _urls = string.Empty;
|
||||||
private string _themetype = string.Empty;
|
private string _themetype = "-";
|
||||||
private string _layouttype = string.Empty;
|
private string _layouttype = "-";
|
||||||
private string _containertype = string.Empty;
|
private string _containertype = "-";
|
||||||
private string _sitetemplatetype = string.Empty;
|
private string _sitetemplatetype = "-";
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_themeList = await ThemeService.GetThemesAsync();
|
|
||||||
_tenants = await TenantService.GetTenantsAsync();
|
_tenants = await TenantService.GetTenantsAsync();
|
||||||
_urls = PageState.Alias.Name;
|
_urls = PageState.Alias.Name;
|
||||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
_themeList = await ThemeService.GetThemesAsync();
|
||||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
_themes = ThemeService.GetThemeControls(_themeList);
|
||||||
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
|
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,15 +265,18 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
if (_themetype != string.Empty)
|
if (_themetype != "-")
|
||||||
{
|
{
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_panelayouts = new Dictionary<string, string>();
|
_layouts = new List<ThemeControl>();
|
||||||
|
_containers = new List<ThemeControl>();
|
||||||
}
|
}
|
||||||
|
_layouttype = "-";
|
||||||
|
_containertype = "-";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -283,7 +288,7 @@ else
|
|||||||
|
|
||||||
private async Task SaveSite()
|
private async Task SaveSite()
|
||||||
{
|
{
|
||||||
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype) && !string.IsNullOrEmpty(_sitetemplatetype))
|
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && (_layouts.Count == 0 || _layouttype != "-") && _containertype != "-" && _sitetemplatetype != "-")
|
||||||
{
|
{
|
||||||
var duplicates = new List<string>();
|
var duplicates = new List<string>();
|
||||||
var aliases = await AliasService.GetAliasesAsync();
|
var aliases = await AliasService.GetAliasesAsync();
|
||||||
|
@ -39,45 +39,48 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||||
<option value=""><Select Theme></option>
|
<option value="-"><Select Theme></option>
|
||||||
@foreach (KeyValuePair<string, string> item in _themes)
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
if (item.Key == _themetype)
|
if (theme.TypeName == _themetype)
|
||||||
{
|
{
|
||||||
<option value="@item.Key" selected>@item.Value</option>
|
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<option value="@item.Key">@item.Value</option>
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@if (_layouts.Count > 0)
|
||||||
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
|
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
|
||||||
<option value=""><Select Layout></option>
|
<option value="-"><Select Layout></option>
|
||||||
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
|
@foreach (var layout in _layouts)
|
||||||
{
|
{
|
||||||
<option value="@panelayout.Key">@panelayout.Value</option>
|
<option value="@(layout.TypeName)">@(layout.Name)</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="defaultIdea" class="form-control" @bind="@_containertype">
|
<select id="defaultIdea" class="form-control" @bind="@_containertype">
|
||||||
<option value=""><Select Container></option>
|
<option value="-"><Select Container></option>
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
@ -103,11 +106,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private Dictionary<string, string> _themes;
|
|
||||||
private Dictionary<string, string> _panelayouts;
|
|
||||||
private Dictionary<string, string> _containers;
|
|
||||||
private Alias _alias;
|
|
||||||
private List<Theme> _themeList;
|
private List<Theme> _themeList;
|
||||||
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _layouts = new List<ThemeControl>();
|
||||||
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
|
private Alias _alias;
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private List<Tenant> _tenantList;
|
private List<Tenant> _tenantList;
|
||||||
private string _tenant = string.Empty;
|
private string _tenant = string.Empty;
|
||||||
@ -147,9 +150,11 @@
|
|||||||
_urls += alias.Name + "\n";
|
_urls += alias.Name + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_themes = ThemeService.GetThemeControls(_themeList);
|
||||||
_themetype = site.DefaultThemeType;
|
_themetype = site.DefaultThemeType;
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
_layouttype = site.DefaultLayoutType;
|
_layouttype = site.DefaultLayoutType;
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
_containertype = site.DefaultContainerType;
|
_containertype = site.DefaultContainerType;
|
||||||
_createdby = site.CreatedBy;
|
_createdby = site.CreatedBy;
|
||||||
_createdon = site.CreatedOn;
|
_createdon = site.CreatedOn;
|
||||||
@ -159,9 +164,6 @@
|
|||||||
_deletedon = site.DeletedOn;
|
_deletedon = site.DeletedOn;
|
||||||
_isdeleted = site.IsDeleted.ToString();
|
_isdeleted = site.IsDeleted.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
|
||||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -175,15 +177,18 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
if (_themetype != string.Empty)
|
if (_themetype != "-")
|
||||||
{
|
{
|
||||||
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
|
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_panelayouts = new Dictionary<string, string>();
|
_layouts = new List<ThemeControl>();
|
||||||
|
_containers = new List<ThemeControl>();
|
||||||
}
|
}
|
||||||
|
_layouttype = "-";
|
||||||
|
_containertype = "-";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -197,7 +202,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (_name != string.Empty && _urls != string.Empty && !string.IsNullOrEmpty(_themetype) && (_panelayouts.Count == 0 || !string.IsNullOrEmpty(_layouttype)) && !string.IsNullOrEmpty(_containertype))
|
if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && (_layouts.Count == 0 || _layouttype != "-") && _containertype != "-")
|
||||||
{
|
{
|
||||||
var unique = true;
|
var unique = true;
|
||||||
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
@ -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>
|
||||||
@ -77,8 +77,10 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await ThemeService.InstallThemesAsync();
|
await ThemeService.InstallThemesAsync();
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Themes
|
@namespace Oqtane.Modules.Admin.Themes
|
||||||
|
@using System.Net
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
@inject IPackageService PackageService
|
@inject IPackageService PackageService
|
||||||
|
|
||||||
@if (themes == null)
|
@if (_themes == null)
|
||||||
{
|
{
|
||||||
<p><em>Loading...</em></p>
|
<p><em>Loading...</em></p>
|
||||||
}
|
}
|
||||||
@ -12,14 +13,16 @@ else
|
|||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Install Theme" />
|
<ActionLink Action="Add" Text="Install Theme" />
|
||||||
|
|
||||||
<Pager Items="@themes">
|
<Pager Items="@_themes">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Name</th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>Version</th>
|
<th scope="col">Name</th>
|
||||||
|
<th scope="col">Version</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
|
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" /></td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName != "Oqtane.Client")
|
@if (context.AssemblyName != "Oqtane.Client")
|
||||||
{
|
{
|
||||||
@ -34,46 +37,79 @@ 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>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Theme> themes;
|
private List<Theme> _themes;
|
||||||
private List<Package> packages;
|
private List<Package> _packages;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
themes = await ThemeService.GetThemesAsync();
|
try
|
||||||
packages = await PackageService.GetPackagesAsync("module");
|
{
|
||||||
|
_themes = await ThemeService.GetThemesAsync();
|
||||||
|
_packages = await PackageService.GetPackagesAsync("theme");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (_themes == null)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Themes {Error}", ex.Message);
|
||||||
|
AddModuleMessage("Error Loading Themes", MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool UpgradeAvailable(string themename, string version)
|
private bool UpgradeAvailable(string themename, string version)
|
||||||
{
|
{
|
||||||
var upgradeavailable = false;
|
var upgradeavailable = false;
|
||||||
var package = packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault();
|
if (_packages != null)
|
||||||
|
{
|
||||||
|
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault();
|
||||||
if (package != null)
|
if (package != null)
|
||||||
{
|
{
|
||||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return upgradeavailable;
|
return upgradeavailable;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DownloadTheme(string themename, string version)
|
private async Task DownloadTheme(string themename, string version)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(themename, version, "Themes");
|
await PackageService.DownloadPackageAsync(themename, version, "Themes");
|
||||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await ThemeService.InstallThemesAsync();
|
await ThemeService.InstallThemesAsync();
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Downloading Theme {ThemeName} {Version} {Error}", themename, version, ex.Message);
|
||||||
|
AddModuleMessage("Error Downloading Theme", MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteTheme(Theme Theme)
|
private async Task DeleteTheme(Theme Theme)
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
||||||
await logger.LogInformation("Theme Deleted {Theme}", Theme);
|
}
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Deleting Theme {Theme} {Error}", Theme, ex.Message);
|
||||||
|
AddModuleMessage("Error Deleting Theme", MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
101
Oqtane.Client/Modules/Admin/Themes/View.razor
Normal file
101
Oqtane.Client/Modules/Admin/Themes/View.razor
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Themes
|
||||||
|
@using System.Net
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject IThemeService ThemeService
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="name" HelpText="The name of the theme">Name: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="name" class="form-control" @bind="@_name" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="themename" HelpText="The internal name of the module">Internal Name: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="themename" class="form-control" @bind="@_themeName" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="version" HelpText="The version of the thene">Version: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="owner" HelpText="The owner or creator of the theme">Owner: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="url" HelpText="The reference url of the theme">Reference Url: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="contact" HelpText="The contact for the theme">Contact: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<Label For="license" HelpText="The license of the theme">License: </Label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private string _themeName = "";
|
||||||
|
private string _name;
|
||||||
|
private string _version;
|
||||||
|
private string _owner = "";
|
||||||
|
private string _url = "";
|
||||||
|
private string _contact = "";
|
||||||
|
private string _license = "";
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_themeName = WebUtility.UrlDecode(PageState.QueryString["name"]);
|
||||||
|
var themes = await ThemeService.GetThemesAsync();
|
||||||
|
var theme = themes.FirstOrDefault(item => item.ThemeName == _themeName);
|
||||||
|
if (theme != null)
|
||||||
|
{
|
||||||
|
_name = theme.Name;
|
||||||
|
_version = theme.Version;
|
||||||
|
_owner = theme.Owner;
|
||||||
|
_url = theme.Url;
|
||||||
|
_contact = theme.Contact;
|
||||||
|
_license = theme.License;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
|
||||||
|
AddModuleMessage("Error Loading Theme", MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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" ShowFiles="false" Folder="Framework" />
|
<FileManager Filter="nupkg" Folder="Framework" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@ -42,8 +42,12 @@
|
|||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
List<Package> packages = await PackageService.GetPackagesAsync("framework");
|
List<Package> packages = await PackageService.GetPackagesAsync("framework");
|
||||||
|
if (packages != null)
|
||||||
|
{
|
||||||
_package = packages.FirstOrDefault();
|
_package = packages.FirstOrDefault();
|
||||||
if (_package != null)
|
if (_package != null)
|
||||||
{
|
{
|
||||||
@ -54,17 +58,43 @@
|
|||||||
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// can be caused by no network connection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task Upgrade()
|
private async Task Upgrade()
|
||||||
{
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await InstallationService.Upgrade();
|
await InstallationService.Upgrade();
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Executing Upgrade {Error}", ex.Message);
|
||||||
|
AddModuleMessage("Error Executing Upgrade", MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Download(string packageid, string version)
|
private async Task Download(string packageid, string version)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.RedirectBrowser(NavigateUrl(), 3);
|
||||||
await InstallationService.Upgrade();
|
await InstallationService.Upgrade();
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Downloading Framework {Error}", ex.Message);
|
||||||
|
AddModuleMessage("Error Downloading Framework", MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
@namespace Oqtane.Modules.Admin.UserProfile
|
@namespace Oqtane.Modules.Admin.UserProfile
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserRoleService UserRoleService
|
@inject IUserService UserService
|
||||||
@inject INotificationService NotificationService
|
@inject INotificationService NotificationService
|
||||||
|
|
||||||
@if (PageState.User != null)
|
@if (PageState.User != null)
|
||||||
@ -9,19 +9,10 @@
|
|||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Label For="to" HelpText="Select the user it is going to">To: </Label>
|
<Label For="to" HelpText="Enter the username you wish to send a message to">To: </Label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<select id="to" class="form-control" @bind="@userid">
|
<input id="to" class="form-control" @bind="@username" />
|
||||||
<option value="-1"><Select User></option>
|
|
||||||
@if (userroles != null)
|
|
||||||
{
|
|
||||||
foreach (UserRole userrole in userroles)
|
|
||||||
{
|
|
||||||
<option value="@userrole.UserId">@userrole.User.DisplayName</option>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -46,8 +37,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<UserRole> userroles;
|
private string username = "";
|
||||||
private string userid = "-1";
|
|
||||||
private string subject = "";
|
private string subject = "";
|
||||||
private string body = "";
|
private string body = "";
|
||||||
|
|
||||||
@ -55,42 +45,37 @@
|
|||||||
|
|
||||||
public override string Title => "Send Notification";
|
public override string Title => "Send Notification";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
|
||||||
userroles = userroles.Where(item => item.Role.Name == Constants.RegisteredRole || item.Role.Name == Constants.HostRole)
|
|
||||||
.OrderBy(item => item.User.DisplayName).ToList();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message);
|
|
||||||
AddModuleMessage("Error Loading Users", MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Send()
|
private async Task Send()
|
||||||
{
|
{
|
||||||
var notification = new Notification();
|
var notification = new Notification();
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
|
||||||
|
if (user != null)
|
||||||
{
|
{
|
||||||
notification.SiteId = PageState.Site.SiteId;
|
notification.SiteId = PageState.Site.SiteId;
|
||||||
notification.FromUserId = PageState.User.UserId;
|
notification.FromUserId = PageState.User.UserId;
|
||||||
notification.ToUserId = int.Parse(userid);
|
notification.FromDisplayName = PageState.User.DisplayName;
|
||||||
notification.ToEmail = "";
|
notification.FromEmail = PageState.User.Email;
|
||||||
|
notification.ToUserId = user.UserId;
|
||||||
|
notification.ToDisplayName = user.DisplayName;
|
||||||
|
notification.ToEmail = user.Email;
|
||||||
notification.Subject = subject;
|
notification.Subject = subject;
|
||||||
notification.Body = body;
|
notification.Body = body;
|
||||||
notification.ParentId = null;
|
notification.ParentId = null;
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage("User Does Not Exist. Please Verify That The Username Provided Is Correct.", MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message);
|
await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message);
|
||||||
|
@ -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>
|
||||||
@ -73,7 +73,7 @@ else
|
|||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Profile">
|
<TabPanel Name="Profile">
|
||||||
@if (profiles != null)
|
@if (profiles != null && settings != null)
|
||||||
{
|
{
|
||||||
<table class="table table-borderless">
|
<table class="table table-borderless">
|
||||||
@foreach (Profile profile in profiles)
|
@foreach (Profile profile in profiles)
|
||||||
@ -111,8 +111,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>
|
||||||
@ -120,13 +120,22 @@ else
|
|||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" /></td>
|
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" /></td>
|
||||||
<td><ActionDialog Header="Delete Notification" Message="@("Are You Sure You Wish To Delete This Notification?")" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" /></td>
|
<td><ActionDialog Header="Delete Notification" Message="@("Are You Sure You Wish To Delete This Notification?")" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" /></td>
|
||||||
<td>@(context.FromUser == null ? "System" : context.FromUser.DisplayName)</td>
|
<td>@context.FromDisplayName</td>
|
||||||
<td>@context.Subject</td>
|
<td>@context.Subject</td>
|
||||||
<td>@context.CreatedOn</td>
|
<td>@context.CreatedOn</td>
|
||||||
</Row>
|
</Row>
|
||||||
<Detail>
|
<Detail>
|
||||||
<td colspan="2"></td>
|
<td colspan="2"></td>
|
||||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0, 100) : context.Body)</td>
|
<td colspan="3">
|
||||||
|
@{
|
||||||
|
string input = "___";
|
||||||
|
if (context.Body.Contains(input)){
|
||||||
|
context.Body = context.Body.Split(input)[0];
|
||||||
|
context.Body = context.Body.Replace("\n", "");
|
||||||
|
context.Body = context.Body.Replace("\r", "");
|
||||||
|
} }
|
||||||
|
@(context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body)
|
||||||
|
</td>
|
||||||
</Detail>
|
</Detail>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
@ -143,13 +152,22 @@ else
|
|||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" /></td>
|
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" /></td>
|
||||||
<td><ActionDialog Header="Delete Notification" Message="@("Are You Sure You Wish To Delete This Notification?")" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" /></td>
|
<td><ActionDialog Header="Delete Notification" Message="@("Are You Sure You Wish To Delete This Notification?")" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" /></td>
|
||||||
<td>@(context.ToUser == null ? context.ToEmail : context.ToUser.DisplayName)</td>
|
<td>@context.ToDisplayName</td>
|
||||||
<td>@context.Subject</td>
|
<td>@context.Subject</td>
|
||||||
<td>@context.CreatedOn</td>
|
<td>@context.CreatedOn</td>
|
||||||
</Row>
|
</Row>
|
||||||
<Detail>
|
<Detail>
|
||||||
<td colspan="2"></td>
|
<td colspan="2"></td>
|
||||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0, 100) : context.Body)</td>
|
<td colspan="3">
|
||||||
|
@{
|
||||||
|
string input = "___";
|
||||||
|
if (context.Body.Contains(input)){
|
||||||
|
context.Body = context.Body.Split(input)[0];
|
||||||
|
context.Body = context.Body.Replace("\n", "");
|
||||||
|
context.Body = context.Body.Replace("\r", "");
|
||||||
|
} }
|
||||||
|
@(context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body)
|
||||||
|
</td>
|
||||||
</Detail>
|
</Detail>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
@namespace Oqtane.Modules.Admin.UserProfile
|
@namespace Oqtane.Modules.Admin.UserProfile
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserRoleService UserRoleService
|
@inject IUserService UserService
|
||||||
@inject INotificationService NotificationService
|
@inject INotificationService NotificationService
|
||||||
|
|
||||||
@if (PageState.User != null)
|
@if (PageState.User != null)
|
||||||
@ -11,26 +11,35 @@
|
|||||||
<td>
|
<td>
|
||||||
<label class="control-label">@title: </label>
|
<label class="control-label">@title: </label>
|
||||||
</td>
|
</td>
|
||||||
|
@if (title == "From")
|
||||||
|
{
|
||||||
<td>
|
<td>
|
||||||
<select class="form-control" readonly @bind="userid">
|
<input class="form-control" @bind="@username" readonly />
|
||||||
<option value="-1"><System></option>
|
|
||||||
@if (userroles != null)
|
|
||||||
{
|
|
||||||
foreach (UserRole userrole in userroles)
|
|
||||||
{
|
|
||||||
<option value="@userrole.UserId">@userrole.User.DisplayName</option>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</td>
|
</td>
|
||||||
|
}
|
||||||
|
@if (title == "To")
|
||||||
|
{
|
||||||
|
<td>
|
||||||
|
<input class="form-control" @bind="@username" />
|
||||||
|
</td>
|
||||||
|
}
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label class="control-label">Subject: </label>
|
<label class="control-label">Subject: </label>
|
||||||
</td>
|
</td>
|
||||||
|
@if (title == "From")
|
||||||
|
{
|
||||||
|
<td>
|
||||||
|
<input class="form-control" @bind="@subject" readonly />
|
||||||
|
</td>
|
||||||
|
}
|
||||||
|
@if (title == "To")
|
||||||
|
{
|
||||||
<td>
|
<td>
|
||||||
<input class="form-control" @bind="@subject" />
|
<input class="form-control" @bind="@subject" />
|
||||||
</td>
|
</td>
|
||||||
|
}
|
||||||
</tr>
|
</tr>
|
||||||
@if (title == "From")
|
@if (title == "From")
|
||||||
{
|
{
|
||||||
@ -39,10 +48,23 @@
|
|||||||
<label class="control-label">Date: </label>
|
<label class="control-label">Date: </label>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input class="form-control" @bind="@createdon" />
|
<input class="form-control" @bind="@createdon" readonly />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
|
@if (title == "From")
|
||||||
|
{
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<label class="control-label">Message: </label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<textarea class="form-control" @bind="@body" rows="5" readonly />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
|
@if (title == "To")
|
||||||
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label class="control-label">Message: </label>
|
<label class="control-label">Message: </label>
|
||||||
@ -51,29 +73,35 @@
|
|||||||
<textarea class="form-control" @bind="@body" rows="5" />
|
<textarea class="form-control" @bind="@body" rows="5" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
}
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
@if (reply != string.Empty)
|
@if (reply != string.Empty)
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick="Send">Send</button>
|
<button type="button" class="btn btn-primary" @onclick="Send">Send</button> }
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (title == "From")
|
if (title == "From")
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick="Reply">Reply</button>
|
<button type="button" class="btn btn-primary" @onclick="Reply">Reply</button>}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<p>@reply</p>
|
@if (title == "To")
|
||||||
|
{
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label">Original Message </label>
|
||||||
|
<textarea class="form-control" @bind="@reply" rows="5" readonly />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private int notificationid;
|
private int notificationid;
|
||||||
private string title = string.Empty;
|
private string title = string.Empty;
|
||||||
private List<UserRole> userroles;
|
private string username = "";
|
||||||
private string userid = "-1";
|
|
||||||
private string subject = string.Empty;
|
private string subject = string.Empty;
|
||||||
private string createdon = string.Empty;
|
private string createdon = string.Empty;
|
||||||
private string body = string.Empty;
|
private string body = string.Empty;
|
||||||
@ -86,20 +114,17 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
|
||||||
userroles = userroles.Where(item => item.Role.Name == Constants.RegisteredRole || item.Role.Name == Constants.HostRole)
|
|
||||||
.OrderBy(item => item.User.DisplayName).ToList();
|
|
||||||
|
|
||||||
notificationid = Int32.Parse(PageState.QueryString["id"]);
|
notificationid = Int32.Parse(PageState.QueryString["id"]);
|
||||||
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
|
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
|
||||||
if (notification != null)
|
if (notification != null)
|
||||||
{
|
{
|
||||||
|
int userid = -1;
|
||||||
if (notification.ToUserId == PageState.User.UserId)
|
if (notification.ToUserId == PageState.User.UserId)
|
||||||
{
|
{
|
||||||
title = "From";
|
title = "From";
|
||||||
if (notification.FromUserId != null)
|
if (notification.FromUserId != null)
|
||||||
{
|
{
|
||||||
userid = notification.FromUserId.ToString();
|
userid = notification.FromUserId.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -107,10 +132,21 @@
|
|||||||
title = "To";
|
title = "To";
|
||||||
if (notification.ToUserId != null)
|
if (notification.ToUserId != null)
|
||||||
{
|
{
|
||||||
userid = notification.ToUserId.ToString();
|
userid = notification.ToUserId.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (userid != -1)
|
||||||
|
{
|
||||||
|
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
username = user.Username;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (username == "")
|
||||||
|
{
|
||||||
|
username = "System";
|
||||||
|
}
|
||||||
subject = notification.Subject;
|
subject = notification.Subject;
|
||||||
createdon = notification.CreatedOn.ToString();
|
createdon = notification.CreatedOn.ToString();
|
||||||
body = notification.Body;
|
body = notification.Body;
|
||||||
@ -126,37 +162,51 @@
|
|||||||
private void Reply()
|
private void Reply()
|
||||||
{
|
{
|
||||||
title = "To";
|
title = "To";
|
||||||
|
if (!subject.Contains("RE:"))
|
||||||
|
{
|
||||||
subject = "RE: " + subject;
|
subject = "RE: " + subject;
|
||||||
|
}
|
||||||
reply = body;
|
reply = body;
|
||||||
|
body = "\n\n____________________________________________\nSent: " + createdon + "\nSubject: " + subject + "\n\n" + body;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Send()
|
private async Task Send()
|
||||||
{
|
{
|
||||||
var notification = new Notification();
|
var notification = new Notification();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
notification.SiteId = PageState.Site.SiteId;
|
notification.SiteId = PageState.Site.SiteId;
|
||||||
notification.FromUserId = PageState.User.UserId;
|
notification.FromUserId = PageState.User.UserId;
|
||||||
notification.ToUserId = int.Parse(userid);
|
notification.FromDisplayName = PageState.User.DisplayName;
|
||||||
notification.ToEmail = string.Empty;
|
notification.FromEmail = PageState.User.Email;
|
||||||
|
notification.ToUserId = user.UserId;
|
||||||
|
notification.ToDisplayName = user.DisplayName;
|
||||||
|
notification.ToEmail = user.Email;
|
||||||
notification.Subject = subject;
|
notification.Subject = subject;
|
||||||
notification.Body = body;
|
notification.Body = body;
|
||||||
notification.ParentId = notificationid;
|
notification.ParentId = notificationid;
|
||||||
notification.CreatedOn = DateTime.UtcNow;
|
notification.CreatedOn = DateTime.UtcNow;
|
||||||
notification.IsDelivered = false;
|
notification.IsDelivered = false;
|
||||||
notification.DeliveredOn = null;
|
notification.DeliveredOn = null;
|
||||||
|
notification.SendOn = DateTime.UtcNow;
|
||||||
try
|
|
||||||
{
|
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage("User Does Not Exist. Please Verify That The Username Provided Is Correct.", MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message);
|
await logger.LogError(ex, "Error Adding Notification {Notification} {Error}", notification, ex.Message);
|
||||||
AddModuleMessage("Error Adding Notification", MessageType.Error);
|
AddModuleMessage("Error Adding Notification", MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,40 +2,79 @@
|
|||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject IUserRoleService UserRoleService
|
@inject IUserRoleService UserRoleService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
|
||||||
@if (userroles == null)
|
@if (userroles == null)
|
||||||
{
|
{
|
||||||
<p><em>Loading...</em></p>
|
<p>
|
||||||
|
<em>Loading...</em>
|
||||||
|
</p>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add User"/>
|
<ActionLink Action="Add" Text="Add User"/>
|
||||||
|
|
||||||
|
<div class="d-flex p-1">
|
||||||
|
<input class="form-control mr-4" @bind="@_search"/><button class="btn btn-outline-primary ml-1" @onclick="OnSearch">Search</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<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>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" /></td>
|
<td>
|
||||||
<td><ActionDialog Header="Delete User" Message="@("Are You Sure You Wish To Delete " + context.User.DisplayName + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUser(context))" /></td>
|
<ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())"/>
|
||||||
<td><ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" /></td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<ActionDialog Header="Delete User" Message="@("Are You Sure You Wish To Delete " + context.User.DisplayName + "?")" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUser(context))"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())"/>
|
||||||
|
</td>
|
||||||
<td>@context.User.DisplayName</td>
|
<td>@context.User.DisplayName</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private List<UserRole> allroles;
|
||||||
private List<UserRole> userroles;
|
private List<UserRole> userroles;
|
||||||
|
private string _search;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
allroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
||||||
userroles = userroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
await LoadSettingsAsync();
|
||||||
|
userroles = Search(_search);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<UserRole> Search(string search)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(_search))
|
||||||
|
{
|
||||||
|
return allroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
||||||
|
}
|
||||||
|
return allroles
|
||||||
|
.Where(item => item.Role.Name == Constants.RegisteredRole &&
|
||||||
|
(
|
||||||
|
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||||
|
item.User.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task OnSearch()
|
||||||
|
{
|
||||||
|
userroles = Search(_search);
|
||||||
|
await UpdateSettingsAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteUser(UserRole UserRole)
|
private async Task DeleteUser(UserRole UserRole)
|
||||||
@ -56,4 +95,20 @@ else
|
|||||||
AddModuleMessage(ex.Message, MessageType.Error);
|
AddModuleMessage(ex.Message, MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string settingSearch = "AU-search";
|
||||||
|
|
||||||
|
private async Task LoadSettingsAsync()
|
||||||
|
{
|
||||||
|
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||||
|
_search = SettingService.GetSetting(settings, settingSearch, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateSettingsAsync()
|
||||||
|
{
|
||||||
|
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||||
|
SettingService.SetSetting(settings, settingSearch, _search);
|
||||||
|
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -52,6 +52,9 @@
|
|||||||
[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
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool IconOnly { get; set; } // optional - specifies only icon in link
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_text = Action;
|
_text = Action;
|
||||||
@ -60,6 +63,11 @@
|
|||||||
_text = Text;
|
_text = Text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IconOnly && !string.IsNullOrEmpty(IconName))
|
||||||
|
{
|
||||||
|
_text = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Parameters))
|
if (!string.IsNullOrEmpty(Parameters))
|
||||||
{
|
{
|
||||||
_parameters = Parameters;
|
_parameters = Parameters;
|
||||||
@ -82,7 +90,8 @@
|
|||||||
|
|
||||||
if (!string.IsNullOrEmpty(IconName))
|
if (!string.IsNullOrEmpty(IconName))
|
||||||
{
|
{
|
||||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span> ";
|
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span>{(IconOnly?"":" ")}";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_url = EditUrl(Action, _parameters);
|
_url = EditUrl(Action, _parameters);
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
@inject IFolderService FolderService
|
@inject IFolderService FolderService
|
||||||
@inject IFileService FileService
|
@inject IFileService FileService
|
||||||
@inject IJSRuntime JsRuntime
|
|
||||||
|
|
||||||
@if (_folders != null)
|
@if (_folders != null)
|
||||||
{
|
{
|
||||||
@ -258,7 +257,7 @@
|
|||||||
|
|
||||||
private async Task UploadFile()
|
private async Task UploadFile()
|
||||||
{
|
{
|
||||||
var interop = new Interop(JsRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
var upload = await interop.GetFiles(_fileinputid);
|
var upload = await interop.GetFiles(_fileinputid);
|
||||||
if (upload.Length > 0)
|
if (upload.Length > 0)
|
||||||
{
|
{
|
||||||
|
@ -10,10 +10,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 +36,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 +52,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 +64,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,7 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
@inject IJSRuntime JsRuntime
|
|
||||||
|
|
||||||
<div class="row" style="margin-bottom: 50px;">
|
<div class="row" style="margin-bottom: 50px;">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@ -108,6 +107,13 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string DebugLevel { get; set; } = "info";
|
public string DebugLevel { get; set; } = "info";
|
||||||
|
|
||||||
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
|
{
|
||||||
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill1.3.6.min.js" },
|
||||||
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
|
||||||
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
|
||||||
|
};
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
_content = Content; // raw HTML
|
_content = Content; // raw HTML
|
||||||
@ -117,8 +123,11 @@
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
await RichTextEditorInterop.CreateEditor(
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
JsRuntime,
|
|
||||||
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
|
|
||||||
|
await interop.CreateEditor(
|
||||||
_editorElement,
|
_editorElement,
|
||||||
_toolBar,
|
_toolBar,
|
||||||
ReadOnly,
|
ReadOnly,
|
||||||
@ -126,14 +135,10 @@
|
|||||||
Theme,
|
Theme,
|
||||||
DebugLevel);
|
DebugLevel);
|
||||||
|
|
||||||
await RichTextEditorInterop.LoadEditorContent(
|
await interop.LoadEditorContent(_editorElement, Content);
|
||||||
JsRuntime,
|
|
||||||
_editorElement, Content);
|
|
||||||
|
|
||||||
// preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor )
|
// preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor )
|
||||||
_original = await RichTextEditorInterop.GetHtml(
|
_original = await interop.GetHtml(_editorElement);
|
||||||
JsRuntime,
|
|
||||||
_editorElement);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,25 +151,22 @@
|
|||||||
|
|
||||||
public async Task RefreshRichText()
|
public async Task RefreshRichText()
|
||||||
{
|
{
|
||||||
await RichTextEditorInterop.LoadEditorContent(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
await interop.LoadEditorContent(_editorElement, _content);
|
||||||
_editorElement, _content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshRawHtml()
|
public async Task RefreshRawHtml()
|
||||||
{
|
{
|
||||||
_content = await RichTextEditorInterop.GetHtml(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
_content = await interop.GetHtml(_editorElement);
|
||||||
_editorElement);
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetHtml()
|
public async Task<string> GetHtml()
|
||||||
{
|
{
|
||||||
// get rich text content
|
// get rich text content
|
||||||
string content = await RichTextEditorInterop.GetHtml(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
string content = await interop.GetHtml(_editorElement);
|
||||||
_editorElement);
|
|
||||||
|
|
||||||
if (_original != content)
|
if (_original != content)
|
||||||
{
|
{
|
||||||
@ -185,9 +187,8 @@
|
|||||||
var fileid = _fileManager.GetFileId();
|
var fileid = _fileManager.GetFileId();
|
||||||
if (fileid != -1)
|
if (fileid != -1)
|
||||||
{
|
{
|
||||||
await RichTextEditorInterop.InsertImage(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
await interop.InsertImage(_editorElement, ContentUrl(fileid));
|
||||||
_editorElement, ContentUrl(fileid));
|
|
||||||
_filemanagervisible = false;
|
_filemanagervisible = false;
|
||||||
_message = string.Empty;
|
_message = string.Empty;
|
||||||
}
|
}
|
||||||
@ -207,22 +208,19 @@
|
|||||||
// other rich text editor methods which can be used by developers
|
// other rich text editor methods which can be used by developers
|
||||||
public async Task<string> GetText()
|
public async Task<string> GetText()
|
||||||
{
|
{
|
||||||
return await RichTextEditorInterop.GetText(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
return await interop.GetText(_editorElement);
|
||||||
_editorElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetContent()
|
public async Task<string> GetContent()
|
||||||
{
|
{
|
||||||
return await RichTextEditorInterop.GetContent(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
return await interop.GetContent(_editorElement);
|
||||||
_editorElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task EnableEditor(bool mode)
|
public async Task EnableEditor(bool mode)
|
||||||
{
|
{
|
||||||
await RichTextEditorInterop.EnableEditor(
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
JsRuntime,
|
await interop.EnableEditor(_editorElement, mode);
|
||||||
_editorElement, mode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,16 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Oqtane.Modules.Controls
|
namespace Oqtane.Modules.Controls
|
||||||
{
|
{
|
||||||
public static class RichTextEditorInterop
|
public class RichTextEditorInterop
|
||||||
{
|
{
|
||||||
internal static ValueTask<object> CreateEditor(
|
private readonly IJSRuntime _jsRuntime;
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
|
public RichTextEditorInterop(IJSRuntime jsRuntime)
|
||||||
|
{
|
||||||
|
_jsRuntime = jsRuntime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CreateEditor(
|
||||||
ElementReference quillElement,
|
ElementReference quillElement,
|
||||||
ElementReference toolbar,
|
ElementReference toolbar,
|
||||||
bool readOnly,
|
bool readOnly,
|
||||||
@ -15,66 +21,103 @@ namespace Oqtane.Modules.Controls
|
|||||||
string theme,
|
string theme,
|
||||||
string debugLevel)
|
string debugLevel)
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<object>(
|
try
|
||||||
"interop.createQuill",
|
{
|
||||||
quillElement, toolbar, readOnly,
|
await _jsRuntime.InvokeAsync<object>(
|
||||||
placeholder, theme, debugLevel);
|
"Oqtane.RichTextEditor.createQuill",
|
||||||
|
quillElement, toolbar, readOnly, placeholder, theme, debugLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// handle exception
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ValueTask<string> GetText(
|
public ValueTask<string> GetText(ElementReference quillElement)
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
ElementReference quillElement)
|
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<string>(
|
try
|
||||||
"interop.getQuillText",
|
{
|
||||||
|
return _jsRuntime.InvokeAsync<string>(
|
||||||
|
"Oqtane.RichTextEditor.getQuillText",
|
||||||
quillElement);
|
quillElement);
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
internal static ValueTask<string> GetHtml(
|
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
ElementReference quillElement)
|
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<string>(
|
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||||
"interop.getQuillHTML",
|
}
|
||||||
quillElement);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ValueTask<string> GetContent(
|
public ValueTask<string> GetHtml(ElementReference quillElement)
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
ElementReference quillElement)
|
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<string>(
|
try
|
||||||
"interop.getQuillContent",
|
{
|
||||||
|
return _jsRuntime.InvokeAsync<string>(
|
||||||
|
"Oqtane.RichTextEditor.getQuillHTML",
|
||||||
quillElement);
|
quillElement);
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
internal static ValueTask<object> LoadEditorContent(
|
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
ElementReference quillElement,
|
|
||||||
string content)
|
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<object>(
|
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||||
"interop.loadQuillContent",
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValueTask<string> GetContent(ElementReference quillElement)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return _jsRuntime.InvokeAsync<string>(
|
||||||
|
"Oqtane.RichTextEditor.getQuillContent",
|
||||||
|
quillElement);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task LoadEditorContent(ElementReference quillElement, string content)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_jsRuntime.InvokeAsync<object>(
|
||||||
|
"Oqtane.RichTextEditor.loadQuillContent",
|
||||||
quillElement, content);
|
quillElement, content);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ValueTask<object> EnableEditor(
|
public Task EnableEditor(ElementReference quillElement, bool mode)
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
ElementReference quillElement,
|
|
||||||
bool mode)
|
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<object>(
|
try
|
||||||
"interop.enableQuillEditor", quillElement, mode);
|
{
|
||||||
|
_jsRuntime.InvokeAsync<object>(
|
||||||
|
"Oqtane.RichTextEditor.enableQuillEditor", quillElement, mode);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static ValueTask<object> InsertImage(
|
public Task InsertImage(ElementReference quillElement, string imageUrl)
|
||||||
IJSRuntime jsRuntime,
|
|
||||||
ElementReference quillElement,
|
|
||||||
string imageUrl)
|
|
||||||
{
|
{
|
||||||
return jsRuntime.InvokeAsync<object>(
|
try
|
||||||
"interop.insertQuillImage",
|
{
|
||||||
|
_jsRuntime.InvokeAsync<object>(
|
||||||
|
"Oqtane.RichTextEditor.insertQuillImage",
|
||||||
quillElement, imageUrl);
|
quillElement, imageUrl);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div>
|
<div>
|
||||||
<a data-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name">
|
<a data-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
|
||||||
<h5>@_heading</h5>
|
<h5>@_heading</h5>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-auto">
|
<div class="ml-auto">
|
||||||
<a data-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name">
|
<a data-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
|
||||||
<i class="oi oi-chevron-bottom"></i>
|
<i class="oi oi-chevron-bottom"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,13 +11,13 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
@if (tabPanel.Name == ActiveTab)
|
@if (tabPanel.Name == ActiveTab)
|
||||||
{
|
{
|
||||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab">
|
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab">
|
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,8 @@
|
|||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
||||||
// the following resources should be declared in the RichTextEditor component however the framework currently only supports resource management for modules and themes
|
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.bubble.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.bubble.css" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css" }
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill1.3.6.min.js" },
|
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill-blot-formatter.min.js" },
|
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill-interop.js" }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private RichTextEditor RichTextEditorHtml;
|
private RichTextEditor RichTextEditorHtml;
|
||||||
|
@ -7,6 +7,8 @@ using System;
|
|||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
using Oqtane.UI;
|
using Oqtane.UI;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Oqtane.Modules
|
namespace Oqtane.Modules
|
||||||
{
|
{
|
||||||
@ -19,6 +21,9 @@ namespace Oqtane.Modules
|
|||||||
[Inject]
|
[Inject]
|
||||||
protected ILogService LoggingService { get; set; }
|
protected ILogService LoggingService { get; set; }
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
protected IJSRuntime JSRuntime { get; set; }
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected PageState PageState { get; set; }
|
protected PageState PageState { get; set; }
|
||||||
|
|
||||||
@ -28,7 +33,6 @@ namespace Oqtane.Modules
|
|||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected ModuleInstance ModuleInstance { get; set; }
|
protected ModuleInstance ModuleInstance { get; set; }
|
||||||
|
|
||||||
|
|
||||||
// optional interface properties
|
// optional interface properties
|
||||||
public virtual SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } set { } } // default security
|
public virtual SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } set { } } // default security
|
||||||
|
|
||||||
@ -40,6 +44,24 @@ namespace Oqtane.Modules
|
|||||||
|
|
||||||
public virtual List<Resource> Resources { get; set; }
|
public virtual List<Resource> Resources { get; set; }
|
||||||
|
|
||||||
|
// base lifecycle method for handling JSInterop script registration
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
||||||
|
{
|
||||||
|
var scripts = new List<object>();
|
||||||
|
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||||
|
{
|
||||||
|
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "" });
|
||||||
|
}
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.IncludeScripts(scripts.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// path method
|
// path method
|
||||||
|
|
||||||
|
@ -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.1</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -15,8 +15,9 @@
|
|||||||
<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.1</PackageReleaseNotes>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -37,5 +38,4 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -7,9 +7,9 @@ namespace Oqtane.Services
|
|||||||
public interface IThemeService
|
public interface IThemeService
|
||||||
{
|
{
|
||||||
Task<List<Theme>> GetThemesAsync();
|
Task<List<Theme>> GetThemesAsync();
|
||||||
Dictionary<string, string> GetThemeTypes(List<Theme> themes);
|
List<ThemeControl> GetThemeControls(List<Theme> themes);
|
||||||
Dictionary<string, string> GetPaneLayoutTypes(List<Theme> themes, string themeName);
|
List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName);
|
||||||
Dictionary<string, string> GetContainerTypes(List<Theme> themes);
|
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
|
||||||
Task InstallThemesAsync();
|
Task InstallThemesAsync();
|
||||||
Task DeleteThemeAsync(string themeName);
|
Task DeleteThemeAsync(string themeName);
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ namespace Oqtane.Services
|
|||||||
public string GetSetting(Dictionary<string, string> settings, string settingName, string defaultValue)
|
public string GetSetting(Dictionary<string, string> settings, string settingName, string defaultValue)
|
||||||
{
|
{
|
||||||
string value = defaultValue;
|
string value = defaultValue;
|
||||||
if (settings.ContainsKey(settingName))
|
if (settings != null && settings.ContainsKey(settingName))
|
||||||
{
|
{
|
||||||
value = settings[settingName];
|
value = settings[settingName];
|
||||||
}
|
}
|
||||||
@ -162,6 +162,10 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue)
|
public Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue)
|
||||||
{
|
{
|
||||||
|
if (settings == null)
|
||||||
|
{
|
||||||
|
settings = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
if (settings.ContainsKey(settingName))
|
if (settings.ContainsKey(settingName))
|
||||||
{
|
{
|
||||||
settings[settingName] = settingValue;
|
settings[settingName] = settingValue;
|
||||||
|
@ -1,81 +1,54 @@
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, string> GetThemeTypes(List<Theme> themes)
|
public List<ThemeControl> GetThemeControls(List<Theme> themes)
|
||||||
{
|
{
|
||||||
var selectableThemes = new Dictionary<string, string>();
|
return themes.SelectMany(item => item.Themes).ToList();
|
||||||
foreach (Theme theme in themes)
|
|
||||||
{
|
|
||||||
foreach (string themecontrol in theme.ThemeControls.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
|
||||||
selectableThemes.Add(themecontrol, theme.Name + " - " + Utilities.GetTypeNameLastSegment(themecontrol, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selectableThemes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, string> GetPaneLayoutTypes(List<Theme> themes, string themeName)
|
public List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName)
|
||||||
{
|
{
|
||||||
var selectablePaneLayouts = new Dictionary<string, string>();
|
return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName)))
|
||||||
foreach (Theme theme in themes)
|
.SelectMany(item => item.Layouts).ToList();
|
||||||
{
|
|
||||||
if (themeName.StartsWith(theme.ThemeName))
|
|
||||||
{
|
|
||||||
foreach (string panelayout in theme.PaneLayouts.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
|
||||||
selectablePaneLayouts.Add(panelayout, theme.Name + " - " + @Utilities.GetTypeNameLastSegment(panelayout, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selectablePaneLayouts;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, string> GetContainerTypes(List<Theme> themes)
|
public List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName)
|
||||||
{
|
{
|
||||||
var selectableContainers = new Dictionary<string, string>();
|
return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName)))
|
||||||
foreach (Theme theme in themes)
|
.SelectMany(item => item.Containers).ToList();
|
||||||
{
|
|
||||||
foreach (string container in theme.ContainerControls.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
|
||||||
selectableContainers.Add(container, theme.Name + " - " + @Utilities.GetTypeNameLastSegment(container, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return selectableContainers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" }
|
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.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://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.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -1,62 +1,12 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.UI;
|
|
||||||
|
|
||||||
namespace Oqtane.Themes
|
namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
public class ContainerBase : ComponentBase, IContainerControl
|
public abstract class ContainerBase : ThemeBase, IContainerControl
|
||||||
{
|
{
|
||||||
[Inject]
|
|
||||||
protected IJSRuntime JSRuntime { get; set; }
|
|
||||||
|
|
||||||
[CascadingParameter]
|
|
||||||
protected PageState PageState { get; set; }
|
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected Module ModuleState { get; set; }
|
protected Module ModuleState { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public string ThemePath()
|
|
||||||
{
|
|
||||||
return "Themes/" + GetType().Namespace + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string NavigateUrl()
|
|
||||||
{
|
|
||||||
return NavigateUrl(PageState.Page.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string NavigateUrl(string path)
|
|
||||||
{
|
|
||||||
return NavigateUrl(path, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string NavigateUrl(string path, string parameters)
|
|
||||||
{
|
|
||||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(string action, string parameters)
|
|
||||||
{
|
|
||||||
return EditUrl(ModuleState.ModuleId, action, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(int moduleid, string action)
|
|
||||||
{
|
|
||||||
return EditUrl(moduleid, action, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(int moduleid, string action, string parameters)
|
|
||||||
{
|
|
||||||
return EditUrl(PageState.Page.Path, moduleid, action, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(string path, int moduleid, string action, string parameters)
|
|
||||||
{
|
|
||||||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
@ -9,6 +8,7 @@
|
|||||||
@inject IPageService PageService
|
@inject IPageService PageService
|
||||||
@inject IPageModuleService PageModuleService
|
@inject IPageModuleService PageModuleService
|
||||||
@inject ILogService logger
|
@inject ILogService logger
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
|
||||||
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||||
{
|
{
|
||||||
@ -49,6 +49,21 @@
|
|||||||
<button class="btn btn-danger btn-block mx-auto" @onclick="ConfirmDelete">Delete</button>
|
<button class="btn btn-danger btn-block mx-auto" @onclick="ConfirmDelete">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="row">
|
||||||
|
@if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(Constants.AllUsersRole))
|
||||||
|
{
|
||||||
|
<div class="col">
|
||||||
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick=@(async () => Publish("unpublish"))>Unpublish Page</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="col">
|
||||||
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick=@(async () => Publish("publish"))>Publish Page</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_deleteConfirmation)
|
@if (_deleteConfirmation)
|
||||||
@ -78,18 +93,18 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
<label for="Module" class="control-label">Module Management: </label>
|
<label for="Module" class="control-label">Module Management: </label>
|
||||||
<select class="form-control" @bind="@_moduleType">
|
<select class="form-control" @bind="@ModuleType">
|
||||||
<option value="new">Add New Module</option>
|
<option value="new">Add New Module</option>
|
||||||
<option value="existing">Add Existing Module</option>
|
<option value="existing">Add Existing Module</option>
|
||||||
</select>
|
</select>
|
||||||
@if (_moduleType == "new")
|
@if (ModuleType == "new")
|
||||||
{
|
{
|
||||||
@if (_moduleDefinitions != null)
|
@if (_moduleDefinitions != null)
|
||||||
{
|
{
|
||||||
<select class="form-control" @onchange="(e => CategoryChanged(e))">
|
<select class="form-control" @onchange="(e => CategoryChanged(e))">
|
||||||
@foreach (var category in _categories)
|
@foreach (var category in _categories)
|
||||||
{
|
{
|
||||||
if (category == _category)
|
if (category == Category)
|
||||||
{
|
{
|
||||||
<option value="@category" selected>@category Modules</option>
|
<option value="@category" selected>@category Modules</option>
|
||||||
}
|
}
|
||||||
@ -100,7 +115,7 @@
|
|||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<select class="form-control" @onchange="(e => ModuleChanged(e))">
|
<select class="form-control" @onchange="(e => ModuleChanged(e))">
|
||||||
@if (_moduleDefinitionName == "-")
|
@if (ModuleDefinitionName == "-")
|
||||||
{
|
{
|
||||||
<option value="-" selected><Select Module></option>
|
<option value="-" selected><Select Module></option>
|
||||||
}
|
}
|
||||||
@ -116,7 +131,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@((MarkupString)@_description)
|
@((MarkupString) Description)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -128,7 +143,7 @@
|
|||||||
<option value="@p.PageId">@p.Name</option>
|
<option value="@p.PageId">@p.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<select class="form-control" @bind="@_moduleId">
|
<select class="form-control" @bind="@ModuleId">
|
||||||
<option value="-"><Select Module></option>
|
<option value="-"><Select Module></option>
|
||||||
@foreach (Module module in _modules)
|
@foreach (Module module in _modules)
|
||||||
{
|
{
|
||||||
@ -141,14 +156,15 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
<label for="Title" class="control-label">Title: </label>
|
<label for="Title" class="control-label">Title: </label>
|
||||||
<input type="text" name="Title" class="form-control" @bind="@_title" />
|
<input type="text" name="Title" class="form-control" @bind="@Title" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if (_pane.Length > 1)
|
||||||
|
{
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
<label for="Pane" class="control-label">Pane: </label>
|
<label for="Pane" class="control-label">Pane: </label>
|
||||||
<select class="form-control" @bind="@_pane">
|
<select class="form-control" @bind="@Pane">
|
||||||
<option value=""><Select Pane></option>
|
|
||||||
@foreach (string pane in PageState.Page.Panes)
|
@foreach (string pane in PageState.Page.Panes)
|
||||||
{
|
{
|
||||||
<option value="@pane">@pane Pane</option>
|
<option value="@pane">@pane Pane</option>
|
||||||
@ -156,13 +172,14 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
<label for="Container" class="control-label">Container: </label>
|
<label for="Container" class="control-label">Container: </label>
|
||||||
<select class="form-control" @bind="@_containerType">
|
<select class="form-control" @bind="@ContainerType">
|
||||||
@foreach (KeyValuePair<string, string> container in _containers)
|
@foreach (var container in _containers)
|
||||||
{
|
{
|
||||||
<option value="@container.Key">@container.Value</option>
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -171,7 +188,7 @@
|
|||||||
<br />
|
<br />
|
||||||
|
|
||||||
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">Add Module To Page</button>
|
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">Add Module To Page</button>
|
||||||
@((MarkupString) _message)
|
@((MarkupString) Message)
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -210,59 +227,74 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code{
|
@code{
|
||||||
|
|
||||||
private bool _deleteConfirmation = false;
|
private bool _deleteConfirmation = false;
|
||||||
private string _moduleType = "new";
|
|
||||||
private List<string> _categories = new List<string>();
|
private List<string> _categories = new List<string>();
|
||||||
private List<ModuleDefinition> _allModuleDefinitions;
|
private List<ModuleDefinition> _allModuleDefinitions;
|
||||||
private List<ModuleDefinition> _moduleDefinitions;
|
private List<ModuleDefinition> _moduleDefinitions;
|
||||||
private List<Page> _pages = new List<Page>();
|
private List<Page> _pages = new List<Page>();
|
||||||
private string _pageId = "-";
|
|
||||||
private string _moduleId = "-";
|
|
||||||
private List<Module> _modules = new List<Module>();
|
private List<Module> _modules = new List<Module>();
|
||||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _moduleDefinitionName = "-";
|
|
||||||
private string _category = "Common";
|
|
||||||
private string _description = "";
|
|
||||||
private string _pane = "";
|
|
||||||
private string _title = "";
|
|
||||||
private string _containerType = "";
|
|
||||||
private string _display = "display: none;";
|
private string _display = "display: none;";
|
||||||
private string _message = "";
|
private string _category = "Common";
|
||||||
|
|
||||||
[Parameter]
|
protected string PageId { get; private set; } = "-";
|
||||||
public string ButtonClass { get; set; }
|
protected string ModuleId { get; private set; } = "-";
|
||||||
|
protected string ModuleType { get; private set; } = "new";
|
||||||
|
protected string ModuleDefinitionName { get; private set; } = "-";
|
||||||
|
|
||||||
[Parameter]
|
protected string Category
|
||||||
public string CardClass { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string HeaderClass { get; set; }
|
|
||||||
|
|
||||||
[Parameter]
|
|
||||||
public string BodyClass { get; set; }
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(ButtonClass))
|
get => _category;
|
||||||
|
private set
|
||||||
{
|
{
|
||||||
ButtonClass = "btn-outline-secondary";
|
if (_category != value)
|
||||||
|
{
|
||||||
|
_category = value;
|
||||||
|
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
||||||
|
ModuleDefinitionName = "-";
|
||||||
|
Description = "";
|
||||||
|
StateHasChanged();
|
||||||
|
_ = UpdateSettingsAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(CardClass))
|
protected string Pane
|
||||||
{
|
{
|
||||||
CardClass = "card border-secondary mb-3";
|
get => _pane;
|
||||||
|
private set
|
||||||
|
{
|
||||||
|
if (_pane != value)
|
||||||
|
{
|
||||||
|
_pane = value;
|
||||||
|
_ = UpdateSettingsAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(HeaderClass))
|
|
||||||
{
|
|
||||||
HeaderClass = "card-header";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(BodyClass))
|
protected string Description { get; private set; } = "";
|
||||||
{
|
|
||||||
BodyClass = "card-body";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
protected string Title { get; private set; } = "";
|
||||||
|
protected string ContainerType { get; private set; } = "";
|
||||||
|
protected string Message { get; private set; } = "";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string ButtonClass { get; set; } = "btn-outline-secondary";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string CardClass { get; set; } = "card border-secondary mb-3";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string HeaderClass { get; set; } = "card-header";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string BodyClass { get; set; } = "card-body";
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||||
{
|
{
|
||||||
_pages?.Clear();
|
_pages?.Clear();
|
||||||
@ -274,78 +306,50 @@
|
|||||||
_pages.Add(p);
|
_pages.Add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
await LoadSettingsAsync();
|
||||||
|
|
||||||
var panes = PageState.Page.Panes;
|
|
||||||
_pane = panes.Count() == 1 ? panes.SingleOrDefault() : "";
|
|
||||||
var themes = await ThemeService.GetThemesAsync();
|
var themes = await ThemeService.GetThemesAsync();
|
||||||
_containers = ThemeService.GetContainerTypes(themes);
|
_containers = ThemeService.GetContainerControls(themes, PageState.Page.ThemeType);
|
||||||
_containerType = PageState.Site.DefaultContainerType;
|
ContainerType = PageState.Site.DefaultContainerType;
|
||||||
|
|
||||||
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||||
|
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
||||||
_categories = new List<string>();
|
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
|
||||||
foreach (ModuleDefinition moduledefinition in _allModuleDefinitions)
|
|
||||||
{
|
|
||||||
if (moduledefinition.Categories != "")
|
|
||||||
{
|
|
||||||
foreach (string category in moduledefinition.Categories.Split(','))
|
|
||||||
{
|
|
||||||
if (!_categories.Contains(category))
|
|
||||||
{
|
|
||||||
_categories.Add(category);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_category = "Common";
|
|
||||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
|
||||||
_moduleDefinitionName = "-";
|
|
||||||
_description = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CategoryChanged(ChangeEventArgs e)
|
private void CategoryChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_category = (string) e.Value;
|
Category = (string) e.Value;
|
||||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
|
||||||
_moduleDefinitionName = "-";
|
|
||||||
_description = "";
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ModuleChanged(ChangeEventArgs e)
|
private void ModuleChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_moduleDefinitionName = (string)e.Value;
|
ModuleDefinitionName = (string) e.Value;
|
||||||
if (_moduleDefinitionName != "-")
|
if (ModuleDefinitionName != "-")
|
||||||
{
|
{
|
||||||
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == _moduleDefinitionName);
|
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName);
|
||||||
_description = "<br /><div class=\"alert alert-info\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
Description = "<br /><div class=\"alert alert-info\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_description = "";
|
Description = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PageChanged(ChangeEventArgs e)
|
private void PageChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_pageId = (string) e.Value;
|
PageId = (string) e.Value;
|
||||||
_modules?.Clear();
|
if (PageId != "-")
|
||||||
|
|
||||||
if (_pageId != "-")
|
|
||||||
{
|
{
|
||||||
foreach (Module module in PageState.Modules.Where(item => item.PageId == int.Parse(_pageId) && !item.IsDeleted))
|
_modules = PageState.Modules
|
||||||
{
|
.Where(module => module.PageId == int.Parse(PageId)
|
||||||
if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.View, module.Permissions))
|
&& !module.IsDeleted
|
||||||
{
|
&& UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||||
_modules.Add(module);
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
ModuleId = "-";
|
||||||
}
|
|
||||||
|
|
||||||
_moduleId = "-";
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,41 +357,41 @@
|
|||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||||
{
|
{
|
||||||
if ((_moduleType == "new" && _moduleDefinitionName != "-") || (_moduleType != "new" && _moduleId != "-"))
|
if ((ModuleType == "new" && ModuleDefinitionName != "-") || (ModuleType != "new" && ModuleId != "-"))
|
||||||
{
|
{
|
||||||
if (_moduleType == "new")
|
if (ModuleType == "new")
|
||||||
{
|
{
|
||||||
Module module = new Module();
|
Module module = new Module();
|
||||||
module.SiteId = PageState.Site.SiteId;
|
module.SiteId = PageState.Site.SiteId;
|
||||||
module.PageId = PageState.Page.PageId;
|
module.PageId = PageState.Page.PageId;
|
||||||
module.ModuleDefinitionName = _moduleDefinitionName;
|
module.ModuleDefinitionName = ModuleDefinitionName;
|
||||||
module.AllPages = false;
|
module.AllPages = false;
|
||||||
module.Permissions = PageState.Page.Permissions;
|
module.Permissions = PageState.Page.Permissions;
|
||||||
module = await ModuleService.AddModuleAsync(module);
|
module = await ModuleService.AddModuleAsync(module);
|
||||||
_moduleId = module.ModuleId.ToString();
|
ModuleId = module.ModuleId.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
var pageModule = new PageModule
|
var pageModule = new PageModule
|
||||||
{
|
{
|
||||||
PageId = PageState.Page.PageId,
|
PageId = PageState.Page.PageId,
|
||||||
ModuleId = int.Parse(_moduleId),
|
ModuleId = int.Parse(ModuleId),
|
||||||
Title = _title
|
Title = Title
|
||||||
};
|
};
|
||||||
if (pageModule.Title == "")
|
if (pageModule.Title == "")
|
||||||
{
|
{
|
||||||
if (_moduleType == "new")
|
if (ModuleType == "new")
|
||||||
{
|
{
|
||||||
pageModule.Title = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == _moduleDefinitionName)?.Name;
|
pageModule.Title = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName)?.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pageModule.Title = _modules.FirstOrDefault(item => item.ModuleId == int.Parse(_moduleId))?.Title;
|
pageModule.Title = _modules.FirstOrDefault(item => item.ModuleId == int.Parse(ModuleId))?.Title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pageModule.Pane = _pane;
|
pageModule.Pane = Pane;
|
||||||
pageModule.Order = int.MaxValue;
|
pageModule.Order = int.MaxValue;
|
||||||
pageModule.ContainerType = _containerType;
|
pageModule.ContainerType = ContainerType;
|
||||||
|
|
||||||
if (pageModule.ContainerType == PageState.Site.DefaultContainerType)
|
if (pageModule.ContainerType == PageState.Site.DefaultContainerType)
|
||||||
{
|
{
|
||||||
@ -397,26 +401,17 @@
|
|||||||
await PageModuleService.AddPageModuleAsync(pageModule);
|
await PageModuleService.AddPageModuleAsync(pageModule);
|
||||||
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
||||||
|
|
||||||
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">Module Added To Page</div>";
|
Message = "<br /><div class=\"alert alert-success\" role=\"alert\">Module Added To Page</div>";
|
||||||
|
|
||||||
_moduleDefinitionName = "-";
|
|
||||||
_description = "";
|
|
||||||
_pane = "";
|
|
||||||
_title = "";
|
|
||||||
_containerType = "";
|
|
||||||
_pageId = "-";
|
|
||||||
_moduleId = "-";
|
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select A Module</div>";
|
Message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select A Module</div>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_message = "<br /><div class=\"alert alert-error\" role=\"alert\">Not Authorized</div>";
|
Message = "<br /><div class=\"alert alert-error\" role=\"alert\">Not Authorized</div>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,6 +427,7 @@
|
|||||||
{
|
{
|
||||||
PageState.EditMode = true;
|
PageState.EditMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -447,14 +443,14 @@
|
|||||||
|
|
||||||
private void ShowControlPanel()
|
private void ShowControlPanel()
|
||||||
{
|
{
|
||||||
_message = "";
|
Message = "";
|
||||||
_display = "width: 25%; min-width: 375px;";
|
_display = "width: 25%; min-width: 375px;";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HideControlPanel()
|
private void HideControlPanel()
|
||||||
{
|
{
|
||||||
_message = "";
|
Message = "";
|
||||||
_display = "width: 0%;";
|
_display = "width: 0%;";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@ -503,6 +499,61 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void Publish(string action)
|
||||||
|
{
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||||
|
{
|
||||||
|
List<PermissionString> permissions;
|
||||||
|
|
||||||
|
if (action == "publish")
|
||||||
|
{
|
||||||
|
// publish all modules
|
||||||
|
foreach (var module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId))
|
||||||
|
{
|
||||||
|
permissions = UserSecurity.GetPermissionStrings(module.Permissions);
|
||||||
|
foreach (var permissionstring in permissions)
|
||||||
|
{
|
||||||
|
if (permissionstring.PermissionName == PermissionNames.View)
|
||||||
|
{
|
||||||
|
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||||
|
if (!ids.Contains(Constants.AllUsersRole)) ids.Add(Constants.AllUsersRole);
|
||||||
|
if (!ids.Contains(Constants.RegisteredRole)) ids.Add(Constants.RegisteredRole);
|
||||||
|
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
||||||
|
await ModuleService.UpdateModuleAsync(module);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// publish page
|
||||||
|
var page = PageState.Page;
|
||||||
|
permissions = UserSecurity.GetPermissionStrings(page.Permissions);
|
||||||
|
foreach (var permissionstring in permissions)
|
||||||
|
{
|
||||||
|
if (permissionstring.PermissionName == PermissionNames.View)
|
||||||
|
{
|
||||||
|
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case "publish":
|
||||||
|
if (!ids.Contains(Constants.AllUsersRole)) ids.Add(Constants.AllUsersRole);
|
||||||
|
if (!ids.Contains(Constants.RegisteredRole)) ids.Add(Constants.RegisteredRole);
|
||||||
|
break;
|
||||||
|
case "unpublish":
|
||||||
|
ids.Remove(Constants.AllUsersRole);
|
||||||
|
ids.Remove(Constants.RegisteredRole);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
page.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
||||||
|
await PageService.UpdatePageAsync(page);
|
||||||
|
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ConfirmDelete()
|
private void ConfirmDelete()
|
||||||
{
|
{
|
||||||
_deleteConfirmation = !_deleteConfirmation;
|
_deleteConfirmation = !_deleteConfirmation;
|
||||||
@ -536,4 +587,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string settingCategory = "CP-category";
|
||||||
|
private string settingPane = "CP-pane";
|
||||||
|
private string _pane = "";
|
||||||
|
|
||||||
|
private async Task LoadSettingsAsync()
|
||||||
|
{
|
||||||
|
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||||
|
_category = SettingService.GetSetting(settings, settingCategory, "Common");
|
||||||
|
var pane = SettingService.GetSetting(settings, settingPane, "");
|
||||||
|
_pane = PageState.Page.Panes.Contains(pane) ? pane : PageState.Page.Panes.FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateSettingsAsync()
|
||||||
|
{
|
||||||
|
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||||
|
SettingService.SetSetting(settings, settingCategory, _category);
|
||||||
|
SettingService.SetSetting(settings, settingPane, _pane);
|
||||||
|
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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">
|
||||||
@ -16,7 +16,7 @@
|
|||||||
if (p.PageId == PageState.Page.PageId)
|
if (p.PageId == PageState.Page.PageId)
|
||||||
{
|
{
|
||||||
<li class="nav-item active">
|
<li class="nav-item active">
|
||||||
<a class="nav-link" href="@NavigateUrl(p.Path)">
|
<a class="nav-link" href="@GetUrl(p)" target="@GetTarget(p)" >
|
||||||
@if (p.Icon != string.Empty)
|
@if (p.Icon != string.Empty)
|
||||||
{
|
{
|
||||||
<span class="oi oi-@p.Icon" aria-hidden="true"></span>
|
<span class="oi oi-@p.Icon" aria-hidden="true"></span>
|
||||||
@ -28,7 +28,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="@NavigateUrl(p.Path)">
|
<a class="nav-link" href="@GetUrl(p)" target="@GetTarget(p)" >
|
||||||
@if (p.Icon != string.Empty)
|
@if (p.Icon != string.Empty)
|
||||||
{
|
{
|
||||||
<span class="oi oi-@p.Icon" aria-hidden="true"></span>
|
<span class="oi oi-@p.Icon" aria-hidden="true"></span>
|
||||||
|
@ -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,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
@ -16,6 +17,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
{
|
{
|
||||||
[Inject] public NavigationManager NavigationManager { get; set; }
|
[Inject] public NavigationManager NavigationManager { get; set; }
|
||||||
[Inject] public IPageModuleService PageModuleService { get; set; }
|
[Inject] public IPageModuleService PageModuleService { get; set; }
|
||||||
|
[Inject] public IModuleService ModuleService { get; set; }
|
||||||
|
|
||||||
protected List<ActionViewModel> Actions;
|
protected List<ActionViewModel> Actions;
|
||||||
|
|
||||||
@ -30,14 +32,23 @@ namespace Oqtane.Themes.Controls
|
|||||||
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 {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))
|
||||||
|
{
|
||||||
|
actionList.Add(new ActionViewModel { Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actionList.Add(new ActionViewModel { 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) });
|
||||||
|
|
||||||
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
||||||
{
|
{
|
||||||
|
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 {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 {Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")});
|
||||||
}
|
}
|
||||||
|
|
||||||
actionList.Add(new ActionViewModel {Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m)});
|
|
||||||
actionList.Add(new ActionViewModel {Name = ""});
|
actionList.Add(new ActionViewModel {Name = ""});
|
||||||
|
|
||||||
if (ModuleState.PaneModuleIndex > 0)
|
if (ModuleState.PaneModuleIndex > 0)
|
||||||
@ -121,6 +132,42 @@ namespace Oqtane.Themes.Controls
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<string> Publish(string s, PageModule pagemodule)
|
||||||
|
{
|
||||||
|
var permissions = UserSecurity.GetPermissionStrings(pagemodule.Module.Permissions);
|
||||||
|
foreach (var permissionstring in permissions)
|
||||||
|
{
|
||||||
|
if (permissionstring.PermissionName == PermissionNames.View)
|
||||||
|
{
|
||||||
|
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||||
|
if (!ids.Contains(Constants.AllUsersRole)) ids.Add(Constants.AllUsersRole);
|
||||||
|
if (!ids.Contains(Constants.RegisteredRole)) ids.Add(Constants.RegisteredRole);
|
||||||
|
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pagemodule.Module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
||||||
|
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
||||||
|
return NavigateUrl(s, "reload");
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> Unpublish(string s, PageModule pagemodule)
|
||||||
|
{
|
||||||
|
var permissions = UserSecurity.GetPermissionStrings(pagemodule.Module.Permissions);
|
||||||
|
foreach (var permissionstring in permissions)
|
||||||
|
{
|
||||||
|
if (permissionstring.PermissionName == PermissionNames.View)
|
||||||
|
{
|
||||||
|
List<string> ids = permissionstring.Permissions.Split(';').ToList();
|
||||||
|
ids.Remove(Constants.AllUsersRole);
|
||||||
|
ids.Remove(Constants.RegisteredRole);
|
||||||
|
permissionstring.Permissions = string.Join(";", ids.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pagemodule.Module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
||||||
|
await ModuleService.UpdateModuleAsync(pagemodule.Module);
|
||||||
|
return NavigateUrl(s, "reload");
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<string> MoveTop(string s, PageModule pagemodule)
|
private async Task<string> MoveTop(string s, PageModule pagemodule)
|
||||||
{
|
{
|
||||||
pagemodule.Order = 0;
|
pagemodule.Order = 0;
|
||||||
|
@ -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,5 +2,6 @@
|
|||||||
{
|
{
|
||||||
public interface IContainerControl
|
public interface IContainerControl
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
{
|
{
|
||||||
public interface ILayoutControl
|
public interface ILayoutControl
|
||||||
{
|
{
|
||||||
string Panes { get; } // identifies all panes in a theme ( delimited by ";" )
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
namespace Oqtane.Themes
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.UI;
|
|
||||||
|
|
||||||
namespace Oqtane.Themes
|
|
||||||
{
|
{
|
||||||
public class LayoutBase : ComponentBase, ILayoutControl
|
public abstract class LayoutBase : ThemeBase, ILayoutControl
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
|
||||||
protected PageState PageState { get; set; }
|
|
||||||
public virtual string Panes { get; set; }
|
|
||||||
|
|
||||||
public string LayoutPath()
|
|
||||||
{
|
|
||||||
return "Themes/" + GetType().Namespace + "/";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,3 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
public override string Name => "Standard Header";
|
||||||
|
}
|
@ -17,14 +17,16 @@
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
public override string Name => "Default";
|
||||||
|
|
||||||
public override string Panes => string.Empty;
|
public override string Panes => string.Empty;
|
||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "BootswatchCyborg.css" },
|
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" },
|
||||||
// remote stylesheets can be linked using the format below, however we want the default theme to display properly in local development scenarios where an Internet connection is not available
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||||
//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.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.Stylesheet, Url = ThemePath() + "Theme.css" }
|
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.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,5 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public override string Panes => "Top;Left;Content;Right;Bottom";
|
public override string Name => "Multiple Panes";
|
||||||
|
|
||||||
|
public override string Panes => "Top,Left,Content,Right,Bottom";
|
||||||
}
|
}
|
@ -7,3 +7,7 @@
|
|||||||
}
|
}
|
||||||
<ModuleInstance />
|
<ModuleInstance />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
public override string Name => "No Header";
|
||||||
|
}
|
@ -6,5 +6,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
public override string Name => "Single Pane";
|
||||||
|
|
||||||
public override string Panes => "Content";
|
public override string Panes => "Content";
|
||||||
}
|
}
|
@ -4,11 +4,12 @@ using Oqtane.Models;
|
|||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using Oqtane.UI;
|
using Oqtane.UI;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Oqtane.Themes
|
namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
public class ThemeBase : ComponentBase, IThemeControl
|
public abstract class ThemeBase : ComponentBase, IThemeControl
|
||||||
{
|
{
|
||||||
[Inject]
|
[Inject]
|
||||||
protected IJSRuntime JSRuntime { get; set; }
|
protected IJSRuntime JSRuntime { get; set; }
|
||||||
@ -17,9 +18,30 @@ namespace Oqtane.Themes
|
|||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected PageState PageState { get; set; }
|
protected PageState PageState { get; set; }
|
||||||
|
public virtual string Name { get; set; }
|
||||||
|
public virtual string Thumbnail { get; set; }
|
||||||
public virtual string Panes { get; set; }
|
public virtual string Panes { get; set; }
|
||||||
public virtual List<Resource> Resources { get; set; }
|
public virtual List<Resource> Resources { get; set; }
|
||||||
|
|
||||||
|
// base lifecycle method for handling JSInterop script registration
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
||||||
|
{
|
||||||
|
var scripts = new List<object>();
|
||||||
|
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||||
|
{
|
||||||
|
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "" });
|
||||||
|
}
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.IncludeScripts(scripts.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// path method
|
// path method
|
||||||
|
|
||||||
public string ThemePath()
|
public string ThemePath()
|
||||||
@ -58,5 +80,10 @@ namespace Oqtane.Themes
|
|||||||
{
|
{
|
||||||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string ContentUrl(int fileid)
|
||||||
|
{
|
||||||
|
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,10 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Oqtane.Shared;
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.UI;
|
|
||||||
|
|
||||||
namespace Oqtane.Themes
|
namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
public class ThemeControlBase : ComponentBase
|
[OqtaneIgnore]
|
||||||
|
public abstract class ThemeControlBase : ThemeBase
|
||||||
{
|
{
|
||||||
[CascadingParameter]
|
|
||||||
protected PageState PageState { get; set; }
|
|
||||||
|
|
||||||
public string NavigateUrl()
|
|
||||||
{
|
|
||||||
return NavigateUrl(PageState.Page.Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string NavigateUrl(string path)
|
|
||||||
{
|
|
||||||
return NavigateUrl(path, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string NavigateUrl(string path, string parameters)
|
|
||||||
{
|
|
||||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(int moduleid, string action)
|
|
||||||
{
|
|
||||||
return EditUrl(moduleid, action, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(int moduleid, string action, string parameters)
|
|
||||||
{
|
|
||||||
return EditUrl(PageState.Page.Path, moduleid, action, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string EditUrl(string path, int moduleid, string action, string parameters)
|
|
||||||
{
|
|
||||||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ContentUrl(int fileid)
|
|
||||||
{
|
|
||||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,18 +27,13 @@
|
|||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
Type containerType = Type.GetType(container);
|
Type containerType = Type.GetType(container);
|
||||||
if (containerType != null)
|
if (containerType == null)
|
||||||
{
|
{
|
||||||
|
// fallback
|
||||||
|
containerType = Type.GetType(Constants.DefaultContainer);
|
||||||
|
}
|
||||||
builder.OpenComponent(0, containerType);
|
builder.OpenComponent(0, containerType);
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// container does not exist with type specified
|
|
||||||
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageComponent));
|
|
||||||
builder.AddAttribute(1, "Message", "Error Loading Module Container " + container);
|
|
||||||
builder.CloseComponent();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
@inject IInstallationService InstallationService
|
@inject IInstallationService InstallationService
|
||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -138,6 +139,15 @@
|
|||||||
private string _integratedSecurityDisplay = "display: none;";
|
private string _integratedSecurityDisplay = "display: none;";
|
||||||
private string _loadingDisplay = "display: none;";
|
private string _loadingDisplay = "display: none;";
|
||||||
|
|
||||||
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.IncludeLink("app-stylesheet", "stylesheet", "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css", "text/css", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", "anonymous", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SetIntegratedSecurity(ChangeEventArgs e)
|
private void SetIntegratedSecurity(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_integratedSecurityDisplay = Convert.ToBoolean((string)e.Value)
|
_integratedSecurityDisplay = Convert.ToBoolean((string)e.Value)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.JSInterop;
|
||||||
using Microsoft.JSInterop;
|
using Oqtane.Models;
|
||||||
using System;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Oqtane.UI
|
namespace Oqtane.UI
|
||||||
@ -18,8 +17,8 @@ namespace Oqtane.UI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.setCookie",
|
"Oqtane.Interop.setCookie",
|
||||||
name, value, days);
|
name, value, days);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -34,7 +33,7 @@ namespace Oqtane.UI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
return _jsRuntime.InvokeAsync<string>(
|
return _jsRuntime.InvokeAsync<string>(
|
||||||
"interop.getCookie",
|
"Oqtane.Interop.getCookie",
|
||||||
name);
|
name);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -47,8 +46,8 @@ namespace Oqtane.UI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.updateTitle",
|
"Oqtane.Interop.updateTitle",
|
||||||
title);
|
title);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -58,13 +57,13 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task IncludeMeta(string id, string attribute, string name, string content)
|
public Task IncludeMeta(string id, string attribute, string name, string content, string key)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.includeMeta",
|
"Oqtane.Interop.includeMeta",
|
||||||
id, attribute, name, content);
|
id, attribute, name, content, key);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -73,13 +72,13 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task IncludeLink(string id, string rel, string url, string type, string integrity, string crossorigin)
|
public Task IncludeLink(string id, string rel, string href, string type, string integrity, string crossorigin, string key)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.includeLink",
|
"Oqtane.Interop.includeLink",
|
||||||
id, rel, url, type, integrity, crossorigin);
|
id, rel, href, type, integrity, crossorigin, key);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -88,13 +87,13 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task IncludeScript(string id, string src, string content, string location, string integrity, string crossorigin)
|
public Task IncludeLinks(object[] links)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.includeScript",
|
"Oqtane.Interop.includeLinks",
|
||||||
id, src, content, location, integrity, crossorigin);
|
(object) links);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -103,13 +102,13 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task IncludeCSS(string id, string url)
|
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string content, string location, string key)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.includeLink",
|
"Oqtane.Interop.includeScript",
|
||||||
id, "stylesheet", url, "text/css");
|
id, src, integrity, crossorigin, content, location, key);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -118,12 +117,26 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task IncludeScripts(object[] scripts)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _jsRuntime.InvokeVoidAsync(
|
||||||
|
"Oqtane.Interop.includeScripts",
|
||||||
|
(object)scripts);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignore exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Task RemoveElementsById(string prefix, string first, string last)
|
public Task RemoveElementsById(string prefix, string first, string last)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.removeElementsById",
|
"Oqtane.Interop.removeElementsById",
|
||||||
prefix, first, last);
|
prefix, first, last);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -133,13 +146,12 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ValueTask<string> GetElementByName(string name)
|
public ValueTask<string> GetElementByName(string name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return _jsRuntime.InvokeAsync<string>(
|
return _jsRuntime.InvokeAsync<string>(
|
||||||
"interop.getElementByName",
|
"Oqtane.Interop.getElementByName",
|
||||||
name);
|
name);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -152,8 +164,8 @@ namespace Oqtane.UI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.submitForm",
|
"Oqtane.Interop.submitForm",
|
||||||
path, fields);
|
path, fields);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -168,7 +180,7 @@ namespace Oqtane.UI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
return _jsRuntime.InvokeAsync<string[]>(
|
return _jsRuntime.InvokeAsync<string[]>(
|
||||||
"interop.getFiles",
|
"Oqtane.Interop.getFiles",
|
||||||
id);
|
id);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -181,8 +193,8 @@ namespace Oqtane.UI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeAsync<string>(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"interop.uploadFiles",
|
"Oqtane.Interop.uploadFiles",
|
||||||
posturl, folder, id);
|
posturl, folder, id);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@ -191,5 +203,36 @@ namespace Oqtane.UI
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task RefreshBrowser(bool force, int wait)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_jsRuntime.InvokeVoidAsync(
|
||||||
|
"Oqtane.Interop.refreshBrowser",
|
||||||
|
force, wait);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task RedirectBrowser(string url, int wait)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_jsRuntime.InvokeVoidAsync(
|
||||||
|
"Oqtane.Interop.redirectBrowser",
|
||||||
|
url, wait);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,13 @@
|
|||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
var layoutType = Type.GetType(PageState.Page.LayoutType);
|
var layoutType = Type.GetType(PageState.Page.LayoutType);
|
||||||
if (layoutType != null)
|
if (layoutType == null)
|
||||||
{
|
{
|
||||||
|
// fallback
|
||||||
|
layoutType = Type.GetType(Constants.DefaultLayout);
|
||||||
|
}
|
||||||
builder.OpenComponent(0, layoutType);
|
builder.OpenComponent(0, layoutType);
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// layout does not exist with type specified
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -90,7 +90,7 @@
|
|||||||
// parse querystring
|
// parse querystring
|
||||||
var querystring = ParseQueryString(uri.Query);
|
var querystring = ParseQueryString(uri.Query);
|
||||||
|
|
||||||
// the reload parameter is used during user login/logout
|
// the reload parameter is used to reload the PageState
|
||||||
if (querystring.ContainsKey("reload"))
|
if (querystring.ContainsKey("reload"))
|
||||||
{
|
{
|
||||||
reload = Reload.Site;
|
reload = Reload.Site;
|
||||||
@ -173,7 +173,7 @@
|
|||||||
|
|
||||||
if (alias.Path != "")
|
if (alias.Path != "")
|
||||||
{
|
{
|
||||||
path = path.Replace(alias.Path + "/", "");
|
path = path.Substring(alias.Path.Length + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// extract admin route elements from path
|
// extract admin route elements from path
|
||||||
@ -277,7 +277,6 @@
|
|||||||
{
|
{
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
await LogService.Log(null, null, null, GetType().AssemblyQualifiedName, Utilities.GetTypeNameLastSegment(GetType().AssemblyQualifiedName, 1), LogFunction.Security, LogLevel.Error, null, "Page Does Not Exist Or User Is Not Authorized To View Page {Path}", path);
|
|
||||||
// redirect to login page
|
// redirect to login page
|
||||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "login", "returnurl=" + path));
|
NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "login", "returnurl=" + path));
|
||||||
}
|
}
|
||||||
@ -361,22 +360,28 @@
|
|||||||
|
|
||||||
string panes = "";
|
string panes = "";
|
||||||
Type themetype = Type.GetType(page.ThemeType);
|
Type themetype = Type.GetType(page.ThemeType);
|
||||||
|
if (themetype != null)
|
||||||
|
{
|
||||||
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
||||||
if (themeobject != null)
|
if (themeobject != null)
|
||||||
{
|
{
|
||||||
panes = themeobject.Panes;
|
panes = themeobject.Panes;
|
||||||
page.Resources = ManagePageResources(page.Resources, themeobject.Resources);
|
page.Resources = ManagePageResources(page.Resources, themeobject.Resources);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(page.LayoutType))
|
if (!string.IsNullOrEmpty(page.LayoutType))
|
||||||
{
|
{
|
||||||
Type layouttype = Type.GetType(page.LayoutType);
|
Type layouttype = Type.GetType(page.LayoutType);
|
||||||
var layoutobject = Activator.CreateInstance(layouttype) as ILayoutControl;
|
if (layouttype != null)
|
||||||
|
{
|
||||||
|
var layoutobject = Activator.CreateInstance(layouttype) as IThemeControl;
|
||||||
if (layoutobject != null)
|
if (layoutobject != null)
|
||||||
{
|
{
|
||||||
panes = layoutobject.Panes;
|
panes = layoutobject.Panes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
page.Panes = panes.Replace(";", ",").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
page.Panes = panes.Replace(";", ",").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,13 @@
|
|||||||
{
|
{
|
||||||
var interop = new Interop(JsRuntime);
|
var interop = new Interop(JsRuntime);
|
||||||
|
|
||||||
|
// handle page redirection
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Page.Url))
|
||||||
|
{
|
||||||
|
NavigationManager.NavigateTo(PageState.Page.Url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// set page title
|
// set page title
|
||||||
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
||||||
{
|
{
|
||||||
@ -23,31 +30,20 @@
|
|||||||
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update page resources
|
// manage stylesheets for this page
|
||||||
int stylesheet = 0;
|
string batch = DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
||||||
int script = 0;
|
var links = new List<object>();
|
||||||
foreach (Resource resource in PageState.Page.Resources)
|
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
{
|
{
|
||||||
switch (resource.ResourceType)
|
links.Add(new { id = "app-stylesheet-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = resource.Url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", key = "" });
|
||||||
{
|
|
||||||
case ResourceType.Stylesheet:
|
|
||||||
stylesheet += 1;
|
|
||||||
await interop.IncludeLink("app-stylesheet" + stylesheet.ToString("00"), "stylesheet", resource.Url, "text/css", resource.Integrity ?? "", resource.CrossOrigin ?? "");
|
|
||||||
break;
|
|
||||||
case ResourceType.Script:
|
|
||||||
script += 1;
|
|
||||||
await interop.IncludeScript("app-script" + script.ToString("00"), resource.Url, "", "body", resource.Integrity ?? "", resource.CrossOrigin ?? "");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
await interop.IncludeLinks(links.ToArray());
|
||||||
// remove any page resources references which are no longer required for this page
|
await interop.RemoveElementsById("app-stylesheet", "", "app-stylesheet-" + batch + "-00");
|
||||||
await interop.RemoveElementsById("app-stylesheet", "app-stylesheet" + (stylesheet + 1).ToString("00"), "");
|
|
||||||
await interop.RemoveElementsById("app-script", "app-script" + (script + 1).ToString("00"), "");
|
|
||||||
|
|
||||||
// add favicon
|
// add favicon
|
||||||
if (PageState.Site.FaviconFileId != null)
|
if (PageState.Site.FaviconFileId != null)
|
||||||
{
|
{
|
||||||
await interop.IncludeLink("fav-icon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "");
|
await interop.IncludeLink("app-favicon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "", "id");
|
||||||
}
|
}
|
||||||
// add PWA support
|
// add PWA support
|
||||||
if (PageState.Site.PwaIsEnabled)
|
if (PageState.Site.PwaIsEnabled)
|
||||||
@ -58,18 +54,13 @@
|
|||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
var themeType = Type.GetType(PageState.Page.ThemeType);
|
var themeType = Type.GetType(PageState.Page.ThemeType);
|
||||||
if (themeType != null)
|
if (themeType == null)
|
||||||
{
|
{
|
||||||
|
// fallback
|
||||||
|
themeType = Type.GetType(Constants.DefaultTheme);
|
||||||
|
}
|
||||||
builder.OpenComponent(0, themeType);
|
builder.OpenComponent(0, themeType);
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// theme does not exist with type specified
|
|
||||||
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageComponent));
|
|
||||||
builder.AddAttribute(1, "Message", "Error Loading Page Theme " + PageState.Page.ThemeType);
|
|
||||||
builder.CloseComponent();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,10 +88,10 @@
|
|||||||
"const serialized = JSON.stringify(manifest); " +
|
"const serialized = JSON.stringify(manifest); " +
|
||||||
"const blob = new Blob([serialized], {type: 'application/javascript'}); " +
|
"const blob = new Blob([serialized], {type: 'application/javascript'}); " +
|
||||||
"const url = URL.createObjectURL(blob); " +
|
"const url = URL.createObjectURL(blob); " +
|
||||||
"document.getElementById('pwa-manifest').setAttribute('href', url); " +
|
"document.getElementById('app-manifest').setAttribute('href', url); " +
|
||||||
"} " +
|
"} " +
|
||||||
", 1000);";
|
", 1000);";
|
||||||
await interop.IncludeScript("pwa-manifestscript", "", manifest, "body", "", "");
|
await interop.IncludeScript("app-pwa", "", "", "", manifest, "body", "id");
|
||||||
|
|
||||||
// service worker must be in root of site
|
// service worker must be in root of site
|
||||||
string serviceworker = "if ('serviceWorker' in navigator) { " +
|
string serviceworker = "if ('serviceWorker' in navigator) { " +
|
||||||
@ -110,6 +101,6 @@
|
|||||||
"console.log('ServiceWorker Registration Failed ', err); " +
|
"console.log('ServiceWorker Registration Failed ', err); " +
|
||||||
"}); " +
|
"}); " +
|
||||||
"}";
|
"}";
|
||||||
await interop.IncludeScript("pwa-serviceworker", "", serviceworker, "body", "", "");
|
await interop.IncludeScript("app-serviceworker", "", "", "", serviceworker, "body", "id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
Oqtane.Package/Oqtane.Client.nuspec
Normal file
23
Oqtane.Package/Oqtane.Client.nuspec
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Oqtane.Client</id>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<authors>Shaun Walker</authors>
|
||||||
|
<owners>.NET Foundation</owners>
|
||||||
|
<title>Oqtane Framework</title>
|
||||||
|
<description>A modular application framework for Blazor</description>
|
||||||
|
<copyright>.NET Foundation</copyright>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<license type="expression">MIT</license>
|
||||||
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
|
<tags>oqtane</tags>
|
||||||
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||||
|
<summary>A modular application framework for Blazor</summary>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib\netstandard2.1" />
|
||||||
|
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.pdb" target="lib\netstandard2.1" />
|
||||||
|
</files>
|
||||||
|
</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.Framework</id>
|
<id>Oqtane.Framework</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</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,13 +13,16 @@
|
|||||||
<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.1</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" />
|
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib\netcoreapp3.1" />
|
||||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib" />
|
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.pdb" target="lib\netcoreapp3.1" />
|
||||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib" />
|
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib\netcoreapp3.1" />
|
||||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Upgrade.dll" target="lib" />
|
<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>
|
23
Oqtane.Package/Oqtane.Server.nuspec
Normal file
23
Oqtane.Package/Oqtane.Server.nuspec
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Oqtane.Server</id>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<authors>Shaun Walker</authors>
|
||||||
|
<owners>.NET Foundation</owners>
|
||||||
|
<title>Oqtane Framework</title>
|
||||||
|
<description>A modular application framework for Blazor</description>
|
||||||
|
<copyright>.NET Foundation</copyright>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<license type="expression">MIT</license>
|
||||||
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
|
<tags>oqtane</tags>
|
||||||
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||||
|
<summary>A modular application framework for Blazor</summary>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<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" />
|
||||||
|
</files>
|
||||||
|
</package>
|
23
Oqtane.Package/Oqtane.Shared.nuspec
Normal file
23
Oqtane.Package/Oqtane.Shared.nuspec
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
|
<metadata>
|
||||||
|
<id>Oqtane.Shared</id>
|
||||||
|
<version>1.0.1</version>
|
||||||
|
<authors>Shaun Walker</authors>
|
||||||
|
<owners>.NET Foundation</owners>
|
||||||
|
<title>Oqtane Framework</title>
|
||||||
|
<description>A modular application framework for Blazor</description>
|
||||||
|
<copyright>.NET Foundation</copyright>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<license type="expression">MIT</license>
|
||||||
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
|
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||||
|
<tags>oqtane</tags>
|
||||||
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.1</releaseNotes>
|
||||||
|
<summary>A modular application framework for Blazor</summary>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib\netstandard2.1" />
|
||||||
|
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.pdb" target="lib\netstandard2.1" />
|
||||||
|
</files>
|
||||||
|
</package>
|
@ -1,3 +0,0 @@
|
|||||||
DEL "*.nupkg"
|
|
||||||
nuget.exe pack Oqtane.Framework.nuspec
|
|
||||||
|
|
5
Oqtane.Package/release.cmd
Normal file
5
Oqtane.Package/release.cmd
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
DEL "*.nupkg"
|
||||||
|
dotnet clean -c Release ..\Oqtane.sln
|
||||||
|
dotnet build -c Release ..\Oqtane.sln
|
||||||
|
dotnet pack -o .\ -c Release ..\Oqtane.sln
|
||||||
|
nuget.exe pack Oqtane.Framework.nuspec
|
@ -47,7 +47,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/name/xxx?sync=yyyyMMddHHmmssfff
|
// GET api/<controller>/name/xxx?sync=yyyyMMddHHmmssfff
|
||||||
[HttpGet("name/{name}")]
|
[HttpGet("name/{**name}")]
|
||||||
public Alias Get(string name, string sync)
|
public Alias Get(string name, string sync)
|
||||||
{
|
{
|
||||||
List<Alias> aliases = _aliases.GetAliases().ToList(); // cached
|
List<Alias> aliases = _aliases.GetAliases().ToList(); // cached
|
||||||
|
@ -9,6 +9,9 @@ using System.IO;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
|
using Oqtane.Modules;
|
||||||
|
using Oqtane.Themes;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -70,8 +73,27 @@ namespace Oqtane.Controllers
|
|||||||
// get list of assemblies which should be downloaded to browser
|
// get list of assemblies which should be downloaded to browser
|
||||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
||||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
||||||
var deps = assemblies.SelectMany(a => a.GetReferencedAssemblies()).Distinct();
|
|
||||||
list.AddRange(deps.Where(a => a.Name.EndsWith(".oqtane", StringComparison.OrdinalIgnoreCase)).Select(a => a.Name));
|
// get module and theme dependencies
|
||||||
|
foreach (var assembly in assemblies)
|
||||||
|
{
|
||||||
|
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModule))))
|
||||||
|
{
|
||||||
|
var instance = Activator.CreateInstance(type) as IModule;
|
||||||
|
foreach (string name in instance.ModuleDefinition.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
if (!list.Contains(name)) list.Add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var type in assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(ITheme))))
|
||||||
|
{
|
||||||
|
var instance = Activator.CreateInstance(type) as ITheme;
|
||||||
|
foreach (string name in instance.Theme.Dependencies.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
if (!list.Contains(name)) list.Add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create zip file containing assemblies and debug symbols
|
// create zip file containing assemblies and debug symbols
|
||||||
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
@ -90,6 +112,7 @@ namespace Oqtane.Controllers
|
|||||||
filestream.CopyTo(entrystream);
|
filestream.CopyTo(entrystream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// include debug symbols ( we may want to consider restricting this to only host users or when running in debug mode for performance )
|
||||||
if (System.IO.File.Exists(Path.Combine(binfolder, file + ".pdb")))
|
if (System.IO.File.Exists(Path.Combine(binfolder, file + ".pdb")))
|
||||||
{
|
{
|
||||||
entry = archive.CreateEntry(file + ".pdb");
|
entry = archive.CreateEntry(file + ".pdb");
|
||||||
|
@ -170,7 +170,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
string rootPath;
|
string rootPath;
|
||||||
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
|
DirectoryInfo rootFolder = Directory.GetParent(_environment.ContentRootPath);
|
||||||
string templatePath = Utilities.PathCombine(rootFolder.FullName, "Oqtane.Client", "Modules", "Admin", "ModuleCreator", "Templates",moduleDefinition.Template,"\\");
|
string templatePath = Utilities.PathCombine(_environment.WebRootPath, "Modules", "Templates", moduleDefinition.Template,"\\");
|
||||||
|
|
||||||
if (moduleDefinition.Template == "internal")
|
if (moduleDefinition.Template == "internal")
|
||||||
{
|
{
|
||||||
|
@ -169,8 +169,8 @@ namespace Oqtane.Controllers
|
|||||||
page.DefaultContainerType = parent.DefaultContainerType;
|
page.DefaultContainerType = parent.DefaultContainerType;
|
||||||
page.Icon = parent.Icon;
|
page.Icon = parent.Icon;
|
||||||
page.Permissions = new List<Permission> {
|
page.Permissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, userid, true),
|
new Permission(PermissionNames.View, int.Parse(userid), true),
|
||||||
new Permission(PermissionNames.Edit, userid, true)
|
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
||||||
}.EncodePermissions();
|
}.EncodePermissions();
|
||||||
page.IsPersonalizable = false;
|
page.IsPersonalizable = false;
|
||||||
page.UserId = int.Parse(userid);
|
page.UserId = int.Parse(userid);
|
||||||
@ -187,8 +187,8 @@ namespace Oqtane.Controllers
|
|||||||
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
|
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
|
||||||
module.AllPages = false;
|
module.AllPages = false;
|
||||||
module.Permissions = new List<Permission> {
|
module.Permissions = new List<Permission> {
|
||||||
new Permission(PermissionNames.View, userid, true),
|
new Permission(PermissionNames.View, int.Parse(userid), true),
|
||||||
new Permission(PermissionNames.Edit, userid, true)
|
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
||||||
}.EncodePermissions();
|
}.EncodePermissions();
|
||||||
module = _modules.AddModule(module);
|
module = _modules.AddModule(module);
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace Oqtane.Controllers
|
|||||||
user.SiteId = int.Parse(siteid);
|
user.SiteId = int.Parse(siteid);
|
||||||
user.Roles = GetUserRoles(user.UserId, user.SiteId);
|
user.Roles = GetUserRoles(user.UserId, user.SiteId);
|
||||||
}
|
}
|
||||||
return user;
|
return Filter(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/name/x?siteid=x
|
// GET api/<controller>/name/x?siteid=x
|
||||||
@ -70,6 +70,29 @@ namespace Oqtane.Controllers
|
|||||||
user.SiteId = int.Parse(siteid);
|
user.SiteId = int.Parse(siteid);
|
||||||
user.Roles = GetUserRoles(user.UserId, user.SiteId);
|
user.Roles = GetUserRoles(user.UserId, user.SiteId);
|
||||||
}
|
}
|
||||||
|
return Filter(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private User Filter(User user)
|
||||||
|
{
|
||||||
|
if (user != null && !User.IsInRole(Constants.AdminRole) && User.Identity.Name?.ToLower() != user.Username.ToLower())
|
||||||
|
{
|
||||||
|
user.DisplayName = "";
|
||||||
|
user.Email = "";
|
||||||
|
user.PhotoFileId = null;
|
||||||
|
user.LastLoginOn = DateTime.MinValue;
|
||||||
|
user.LastIPAddress = "";
|
||||||
|
user.Roles = "";
|
||||||
|
user.CreatedBy = "";
|
||||||
|
user.CreatedOn = DateTime.MinValue;
|
||||||
|
user.ModifiedBy = "";
|
||||||
|
user.ModifiedOn = DateTime.MinValue;
|
||||||
|
user.DeletedBy = "";
|
||||||
|
user.DeletedOn = DateTime.MinValue;
|
||||||
|
user.IsDeleted = false;
|
||||||
|
user.Password = "";
|
||||||
|
user.IsAuthenticated = false;
|
||||||
|
}
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +148,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);
|
||||||
@ -134,6 +157,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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +386,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);
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@ namespace Oqtane.Controllers
|
|||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/<controller>?userid=x
|
// GET: api/<controller>?siteid=x
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Authorize]
|
[Authorize(Roles = Constants.AdminRole)]
|
||||||
public IEnumerable<UserRole> Get(string siteid)
|
public IEnumerable<UserRole> Get(string siteid)
|
||||||
{
|
{
|
||||||
return _userRoles.GetUserRoles(int.Parse(siteid));
|
return _userRoles.GetUserRoles(int.Parse(siteid));
|
||||||
@ -35,7 +35,7 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
// GET api/<controller>/5
|
// GET api/<controller>/5
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
[Authorize]
|
[Authorize(Roles = Constants.AdminRole)]
|
||||||
public UserRole Get(int id)
|
public UserRole Get(int id)
|
||||||
{
|
{
|
||||||
return _userRoles.GetUserRole(id);
|
return _userRoles.GetUserRole(id);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +194,8 @@ namespace Oqtane.Infrastructure
|
|||||||
|
|
||||||
if (install.TenantName == Constants.MasterTenant)
|
if (install.TenantName == Constants.MasterTenant)
|
||||||
{
|
{
|
||||||
|
MigrateScriptNamingConvention("Master", install.ConnectionString);
|
||||||
|
|
||||||
var upgradeConfig = DeployChanges
|
var upgradeConfig = DeployChanges
|
||||||
.To
|
.To
|
||||||
.SqlDatabase(NormalizeConnectionString(install.ConnectionString))
|
.SqlDatabase(NormalizeConnectionString(install.ConnectionString))
|
||||||
@ -285,6 +287,8 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
foreach (var tenant in db.Tenant.ToList())
|
foreach (var tenant in db.Tenant.ToList())
|
||||||
{
|
{
|
||||||
|
MigrateScriptNamingConvention("Tenant", tenant.DBConnectionString);
|
||||||
|
|
||||||
var upgradeConfig = DeployChanges.To.SqlDatabase(NormalizeConnectionString(tenant.DBConnectionString))
|
var upgradeConfig = DeployChanges.To.SqlDatabase(NormalizeConnectionString(tenant.DBConnectionString))
|
||||||
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains("Tenant.") && s.EndsWith(".sql", StringComparison.OrdinalIgnoreCase));
|
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s.Contains("Tenant.") && s.EndsWith(".sql", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
@ -569,5 +573,17 @@ namespace Oqtane.Infrastructure
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MigrateScriptNamingConvention(string scriptType, string connectionString)
|
||||||
|
{
|
||||||
|
// migrate to new naming convention for scripts
|
||||||
|
var migrateConfig = DeployChanges.To.SqlDatabase(NormalizeConnectionString(connectionString))
|
||||||
|
.WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly(), s => s == scriptType + ".00.00.00.00.sql");
|
||||||
|
var migrate = migrateConfig.Build();
|
||||||
|
if (migrate.IsUpgradeRequired())
|
||||||
|
{
|
||||||
|
migrate.PerformUpgrade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,10 +52,6 @@ namespace Oqtane.Infrastructure
|
|||||||
// iterate through Nuget packages in source folder
|
// iterate through Nuget packages in source folder
|
||||||
foreach (string packagename in Directory.GetFiles(sourceFolder, "*.nupkg"))
|
foreach (string packagename in Directory.GetFiles(sourceFolder, "*.nupkg"))
|
||||||
{
|
{
|
||||||
string name = Path.GetFileNameWithoutExtension(packagename);
|
|
||||||
string[] segments = name?.Split('.');
|
|
||||||
if (segments != null) name = string.Join('.', segments, 0, segments.Length - 3);
|
|
||||||
|
|
||||||
// iterate through files
|
// iterate through files
|
||||||
using (ZipArchive archive = ZipFile.OpenRead(packagename))
|
using (ZipArchive archive = ZipFile.OpenRead(packagename))
|
||||||
{
|
{
|
||||||
@ -84,6 +80,11 @@ namespace Oqtane.Infrastructure
|
|||||||
// if compatible with framework version
|
// if compatible with framework version
|
||||||
if (frameworkversion == "" || Version.Parse(Constants.Version).CompareTo(Version.Parse(frameworkversion)) >= 0)
|
if (frameworkversion == "" || Version.Parse(Constants.Version).CompareTo(Version.Parse(frameworkversion)) >= 0)
|
||||||
{
|
{
|
||||||
|
// module and theme packages must be in form of name.1.0.0.nupkg
|
||||||
|
string name = Path.GetFileNameWithoutExtension(packagename);
|
||||||
|
string[] segments = name?.Split('.');
|
||||||
|
if (segments != null) name = string.Join('.', segments, 0, segments.Length - 3);
|
||||||
|
|
||||||
// deploy to appropriate locations
|
// deploy to appropriate locations
|
||||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||||
{
|
{
|
||||||
@ -97,16 +98,9 @@ namespace Oqtane.Infrastructure
|
|||||||
ExtractFile(entry, filename);
|
ExtractFile(entry, filename);
|
||||||
break;
|
break;
|
||||||
case "wwwroot":
|
case "wwwroot":
|
||||||
filename = Path.Combine(sourceFolder, Utilities.PathCombine(entry.FullName.Replace("wwwroot", name).Split('/')));
|
filename = Path.Combine(webRootPath, Utilities.PathCombine(entry.FullName.Replace("wwwroot/", "").Split('/')));
|
||||||
ExtractFile(entry, filename);
|
ExtractFile(entry, filename);
|
||||||
break;
|
break;
|
||||||
case "content":
|
|
||||||
if (Path.GetDirectoryName(entry.FullName) != "content") // assets must be in subfolders
|
|
||||||
{
|
|
||||||
filename = Path.Combine(webRootPath, Utilities.PathCombine(entry.FullName.Replace("content", "").Split('/')));
|
|
||||||
ExtractFile(entry, filename);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,10 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
MailMessage mailMessage = new MailMessage();
|
MailMessage mailMessage = new MailMessage();
|
||||||
mailMessage.From = new MailAddress(settings["SMTPUsername"], site.Name);
|
mailMessage.From = new MailAddress(settings["SMTPUsername"], site.Name);
|
||||||
|
mailMessage.Subject = notification.Subject;
|
||||||
if (notification.FromUserId != null)
|
if (notification.FromUserId != null)
|
||||||
{
|
{
|
||||||
mailMessage.Body = "From: " + notification.FromUser.DisplayName + "<" + notification.FromUser.Email + ">" + "\n";
|
mailMessage.Body = "From: " + notification.FromDisplayName + "<" + notification.FromEmail + ">" + "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -78,8 +78,8 @@ namespace Oqtane.Infrastructure
|
|||||||
mailMessage.Body += "Sent: " + notification.CreatedOn + "\n";
|
mailMessage.Body += "Sent: " + notification.CreatedOn + "\n";
|
||||||
if (notification.ToUserId != null)
|
if (notification.ToUserId != null)
|
||||||
{
|
{
|
||||||
mailMessage.To.Add(new MailAddress(notification.ToUser.Email, notification.ToUser.DisplayName));
|
mailMessage.To.Add(new MailAddress(notification.ToEmail, notification.ToDisplayName));
|
||||||
mailMessage.Body += "To: " + notification.ToUser.DisplayName + "<" + notification.ToUser.Email + ">" + "\n";
|
mailMessage.Body += "To: " + notification.ToDisplayName + "<" + notification.ToEmail + ">" + "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -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.1</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -13,14 +13,25 @@
|
|||||||
<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.1</PackageReleaseNotes>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Scripts\Master.0.9.0.sql" />
|
<Compile Remove="wwwroot\Modules\Templates\**" />
|
||||||
<EmbeddedResource Include="Scripts\Tenant.0.9.0.sql" />
|
<Content Remove="wwwroot\Modules\Templates\**" />
|
||||||
<EmbeddedResource Include="Scripts\Tenant.0.9.1.sql" />
|
<EmbeddedResource Remove="wwwroot\Modules\Templates\**" />
|
||||||
<EmbeddedResource Include="Scripts\Tenant.0.9.2.sql" />
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="Scripts\Master.00.00.00.00.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Master.00.09.00.00.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Master.01.00.01.00.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Tenant.00.00.00.00.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Tenant.00.09.00.00.sql" />
|
||||||
|
<EmbeddedResource Include="Scripts\Tenant.00.09.01.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.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>
|
||||||
@ -28,7 +39,7 @@
|
|||||||
<PackageReference Include="dbup" Version="4.3.0" />
|
<PackageReference Include="dbup" Version="4.3.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.4" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.4" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.4.1" />
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>Oqtane</title>
|
<title>Oqtane</title>
|
||||||
<base href="~/" />
|
<base href="~/" />
|
||||||
<link id="fav-icon" rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
<link id="app-favicon" rel="shortcut icon" type="image/x-icon" href="favicon.ico" />
|
||||||
<!-- stub the PWA manifest but defer the assignment of href -->
|
<!-- stub the PWA manifest but defer the assignment of href -->
|
||||||
<link id="pwa-manifest" rel="manifest" />
|
<link id="app-manifest" rel="manifest" />
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
<link rel="stylesheet" href="css/app.css" />
|
||||||
<link href="css/app.css" rel="stylesheet" />
|
<script src="js/loadjs.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@(Html.AntiForgeryToken())
|
@(Html.AntiForgeryToken())
|
||||||
@ -23,10 +23,18 @@
|
|||||||
<component type="typeof(Oqtane.App)" render-mode="Server" />
|
<component type="typeof(Oqtane.App)" render-mode="Server" />
|
||||||
</app>
|
</app>
|
||||||
|
|
||||||
|
<div id="blazor-error-ui">
|
||||||
|
<environment include="Staging,Production">
|
||||||
|
An error has occurred. This application may no longer respond until reloaded.
|
||||||
|
</environment>
|
||||||
|
<environment include="Development">
|
||||||
|
An unhandled exception has occurred. See browser dev tools for details.
|
||||||
|
</environment>
|
||||||
|
<a href="~/" class="reload">Reload</a>
|
||||||
|
<a class="dismiss">🗙</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="js/interop.js"></script>
|
<script src="js/interop.js"></script>
|
||||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
@if (Configuration.GetSection("Runtime").Value == "WebAssembly")
|
@if (Configuration.GetSection("Runtime").Value == "WebAssembly")
|
||||||
{
|
{
|
||||||
|
@ -188,18 +188,15 @@ namespace Oqtane.Repository
|
|||||||
private List<ModuleDefinition> LoadModuleDefinitionsFromAssembly(List<ModuleDefinition> moduledefinitions, Assembly assembly)
|
private List<ModuleDefinition> LoadModuleDefinitionsFromAssembly(List<ModuleDefinition> moduledefinitions, Assembly assembly)
|
||||||
{
|
{
|
||||||
ModuleDefinition moduledefinition;
|
ModuleDefinition moduledefinition;
|
||||||
|
|
||||||
Type[] modulecontroltypes = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModuleControl))).ToArray();
|
Type[] modulecontroltypes = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IModuleControl))).ToArray();
|
||||||
foreach (Type modulecontroltype in modulecontroltypes)
|
foreach (Type modulecontroltype in modulecontroltypes)
|
||||||
{
|
{
|
||||||
// Check if type should be ignored
|
// Check if type should be ignored
|
||||||
if (modulecontroltype.Name == "ModuleBase"
|
if (modulecontroltype.IsOqtaneIgnore()) continue;
|
||||||
|| modulecontroltype.IsGenericType
|
|
||||||
|| modulecontroltype.IsAbstract
|
|
||||||
|| Attribute.IsDefined(modulecontroltype, typeof(OqtaneIgnoreAttribute))
|
|
||||||
) continue;
|
|
||||||
|
|
||||||
string moduleNamespace = modulecontroltype.Namespace;
|
// create namespace root typename
|
||||||
string qualifiedModuleType = moduleNamespace + ", " + modulecontroltype.Assembly.GetName().Name;
|
string qualifiedModuleType = modulecontroltype.Namespace + ", " + modulecontroltype.Assembly.GetName().Name;
|
||||||
|
|
||||||
int index = moduledefinitions.FindIndex(item => item.ModuleDefinitionName == qualifiedModuleType);
|
int index = moduledefinitions.FindIndex(item => item.ModuleDefinitionName == qualifiedModuleType);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
@ -208,7 +205,7 @@ namespace Oqtane.Repository
|
|||||||
Type moduletype = assembly
|
Type moduletype = assembly
|
||||||
.GetTypes()
|
.GetTypes()
|
||||||
.Where(item => item.Namespace != null)
|
.Where(item => item.Namespace != null)
|
||||||
.Where(item => item.Namespace.StartsWith(moduleNamespace))
|
.Where(item => item.Namespace == modulecontroltype.Namespace || item.Namespace.StartsWith(modulecontroltype.Namespace + "."))
|
||||||
.FirstOrDefault(item => item.GetInterfaces().Contains(typeof(IModule)));
|
.FirstOrDefault(item => item.GetInterfaces().Contains(typeof(IModule)));
|
||||||
if (moduletype != null)
|
if (moduletype != null)
|
||||||
{
|
{
|
||||||
@ -221,8 +218,8 @@ namespace Oqtane.Repository
|
|||||||
// set default property values
|
// set default property values
|
||||||
moduledefinition = new ModuleDefinition
|
moduledefinition = new ModuleDefinition
|
||||||
{
|
{
|
||||||
Name = moduleNamespace.Substring(moduleNamespace.LastIndexOf(".") + 1),
|
Name = Utilities.GetTypeNameLastSegment(modulecontroltype.Namespace, 0),
|
||||||
Description = "Manage " + moduleNamespace.Substring(moduleNamespace.LastIndexOf(".") + 1),
|
Description = "Manage " + Utilities.GetTypeNameLastSegment(modulecontroltype.Namespace, 0),
|
||||||
Categories = ((qualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "Admin" : "")
|
Categories = ((qualifiedModuleType.StartsWith("Oqtane.Modules.Admin.")) ? "Admin" : "")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -230,7 +227,7 @@ namespace Oqtane.Repository
|
|||||||
// set internal properties
|
// set internal properties
|
||||||
moduledefinition.ModuleDefinitionName = qualifiedModuleType;
|
moduledefinition.ModuleDefinitionName = qualifiedModuleType;
|
||||||
moduledefinition.Version = ""; // will be populated from database
|
moduledefinition.Version = ""; // will be populated from database
|
||||||
moduledefinition.ControlTypeTemplate = moduleNamespace + "." + Constants.ActionToken + ", " + modulecontroltype.Assembly.GetName().Name;
|
moduledefinition.ControlTypeTemplate = modulecontroltype.Namespace + "." + Constants.ActionToken + ", " + modulecontroltype.Assembly.GetName().Name;
|
||||||
moduledefinition.AssemblyName = assembly.GetName().Name;
|
moduledefinition.AssemblyName = assembly.GetName().Name;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(moduledefinition.Categories))
|
if (string.IsNullOrEmpty(moduledefinition.Categories))
|
||||||
|
@ -21,8 +21,7 @@ namespace Oqtane.Repository
|
|||||||
return _db.Notification
|
return _db.Notification
|
||||||
.Where(item => item.SiteId == siteId)
|
.Where(item => item.SiteId == siteId)
|
||||||
.Where(item => item.IsDelivered == false)
|
.Where(item => item.IsDelivered == false)
|
||||||
.Include(item => item.FromUser)
|
.Where(item => item.SendOn < System.DateTime.UtcNow)
|
||||||
.Include(item => item.ToUser)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +29,6 @@ namespace Oqtane.Repository
|
|||||||
.Where(item => item.SiteId == siteId)
|
.Where(item => item.SiteId == siteId)
|
||||||
.Where(item => item.ToUserId == toUserId || toUserId == -1)
|
.Where(item => item.ToUserId == toUserId || toUserId == -1)
|
||||||
.Where(item => item.FromUserId == fromUserId || fromUserId == -1)
|
.Where(item => item.FromUserId == fromUserId || fromUserId == -1)
|
||||||
.Include(item => item.FromUser)
|
|
||||||
.Include(item => item.ToUser)
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ namespace Oqtane.Repository
|
|||||||
return _db.Role.Where(item => item.SiteId == siteId || item.SiteId == null);
|
return _db.Role.Where(item => item.SiteId == siteId || item.SiteId == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Role AddRole(Role role)
|
public Role AddRole(Role role)
|
||||||
{
|
{
|
||||||
|
role.Description = role.Description.Substring(0, (role.Description.Length > 256) ? 256 : role.Description.Length);
|
||||||
_db.Role.Add(role);
|
_db.Role.Add(role);
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
return role;
|
return role;
|
||||||
@ -34,6 +34,7 @@ namespace Oqtane.Repository
|
|||||||
|
|
||||||
public Role UpdateRole(Role role)
|
public Role UpdateRole(Role role)
|
||||||
{
|
{
|
||||||
|
role.Description = role.Description.Substring(0, (role.Description.Length > 256) ? 256 : role.Description.Length);
|
||||||
_db.Entry(role).State = EntityState.Modified;
|
_db.Entry(role).State = EntityState.Modified;
|
||||||
_db.SaveChanges();
|
_db.SaveChanges();
|
||||||
return role;
|
return role;
|
||||||
|
@ -44,26 +44,32 @@ namespace Oqtane.Repository
|
|||||||
private List<Theme> LoadThemesFromAssembly(List<Theme> themes, Assembly assembly)
|
private List<Theme> LoadThemesFromAssembly(List<Theme> themes, Assembly assembly)
|
||||||
{
|
{
|
||||||
Theme theme;
|
Theme theme;
|
||||||
|
List<Type> themeTypes = new List<Type>();
|
||||||
|
|
||||||
Type[] themeControlTypes = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IThemeControl))).ToArray();
|
Type[] themeControlTypes = assembly.GetTypes().Where(item => item.GetInterfaces().Contains(typeof(IThemeControl))).ToArray();
|
||||||
foreach (Type themeControlType in themeControlTypes)
|
foreach (Type themeControlType in themeControlTypes)
|
||||||
{
|
{
|
||||||
// Check if type should be ignored
|
// Check if type should be ignored
|
||||||
if (themeControlType.Name == "ThemeBase"
|
if (themeControlType.IsOqtaneIgnore() ||
|
||||||
|| themeControlType.IsGenericType
|
themeControlType.GetInterfaces().Contains(typeof(ILayoutControl)) ||
|
||||||
|| Attribute.IsDefined(themeControlType, typeof(OqtaneIgnoreAttribute))
|
themeControlType.GetInterfaces().Contains(typeof(IContainerControl))) continue;
|
||||||
) continue;
|
|
||||||
|
|
||||||
string themeNamespace = themeControlType.Namespace;
|
// create namespace root typename
|
||||||
string qualifiedModuleType = themeNamespace + ", " + themeControlType.Assembly.GetName().Name;
|
string qualifiedThemeType = themeControlType.Namespace + ", " + themeControlType.Assembly.GetName().Name;
|
||||||
|
|
||||||
int index = themes.FindIndex(item => item.ThemeName == themeNamespace);
|
int index = themes.FindIndex(item => item.ThemeName == qualifiedThemeType);
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
{
|
{
|
||||||
// determine if this theme implements ITheme
|
// Find all types in the assembly with the same namespace root
|
||||||
Type themetype = assembly.GetTypes()
|
themeTypes = assembly.GetTypes()
|
||||||
|
.Where(item => !item.IsOqtaneIgnore())
|
||||||
.Where(item => item.Namespace != null)
|
.Where(item => item.Namespace != null)
|
||||||
.Where(item => item.Namespace.StartsWith(themeNamespace))
|
.Where(item => item.Namespace == themeControlType.Namespace || item.Namespace.StartsWith(themeControlType.Namespace + "."))
|
||||||
.Where(item => item.GetInterfaces().Contains(typeof(ITheme))).FirstOrDefault();
|
.ToList();
|
||||||
|
|
||||||
|
// determine if this theme implements ITheme
|
||||||
|
Type themetype = themeTypes
|
||||||
|
.FirstOrDefault(item => item.GetInterfaces().Contains(typeof(ITheme)));
|
||||||
if (themetype != null)
|
if (themetype != null)
|
||||||
{
|
{
|
||||||
var themeobject = Activator.CreateInstance(themetype) as ITheme;
|
var themeobject = Activator.CreateInstance(themetype) as ITheme;
|
||||||
@ -78,43 +84,59 @@ namespace Oqtane.Repository
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// set internal properties
|
// set internal properties
|
||||||
theme.ThemeName = themeNamespace;
|
theme.ThemeName = qualifiedThemeType;
|
||||||
theme.ThemeControls = "";
|
theme.Themes = new List<ThemeControl>();
|
||||||
theme.PaneLayouts = "";
|
theme.Layouts = new List<ThemeControl>();
|
||||||
theme.ContainerControls = "";
|
theme.Containers = new List<ThemeControl>();
|
||||||
theme.AssemblyName = assembly.FullName.Split(",")[0];
|
theme.AssemblyName = assembly.FullName.Split(",")[0];
|
||||||
themes.Add(theme);
|
themes.Add(theme);
|
||||||
index = themes.FindIndex(item => item.ThemeName == themeNamespace);
|
index = themes.FindIndex(item => item.ThemeName == qualifiedThemeType);
|
||||||
}
|
}
|
||||||
theme = themes[index];
|
theme = themes[index];
|
||||||
theme.ThemeControls += (themeControlType.FullName + ", " + themeControlType.Assembly.GetName().Name + ";");
|
|
||||||
|
var themecontrolobject = Activator.CreateInstance(themeControlType) as IThemeControl;
|
||||||
|
theme.Themes.Add(
|
||||||
|
new ThemeControl
|
||||||
|
{
|
||||||
|
TypeName = themeControlType.FullName + ", " + themeControlType.Assembly.GetName().Name,
|
||||||
|
Name = theme.Name + " - " + ((string.IsNullOrEmpty(themecontrolobject.Name)) ? Utilities.GetTypeNameLastSegment(themeControlType.FullName, 0) : themecontrolobject.Name),
|
||||||
|
Thumbnail = themecontrolobject.Thumbnail,
|
||||||
|
Panes = themecontrolobject.Panes
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// layouts
|
// layouts
|
||||||
Type[] layouttypes = assembly.GetTypes()
|
Type[] layouttypes = themeTypes
|
||||||
.Where(item => item.Namespace != null)
|
|
||||||
.Where(item => item.Namespace.StartsWith(themeNamespace))
|
|
||||||
.Where(item => item.GetInterfaces().Contains(typeof(ILayoutControl))).ToArray();
|
.Where(item => item.GetInterfaces().Contains(typeof(ILayoutControl))).ToArray();
|
||||||
foreach (Type layouttype in layouttypes)
|
foreach (Type layouttype in layouttypes)
|
||||||
{
|
{
|
||||||
string panelayout = layouttype.FullName + ", " + themeControlType.Assembly.GetName().Name + ";";
|
var layoutobject = Activator.CreateInstance(layouttype) as IThemeControl;
|
||||||
if (!theme.PaneLayouts.Contains(panelayout))
|
theme.Layouts.Add(
|
||||||
|
new ThemeControl
|
||||||
{
|
{
|
||||||
theme.PaneLayouts += panelayout;
|
TypeName = layouttype.FullName + ", " + themeControlType.Assembly.GetName().Name,
|
||||||
|
Name = (string.IsNullOrEmpty(layoutobject.Name)) ? Utilities.GetTypeNameLastSegment(layouttype.FullName, 0) : layoutobject.Name,
|
||||||
|
Thumbnail = layoutobject.Thumbnail,
|
||||||
|
Panes = layoutobject.Panes
|
||||||
}
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// containers
|
// containers
|
||||||
Type[] containertypes = assembly.GetTypes()
|
Type[] containertypes = themeTypes
|
||||||
.Where(item => item.Namespace != null)
|
|
||||||
.Where(item => item.Namespace.StartsWith(themeNamespace))
|
|
||||||
.Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray();
|
.Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray();
|
||||||
foreach (Type containertype in containertypes)
|
foreach (Type containertype in containertypes)
|
||||||
{
|
{
|
||||||
string container = containertype.FullName + ", " + themeControlType.Assembly.GetName().Name + ";";
|
var containerobject = Activator.CreateInstance(containertype) as IThemeControl;
|
||||||
if (!theme.ContainerControls.Contains(container))
|
theme.Containers.Add(
|
||||||
|
new ThemeControl
|
||||||
{
|
{
|
||||||
theme.ContainerControls += container;
|
TypeName = containertype.FullName + ", " + themeControlType.Assembly.GetName().Name,
|
||||||
|
Name = (string.IsNullOrEmpty(containerobject.Name)) ? Utilities.GetTypeNameLastSegment(containertype.FullName, 0) : containerobject.Name,
|
||||||
|
Thumbnail = containerobject.Thumbnail,
|
||||||
|
Panes = ""
|
||||||
}
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
themes[index] = theme;
|
themes[index] = theme;
|
||||||
|
10
Oqtane.Server/Scripts/Master.00.00.00.00.sql
Normal file
10
Oqtane.Server/Scripts/Master.00.00.00.00.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
migrate to new naming convention for scripts
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
UPDATE [dbo].[SchemaVersions] SET ScriptName = 'Oqtane.Scripts.Master.00.09.00.00.sql' WHERE ScriptName = 'Oqtane.Scripts.Master.0.9.0.sql'
|
||||||
|
GO
|
||||||
|
UPDATE [dbo].[SchemaVersions] SET ScriptName = 'Oqtane.Scripts.Master.01.00.01.00.sql' WHERE ScriptName = 'Oqtane.Scripts.Master.1.0.1.sql'
|
||||||
|
GO
|
29
Oqtane.Server/Scripts/Master.01.00.01.00.sql
Normal file
29
Oqtane.Server/Scripts/Master.01.00.01.00.sql
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Version 1.0.1 Master migration script
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_Tenant ON [dbo].[Tenant]
|
||||||
|
(
|
||||||
|
[Name]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_Alias ON [dbo].[Alias]
|
||||||
|
(
|
||||||
|
[Name]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_ModuleDefinition ON [dbo].[ModuleDefinition]
|
||||||
|
(
|
||||||
|
[ModuleDefinitionName]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_Job ON [dbo].[Job]
|
||||||
|
(
|
||||||
|
[JobType]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
14
Oqtane.Server/Scripts/Tenant.00.00.00.00.sql
Normal file
14
Oqtane.Server/Scripts/Tenant.00.00.00.00.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
migrate to new naming convention for scripts
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
UPDATE [dbo].[SchemaVersions] SET ScriptName = 'Oqtane.Scripts.Tenant.00.09.00.00.sql' WHERE ScriptName = 'Oqtane.Scripts.Tenant.0.9.0.sql'
|
||||||
|
GO
|
||||||
|
UPDATE [dbo].[SchemaVersions] SET ScriptName = 'Oqtane.Scripts.Tenant.00.09.01.00.sql' WHERE ScriptName = 'Oqtane.Scripts.Tenant.0.9.1.sql'
|
||||||
|
GO
|
||||||
|
UPDATE [dbo].[SchemaVersions] SET ScriptName = 'Oqtane.Scripts.Tenant.00.09.02.00.sql' WHERE ScriptName = 'Oqtane.Scripts.Tenant.0.9.2.sql'
|
||||||
|
GO
|
||||||
|
UPDATE [dbo].[SchemaVersions] SET ScriptName = 'Oqtane.Scripts.Tenant.01.00.01.00.sql' WHERE ScriptName = 'Oqtane.Scripts.Tenant.1.0.1.sql'
|
||||||
|
GO
|
39
Oqtane.Server/Scripts/Tenant.01.00.01.00.sql
Normal file
39
Oqtane.Server/Scripts/Tenant.01.00.01.00.sql
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Version 1.0.1 Tenant migration script
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_Site ON [dbo].[Site]
|
||||||
|
(
|
||||||
|
[TenantId],
|
||||||
|
[Name]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_Role ON [dbo].[Role]
|
||||||
|
(
|
||||||
|
[SiteId],
|
||||||
|
[Name]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_Profile ON [dbo].[Profile]
|
||||||
|
(
|
||||||
|
[SiteId],
|
||||||
|
[Name]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
CREATE UNIQUE NONCLUSTERED INDEX IX_File ON [dbo].[File]
|
||||||
|
(
|
||||||
|
[FolderId],
|
||||||
|
[Name]
|
||||||
|
) ON [PRIMARY]
|
||||||
|
GO
|
||||||
|
|
||||||
|
ALTER TABLE [dbo].[Notification] ADD
|
||||||
|
[FromDisplayName] [nvarchar](50) NULL,
|
||||||
|
[FromEmail] [nvarchar](256) NULL,
|
||||||
|
[ToDisplayName] [nvarchar](50) NULL
|
||||||
|
GO
|
12
Oqtane.Server/Scripts/Tenant.01.00.01.01.sql
Normal file
12
Oqtane.Server/Scripts/Tenant.01.00.01.01.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Version 1.0.1 Notification migration script
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
ALTER TABLE [dbo].[Notification] ADD
|
||||||
|
[SendOn] [datetime] NULL
|
||||||
|
GO
|
||||||
|
|
||||||
|
UPDATE [dbo].[Notification] SET SendOn = CreatedOn WHERE SendOn IS NULL
|
||||||
|
GO
|
@ -29,6 +29,7 @@ namespace Oqtane
|
|||||||
public IConfigurationRoot Configuration { get; }
|
public IConfigurationRoot Configuration { get; }
|
||||||
private string _webRoot;
|
private string _webRoot;
|
||||||
private Runtime _runtime;
|
private Runtime _runtime;
|
||||||
|
private bool _useSwagger;
|
||||||
|
|
||||||
public Startup(IWebHostEnvironment env)
|
public Startup(IWebHostEnvironment env)
|
||||||
{
|
{
|
||||||
@ -39,6 +40,9 @@ namespace Oqtane
|
|||||||
|
|
||||||
_runtime = (Configuration.GetSection("Runtime").Value == "WebAssembly") ? Runtime.WebAssembly : Runtime.Server;
|
_runtime = (Configuration.GetSection("Runtime").Value == "WebAssembly") ? Runtime.WebAssembly : Runtime.Server;
|
||||||
|
|
||||||
|
//add possibility to switch off swagger on production.
|
||||||
|
_useSwagger = Configuration.GetSection("UseSwagger").Value != "false";
|
||||||
|
|
||||||
_webRoot = env.WebRootPath;
|
_webRoot = env.WebRootPath;
|
||||||
AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(env.ContentRootPath, "Data"));
|
AppDomain.CurrentDomain.SetData("DataDirectory", Path.Combine(env.ContentRootPath, "Data"));
|
||||||
}
|
}
|
||||||
@ -47,7 +51,6 @@ namespace Oqtane
|
|||||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
|
||||||
services.AddServerSideBlazor();
|
services.AddServerSideBlazor();
|
||||||
|
|
||||||
// setup HttpClient for server side in a client side compatible fashion ( with auth cookie )
|
// setup HttpClient for server side in a client side compatible fashion ( with auth cookie )
|
||||||
@ -201,12 +204,10 @@ namespace Oqtane
|
|||||||
.AddOqtaneApplicationParts() // register any Controllers from custom modules
|
.AddOqtaneApplicationParts() // register any Controllers from custom modules
|
||||||
.ConfigureOqtaneMvc(); // any additional configuration from IStart classes.
|
.ConfigureOqtaneMvc(); // any additional configuration from IStart classes.
|
||||||
|
|
||||||
services.AddSwaggerGen(c =>
|
if (_useSwagger)
|
||||||
{
|
{
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Oqtane", Version = "v1" });
|
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo {Title = "Oqtane", Version = "v1"}); });
|
||||||
});
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
@ -222,17 +223,19 @@ namespace Oqtane
|
|||||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||||
app.UseHsts();
|
app.UseHsts();
|
||||||
}
|
}
|
||||||
|
// to allow install middleware it should be moved up
|
||||||
|
app.ConfigureOqtaneAssemblies(env);
|
||||||
app.UseHttpsRedirection();
|
app.UseHttpsRedirection();
|
||||||
app.UseStaticFiles();
|
app.UseStaticFiles();
|
||||||
app.UseBlazorFrameworkFiles();
|
app.UseBlazorFrameworkFiles();
|
||||||
app.UseRouting();
|
app.UseRouting();
|
||||||
app.UseAuthentication();
|
app.UseAuthentication();
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
app.UseSwagger();
|
if (_useSwagger)
|
||||||
app.UseSwaggerUI(c =>
|
|
||||||
{
|
{
|
||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Oqtane V1");
|
app.UseSwagger();
|
||||||
});
|
app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "Oqtane V1"); });
|
||||||
|
}
|
||||||
|
|
||||||
app.UseEndpoints(endpoints =>
|
app.UseEndpoints(endpoints =>
|
||||||
{
|
{
|
||||||
@ -240,7 +243,6 @@ namespace Oqtane
|
|||||||
endpoints.MapControllers();
|
endpoints.MapControllers();
|
||||||
endpoints.MapFallbackToPage("/_Host");
|
endpoints.MapFallbackToPage("/_Host");
|
||||||
});
|
});
|
||||||
app.ConfigureOqtaneAssemblies(env);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user