Merge pull request #17 from oqtane/master

Sync upstream master
This commit is contained in:
Jim Spillane 2020-06-10 12:20:54 -04:00 committed by GitHub
commit 2ceeb25d0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 875 additions and 563 deletions

View File

@ -4,29 +4,30 @@
@inject IFileService FileService @inject IFileService FileService
@inject IModuleDefinitionService ModuleDefinitionService @inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IJSRuntime JsRuntime
@if (_packages != null) @if (_packages != null)
{ {
<TabStrip> <TabStrip>
@if (_packages.Count > 0) @if (_packages.Count > 0)
{ {
<TabPanel Name="Download"> <TabPanel Name="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage> <ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<Pager Items="@_packages"> <Pager Items="@_packages">
<Header> <Header>
<th>Name</th> <th>Name</th>
<th>Version</th> <th>Version</th>
<th></th> <th></th>
</Header> </Header>
<Row> <Row>
<td>@context.Name</td> <td>@context.Name</td>
<td>@context.Version</td> <td>@context.Version</td>
<td> <td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>Download</button> <button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>Download</button>
</td> </td>
</Row> </Row>
</Pager> </Pager>
</TabPanel> </TabPanel>
} }
<TabPanel Name="Upload"> <TabPanel Name="Upload">
<table class="table table-borderless"> <table class="table table-borderless">
@ -77,8 +78,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)
{ {

View File

@ -3,6 +3,7 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IModuleDefinitionService ModuleDefinitionService @inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IJSRuntime JsRuntime
@if (_moduleDefinitions == null) @if (_moduleDefinitions == null)
{ {
@ -24,17 +25,17 @@ else
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" /></td> <td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" /></td>
<td> <td>
@if (context.AssemblyName != "Oqtane.Client") @if (context.AssemblyName != "Oqtane.Client")
{ {
<ActionDialog Header="Delete Module" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Module?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" /> <ActionDialog Header="Delete Module" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Module?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" />
} }
</td> </td>
<td>@context.Name</td> <td>@context.Name</td>
<td>@context.Version</td> <td>@context.Version</td>
<td> <td>
@if (UpgradeAvailable(context.ModuleDefinitionName, context.Version)) @if (UpgradeAvailable(context.ModuleDefinitionName, context.Version))
{ {
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.ModuleDefinitionName, context.Version))>Upgrade</button> <button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.ModuleDefinitionName, context.Version))>Upgrade</button>
} }
</td> </td>
</Row> </Row>
</Pager> </Pager>
@ -83,9 +84,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)
{ {
@ -98,9 +101,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)
{ {

View File

@ -25,9 +25,9 @@
<td> <td>
<select id="container" class="form-control" @bind="@_containerType"> <select id="container" class="form-control" @bind="@_containerType">
<option value="-">&lt;Inherit From Page Or Site&gt;</option> <option value="-">&lt;Inherit From Page Or Site&gt;</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)
{ {

View File

@ -102,41 +102,44 @@
<td> <td>
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))"> <select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;Inherit From Site&gt;</option> <option value="-">&lt;Inherit From Site&gt;</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>
<tr> @if (_layouts.Count > 0)
<td> {
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label> <tr>
</td> <td>
<td> <Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
<select id="Layout" class="form-control" @bind="@_layouttype"> </td>
<option value="-">&lt;Inherit From Site&gt;</option> <td>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts) <select id="Layout" class="form-control" @bind="@_layouttype">
{ <option value="-">&lt;Inherit From Site&gt;</option>
if (panelayout.Key == _layouttype) @foreach (var layout in _layouts)
{ {
<option value="@panelayout.Key" selected>@panelayout.Value</option> if (layout.TypeName == _layouttype)
{
<option value="@(layout.TypeName)" selected>@(layout.Name)</option>
}
else
{
<option value="@(layout.TypeName)">@(layout.Name)</option>
}
} }
else </select>
{ </td>
<option value="@panelayout.Key">@panelayout.Value</option> </tr>
} }
}
</select>
</td>
</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="-">&lt;Inherit From Site&gt;</option> <option value="-">&lt;Inherit From Site&gt;</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;

View File

@ -113,41 +113,44 @@
<td> <td>
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))"> <select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;Inherit From Site&gt;</option> <option value="-">&lt;Inherit From Site&gt;</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>
<tr> @if (_layouts.Count > 0)
<td> {
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label> <tr>
</td> <td>
<td> <Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
<select id="Layout" class="form-control" @bind="@_layouttype"> </td>
<option value="-">&lt;Inherit From Site&gt;</option> <td>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts) <select id="Layout" class="form-control" @bind="@_layouttype">
{ <option value="-">&lt;Inherit From Site&gt;</option>
if (panelayout.Key == _layouttype) @foreach (var layout in _layouts)
{ {
<option value="@panelayout.Key" selected>@panelayout.Value</option> if (layout.TypeName == _layouttype)
{
<option value="@(layout.TypeName)" selected>@(layout.Name)</option>
}
else
{
<option value="@(layout.TypeName)">@(layout.Name)</option>
}
} }
else </select>
{ </td>
<option value="@panelayout.Key">@panelayout.Value</option> </tr>
} }
}
</select>
</td>
</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="-">&lt;Inherit From Site&gt;</option> <option value="-">&lt;Inherit From Site&gt;</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,23 +202,26 @@
} }
</TabPanel> </TabPanel>
<TabPanel Name="Permissions"> <TabPanel Name="Permissions">
<table class="table table-borderless"> @if (_permissions != null)
<tr> {
<td> <table class="table table-borderless">
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" /> <tr>
</td> <td>
</tr> <PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
</table> </td>
</tr>
</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)

