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 IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService
@inject IJSRuntime JsRuntime
@if (_packages != null)
{
<TabStrip>
@if (_packages.Count > 0)
{
<TabPanel Name="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<Pager Items="@_packages">
<Header>
<th>Name</th>
<th>Version</th>
<th></th>
</Header>
<Row>
<td>@context.Name</td>
<td>@context.Version</td>
<td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>Download</button>
</td>
</Row>
</Pager>
</TabPanel>
<TabPanel Name="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<Pager Items="@_packages">
<Header>
<th>Name</th>
<th>Version</th>
<th></th>
</Header>
<Row>
<td>@context.Name</td>
<td>@context.Version</td>
<td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>Download</button>
</td>
</Row>
</Pager>
</TabPanel>
}
<TabPanel Name="Upload">
<table class="table table-borderless">
@ -77,8 +78,10 @@
{
try
{
ShowProgressIndicator();
var interop = new Interop(JsRuntime);
await interop.RedirectBrowser(NavigateUrl(), 3);
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
NavigationManager.NavigateTo(NavigateUrl());
}
catch (Exception ex)
{

View File

@ -3,6 +3,7 @@
@inject NavigationManager NavigationManager
@inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService
@inject IJSRuntime JsRuntime
@if (_moduleDefinitions == null)
{
@ -24,17 +25,17 @@ else
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ModuleDefinitionId.ToString())" /></td>
<td>
@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))" />
}
}
</td>
<td>@context.Name</td>
<td>@context.Version</td>
<td>
@if (UpgradeAvailable(context.ModuleDefinitionName, context.Version))
{
{
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.ModuleDefinitionName, context.Version))>Upgrade</button>
}
}
</td>
</Row>
</Pager>
@ -83,9 +84,11 @@ else
try
{
await PackageService.DownloadPackageAsync(moduledefinitionname, version, "Modules");
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
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)
{
@ -98,9 +101,10 @@ else
{
try
{
ShowProgressIndicator();
var interop = new Interop(JsRuntime);
await interop.RedirectBrowser(NavigateUrl(), 3);
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
await logger.LogInformation("Module Deleted {ModuleDefinition}", moduleDefinition);
NavigationManager.NavigateTo(NavigateUrl());
}
catch (Exception ex)
{

View File

@ -25,9 +25,9 @@
<td>
<select id="container" class="form-control" @bind="@_containerType">
<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>
</td>
@ -63,7 +63,7 @@
}
</TabPanel>
<TabPanel Name="Permissions">
@if (_containers != null)
@if (_permissions != null)
{
<table class="table table-borderless">
<tr>
@ -85,12 +85,12 @@
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code {
private Dictionary<string, string> _containers;
private List<ThemeControl> _containers = new List<ThemeControl>();
private string _title;
private string _containerType;
private string _allPages = "false";
private string _permissionNames = "";
private string _permissions;
private string _permissions = null;
private string _pageId;
private PermissionGrid _permissionGrid;
private Type _settingsModuleType;
@ -105,7 +105,7 @@
protected override async Task OnInitializedAsync()
{
_title = ModuleState.Title;
_containers = ThemeService.GetContainerTypes(await ThemeService.GetThemesAsync());
_containers = ThemeService.GetContainerControls(await ThemeService.GetThemesAsync(), PageState.Page.ThemeType);
_containerType = ModuleState.ContainerType;
if (!string.IsNullOrEmpty(PageState.Page.DefaultContainerType) && _containerType == PageState.Page.DefaultContainerType)
{

View File

@ -102,41 +102,44 @@
<td>
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
<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
{
<option value="@item.Key">@item.Value</option>
<option value="@theme.TypeName">@theme.Name</option>
}
}
</select>
</td>
</tr>
<tr>
<td>
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
</td>
<td>
<select id="Layout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Inherit From Site&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
{
if (panelayout.Key == _layouttype)
@if (_layouts.Count > 0)
{
<tr>
<td>
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
</td>
<td>
<select id="Layout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Inherit From Site&gt;</option>
@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
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
}
</select>
</td>
</tr>
</select>
</td>
</tr>
}
<tr>
<td>
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
@ -144,9 +147,9 @@
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<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>
</td>
@ -199,10 +202,10 @@
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@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<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _layouts = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>();
private List<Page> _pageList;
private string _name;
private string _title;
@ -232,10 +235,7 @@
_pageList = PageState.Pages;
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
_themes = ThemeService.GetThemeTypes(_themeList);
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_containers = ThemeService.GetContainerTypes(_themeList);
_themes = ThemeService.GetThemeControls(_themeList);
_permissions = string.Empty;
}
catch (Exception ex)
@ -287,12 +287,16 @@
_themetype = (string)e.Value;
if (_themetype != "-")
{
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
}
else
{
_panelayouts = new Dictionary<string, string>();
_layouts = new List<ThemeControl>();
_containers = new List<ThemeControl>();
}
_layouttype = "-";
_containertype = "-";
StateHasChanged();
}
catch (Exception ex)
@ -307,7 +311,7 @@
Page page = null;
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.SiteId = PageState.Page.SiteId;

View File

@ -113,41 +113,44 @@
<td>
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
<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
{
<option value="@item.Key">@item.Value</option>
<option value="@theme.TypeName">@theme.Name</option>
}
}
</select>
</td>
</tr>
<tr>
<td>
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
</td>
<td>
<select id="Layout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Inherit From Site&gt;</option>
@foreach (KeyValuePair<string, string> panelayout in _panelayouts)
{
if (panelayout.Key == _layouttype)
@if (_layouts.Count > 0)
{
<tr>
<td>
<Label For="Layout" HelpText="Select a layout for the page (if the selected theme supports it)">Layout: </Label>
</td>
<td>
<select id="Layout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Inherit From Site&gt;</option>
@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
{
<option value="@panelayout.Key">@panelayout.Value</option>
}
}
</select>
</td>
</tr>
</select>
</td>
</tr>
}
<tr>
<td>
<Label For="defaultContainer" HelpText="Select the default container for the page">Default Container: </Label>
@ -155,9 +158,9 @@
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<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>
</td>
@ -199,23 +202,26 @@
}
</TabPanel>
<TabPanel Name="Permissions">
<table class="table table-borderless">
<tr>
<td>
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
</td>
</tr>
</table>
@if (_permissions != null)
{
<table class="table table-borderless">
<tr>
<td>
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
</td>
</tr>
</table>
}
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">Save</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
@code {
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<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _layouts = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>();
private List<Page> _pageList;
private int _pageId;
private string _name;
@ -234,7 +240,7 @@
private string _layouttype = "-";
private string _containertype = "-";
private string _icon;
private string _permissions;
private string _permissions = null;
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
@ -252,12 +258,11 @@
{
try
{
_themeList = await ThemeService.GetThemesAsync();
_pageList = PageState.Pages;
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
_themes = ThemeService.GetThemeTypes(_themeList);
_containers = ThemeService.GetContainerTypes(_themeList);
_themeList = await ThemeService.GetThemesAsync();
_themes = ThemeService.GetThemeControls(_themeList);
_pageId = Int32.Parse(PageState.QueryString["id"]);
var page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
@ -291,12 +296,13 @@
{
_themetype = "-";
}
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_layouts = ThemeService.GetLayoutControls(_themeList, page.ThemeType);
_layouttype = page.LayoutType;
if (_layouttype == PageState.Site.DefaultLayoutType)
{
_layouttype = "-";
}
_containers = ThemeService.GetContainerControls(_themeList, page.ThemeType);
_containertype = page.DefaultContainerType;
if (string.IsNullOrEmpty(_containertype))
{
@ -369,12 +375,16 @@
_themetype = (string)e.Value;
if (_themetype != "-")
{
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
}
else
{
_panelayouts = new Dictionary<string, string>();
_layouts = new List<ThemeControl>();
_containers = new List<ThemeControl>();
}
_layouttype = "-";
_containertype = "-";
StateHasChanged();
}
catch (Exception ex)

View File

@ -56,45 +56,48 @@
</td>
<td>
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in _themes)
<option value="-">&lt;Select Theme&gt;</option>
@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
{
<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 sites default layout">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>
</td>
</tr>
@if (_layouts.Count > 0)
{
<tr>
<td>
<Label For="defaultLayout" HelpText="Select the sites default layout">Default Layout: </Label>
</td>
<td>
<select id="defaultLayout" class="form-control" @bind="@_layouttype">
<option value="-">&lt;Select Layout&gt;</option>
@foreach (var layout in _layouts)
{
<option value="@(layout.TypeName)">@(layout.Name)</option>
}
</select>
</td>
</tr>
}
<tr>
<td>
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
</td>
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<option value="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in _containers)
<option value="-">&lt;Select Container&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.Key">@container.Value</option>
<option value="@container.TypeName">@container.Name</option>
}
</select>
</td>
@ -208,10 +211,10 @@
}
@code {
private Dictionary<string, string> _themes;
private Dictionary<string, string> _panelayouts;
private Dictionary<string, string> _containers;
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 List<Tenant> _tenantList;
private string _tenant = string.Empty;
@ -221,9 +224,9 @@
private FileManager _logofilemanager;
private int _faviconfileid = -1;
private FileManager _faviconfilemanager;
private string _themetype;
private string _layouttype;
private string _containertype;
private string _themetype = "-";
private string _layouttype = "-";
private string _containertype = "-";
private string _allowregistration;
private string _smtphost = string.Empty;
private string _smtpport = string.Empty;
@ -271,9 +274,11 @@
_faviconfileid = site.FaviconFileId.Value;
}
_themes = ThemeService.GetThemeControls(_themeList);
_themetype = site.DefaultThemeType;
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
_layouttype = site.DefaultLayoutType;
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = site.DefaultContainerType;
_allowregistration = site.AllowRegistration.ToString();
@ -314,9 +319,6 @@
_deletedon = site.DeletedOn;
_isdeleted = site.IsDeleted.ToString();
}
_themes = ThemeService.GetThemeTypes(_themeList);
_containers = ThemeService.GetContainerTypes(_themeList);
}
catch (Exception ex)
{
@ -330,14 +332,18 @@
try
{
_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
{
_panelayouts = new Dictionary<string, string>();
_layouts = new List<ThemeControl>();
_containers = new List<ThemeControl>();
}
_layouttype = "-";
_containertype = "-";
StateHasChanged();
}
catch (Exception ex)
@ -351,7 +357,7 @@
{
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;
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
@ -376,7 +382,7 @@
}
site.DefaultThemeType = _themetype;
site.DefaultLayoutType = (_layouttype == null ? string.Empty : _layouttype);
site.DefaultLayoutType = (_layouttype == "-" ? string.Empty : _layouttype);
site.DefaultContainerType = _containertype;
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));