View File

@ -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="">&lt;Select Theme&gt;</option> <option value="-">&lt;Select Theme&gt;</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>
<tr> @if (_layouts.Count > 0)
<td> {
<Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label> <tr>
</td> <td>
<td> <Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label>
<select id="defaultLayout" class="form-control" @bind="@_layouttype"> </td>
<option value="">&lt;Select Layout&gt;</option> <td>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts) <select id="defaultLayout" class="form-control" @bind="@_layouttype">
{ <option value="-">&lt;Select Layout&gt;</option>
<option value="@panelayout.Key">@panelayout.Value</option> @foreach (var layout in _layouts)
} {
</select> <option value="@(layout.TypeName)">@(layout.Name)</option>
</td> }
</tr> </select>
</td>
</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="">&lt;Select Container&gt;</option> <option value="-">&lt;Select Container&gt;</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));

View File

@ -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="">&lt;Select Theme&gt;</option> <option value="-">&lt;Select Theme&gt;</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>
</td>
</tr>
<tr>
<td>
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
</td>
<td>
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
<option value="">&lt;Select Layout&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
{
<option value="@panelayout.Key">@panelayout.Value</option>
} }
</select> </select>
</td> </td>
</tr> </tr>
@if (_layouts.Count > 0)
{
<tr>
<td>
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
</td>
<td>
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Select Layout&gt;</option>
@foreach (var layout in _layouts)
{
<option value="@(layout.TypeName)">@(layout.Name)</option>
}
</select>
</td>
</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="">&lt;Select Container&gt;</option> <option value="-">&lt;Select Container&gt;</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="">&lt;Select Site Template&gt;</option> <option value="-">&lt;Select Site Template&gt;</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();

View File

@ -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="">&lt;Select Theme&gt;</option> <option value="-">&lt;Select Theme&gt;</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>
<tr> @if (_layouts.Count > 0)
<td> {
<Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label> <tr>
</td> <td>
<td> <Label For="defaultLayout" HelpText="Select the default layout for the site">Default Layout: </Label>
<select id="defaultLayout" class="form-control" @bind="@_layouttype"> </td>
<option value="">&lt;Select Layout&gt;</option> <td>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts) <select id="defaultLayout" class="form-control" @bind="@_layouttype">
{ <option value="-">&lt;Select Layout&gt;</option>
<option value="@panelayout.Key">@panelayout.Value</option> @foreach (var layout in _layouts)
} {
</select> <option value="@(layout.TypeName)">@(layout.Name)</option>
</td> }
</tr> </select>
</td>
</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="">&lt;Select Container&gt;</option> <option value="-">&lt;Select Container&gt;</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))

View File

@ -4,46 +4,47 @@
@inject IFileService FileService @inject IFileService FileService
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IJSRuntime JsRuntime
@if (_packages != null) @if (_packages != null)
{ {
<TabStrip> <TabStrip>
@if (_packages.Count > 0) @if (_packages.Count > 0)
{ {
<TabPanel Name="Download"> <TabPanel Name="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more themes from the list below. Once you are ready click Install to complete the installation."></ModuleMessage> <ModuleMessage Type="MessageType.Info" Message="Download one or more themes from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<Pager Items="@_packages"> <Pager Items="@_packages">
<Header> <Header>
<th>Name</th> <th>Name</th>
<th>Version</th> <th>Version</th>
<th></th> <th></th>
</Header> </Header>
<Row> <Row>
<td>@context.Name</td> <td>@context.Name</td>
<td>@context.Version</td> <td>@context.Version</td>
<td> <td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>Download</button> <button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>Download</button>
</td> </td>
</Row> </Row>
</Pager> </Pager>
</TabPanel> </TabPanel>
} }
<TabPanel Name="Upload"> <TabPanel Name="Upload">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td>
<Label HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation.">Theme: </Label> <Label HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation.">Theme: </Label>
</td> </td>
<td> <td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Themes" UploadMultiple="@true" /> <FileManager Filter="nupkg" ShowFiles="false" Folder="Themes" UploadMultiple="@true" />
</td> </td>
</tr> </tr>
</table> </table>
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="InstallThemes">Install</button> <button type="button" class="btn btn-success" @onclick="InstallThemes">Install</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
} }
@code { @code {
@ -77,8 +78,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)
{ {
@ -101,4 +104,4 @@
AddModuleMessage("Error Downloading Theme", MessageType.Error); AddModuleMessage("Error Downloading Theme", MessageType.Error);
} }
} }
} }

View File