View File

@ -38,38 +38,41 @@ else
</td>
<td>
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in _themes)
<option value="-">&lt;Select Theme&gt;</option>
@foreach (var theme in _themes)
{
<option value="@item.Key">@item.Value</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>
<option value="@theme.TypeName">@theme.Name</option>
}
</select>
</td>
</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>
<td>
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
</td>
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<option value="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in _containers)
<option value="-">&lt;Select Container&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.Key">@container.Value</option>
<option value="@container.TypeName">@container.Name</option>
}
</select>
</td>
@ -80,7 +83,7 @@ else
</td>
<td>
<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)
{
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option>
@ -198,11 +201,11 @@ else
}
@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<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 string _tenantid = "-";
@ -218,20 +221,19 @@ else
private string _name = string.Empty;
private string _urls = string.Empty;
private string _themetype = string.Empty;
private string _layouttype = string.Empty;
private string _containertype = string.Empty;
private string _sitetemplatetype = string.Empty;
private string _themetype = "-";
private string _layouttype = "-";
private string _containertype = "-";
private string _sitetemplatetype = "-";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override async Task OnInitializedAsync()
{
_themeList = await ThemeService.GetThemesAsync();
_tenants = await TenantService.GetTenantsAsync();
_urls = PageState.Alias.Name;
_themes = ThemeService.GetThemeTypes(_themeList);
_containers = ThemeService.GetContainerTypes(_themeList);
_themeList = await ThemeService.GetThemesAsync();
_themes = ThemeService.GetThemeControls(_themeList);
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
}
@ -263,15 +265,18 @@ else
try
{
_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
{
_panelayouts = new Dictionary<string, string>();
_layouts = new List<ThemeControl>();
_containers = new List<ThemeControl>();
}
_layouttype = "-";
_containertype = "-";
StateHasChanged();
}
catch (Exception ex)
@ -283,7 +288,7 @@ else
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 aliases = await AliasService.GetAliasesAsync();

View File

@ -39,45 +39,48 @@
</td>
<td>
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="">&lt;Select Theme&gt;</option>
@foreach (KeyValuePair<string, string> item in _themes)
<option value="-">&lt;Select Theme&gt;</option>
@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
{
<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>
</td>
</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>
<td>
<Label For="defaultContainer" HelpText="Select the default container for the site">Default Container: </Label>
</td>
<td>
<select id="defaultIdea" class="form-control" @bind="@_containertype">
<option value="">&lt;Select Container&gt;</option>
@foreach (KeyValuePair<string, string> container in _containers)
<option value="-">&lt;Select Container&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.Key">@container.Value</option>
<option value="@container.TypeName">@container.Name</option>
}
</select>
</td>
@ -103,11 +106,11 @@
}
@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<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 List<Tenant> _tenantList;
private string _tenant = string.Empty;
@ -147,9 +150,11 @@
_urls += alias.Name + "\n";
}
_themes = ThemeService.GetThemeControls(_themeList);
_themetype = site.DefaultThemeType;
_panelayouts = ThemeService.GetPaneLayoutTypes(_themeList, _themetype);
_layouts = ThemeService.GetLayoutControls(_themeList, _themetype);
_layouttype = site.DefaultLayoutType;
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = site.DefaultContainerType;
_createdby = site.CreatedBy;
_createdon = site.CreatedOn;
@ -159,9 +164,6 @@
_deletedon = site.DeletedOn;
_isdeleted = site.IsDeleted.ToString();
}
_themes = ThemeService.GetThemeTypes(_themeList);
_containers = ThemeService.GetContainerTypes(_themeList);
}
catch (Exception ex)
{
@ -175,15 +177,18 @@
try
{
_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
{
_panelayouts = new Dictionary<string, string>();
_layouts = new List<ThemeControl>();
_containers = new List<ThemeControl>();
}
_layouttype = "-";
_containertype = "-";
StateHasChanged();
}
catch (Exception ex)
@ -197,7 +202,7 @@
{
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;
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Admin.UserProfile
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserRoleService UserRoleService
@inject IUserService UserService
@inject INotificationService NotificationService
@if (PageState.User != null)
@ -9,19 +9,10 @@
<table class="table table-borderless">
<tr>
<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>
<select id="to" class="form-control" @bind="@userid">
<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>
<input id="to" class="form-control" @bind="@username" />
</td>
</tr>
<tr>
@ -46,8 +37,7 @@
}
@code {
private List<UserRole> userroles;
private string userid = "-1";
private string username = "";
private string subject = "";
private string body = "";
@ -55,41 +45,35 @@
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()
{
var notification = new Notification();
try
{
notification.SiteId = PageState.Site.SiteId;
notification.FromUserId = PageState.User.UserId;
notification.ToUserId = int.Parse(userid);
notification.ToEmail = "";
notification.Subject = subject;
notification.Body = body;
notification.ParentId = null;
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());
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
{
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 = null;
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)
{

View File

@ -120,7 +120,7 @@ else
<Row>
<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>@(context.FromUser == null ? "System" : context.FromUser.DisplayName)</td>
<td>@context.FromDisplayName</td>
<td>@context.Subject</td>
<td>@context.CreatedOn</td>
</Row>
@ -143,7 +143,7 @@ else
<Row>
<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>@(context.ToUser == null ? context.ToEmail : context.ToUser.DisplayName)</td>
<td>@context.ToDisplayName</td>
<td>@context.Subject</td>
<td>@context.CreatedOn</td>
</Row>

View File

@ -1,7 +1,7 @@
@namespace Oqtane.Modules.Admin.UserProfile
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserRoleService UserRoleService
@inject IUserService UserService
@inject INotificationService NotificationService
@if (PageState.User != null)
@ -12,16 +12,7 @@
<label class="control-label">@title: </label>
</td>
<td>
<select class="form-control" readonly @bind="userid">
<option value="-1">&lt;System&gt;</option>
@if (userroles != null)
{
foreach (UserRole userrole in userroles)
{
<option value="@userrole.UserId">@userrole.User.DisplayName</option>
}
}
</select>
<input class="form-control" @bind="@username" />
</td>
</tr>
<tr>
@ -72,8 +63,7 @@
@code {
private int notificationid;
private string title = string.Empty;
private List<UserRole> userroles;
private string userid = "-1";
private string username = "";
private string subject = string.Empty;
private string createdon = string.Empty;
private string body = string.Empty;
@ -86,20 +76,17 @@
{
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"]);
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
if (notification != null)
{
int userid = -1;
if (notification.ToUserId == PageState.User.UserId)
{
title = "From";
if (notification.FromUserId != null)
{
userid = notification.FromUserId.ToString();
userid = notification.FromUserId.Value;
}
}
else
@ -107,10 +94,21 @@
title = "To";
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;
createdon = notification.CreatedOn.ToString();
body = notification.Body;
@ -134,23 +132,32 @@
private async Task Send()
{
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
{
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {Notification}", notification);
NavigationManager.NavigateTo(NavigateUrl());
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
{
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)
{

View File

@ -2,17 +2,20 @@
@inherits ModuleBase
@inject IUserRoleService UserRoleService
@inject IUserService UserService
@inject ISettingService SettingService
@if (userroles == null)
{
<p><em>Loading...</em></p>
<p>
<em>Loading...</em>
</p>
}
else
{
<ActionLink Action="Add" Text="Add User"/>
<div class="d-flex p-1">
<input class="form-control mr-4" @bind="@search"/><button class="btn btn-outline-primary ml-1" @onclick="OnSearch">Search</button>
<input class="form-control mr-4" @bind="@_search"/><button class="btn btn-outline-primary ml-1" @onclick="OnSearch">Search</button>
</div>
<Pager Items="@userroles">
@ -23,9 +26,15 @@ else
<th>Name</th>
</Header>
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" /></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>
<ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())"/>
</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>
</Row>
</Pager>
@ -34,19 +43,24 @@ else
@code {
private List<UserRole> allroles;
private List<UserRole> userroles;
private string search;
private string _search;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnInitializedAsync()
{
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 &&
(
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
@ -57,6 +71,11 @@ else
.ToList();
}
private async Task OnSearch()
{
userroles = Search(_search);
await UpdateSettingsAsync();
}
private async Task DeleteUser(UserRole UserRole)
{
@ -76,4 +95,20 @@ else
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]
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()
{
@ -60,6 +63,11 @@
_text = Text;
}
if (IconOnly && !string.IsNullOrEmpty(IconName))
{
_text = string.Empty;
}
if (!string.IsNullOrEmpty(Parameters))
{
_parameters = Parameters;

View File

@ -7,9 +7,9 @@ namespace Oqtane.Services
public interface IThemeService
{
Task<List<Theme>> GetThemesAsync();
Dictionary<string, string> GetThemeTypes(List<Theme> themes);
Dictionary<string, string> GetPaneLayoutTypes(List<Theme> themes, string themeName);
Dictionary<string, string> GetContainerTypes(List<Theme> themes);
List<ThemeControl> GetThemeControls(List<Theme> themes);
List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName);
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
Task InstallThemesAsync();
Task DeleteThemeAsync(string themeName);
}

View File

@ -26,46 +26,21 @@ namespace Oqtane.Services
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>();
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;
return themes.SelectMany(item => item.Themes).ToList();
}
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>();
foreach (Theme theme in themes)
{
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;
return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName)))
.SelectMany(item => item.Layouts).ToList();
}
public Dictionary<string, string> GetContainerTypes(List<Theme> themes)
public List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName)
{
var selectableContainers = new Dictionary<string, string>();
foreach (Theme theme in themes)
{
foreach (string container in theme.ContainerControls.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{
selectableContainers.Add(container, theme.Name + " - " + @Utilities.GetTypeNameLastSegment(container, 0));
}
}
return selectableContainers;
return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName)))
.SelectMany(item => item.Containers).ToList();
}
public async Task InstallThemesAsync()

View File

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

View File

@ -32,7 +32,7 @@
</div>
</div>
<hr class="app-rule"/>
<hr class="app-rule" />
<div class="row">
<div class="col text-center">
@ -50,6 +50,21 @@
<button class="btn btn-danger btn-block mx-auto" @onclick="ConfirmDelete">Delete</button>
</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)
@ -74,7 +89,7 @@
</div>
</div>
}
<hr class="app-rule"/>
<hr class="app-rule" />
<div class="row">
<div class="col text-center">
@ -142,34 +157,36 @@
<div class="row">
<div class="col text-center">
<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 class="row">
<div class="col text-center">
<label for="Pane" class="control-label">Pane: </label>
<select class="form-control" @bind="@Pane">
<option value="">&lt;Select Pane&gt;</option>
@foreach (string pane in PageState.Page.Panes)
{
<option value="@pane">@pane Pane</option>
}
</select>
@if (_pane.Length > 1)
{
<div class="row">
<div class="col text-center">
<label for="Pane" class="control-label">Pane: </label>
<select class="form-control" @bind="@Pane">
@foreach (string pane in PageState.Page.Panes)
{
<option value="@pane">@pane Pane</option>
}
</select>
</div>
</div>
</div>
}
<div class="row">
<div class="col text-center">
<label for="Container" class="control-label">Container: </label>
<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>
</div>
</div>
<br/>
<br />
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">Add Module To Page</button>
@((MarkupString) Message)
@ -218,7 +235,7 @@
private List<ModuleDefinition> _moduleDefinitions;
private List<Page> _pages = new List<Page>();
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 _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 Pane { get; private set; } = "";
protected string Title { get; private set; } = "";
protected string ContainerType { get; private set; } = "";
protected string Message { get; private set; } = "";
[Parameter]
public string ButtonClass { get; set; }
public string ButtonClass { get; set; } = "btn-outline-secondary";
[Parameter]
public string CardClass { get; set; }
public string CardClass { get; set; } = "card border-secondary mb-3";
[Parameter]
public string HeaderClass { get; set; }
public string HeaderClass { get; set; } = "card-header";
[Parameter]
public string BodyClass { get; set; }
public string BodyClass { get; set; } = "card-body";
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))
{
_pages?.Clear();
@ -298,15 +309,11 @@
}
await LoadSettingsAsync();
var panes = PageState.Page.Panes;
Pane = panes.Count() == 1 ? panes.SingleOrDefault() : "";
var themes = await ThemeService.GetThemesAsync();
_containers = ThemeService.GetContainerTypes(themes);
_containers = ThemeService.GetContainerControls(themes, PageState.Page.ThemeType);
ContainerType = PageState.Site.DefaultContainerType;
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
}
}
@ -456,7 +463,7 @@
switch (location)
{
case "Admin":
// get admin dashboard moduleid
// get admin dashboard moduleid
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.AdminDashboardModule);
if (module != null)
@ -468,7 +475,7 @@
case "Add":
case "Edit":
string url = "";
// get page management moduleid
// get page management moduleid
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.PageManagementModule);
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()
{
_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()
{
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()
{
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);
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Oqtane.Models;
@ -16,6 +17,7 @@ namespace Oqtane.Themes.Controls
{
[Inject] public NavigationManager NavigationManager { get; set; }
[Inject] public IPageModuleService PageModuleService { get; set; }
[Inject] public IModuleService ModuleService { get; set; }
protected List<ActionViewModel> Actions;
@ -30,14 +32,23 @@ namespace Oqtane.Themes.Controls
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)});
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 != "")
{
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 = "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 = ""});
if (ModuleState.PaneModuleIndex > 0)
@ -121,6 +132,42 @@ namespace Oqtane.Themes.Controls
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)
{
pagemodule.Order = 0;

View File

@ -2,5 +2,7 @@
{
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
{
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
{
public class LayoutBase : ComponentBase, ILayoutControl
public abstract class LayoutBase : ComponentBase, ILayoutControl
{
[CascadingParameter]
protected PageState PageState { get; set; }
public virtual string Name { get; set; }
public virtual string Thumbnail { get; set; }
public virtual string Panes { get; set; }
public string LayoutPath()

View File

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

View File

@ -17,6 +17,8 @@
</main>
@code {
public override string Name => "Default";
public override string Panes => string.Empty;
public override List<Resource> Resources => new List<Resource>()

View File

@ -14,5 +14,7 @@
</div>
@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 />
}
<ModuleInstance />
</div>
</div>
@code {
public override string Name => "No Header";
}

View File

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

View File

@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace Oqtane.Themes
{
public class ThemeBase : ComponentBase, IThemeControl
public abstract class ThemeBase : ComponentBase, IThemeControl
{
[Inject]
protected IJSRuntime JSRuntime { get; set; }
@ -17,6 +17,8 @@ namespace Oqtane.Themes
[CascadingParameter]
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 List<Resource> Resources { get; set; }

View File

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

View File

@ -27,18 +27,13 @@
DynamicComponent = builder =>
{
Type containerType = Type.GetType(container);
if (containerType != null)
if (containerType == null)
{
builder.OpenComponent(0, containerType);
builder.CloseComponent();
}
else
{
// container does not exist with type specified
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageComponent));
builder.AddAttribute(1, "Message", "Error Loading Module Container " + container);
builder.CloseComponent();
// fallback
containerType = Type.GetType(Constants.DefaultContainer);
}
builder.OpenComponent(0, containerType);
builder.CloseComponent();
};
}
}

View File

@ -204,5 +204,35 @@ namespace Oqtane.UI
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 =>
{
var layoutType = Type.GetType(PageState.Page.LayoutType);
if (layoutType != null)
if (layoutType == null)
{
builder.OpenComponent(0, layoutType);
builder.CloseComponent();
}
else
{
// layout does not exist with type specified
// fallback
layoutType = Type.GetType(Constants.DefaultLayout);
}
builder.OpenComponent(0, layoutType);
builder.CloseComponent();
};
}
}

View File

@ -90,7 +90,7 @@
// parse querystring
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"))
{
reload = Reload.Site;

View File

@ -66,18 +66,13 @@
DynamicComponent = builder =>
{
var themeType = Type.GetType(PageState.Page.ThemeType);
if (themeType != null)
if (themeType == null)
{
builder.OpenComponent(0, themeType);
builder.CloseComponent();
}
else
{
// theme does not exist with type specified
builder.OpenComponent(0, Type.GetType(Constants.ModuleMessageComponent));
builder.AddAttribute(1, "Message", "Error Loading Page Theme " + PageState.Page.ThemeType);
builder.CloseComponent();
// fallback
themeType = Type.GetType(Constants.DefaultTheme);
}
builder.OpenComponent(0, themeType);
builder.CloseComponent();
};
}

View File

@ -9,6 +9,9 @@ using System.IO;
using System.Reflection;
using System.Linq;
using System.IO.Compression;
using Oqtane.Modules;
using Oqtane.Themes;
using System.Diagnostics;
namespace Oqtane.Controllers
{
@ -70,8 +73,27 @@ namespace Oqtane.Controllers
// get list of assemblies which should be downloaded to browser
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
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
string binfolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
@ -90,6 +112,7 @@ namespace Oqtane.Controllers
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")))
{
entry = archive.CreateEntry(file + ".pdb");

View File

@ -169,8 +169,8 @@ namespace Oqtane.Controllers
page.DefaultContainerType = parent.DefaultContainerType;
page.Icon = parent.Icon;
page.Permissions = new List<Permission> {
new Permission(PermissionNames.View, userid, true),
new Permission(PermissionNames.Edit, userid, true)
new Permission(PermissionNames.View, int.Parse(userid), true),
new Permission(PermissionNames.Edit, int.Parse(userid), true)
}.EncodePermissions();
page.IsPersonalizable = false;
page.UserId = int.Parse(userid);
@ -187,8 +187,8 @@ namespace Oqtane.Controllers
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
module.AllPages = false;
module.Permissions = new List<Permission> {
new Permission(PermissionNames.View, userid, true),
new Permission(PermissionNames.Edit, userid, true)
new Permission(PermissionNames.View, int.Parse(userid), true),
new Permission(PermissionNames.Edit, int.Parse(userid), true)
}.EncodePermissions();
module = _modules.AddModule(module);

View File

@ -57,7 +57,7 @@ namespace Oqtane.Controllers
user.SiteId = int.Parse(siteid);
user.Roles = GetUserRoles(user.UserId, user.SiteId);
}
return user;
return Filter(user);
}
// GET api/<controller>/name/x?siteid=x
@ -70,6 +70,29 @@ namespace Oqtane.Controllers
user.SiteId = int.Parse(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;
}

View File

@ -25,9 +25,9 @@ namespace Oqtane.Controllers
_logger = logger;
}
// GET: api/<controller>?userid=x
// GET: api/<controller>?siteid=x
[HttpGet]
[Authorize]
[Authorize(Roles = Constants.AdminRole)]
public IEnumerable<UserRole> Get(string siteid)
{
return _userRoles.GetUserRoles(int.Parse(siteid));
@ -35,7 +35,7 @@ namespace Oqtane.Controllers
// GET api/<controller>/5
[HttpGet("{id}")]
[Authorize]
[Authorize(Roles = Constants.AdminRole)]
public UserRole Get(int id)
{
return _userRoles.GetUserRole(id);

View File

@ -69,7 +69,7 @@ namespace Oqtane.Infrastructure
mailMessage.Subject = notification.Subject;
if (notification.FromUserId != null)
{
mailMessage.Body = "From: " + notification.FromUser.DisplayName + "<" + notification.FromUser.Email + ">" + "\n";
mailMessage.Body = "From: " + notification.FromDisplayName + "<" + notification.FromEmail + ">" + "\n";
}
else
{
@ -78,8 +78,8 @@ namespace Oqtane.Infrastructure
mailMessage.Body += "Sent: " + notification.CreatedOn + "\n";
if (notification.ToUserId != null)
{
mailMessage.To.Add(new MailAddress(notification.ToUser.Email, notification.ToUser.DisplayName));
mailMessage.Body += "To: " + notification.ToUser.DisplayName + "<" + notification.ToUser.Email + ">" + "\n";
mailMessage.To.Add(new MailAddress(notification.ToEmail, notification.ToDisplayName));
mailMessage.Body += "To: " + notification.ToDisplayName + "<" + notification.ToEmail + ">" + "\n";
}
else
{

View File

@ -193,11 +193,7 @@ namespace Oqtane.Repository
foreach (Type modulecontroltype in modulecontroltypes)
{
// Check if type should be ignored
if (modulecontroltype.Name == "ModuleBase"
|| modulecontroltype.IsGenericType
|| modulecontroltype.IsAbstract
|| modulecontroltype.IsOqtaneIgnore()
) continue;
if (modulecontroltype.IsOqtaneIgnore()) continue;
// create namespace root typename
string qualifiedModuleType = modulecontroltype.Namespace + ", " + modulecontroltype.Assembly.GetName().Name;

View File

@ -21,8 +21,6 @@ namespace Oqtane.Repository
return _db.Notification
.Where(item => item.SiteId == siteId)
.Where(item => item.IsDelivered == false)
.Include(item => item.FromUser)
.Include(item => item.ToUser)
.ToList();
}
@ -30,8 +28,6 @@ namespace Oqtane.Repository
.Where(item => item.SiteId == siteId)
.Where(item => item.ToUserId == toUserId || toUserId == -1)
.Where(item => item.FromUserId == fromUserId || fromUserId == -1)
.Include(item => item.FromUser)
.Include(item => item.ToUser)
.ToList();
}

View File

@ -50,10 +50,7 @@ namespace Oqtane.Repository
foreach (Type themeControlType in themeControlTypes)
{
// Check if type should be ignored
if (themeControlType.Name == "ThemeBase"
|| themeControlType.IsGenericType
|| themeControlType.IsAbstract
|| themeControlType.IsOqtaneIgnore()
if (themeControlType.IsOqtaneIgnore()
) continue;
// create namespace root typename
@ -87,26 +84,41 @@ namespace Oqtane.Repository
}
// set internal properties
theme.ThemeName = qualifiedThemeType;
theme.ThemeControls = "";
theme.PaneLayouts = "";
theme.ContainerControls = "";
theme.Themes = new List<ThemeControl>();
theme.Layouts = new List<ThemeControl>();
theme.Containers = new List<ThemeControl>();
theme.AssemblyName = assembly.FullName.Split(",")[0];
themes.Add(theme);
index = themes.FindIndex(item => item.ThemeName == qualifiedThemeType);
}
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
Type[] layouttypes = themeTypes
.Where(item => item.GetInterfaces().Contains(typeof(ILayoutControl))).ToArray();
foreach (Type layouttype in layouttypes)
{
string panelayout = layouttype.FullName + ", " + themeControlType.Assembly.GetName().Name + ";";
if (!theme.PaneLayouts.Contains(panelayout))
{
theme.PaneLayouts += panelayout;
}
var layoutobject = Activator.CreateInstance(layouttype) as ILayoutControl;
theme.Layouts.Add(
new ThemeControl
{
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
@ -114,11 +126,16 @@ namespace Oqtane.Repository
.Where(item => item.GetInterfaces().Contains(typeof(IContainerControl))).ToArray();
foreach (Type containertype in containertypes)
{
string container = containertype.FullName + ", " + themeControlType.Assembly.GetName().Name + ";";
if (!theme.ContainerControls.Contains(container))
{
theme.ContainerControls += container;
}
var containerobject = Activator.CreateInstance(containertype) as IContainerControl;
theme.Containers.Add(
new ThemeControl
{
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;

View File

@ -31,3 +31,9 @@ CREATE UNIQUE NONCLUSTERED INDEX IX_File ON [dbo].[File]
[Name]
) ON [PRIMARY]
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.
app.UseHsts();
}
// to allow install middleware it should be moved up
app.ConfigureOqtaneAssemblies(env);
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseBlazorFrameworkFiles();
@ -240,7 +242,7 @@ namespace Oqtane
endpoints.MapControllers();
endpoints.MapFallbackToPage("/_Host");
});
app.ConfigureOqtaneAssemblies(env);
}
}
}

View File

@ -11,7 +11,8 @@ namespace [Owner].[Module]s
Description = "[Module]",
Version = "1.0.0",
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;
}
if (crossorigin !== "") {
script.crossorigin = crossorigin;
script.crossOrigin = crossorigin;
}
}
else {
@ -311,5 +311,15 @@ Oqtane.Interop = {
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()
//.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)
{
return assembly.GetTypes(typeof(T));
}
public static IEnumerable<T> GetInstances<T>(this Assembly assembly) where T : class
{
if (assembly is null)
@ -51,7 +51,7 @@ namespace System.Reflection
}
var type = typeof(T);
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)
{
@ -80,9 +80,14 @@ namespace System.Reflection
.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)
{
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
{
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
}
}

View File

@ -8,7 +8,10 @@ namespace Oqtane.Models
public int NotificationId { get; set; }
public int SiteId { get; set; }
public int? FromUserId { get; set; }
public string FromDisplayName { get; set; }
public string FromEmail { get; set; }
public int? ToUserId { get; set; }
public string ToDisplayName { get; set; }
public string ToEmail { get; set; }
public int? ParentId { get; set; }
public string Subject { get; set; }
@ -19,11 +22,6 @@ namespace Oqtane.Models
public string DeletedBy { get; set; }
public DateTime? DeletedOn { 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
{
@ -23,9 +24,16 @@ namespace Oqtane.Models
public string Contact { get; set; }
public string License { 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 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; }
}
}