@ -4,6 +4,7 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IJSRuntime JsRuntime
@if (_themes == null) @if (_themes == null)
{ {
@ -83,9 +84,11 @@ else
try try
{ {
await PackageService.DownloadPackageAsync(themename, version, "Themes"); await PackageService.DownloadPackageAsync(themename, version, "Themes");
await ThemeService.InstallThemesAsync();
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version); await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
NavigationManager.NavigateTo(NavigateUrl()); ShowProgressIndicator();
var interop = new Interop(JsRuntime);
await interop.RedirectBrowser(NavigateUrl(), 3);
await ThemeService.InstallThemesAsync();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -98,9 +101,10 @@ else
{ {
try 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) catch (Exception ex)
{ {

View File

@ -4,35 +4,36 @@
@inject IFileService FileService @inject IFileService FileService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IInstallationService InstallationService @inject IInstallationService InstallationService
@inject IJSRuntime JsRuntime
@if (_package != null) @if (_package != null)
{ {
<TabStrip> <TabStrip>
<TabPanel Name="Download"> <TabPanel Name="Download">
@if (_upgradeavailable) @if (_upgradeavailable)
{ {
<ModuleMessage Type="MessageType.Info" Message="Select The Upgrade Button To Install a New Framework Version"></ModuleMessage> <ModuleMessage Type="MessageType.Info" Message="Select The Upgrade Button To Install a New Framework Version"></ModuleMessage>
@("Framework") @_package.Version <button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Upgrade</button> @("Framework") @_package.Version <button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, Constants.Version))>Upgrade</button>
} }
else else
{ {
<ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage> <ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage>
} }
</TabPanel> </TabPanel>
<TabPanel Name="Upload"> <TabPanel Name="Upload">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td>
<Label HelpText="Upload a framework package and select Install to complete the installation">Framework: </Label> <Label HelpText="Upload a framework package and select Install to complete the installation">Framework: </Label>
</td> </td>
<td> <td>
<FileManager Filter="nupkg" Folder="Framework" /> <FileManager Filter="nupkg" Folder="Framework" />
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="Upgrade">Install</button> <button type="button" class="btn btn-success" @onclick="Upgrade">Install</button>
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
} }
@code { @code {
@ -59,7 +60,7 @@
} }
} }
} }
catch catch
{ {
// can be caused by no network connection // can be caused by no network connection
} }
@ -69,8 +70,10 @@
{ {
try try
{ {
ShowProgressIndicator();
var interop = new Interop(JsRuntime);
await interop.RedirectBrowser(NavigateUrl(), 3);
await InstallationService.Upgrade(); await InstallationService.Upgrade();
NavigationManager.NavigateTo(NavigateUrl());
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -84,8 +87,10 @@
try 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) catch (Exception ex)
{ {

View File

@ -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">&lt;Select User&gt;</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,41 +45,35 @@
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
{ {
notification.SiteId = PageState.Site.SiteId; var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
notification.FromUserId = PageState.User.UserId; if (user != null)
notification.ToUserId = int.Parse(userid); {
notification.ToEmail = ""; notification.SiteId = PageState.Site.SiteId;
notification.Subject = subject; notification.FromUserId = PageState.User.UserId;
notification.Body = body; notification.FromDisplayName = PageState.User.DisplayName;
notification.ParentId = null; notification.FromEmail = PageState.User.Email;
notification.CreatedOn = DateTime.UtcNow; notification.ToUserId = user.UserId;
notification.IsDelivered = false; notification.ToDisplayName = user.DisplayName;
notification.DeliveredOn = null; notification.ToEmail = user.Email;
notification.Subject = subject;
notification = await NotificationService.AddNotificationAsync(notification); notification.Body = body;
notification.ParentId = null;
await logger.LogInformation("Notification Created {Notification}", notification); notification.CreatedOn = DateTime.UtcNow;
NavigationManager.NavigateTo(NavigateUrl()); notification.IsDelivered = false;
notification.DeliveredOn = null;
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {Notification}", notification);
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)
{ {

View File

@ -120,7 +120,7 @@ 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>
@ -143,7 +143,7 @@ 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>

View File

@ -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)
@ -12,16 +12,7 @@
<label class="control-label">@title: </label> <label class="control-label">@title: </label>
</td> </td>
<td> <td>
<select class="form-control" readonly @bind="userid"> <input class="form-control" @bind="@username" />
<option value="-1">&lt;System&gt;</option>
@if (userroles != null)
{
foreach (UserRole userrole in userroles)
{
<option value="@userrole.UserId">@userrole.User.DisplayName</option>
}
}
</select>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -72,8 +63,7 @@
@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 +76,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 +94,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;
@ -134,23 +132,32 @@
private async Task Send() private async Task Send()
{ {
var notification = new Notification(); var notification = new Notification();
notification.SiteId = PageState.Site.SiteId;
notification.FromUserId = PageState.User.UserId;
notification.ToUserId = int.Parse(userid);
notification.ToEmail = string.Empty;
notification.Subject = subject;
notification.Body = body;
notification.ParentId = notificationid;
notification.CreatedOn = DateTime.UtcNow;
notification.IsDelivered = false;
notification.DeliveredOn = null;
try try
{ {
notification = await NotificationService.AddNotificationAsync(notification); var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
await logger.LogInformation("Notification Created {Notification}", notification); {
NavigationManager.NavigateTo(NavigateUrl()); notification.SiteId = PageState.Site.SiteId;
notification.FromUserId = PageState.User.UserId;
notification.FromDisplayName = PageState.User.DisplayName;
notification.FromEmail = PageState.User.Email;
notification.ToUserId = user.UserId;
notification.ToDisplayName = user.DisplayName;
notification.ToEmail = user.Email;
notification.Subject = subject;
notification.Body = body;
notification.ParentId = notificationid;
notification.CreatedOn = DateTime.UtcNow;
notification.IsDelivered = false;
notification.DeliveredOn = null;
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {Notification}", notification);
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)
{ {

View File

@ -2,17 +2,20 @@
@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"> <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> <input class="form-control mr-4" @bind="@_search"/><button class="btn btn-outline-primary ml-1" @onclick="OnSearch">Search</button>
</div> </div>
<Pager Items="@userroles"> <Pager Items="@userroles">
@ -23,9 +26,15 @@ else
<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>
@ -34,19 +43,24 @@ else
@code { @code {
private List<UserRole> allroles; private List<UserRole> allroles;
private List<UserRole> userroles; private List<UserRole> userroles;
private string search; 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()
{ {
allroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId); allroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
userroles = allroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList(); await LoadSettingsAsync();
userroles = Search(_search);
} }
private void OnSearch() private List<UserRole> Search(string search)
{ {
userroles = allroles if (string.IsNullOrEmpty(_search))
{
return allroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
}
return allroles
.Where(item => item.Role.Name == Constants.RegisteredRole && .Where(item => item.Role.Name == Constants.RegisteredRole &&
( (
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) || item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
@ -57,6 +71,11 @@ else
.ToList(); .ToList();
} }
private async Task OnSearch()
{
userroles = Search(_search);
await UpdateSettingsAsync();
}
private async Task DeleteUser(UserRole UserRole) private async Task DeleteUser(UserRole UserRole)
{ {
@ -76,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);
}
} }

View File

@ -51,6 +51,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()
{ {
@ -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;

View File

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

View File

@ -26,46 +26,21 @@ namespace Oqtane.Services
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()

View File

@ -6,7 +6,7 @@ using Oqtane.UI;
namespace Oqtane.Themes namespace Oqtane.Themes
{ {
public class ContainerBase : ComponentBase, IContainerControl public abstract class ContainerBase : ComponentBase, IContainerControl
{ {
[Inject] [Inject]
protected IJSRuntime JSRuntime { get; set; } protected IJSRuntime JSRuntime { get; set; }
@ -17,6 +17,8 @@ namespace Oqtane.Themes
[CascadingParameter] [CascadingParameter]
protected Module ModuleState { get; set; } protected Module ModuleState { get; set; }
public virtual string Name { get; set; }
public virtual string Thumbnail { get; set; }
public string ThemePath() public string ThemePath()
{ {

View File

@ -32,7 +32,7 @@
</div> </div>
</div> </div>
<hr class="app-rule"/> <hr class="app-rule" />
<div class="row"> <div class="row">
<div class="col text-center"> <div class="col text-center">
@ -50,6 +50,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)
@ -74,7 +89,7 @@
</div> </div>
</div> </div>
} }
<hr class="app-rule"/> <hr class="app-rule" />
<div class="row"> <div class="row">
<div class="col text-center"> <div class="col text-center">
@ -142,34 +157,36 @@
<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>
<div class="row"> @if (_pane.Length > 1)
<div class="col text-center"> {
<label for="Pane" class="control-label">Pane: </label> <div class="row">
<select class="form-control" @bind="@Pane"> <div class="col text-center">
<option value="">&lt;Select Pane&gt;</option> <label for="Pane" class="control-label">Pane: </label>
@foreach (string pane in PageState.Page.Panes) <select class="form-control" @bind="@Pane">
{ @foreach (string pane in PageState.Page.Panes)
<option value="@pane">@pane Pane</option> {
} <option value="@pane">@pane Pane</option>
</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>
</div> </div>
<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)
@ -218,7 +235,7 @@
private List<ModuleDefinition> _moduleDefinitions; private List<ModuleDefinition> _moduleDefinitions;
private List<Page> _pages = new List<Page>(); private List<Page> _pages = new List<Page>();
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 _display = "display: none;"; private string _display = "display: none;";
private string _category = "Common"; private string _category = "Common";
@ -244,47 +261,41 @@
} }
} }
protected string Pane
{
get => _pane;
private set
{
if (_pane != value)
{
_pane = value;
_ = UpdateSettingsAsync();
}
}
}
protected string Description { get; private set; } = ""; protected string Description { get; private set; } = "";
protected string Pane { get; private set; } = "";
protected string Title { get; private set; } = ""; protected string Title { get; private set; } = "";
protected string ContainerType { get; private set; } = ""; protected string ContainerType { get; private set; } = "";
protected string Message { get; private set; } = ""; protected string Message { get; private set; } = "";
[Parameter] [Parameter]
public string ButtonClass { get; set; } public string ButtonClass { get; set; } = "btn-outline-secondary";
[Parameter] [Parameter]
public string CardClass { get; set; } public string CardClass { get; set; } = "card border-secondary mb-3";
[Parameter] [Parameter]
public string HeaderClass { get; set; } public string HeaderClass { get; set; } = "card-header";
[Parameter] [Parameter]
public string BodyClass { get; set; } public string BodyClass { get; set; } = "card-body";
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
if (string.IsNullOrEmpty(ButtonClass))
{
ButtonClass = "btn-outline-secondary";
}
if (string.IsNullOrEmpty(CardClass))
{
CardClass = "card border-secondary mb-3";
}
if (string.IsNullOrEmpty(HeaderClass))
{
HeaderClass = "card-header";
}
if (string.IsNullOrEmpty(BodyClass))
{
BodyClass = "card-body";
}
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
{ {
_pages?.Clear(); _pages?.Clear();
@ -298,15 +309,11 @@
} }
await LoadSettingsAsync(); 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(); _moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList(); _categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
} }
} }
@ -456,7 +463,7 @@
switch (location) switch (location)
{ {
case "Admin": case "Admin":
// get admin dashboard moduleid // get admin dashboard moduleid
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.AdminDashboardModule); module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.AdminDashboardModule);
if (module != null) if (module != null)
@ -468,7 +475,7 @@
case "Add": case "Add":
case "Edit": case "Edit":
string url = ""; string url = "";
// get page management moduleid // get page management moduleid
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.PageManagementModule); module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.PageManagementModule);
if (module != null) if (module != null)
@ -493,6 +500,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;
@ -526,18 +588,24 @@
} }
} }
private string settingName = "CP-category"; private string settingCategory = "CP-category";
private string settingPane = "CP-pane";
private string _pane = "";
private async Task LoadSettingsAsync() private async Task LoadSettingsAsync()
{ {
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
_category = SettingService.GetSetting(settings, settingName, "Common"); _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() private async Task UpdateSettingsAsync()
{ {
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId); Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
SettingService.SetSetting(settings, settingName, _category); SettingService.SetSetting(settings, settingCategory, _category);
SettingService.SetSetting(settings, settingPane, _pane);
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId); await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
} }
} }

View File

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

View File

@ -2,5 +2,7 @@
{ {
public interface IContainerControl public interface IContainerControl
{ {
string Name { get; } // friendly name for a container
string Thumbnail { get; } // screen shot of a container - assumed to be in the ThemePath() folder
} }
} }

View File

@ -2,7 +2,9 @@
{ {
public interface ILayoutControl public interface ILayoutControl
{ {
string Panes { get; } // identifies all panes in a theme ( delimited by ";" ) string Name { get; } // friendly name for a layout
string Thumbnail { get; } // screen shot of a layout - assumed to be in the ThemePath() folder
string Panes { get; } // identifies all panes in a theme ( delimited by "," or ";" )
} }
} }

View File

@ -4,10 +4,12 @@ using Oqtane.UI;
namespace Oqtane.Themes namespace Oqtane.Themes
{ {
public class LayoutBase : ComponentBase, ILayoutControl public abstract class LayoutBase : ComponentBase, ILayoutControl
{ {
[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 string LayoutPath() public string LayoutPath()

View File

@ -12,4 +12,8 @@
<ModuleInstance /> <ModuleInstance />
</div> </div>
</div> </div>
</div> </div>
@code {
public override string Name => "Standard Header";
}

View File

@ -17,6 +17,8 @@
</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>()

View File

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

View File

@ -6,4 +6,8 @@
<ModuleActions /> <ModuleActions />
} }
<ModuleInstance /> <ModuleInstance />
</div> </div>
@code {
public override string Name => "No Header";
}

View File

@ -6,5 +6,7 @@
</div> </div>
@code { @code {
public override string Name => "Single Pane";
public override string Panes => "Content"; public override string Panes => "Content";
} }

View File

@ -8,7 +8,7 @@ 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,6 +17,8 @@ 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; }

View File

@ -4,7 +4,7 @@ using Oqtane.UI;
namespace Oqtane.Themes namespace Oqtane.Themes
{ {
public class ThemeControlBase : ComponentBase public abstract class ThemeControlBase : ComponentBase
{ {
[CascadingParameter] [CascadingParameter]
protected PageState PageState { get; set; } protected PageState PageState { get; set; }

View File

@ -27,18 +27,13 @@
DynamicComponent = builder => DynamicComponent = builder =>
{ {
Type containerType = Type.GetType(container); Type containerType = Type.GetType(container);
if (containerType != null) if (containerType == null)
{ {
builder.OpenComponent(0, containerType); // fallback
builder.CloseComponent(); containerType = Type.GetType(Constants.DefaultContainer);
}
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();
} }
builder.OpenComponent(0, containerType);
builder.CloseComponent();
}; };
} }
} }

View File

@ -204,5 +204,35 @@ namespace Oqtane.UI
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
public Task RefreshBrowser(bool force, int wait)
{
try
{
_jsRuntime.InvokeAsync<object>(
"Oqtane.Interop.refreshBrowser",
force, wait);
return Task.CompletedTask;
}
catch
{
return Task.CompletedTask;
}
}
public Task RedirectBrowser(string url, int wait)
{
try
{
_jsRuntime.InvokeAsync<object>(
"Oqtane.Interop.redirectBrowser",
url, wait);
return Task.CompletedTask;
}
catch
{
return Task.CompletedTask;
}
}
} }
} }

View File

@ -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)
{ {
builder.OpenComponent(0, layoutType); // fallback
builder.CloseComponent(); layoutType = Type.GetType(Constants.DefaultLayout);
}
else
{
// layout does not exist with type specified
} }
builder.OpenComponent(0, layoutType);
builder.CloseComponent();
}; };
} }
} }

View File

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

View File

@ -66,18 +66,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)
{ {
builder.OpenComponent(0, themeType); // fallback
builder.CloseComponent(); themeType = Type.GetType(Constants.DefaultTheme);
}
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();
} }
builder.OpenComponent(0, themeType);
builder.CloseComponent();
}; };
} }

View File

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

View File

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

View File

@ -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 != user.Username)
{
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;
} }

View File

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

View File

@ -69,7 +69,7 @@ namespace Oqtane.Infrastructure
mailMessage.Subject = notification.Subject; 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
{ {

View File

@ -193,11 +193,7 @@ namespace Oqtane.Repository
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
|| modulecontroltype.IsOqtaneIgnore()
) continue;
// create namespace root typename // create namespace root typename
string qualifiedModuleType = modulecontroltype.Namespace + ", " + modulecontroltype.Assembly.GetName().Name; string qualifiedModuleType = modulecontroltype.Namespace + ", " + modulecontroltype.Assembly.GetName().Name;

View File

@ -21,8 +21,6 @@ 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)
.Include(item => item.ToUser)
.ToList(); .ToList();
} }
@ -30,8 +28,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();
} }

View File

@ -50,10 +50,7 @@ namespace Oqtane.Repository
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.IsAbstract
|| themeControlType.IsOqtaneIgnore()
) continue; ) continue;
// create namespace root typename // create namespace root typename
@ -87,26 +84,41 @@ namespace Oqtane.Repository
} }
// set internal properties // set internal properties
theme.ThemeName = qualifiedThemeType; 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 == qualifiedThemeType); 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 = themeTypes Type[] layouttypes = themeTypes
.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 ILayoutControl;
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
@ -114,11 +126,16 @@ namespace Oqtane.Repository
.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 IContainerControl;
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;

View File

@ -31,3 +31,9 @@ CREATE UNIQUE NONCLUSTERED INDEX IX_File ON [dbo].[File]
[Name] [Name]
) ON [PRIMARY] ) ON [PRIMARY]
GO GO
ALTER TABLE [dbo].[Notification] ADD
[FromDisplayName] [nvarchar](50) NULL,
[FromEmail] [nvarchar](256) NULL,
[ToDisplayName] [nvarchar](50) NULL
GO

View File

@ -222,6 +222,8 @@ 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();
@ -240,7 +242,7 @@ namespace Oqtane
endpoints.MapControllers(); endpoints.MapControllers();
endpoints.MapFallbackToPage("/_Host"); endpoints.MapFallbackToPage("/_Host");
}); });
app.ConfigureOqtaneAssemblies(env);
} }
} }
} }

View File

@ -11,7 +11,8 @@ namespace [Owner].[Module]s
Description = "[Module]", Description = "[Module]",
Version = "1.0.0", Version = "1.0.0",
ServerManagerType = "[ServerManagerType]", ServerManagerType = "[ServerManagerType]",
ReleaseVersions = "1.0.0" ReleaseVersions = "1.0.0",
Dependencies = "[Owner].[Module]s.Shared.Oqtane"
}; };
} }
} }

View File

@ -138,7 +138,7 @@ Oqtane.Interop = {
script.integrity = integrity; script.integrity = integrity;
} }
if (crossorigin !== "") { if (crossorigin !== "") {
script.crossorigin = crossorigin; script.crossOrigin = crossorigin;
} }
} }
else { else {
@ -311,5 +311,15 @@ Oqtane.Interop = {
request.send(data); request.send(data);
} }
} }
},
refreshBrowser: function (reload, wait) {
setInterval(function () {
window.location.reload(reload);
}, wait * 1000);
},
redirectBrowser: function (url, wait) {
setInterval(function () {
window.location.href = url;
}, wait * 1000);
} }
}; };

View File

@ -35,14 +35,14 @@ namespace System.Reflection
return assembly.GetTypes() return assembly.GetTypes()
//.Where(t => t.GetInterfaces().Contains(interfaceType)); //.Where(t => t.GetInterfaces().Contains(interfaceType));
.Where(x => interfaceType.IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract); .Where(x => !x.IsInterface && !x.IsAbstract && interfaceType.IsAssignableFrom(x));
} }
public static IEnumerable<Type> GetTypes<T>(this Assembly assembly) public static IEnumerable<Type> GetTypes<T>(this Assembly assembly)
{ {
return assembly.GetTypes(typeof(T)); return assembly.GetTypes(typeof(T));
} }
public static IEnumerable<T> GetInstances<T>(this Assembly assembly) where T : class public static IEnumerable<T> GetInstances<T>(this Assembly assembly) where T : class
{ {
if (assembly is null) if (assembly is null)
@ -51,7 +51,7 @@ namespace System.Reflection
} }
var type = typeof(T); var type = typeof(T);
var list = assembly.GetTypes() var list = assembly.GetTypes()
.Where(x => type.IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract && !x.IsGenericType); .Where(x => !x.IsInterface && !x.IsAbstract && !x.IsGenericType && type.IsAssignableFrom(x));
foreach (var type1 in list) foreach (var type1 in list)
{ {
@ -80,9 +80,14 @@ namespace System.Reflection
.Where(a => Utilities.GetFullTypeName(a.GetName().Name) != "Oqtane.Client"); .Where(a => Utilities.GetFullTypeName(a.GetName().Name) != "Oqtane.Client");
} }
/// <summary>
/// Checks if type should be ignored by oqtane dynamic loader
/// </summary>
/// <param name="type">Checked type</param>
/// <returns></returns>
public static bool IsOqtaneIgnore(this Type type) public static bool IsOqtaneIgnore(this Type type)
{ {
return Attribute.IsDefined(type, typeof(OqtaneIgnoreAttribute)); return Attribute.IsDefined(type, typeof(OqtaneIgnoreAttribute)) || type.IsAbstract || type.IsGenericType;
} }
} }
} }

View File

@ -5,7 +5,9 @@ namespace Oqtane.Themes
{ {
public interface IThemeControl public interface IThemeControl
{ {
string Panes { get; } // identifies all panes in a theme ( delimited by ";" ) - assumed to be a layout if no panes specified string Name { get; } // friendly name for a theme
string Thumbnail { get; } // screen shot of a theme - assumed to be in the ThemePath() folder
string Panes { get; } // identifies all panes in a theme ( delimited by "," or ";") - assumed to be a layout if no panes specified
List<Resource> Resources { get; } // identifies all resources in a theme List<Resource> Resources { get; } // identifies all resources in a theme
} }
} }

View File

@ -8,7 +8,10 @@ namespace Oqtane.Models
public int NotificationId { get; set; } public int NotificationId { get; set; }
public int SiteId { get; set; } public int SiteId { get; set; }
public int? FromUserId { get; set; } public int? FromUserId { get; set; }
public string FromDisplayName { get; set; }
public string FromEmail { get; set; }
public int? ToUserId { get; set; } public int? ToUserId { get; set; }
public string ToDisplayName { get; set; }
public string ToEmail { get; set; } public string ToEmail { get; set; }
public int? ParentId { get; set; } public int? ParentId { get; set; }
public string Subject { get; set; } public string Subject { get; set; }
@ -19,11 +22,6 @@ namespace Oqtane.Models
public string DeletedBy { get; set; } public string DeletedBy { get; set; }
public DateTime? DeletedOn { get; set; } public DateTime? DeletedOn { get; set; }
public bool IsDeleted { get; set; } public bool IsDeleted { get; set; }
[ForeignKey("FromUserId")]
public User FromUser { get; set; }
[ForeignKey("ToUserId")]
public User ToUser { get; set; }
} }
} }

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
namespace Oqtane.Models namespace Oqtane.Models
{ {
@ -23,9 +24,16 @@ namespace Oqtane.Models
public string Contact { get; set; } public string Contact { get; set; }
public string License { get; set; } public string License { get; set; }
public string Dependencies { get; set; } public string Dependencies { get; set; }
public string ThemeControls { get; set; }
public string PaneLayouts { get; set; }
public string ContainerControls { get; set; }
public string AssemblyName { get; set; } public string AssemblyName { get; set; }
public List<ThemeControl> Themes { get; set; }
public List<ThemeControl> Layouts { get; set; }
public List<ThemeControl> Containers { get; set; }
//[Obsolete("This property is obsolete. Use Themes instead.", false)]
public string ThemeControls { get; set; }
//[Obsolete("This property is obsolete. Use Layouts instead.", false)]
public string PaneLayouts { get; set; }
//[Obsolete("This property is obsolete. Use Containers instead.", false)]
public string ContainerControls { get; set; }
} }
} }

View File

@ -0,0 +1,10 @@
namespace Oqtane.Models
{
public class ThemeControl
{
public string TypeName { get; set; }
public string Name { get; set; }
public string Thumbnail { get; set; }
public string Panes { get; set; }
}
}