Compare commits
284 Commits
Author | SHA1 | Date | |
---|---|---|---|
6bcb769fe5 | |||
90110a653c | |||
3c561cc413 | |||
73f9622ba2 | |||
cf198ff781 | |||
648fc56495 | |||
ea6dc6b983 | |||
c0e8d09ce1 | |||
a471784cf3 | |||
1d2a4bf484 | |||
3fa620f3bc | |||
35f186b532 | |||
5cf35fd70a | |||
1eef08eaeb | |||
1750f28a9f | |||
41edbc5e22 | |||
04257f75e7 | |||
5fb602f733 | |||
94f0bdcce9 | |||
0ba24f9a3a | |||
aac7d6b97a | |||
bcc33af52b | |||
24fd42636a | |||
8d539d058c | |||
abda377f6f | |||
51bf822392 | |||
d3f135a9c7 | |||
07ba99cc41 | |||
336550c571 | |||
679cc04178 | |||
75fe4e7c89 | |||
410f8c74e5 | |||
05f67d6a2a | |||
3a6cde0e24 | |||
fe1de2b243 | |||
62a6b5f28a | |||
d648fa0f02 | |||
e706e8cf1f | |||
9eb8a7e65c | |||
11c610edf0 | |||
a65cdbd7ad | |||
97c56ba142 | |||
9fe72a1c98 | |||
7b40725534 | |||
5e1671afe3 | |||
50d74cbcee | |||
bc73e5e3d0 | |||
b02bdee8cb | |||
9db4985b14 | |||
6f281c256b | |||
807252c9e5 | |||
23e7f66188 | |||
57c500f4bc | |||
fe302aa9e4 | |||
f14f927df7 | |||
c3f74a5217 | |||
457d1bb563 | |||
25918056cb | |||
86517dd793 | |||
00ce083a2c | |||
bce262cd8e | |||
b5db62ef6a | |||
3703d87d50 | |||
f515def414 | |||
4bdf20822f | |||
49f4e64cb4 | |||
e615263706 | |||
2a7e256116 | |||
a083405b48 | |||
3ea280c82a | |||
192433f02d | |||
56a2e9dcea | |||
921cced1c8 | |||
b17f679f38 | |||
8e43fcab21 | |||
73c5092e46 | |||
56537e4785 | |||
3bd7d7196d | |||
7b5a192b82 | |||
d4be058d07 | |||
6c20fea46a | |||
2e7cfefb2e | |||
038894cf64 | |||
954e30d89f | |||
93d9c4534d | |||
468ca8c6a9 | |||
e7a4c08dea | |||
69d639ee42 | |||
a780569a6f | |||
568c283efd | |||
fccdd07a08 | |||
5e816ea912 | |||
cb2d529689 | |||
c5037e7084 | |||
fdc39d57fb | |||
4960e2c668 | |||
66cc3a1392 | |||
6e7c8e7b05 | |||
727b943fa3 | |||
a4a0334ec0 | |||
9ea5da525b | |||
fa15a5e44b | |||
35d037bbf4 | |||
e8387103f1 | |||
16965fd027 | |||
f81ef89c61 | |||
6034a161e7 | |||
ff23865711 | |||
3ac4116a84 | |||
65df0549fd | |||
04ffb079ea | |||
99d99ca6ad | |||
0659fc53b7 | |||
2febd81b4a | |||
0f814bfefe | |||
120066fce1 | |||
f4ca525bb5 | |||
5dced08f7a | |||
882412b8ff | |||
563345638a | |||
20b83c8809 | |||
7d89670930 | |||
40571bfb6e | |||
5a7a47ef27 | |||
ee5553ad8a | |||
ab8a1e7324 | |||
9e633d2d6d | |||
975e7217a5 | |||
95053d8671 | |||
61498862b5 | |||
a57e25d3d3 | |||
7cd18b1fe1 | |||
0636227284 | |||
d4d12b6f41 | |||
7c24bae753 | |||
06480d9a7e | |||
71b3b695fc | |||
db6d5d2b64 | |||
7d7e8e9e66 | |||
354382a580 | |||
288cad3d3f | |||
597a935cac | |||
1e4b2404c4 | |||
048d8f1b87 | |||
ec416a7fef | |||
c8630d7b05 | |||
42696eacbd | |||
b668a5d0ae | |||
4285603563 | |||
1c0d24ac25 | |||
4e6b4a20ef | |||
ea89cc1a64 | |||
79622819aa | |||
88e3a9adc3 | |||
f0c95c46c9 | |||
1a0e8f7e19 | |||
b5d4f8b176 | |||
8053cc0af6 | |||
134f21e29c | |||
a67330dbbb | |||
06820b9b63 | |||
f5d47a0308 | |||
937ae32a9e | |||
5124dea72c | |||
2ceeb25d0e | |||
e2732d83bd | |||
3e56e9cc04 | |||
836c4505b9 | |||
ef5ae77060 | |||
86b7fe193f | |||
3503f20255 | |||
51b69e05fb | |||
095a95a3a9 | |||
8d17153686 | |||
6efbeeb2b4 | |||
af1aab5b8d | |||
f854b948ce | |||
7b9cd39cb7 | |||
6f6f2b77d7 | |||
ed2822ac7c | |||
41348b285d | |||
5b0da056b4 | |||
2d079bdc06 | |||
aed71fbf96 | |||
4ebdf5721c | |||
99cad13890 | |||
4edb3f32f0 | |||
01a3b7ed95 | |||
c79199357e | |||
e24c6fc235 | |||
cdc4de432a | |||
5544d2bed3 | |||
aa4b00c900 | |||
c4f1d37421 | |||
c6b22d660b | |||
ec11587b28 | |||
1b7ca45d4a | |||
01491b063d | |||
4142cc63e7 | |||
20dc749d05 | |||
4144be5323 | |||
27a3ac8d1c | |||
f45cb8b069 | |||
0cc325ee95 | |||
7d21cfefc1 | |||
652d46f64a | |||
be4813d9c0 | |||
fe92d3d74f | |||
833ea9461a | |||
47a917a3df | |||
cb484665ca | |||
64b0c2f128 | |||
6402723d2a | |||
b1a007491f | |||
17ef268594 | |||
58d97dd731 | |||
ee3a4d1624 | |||
f9035f8fdf | |||
3a5b6954e3 | |||
1794d54a3f | |||
7d251b20cc | |||
0f09df13b5 | |||
73763f1623 | |||
1b2c7772ef | |||
3b2583a1bd | |||
f7470e3c5b | |||
19f8b3d429 | |||
fd249a7734 | |||
d5f3b7513d | |||
2a3b7caa9f | |||
612a820dac | |||
e80f42f1d9 | |||
8b5004c628 | |||
151e37c470 | |||
e935451d93 | |||
b0af00aa47 | |||
cbbac26881 | |||
f2230dd530 | |||
963148c639 | |||
215e52e42e | |||
945d7870c0 | |||
cc40733cff | |||
795f591da2 | |||
4cab49e022 | |||
3b685fe571 | |||
97df673609 | |||
cbcec0481a | |||
2f272ef4b6 | |||
a4ed06f2fc | |||
3339690e2a | |||
e4b37c17d8 | |||
f1f07f45c6 | |||
068803615b | |||
ddbb08ea75 | |||
6ac2b64d7d | |||
93497eb776 | |||
e1b0dbcdf7 | |||
c2ddd248e4 | |||
a4ec456205 | |||
23764d1ae4 | |||
f77a8a964f | |||
c089b90659 | |||
32cd34b090 | |||
d8fca5de20 | |||
2f8a15fb89 | |||
1495a5c017 | |||
61b1b710db | |||
24579dc4d0 | |||
066ef44773 | |||
1355233b92 | |||
dc55c5b3ec | |||
ed3f07ff61 | |||
028485b653 | |||
b43d191536 | |||
43dfad38c9 | |||
6f1e930474 | |||
1d52de53a6 | |||
3aec68d9fa | |||
4dc24f4c78 | |||
a73e088abc | |||
b61446a50a | |||
31773abb01 | |||
85c491224d | |||
71f79bd90b |
2
.deployment
Normal file
2
.deployment
Normal file
@ -0,0 +1,2 @@
|
||||
[config]
|
||||
project = Oqtane.Server/Oqtane.Server.csproj
|
@ -28,7 +28,7 @@
|
||||
</table>
|
||||
<Pager Items="@_files">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
<th>Modified</th>
|
||||
<th>Type</th>
|
||||
|
@ -63,10 +63,18 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="retention-log" HelpText="What items do you want in the retention log">Retention Log (Items): </Label>
|
||||
<Label For="retention" HelpText="Number of log entries to retain for this job">Retention Log (Items): </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="retention-log" class="form-control" @bind="@_retentionHistory" />
|
||||
<input id="retention" class="form-control" @bind="@_retentionHistory" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="next" HelpText="Next execution for this job.">Next Execution: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="next" class="form-control" @bind="@_nextExecution" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -83,6 +91,7 @@
|
||||
private string _startDate = string.Empty;
|
||||
private string _endDate = string.Empty;
|
||||
private string _retentionHistory = string.Empty;
|
||||
private string _nextExecution = string.Empty;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
@ -102,6 +111,7 @@
|
||||
_startDate = (job.StartDate != null) ? job.StartDate.ToString() : string.Empty;
|
||||
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
|
||||
_retentionHistory = job.RetentionHistory.ToString();
|
||||
_nextExecution = job.NextExecution.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -140,6 +150,15 @@
|
||||
job.EndDate = DateTime.Parse(_endDate);
|
||||
}
|
||||
|
||||
if (_nextExecution == string.Empty)
|
||||
{
|
||||
job.NextExecution = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
job.NextExecution = DateTime.Parse(_nextExecution);
|
||||
}
|
||||
|
||||
job.RetentionHistory = int.Parse(_retentionHistory);
|
||||
|
||||
try
|
||||
|
@ -15,14 +15,14 @@ else
|
||||
|
||||
<Pager Items="@_jobs">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
<th>Status</th>
|
||||
<th>Frequency</th>
|
||||
<th>Next Execution</th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.JobId.ToString())" /></td>
|
||||
|
@ -22,7 +22,7 @@ else
|
||||
<td>@context.FinishDate</td>
|
||||
</Row>
|
||||
<Detail>
|
||||
<td colspan="4">@context.Notes</td>
|
||||
<td colspan="4">@((MarkupString)context.Notes)</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
@namespace Oqtane.Modules.Admin.Login
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inject IUserService UserService
|
||||
@inject IServiceProvider ServiceProvider
|
||||
|
||||
@ -96,7 +95,7 @@
|
||||
{
|
||||
await logger.LogInformation("Login Successful For Username {Username}", _username);
|
||||
// complete the login on the server so that the cookies are set correctly on SignalR
|
||||
var interop = new Interop(JsRuntime);
|
||||
var interop = new Interop(JSRuntime);
|
||||
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
|
||||
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
|
||||
|
@ -49,7 +49,7 @@ else
|
||||
{
|
||||
<Pager Items="@_logs">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Date</th>
|
||||
<th>Level</th>
|
||||
<th>Feature</th>
|
||||
|
@ -1,49 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Oqtane.Modules;
|
||||
using Oqtane.Services;
|
||||
using Oqtane.Shared;
|
||||
using [Owner].[Module]s.Models;
|
||||
|
||||
namespace [Owner].[Module]s.Services
|
||||
{
|
||||
public class [Module]Service : ServiceBase, I[Module]Service, IService
|
||||
{
|
||||
private readonly SiteState _siteState;
|
||||
|
||||
public [Module]Service(HttpClient http, SiteState siteState) : base(http)
|
||||
{
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private string Apiurl=> CreateApiUrl(_siteState.Alias, "[Module]");
|
||||
|
||||
public async Task<List<[Module]>> Get[Module]sAsync(int ModuleId)
|
||||
{
|
||||
List<[Module]> [Module]s = await GetJsonAsync<List<[Module]>>($"{Apiurl}?moduleid={ModuleId}");
|
||||
return [Module]s.OrderBy(item => item.Name).ToList();
|
||||
}
|
||||
|
||||
public async Task<[Module]> Get[Module]Async(int [Module]Id)
|
||||
{
|
||||
return await GetJsonAsync<[Module]>($"{Apiurl}/{[Module]Id}");
|
||||
}
|
||||
|
||||
public async Task<[Module]> Add[Module]Async([Module] [Module])
|
||||
{
|
||||
return await PostJsonAsync<[Module]>($"{Apiurl}?entityid={[Module].ModuleId}", [Module]);
|
||||
}
|
||||
|
||||
public async Task<[Module]> Update[Module]Async([Module] [Module])
|
||||
{
|
||||
return await PutJsonAsync<[Module]>($"{Apiurl}/{[Module].[Module]Id}?entityid={[Module].ModuleId}", [Module]);
|
||||
}
|
||||
|
||||
public async Task Delete[Module]Async(int [Module]Id)
|
||||
{
|
||||
await DeleteAsync($"{Apiurl}/{[Module]Id}");
|
||||
}
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
This is the location where static resources for third party libraries should be located ( the third party library assemblies will be included in the /lib folder ). They should be placed in subfolders which match the naming convention of the third party library. When the module package is deployed the static resource subfolders will be extracted under the web root.
|
@ -1 +0,0 @@
|
||||
This is the location where static resources such as images, style sheets, or scripts for this module will be located. Static assets can be organized in subfolders. When the module package is deployed the assets will be extracted under the web root in a folder that matches the module namespace.
|
@ -10,23 +10,23 @@
|
||||
<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 style="width: 1px"></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 +77,10 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -75,12 +75,20 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="license" HelpText="The license of the module">License: </Label>
|
||||
<Label For="license" HelpText="The module license terms">License: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="runtimes" HelpText="The Blazor runtimes which this module supports">Runtimes: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</Section>
|
||||
</TabPanel>
|
||||
@ -110,6 +118,7 @@
|
||||
private string _url = "";
|
||||
private string _contact = "";
|
||||
private string _license = "";
|
||||
private string _runtimes = "";
|
||||
private string _permissions;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
@ -139,6 +148,7 @@
|
||||
_url = moduleDefinition.Url;
|
||||
_contact = moduleDefinition.Contact;
|
||||
_license = moduleDefinition.License;
|
||||
_runtimes = moduleDefinition.Runtimes;
|
||||
_permissions = moduleDefinition.Permissions;
|
||||
_createdby = moduleDefinition.CreatedBy;
|
||||
_createdon = moduleDefinition.CreatedOn;
|
||||
|
@ -14,27 +14,27 @@ else
|
||||
|
||||
<Pager Items="@_moduleDefinitions">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<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>
|
||||
@ -55,20 +55,26 @@ else
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Modules {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Modules", MessageType.Error);
|
||||
if (_moduleDefinitions == null)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Modules {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Modules", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool UpgradeAvailable(string moduledefinitionname, string version)
|
||||
{
|
||||
var upgradeavailable = false;
|
||||
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault();
|
||||
if (package != null)
|
||||
if (_packages != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||
}
|
||||
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(moduledefinitionname)).FirstOrDefault();
|
||||
if (package != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||
}
|
||||
|
||||
}
|
||||
return upgradeavailable;
|
||||
}
|
||||
|
||||
@ -77,24 +83,27 @@ 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(), 10);
|
||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version} {Error}", moduledefinitionname, version, ex.Message);
|
||||
AddModuleMessage("Error Downloading Module", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteModule(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||
await logger.LogInformation("Module Deleted {ModuleDefinition}", moduleDefinition);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -31,9 +31,15 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
||||
StateHasChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
|
||||
if (success)
|
||||
{
|
||||
AddModuleMessage("Content Imported Successfully", MessageType.Success);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage("A Problem Was Encountered Importing Content. Please Ensure The Content Is Formatted Correctly For The Module.", MessageType.Warning);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -25,9 +25,9 @@
|
||||
<td>
|
||||
<select id="container" class="form-control" @bind="@_containerType">
|
||||
<option value="-"><Inherit From Page Or Site></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</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)
|
||||
{
|
||||
|
@ -102,41 +102,44 @@
|
||||
<td>
|
||||
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
@foreach (var theme in _themes)
|
||||
{
|
||||
if (item.Key == _themetype)
|
||||
if (theme.TypeName == _themetype)
|
||||
{
|
||||
<option value="@item.Key" selected>@item.Value</option>
|
||||
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<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="-"><Inherit From Site></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="-"><Inherit From Site></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="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
@ -159,17 +162,6 @@
|
||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Default-Mode" class="form-control" @bind="@_mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||
@ -199,10 +191,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;
|
||||
@ -214,7 +206,6 @@
|
||||
private string _isnavigation = "True";
|
||||
private string _url;
|
||||
private string _ispersonalizable = "False";
|
||||
private string _mode = "view";
|
||||
private string _themetype = "-";
|
||||
private string _layouttype = "-";
|
||||
private string _containertype = "-";
|
||||
@ -232,10 +223,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 +275,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 +299,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;
|
||||
@ -342,6 +334,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (!PagePathIsUnique(page.Path, page.SiteId, _pageList))
|
||||
{
|
||||
AddModuleMessage($"A page with path {_path} already exists for the selected parent page. The page path needs to be unique for the selected parent.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
Page child;
|
||||
switch (_insert)
|
||||
{
|
||||
@ -363,7 +361,6 @@
|
||||
|
||||
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
||||
page.Url = _url;
|
||||
page.EditMode = (_mode == "edit" ? true : false);
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
@ -403,4 +400,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
private static bool PagePathIsUnique(string pagePath, int siteId, List<Page> existingPages)
|
||||
{
|
||||
return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath);
|
||||
}
|
||||
}
|
||||
|
@ -113,41 +113,44 @@
|
||||
<td>
|
||||
<select id="Theme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
@foreach (var theme in _themes)
|
||||
{
|
||||
if (item.Key == _themetype)
|
||||
if (theme.TypeName == _themetype)
|
||||
{
|
||||
<option value="@item.Key" selected>@item.Value</option>
|
||||
<option value="@theme.TypeName" selected>@theme.Name</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<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="-"><Inherit From Site></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="-"><Inherit From Site></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="-"><Inherit From Site></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</td>
|
||||
@ -170,17 +173,6 @@
|
||||
<input id="Icon" class="form-control" @bind="@_icon" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Default-Mode" HelpText="Select the default administration mode you want for this page">Default Mode? </Label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="Default-Mode" class="form-control" @bind="@_mode">
|
||||
<option value="view">View Mode</option>
|
||||
<option value="edit">Edit Mode</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content">Personalizable? </Label>
|
||||
@ -199,23 +191,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;
|
||||
@ -229,12 +224,11 @@
|
||||
private string _isnavigation;
|
||||
private string _url;
|
||||
private string _ispersonalizable;
|
||||
private string _mode;
|
||||
private string _themetype = "-";
|
||||
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 +246,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);
|
||||
@ -285,18 +278,18 @@
|
||||
_isnavigation = page.IsNavigation.ToString();
|
||||
_url = page.Url;
|
||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
||||
_mode = (page.EditMode) ? "edit" : "view";
|
||||
_themetype = page.ThemeType;
|
||||
if (_themetype == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
_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))
|
||||
{
|
||||
@ -327,7 +320,7 @@
|
||||
_children = new List<Page>();
|
||||
if (_parentid == "-1")
|
||||
{
|
||||
foreach(Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
@ -369,12 +362,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)
|
||||
@ -423,6 +420,13 @@
|
||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PagePathIsUnique(page.Path, page.SiteId, page.PageId, _pageList))
|
||||
{
|
||||
AddModuleMessage($"A page with path {_path} already exists for the selected parent page. The page path needs to be unique for the selected parent.", MessageType.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_insert != "=")
|
||||
{
|
||||
Page child;
|
||||
@ -446,7 +450,6 @@
|
||||
}
|
||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||
page.Url = _url;
|
||||
page.EditMode = (_mode == "edit");
|
||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||
{
|
||||
@ -502,4 +505,9 @@
|
||||
AddModuleMessage("Error Saving Page", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool PagePathIsUnique(string pagePath, int siteId, int pageId, List<Page> existingPages)
|
||||
{
|
||||
return !existingPages.Any(page => page.SiteId == siteId && page.Path == pagePath && page.PageId != pageId);
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
</Header>
|
||||
<Row>
|
||||
|
@ -12,8 +12,8 @@ else
|
||||
|
||||
<Pager Items="@_profiles">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
</Header>
|
||||
<Row>
|
||||
|
@ -16,8 +16,8 @@
|
||||
{
|
||||
<Pager Items="@_pages">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
<th>Deleted By</th>
|
||||
<th>Deleted On</th>
|
||||
@ -42,8 +42,8 @@
|
||||
{
|
||||
<Pager Items="@_modules">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Page</th>
|
||||
<th>Module</th>
|
||||
<th>Deleted By</th>
|
||||
|
@ -12,9 +12,9 @@ else
|
||||
|
||||
<Pager Items="@_roles">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
</Header>
|
||||
<Row>
|
||||
|
@ -7,7 +7,7 @@
|
||||
@inject IThemeService ThemeService
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (_themes != null)
|
||||
@if (_initialized)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
@ -56,45 +56,48 @@
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
<option value="-"><Select Theme></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=""><Select Layout></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="-"><Select Layout></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=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
<option value="-"><Select Container></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,11 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
private Dictionary<string, string> _themes;
|
||||
private Dictionary<string, string> _panelayouts;
|
||||
private Dictionary<string, string> _containers;
|
||||
private bool _initialized = false;
|
||||
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 +225,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 +275,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();
|
||||
|
||||
@ -313,10 +319,9 @@
|
||||
_deletedby = site.DeletedBy;
|
||||
_deletedon = site.DeletedOn;
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
}
|
||||
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -330,14 +335,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 +360,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 +385,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));
|
||||
|
@ -38,38 +38,41 @@ else
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
<option value="-"><Select Theme></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=""><Select Layout></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="-"><Select Layout></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=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
<option value="-"><Select Container></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=""><Select Site Template></option>
|
||||
<option value="-"><Select Site Template></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();
|
||||
|
@ -6,7 +6,7 @@
|
||||
@inject IAliasService AliasService
|
||||
@inject IThemeService ThemeService
|
||||
|
||||
@if (_themes != null)
|
||||
@if (_initialized)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
@ -39,45 +39,48 @@
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
|
||||
<option value=""><Select Theme></option>
|
||||
@foreach (KeyValuePair<string, string> item in _themes)
|
||||
<option value="-"><Select Theme></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=""><Select Layout></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="-"><Select Layout></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=""><Select Container></option>
|
||||
@foreach (KeyValuePair<string, string> container in _containers)
|
||||
<option value="-"><Select Container></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,12 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
private Dictionary<string, string> _themes;
|
||||
private Dictionary<string, string> _panelayouts;
|
||||
private Dictionary<string, string> _containers;
|
||||
private Alias _alias;
|
||||
private bool _initialized = false;
|
||||
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 +151,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;
|
||||
@ -158,10 +164,9 @@
|
||||
_deletedby = site.DeletedBy;
|
||||
_deletedon = site.DeletedOn;
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
}
|
||||
|
||||
_themes = ThemeService.GetThemeTypes(_themeList);
|
||||
_containers = ThemeService.GetContainerTypes(_themeList);
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -175,15 +180,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 +205,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))
|
||||
|
@ -14,8 +14,8 @@ else
|
||||
|
||||
<Pager Items="@_sites">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
</Header>
|
||||
<Row>
|
||||
|
@ -11,8 +11,8 @@ else
|
||||
{
|
||||
<Pager Items="@tenants">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>Name</th>
|
||||
</Header>
|
||||
<Row>
|
||||
|
@ -7,43 +7,43 @@
|
||||
|
||||
@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 style="width: 1px;"></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 +77,10 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ThemeService.InstallThemesAsync();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -101,4 +103,4 @@
|
||||
AddModuleMessage("Error Downloading Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
@namespace Oqtane.Modules.Admin.Themes
|
||||
@using System.Net
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IThemeService ThemeService
|
||||
@inject IPackageService PackageService
|
||||
|
||||
@if (themes == null)
|
||||
@if (_themes == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
@ -12,68 +13,103 @@ else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Install Theme" />
|
||||
|
||||
<Pager Items="@themes">
|
||||
<Pager Items="@_themes">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th>Name</th>
|
||||
<th>Version</th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Version</th>
|
||||
<th> </th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" /></td>
|
||||
<td>
|
||||
@if (context.AssemblyName != "Oqtane.Client")
|
||||
{
|
||||
{
|
||||
<ActionDialog Header="Delete Theme" Message="@("Are You Sure You Wish To Delete The " + context.Name + " Theme?")" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTheme(context))" />
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
@if (UpgradeAvailable(context.ThemeName, context.Version))
|
||||
{
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.ThemeName, context.Version))>Upgrade</button>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td></td>
|
||||
</Row>
|
||||
</Pager>
|
||||
}
|
||||
|
||||
@code {
|
||||
private List<Theme> themes;
|
||||
private List<Package> packages;
|
||||
private List<Theme> _themes;
|
||||
private List<Package> _packages;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
themes = await ThemeService.GetThemesAsync();
|
||||
packages = await PackageService.GetPackagesAsync("module");
|
||||
try
|
||||
{
|
||||
_themes = await ThemeService.GetThemesAsync();
|
||||
_packages = await PackageService.GetPackagesAsync("theme");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (_themes == null)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Themes {Error}", ex.Message);
|
||||
AddModuleMessage("Error Loading Themes", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool UpgradeAvailable(string themename, string version)
|
||||
{
|
||||
var upgradeavailable = false;
|
||||
var package = packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault();
|
||||
if (package != null)
|
||||
if (_packages != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||
var package = _packages.Where(item => item.PackageId == Utilities.GetTypeName(themename)).FirstOrDefault();
|
||||
if (package != null)
|
||||
{
|
||||
upgradeavailable = (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
return upgradeavailable;
|
||||
}
|
||||
|
||||
private async Task DownloadTheme(string themename, string version)
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(themename, version, "Themes");
|
||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
||||
await ThemeService.InstallThemesAsync();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
try
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(themename, version, "Themes");
|
||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", themename, version);
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ThemeService.InstallThemesAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Theme {ThemeName} {Version} {Error}", themename, version, ex.Message);
|
||||
AddModuleMessage("Error Downloading Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteTheme(Theme Theme)
|
||||
{
|
||||
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
||||
await logger.LogInformation("Theme Deleted {Theme}", Theme);
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Theme {Theme} {Error}", Theme, ex.Message);
|
||||
AddModuleMessage("Error Deleting Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
101
Oqtane.Client/Modules/Admin/Themes/View.razor
Normal file
101
Oqtane.Client/Modules/Admin/Themes/View.razor
Normal file
@ -0,0 +1,101 @@
|
||||
@namespace Oqtane.Modules.Admin.Themes
|
||||
@using System.Net
|
||||
@inherits ModuleBase
|
||||
@inject IThemeService ThemeService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="name" HelpText="The name of the theme">Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="name" class="form-control" @bind="@_name" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="themename" HelpText="The internal name of the module">Internal Name: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="themename" class="form-control" @bind="@_themeName" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="version" HelpText="The version of the thene">Version: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="owner" HelpText="The owner or creator of the theme">Owner: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="url" HelpText="The reference url of the theme">Reference Url: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="contact" HelpText="The contact for the theme">Contact: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<Label For="license" HelpText="The license of the theme">License: </Label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
|
||||
@code {
|
||||
private string _themeName = "";
|
||||
private string _name;
|
||||
private string _version;
|
||||
private string _owner = "";
|
||||
private string _url = "";
|
||||
private string _contact = "";
|
||||
private string _license = "";
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_themeName = WebUtility.UrlDecode(PageState.QueryString["name"]);
|
||||
var themes = await ThemeService.GetThemesAsync();
|
||||
var theme = themes.FirstOrDefault(item => item.ThemeName == _themeName);
|
||||
if (theme != null)
|
||||
{
|
||||
_name = theme.Name;
|
||||
_version = theme.Version;
|
||||
_owner = theme.Owner;
|
||||
_url = theme.Url;
|
||||
_contact = theme.Contact;
|
||||
_license = theme.License;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
|
||||
AddModuleMessage("Error Loading Theme", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
@ -7,32 +7,32 @@
|
||||
|
||||
@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" ShowFiles="false" 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>
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>Upgrade To @_package.Version</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" ShowFiles="false" Folder="Framework" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button type="button" class="btn btn-success" @onclick="Upgrade">Install</button>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
}
|
||||
|
||||
@code {
|
||||
@ -43,28 +43,58 @@
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
List<Package> packages = await PackageService.GetPackagesAsync("framework");
|
||||
_package = packages.FirstOrDefault();
|
||||
if (_package != null)
|
||||
try
|
||||
{
|
||||
_upgradeavailable = (Version.Parse(_package.Version).CompareTo(Version.Parse(Constants.Version)) > 0);
|
||||
List<Package> packages = await PackageService.GetPackagesAsync("framework");
|
||||
if (packages != null)
|
||||
{
|
||||
_package = packages.FirstOrDefault();
|
||||
if (_package != null)
|
||||
{
|
||||
_upgradeavailable = (Version.Parse(_package.Version).CompareTo(Version.Parse(Constants.Version)) > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
catch
|
||||
{
|
||||
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
||||
// can be caused by no network connection
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Upgrade()
|
||||
{
|
||||
await InstallationService.Upgrade();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await InstallationService.Upgrade();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Executing Upgrade {Error}", ex.Message);
|
||||
AddModuleMessage("Error Executing Upgrade", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Download(string packageid, string version)
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
||||
await InstallationService.Upgrade();
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
try
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(packageid, version, "Framework");
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await InstallationService.Upgrade();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Framework {Error}", ex.Message);
|
||||
AddModuleMessage("Error Downloading Framework", MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
@namespace Oqtane.Modules.Admin.UserProfile
|
||||
@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"><Select User></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,36 @@
|
||||
|
||||
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.SendOn = DateTime.UtcNow;
|
||||
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)
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ else
|
||||
<label for="Name" class="control-label">Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@password" />
|
||||
<input type="password" class="form-control" @bind="@password" autocomplete="new-password" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -40,7 +40,7 @@ else
|
||||
<label for="Name" class="control-label">Confirm Password: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input type="password" class="form-control" @bind="@confirm" />
|
||||
<input type="password" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -73,7 +73,7 @@ else
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Profile">
|
||||
@if (profiles != null)
|
||||
@if (profiles != null && settings != null)
|
||||
{
|
||||
<table class="table table-borderless">
|
||||
@foreach (Profile profile in profiles)
|
||||
@ -111,8 +111,8 @@ else
|
||||
{
|
||||
<Pager Items="@notifications">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>From</th>
|
||||
<th>Subject</th>
|
||||
<th>Received</th>
|
||||
@ -120,13 +120,22 @@ 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>
|
||||
<Detail>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0, 100) : context.Body)</td>
|
||||
<td colspan="3">
|
||||
@{
|
||||
string input = "___";
|
||||
if (context.Body.Contains(input)){
|
||||
context.Body = context.Body.Split(input)[0];
|
||||
context.Body = context.Body.Replace("\n", "");
|
||||
context.Body = context.Body.Replace("\r", "");
|
||||
} }
|
||||
@(context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body)
|
||||
</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
}
|
||||
@ -143,13 +152,22 @@ 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>
|
||||
<Detail>
|
||||
<td colspan="2"></td>
|
||||
<td colspan="3">@(context.Body.Length > 100 ? context.Body.Substring(0, 100) : context.Body)</td>
|
||||
<td colspan="3">
|
||||
@{
|
||||
string input = "___";
|
||||
if (context.Body.Contains(input)){
|
||||
context.Body = context.Body.Split(input)[0];
|
||||
context.Body = context.Body.Replace("\n", "");
|
||||
context.Body = context.Body.Replace("\r", "");
|
||||
} }
|
||||
@(context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body)
|
||||
</td>
|
||||
</Detail>
|
||||
</Pager>
|
||||
}
|
||||
|
@ -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,71 +9,99 @@
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">@title: </label>
|
||||
</td>
|
||||
<td>
|
||||
<select class="form-control" readonly @bind="userid">
|
||||
<option value="-1"><System></option>
|
||||
@if (userroles != null)
|
||||
{
|
||||
foreach (UserRole userrole in userroles)
|
||||
{
|
||||
<option value="@userrole.UserId">@userrole.User.DisplayName</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<label class="control-label">@title: </label>
|
||||
</td>
|
||||
@if (title == "From")
|
||||
{
|
||||
<td>
|
||||
<input class="form-control" @bind="@username" readonly />
|
||||
</td>
|
||||
}
|
||||
@if (title == "To")
|
||||
{
|
||||
<td>
|
||||
<input class="form-control" @bind="@username" />
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Subject: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@subject" />
|
||||
<label class="control-label">Subject: </label>
|
||||
</td>
|
||||
@if (title == "From")
|
||||
{
|
||||
<td>
|
||||
<input class="form-control" @bind="@subject" readonly />
|
||||
</td>
|
||||
}
|
||||
@if (title == "To")
|
||||
{
|
||||
<td>
|
||||
<input class="form-control" @bind="@subject" />
|
||||
</td>
|
||||
}
|
||||
</tr>
|
||||
@if (title == "From")
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Date: </label>
|
||||
<label class="control-label">Date: </label>
|
||||
</td>
|
||||
<td>
|
||||
<input class="form-control" @bind="@createdon" />
|
||||
<input class="form-control" @bind="@createdon" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (title == "From")
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Message: </label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@body" rows="5" readonly />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@if (title == "To")
|
||||
{
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Message: </label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@body" rows="5" />
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
<tr>
|
||||
<td>
|
||||
<label class="control-label">Message: </label>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" @bind="@body" rows="5" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@if (reply != string.Empty)
|
||||
{
|
||||
<button type="button" class="btn btn-primary" @onclick="Send">Send</button>
|
||||
}
|
||||
<button type="button" class="btn btn-primary" @onclick="Send">Send</button> }
|
||||
else
|
||||
{
|
||||
if (title == "From")
|
||||
{
|
||||
<button type="button" class="btn btn-primary" @onclick="Reply">Reply</button>
|
||||
}
|
||||
<button type="button" class="btn btn-primary" @onclick="Reply">Reply</button>}
|
||||
}
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">Cancel</NavLink>
|
||||
<br />
|
||||
<br />
|
||||
<p>@reply</p>
|
||||
}
|
||||
@if (title == "To")
|
||||
{
|
||||
<div class="control-group">
|
||||
<label class="control-label">Original Message </label>
|
||||
<textarea class="form-control" @bind="@reply" rows="5" readonly />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
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 +114,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 +132,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;
|
||||
@ -126,31 +162,45 @@
|
||||
private void Reply()
|
||||
{
|
||||
title = "To";
|
||||
subject = "RE: " + subject;
|
||||
if (!subject.Contains("RE:"))
|
||||
{
|
||||
subject = "RE: " + subject;
|
||||
}
|
||||
reply = body;
|
||||
body = "\n\n____________________________________________\nSent: " + createdon + "\nSubject: " + subject + "\n\n" + body;
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
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.SendOn = DateTime.UtcNow;
|
||||
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)
|
||||
{
|
||||
@ -158,5 +208,5 @@
|
||||
AddModuleMessage("Error Adding Notification", MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,40 +2,79 @@
|
||||
@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" />
|
||||
<ActionLink Action="Add" Text="Add User"/>
|
||||
|
||||
<div class="d-flex p-1">
|
||||
<input class="form-control mr-4" @bind="@_search"/><button class="btn btn-outline-primary ml-1" @onclick="OnSearch">Search</button>
|
||||
</div>
|
||||
|
||||
<Pager Items="@userroles">
|
||||
<Header>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<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>
|
||||
}
|
||||
|
||||
@code {
|
||||
private List<UserRole> allroles;
|
||||
private List<UserRole> userroles;
|
||||
private string _search;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
userroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
||||
userroles = userroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
||||
allroles = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId);
|
||||
await LoadSettingsAsync();
|
||||
userroles = Search(_search);
|
||||
}
|
||||
|
||||
private List<UserRole> Search(string search)
|
||||
{
|
||||
if (string.IsNullOrEmpty(_search))
|
||||
{
|
||||
return allroles.Where(item => item.Role.Name == Constants.RegisteredRole).ToList();
|
||||
}
|
||||
return allroles
|
||||
.Where(item => item.Role.Name == Constants.RegisteredRole &&
|
||||
(
|
||||
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||
item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) ||
|
||||
item.User.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase)
|
||||
)
|
||||
)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private async Task OnSearch()
|
||||
{
|
||||
userroles = Search(_search);
|
||||
await UpdateSettingsAsync();
|
||||
}
|
||||
|
||||
private async Task DeleteUser(UserRole UserRole)
|
||||
@ -56,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);
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
@if (_visible)
|
||||
{
|
||||
<div class="app-admin-modal">
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
@code {
|
||||
private bool _visible = false;
|
||||
private bool _editmode = true;
|
||||
private bool _editmode = false;
|
||||
private bool _authorized = false;
|
||||
private string _iconSpan = string.Empty;
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
public bool Disabled { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
||||
public string EditMode { get; set; } // optional - specifies if an authorized user must be in edit mode to see the action - default is false
|
||||
|
||||
[Parameter]
|
||||
public Action OnClick { get; set; } // required if an Action is specified - executes a method in the calling component
|
||||
@ -84,6 +84,7 @@
|
||||
{
|
||||
Class = "btn btn-success";
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(EditMode))
|
||||
{
|
||||
_editmode = bool.Parse(EditMode);
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@inject IUserService UserService
|
||||
|
||||
@if (_authorized)
|
||||
@ -21,7 +20,7 @@
|
||||
private string _parameters = string.Empty;
|
||||
private string _classname = "btn btn-primary";
|
||||
private string _style = string.Empty;
|
||||
private bool _editmode = true;
|
||||
private bool _editmode = false;
|
||||
private bool _authorized = false;
|
||||
private string _iconSpan = string.Empty;
|
||||
|
||||
@ -47,11 +46,14 @@
|
||||
public bool Disabled { get; set; } // optional
|
||||
|
||||
[Parameter]
|
||||
public string EditMode { get; set; } // optional - specifies if a user must be in edit mode to see the action - default is true
|
||||
public string EditMode { get; set; } // optional - specifies if an authorized user must be in edit mode to see the action - default is false.
|
||||
|
||||
[Parameter]
|
||||
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()
|
||||
{
|
||||
_text = Action;
|
||||
@ -60,6 +62,11 @@
|
||||
_text = Text;
|
||||
}
|
||||
|
||||
if (IconOnly && !string.IsNullOrEmpty(IconName))
|
||||
{
|
||||
_text = string.Empty;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(Parameters))
|
||||
{
|
||||
_parameters = Parameters;
|
||||
@ -82,7 +89,8 @@
|
||||
|
||||
if (!string.IsNullOrEmpty(IconName))
|
||||
{
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span> ";
|
||||
_iconSpan = $"<span class=\"oi oi-{IconName}\"></span>{(IconOnly ? "" : " ")}";
|
||||
|
||||
}
|
||||
|
||||
_url = EditUrl(Action, _parameters);
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
@if (_text != string.Empty)
|
||||
{
|
||||
|
@ -1,10 +1,7 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@inject IFolderService FolderService
|
||||
@inject IFileService FileService
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
@if (_folders != null)
|
||||
{
|
||||
@ -57,16 +54,16 @@
|
||||
<div>
|
||||
@if (UploadMultiple)
|
||||
{
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple/>
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple />
|
||||
}
|
||||
else
|
||||
{
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter"/>
|
||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
|
||||
}
|
||||
<span id="@_progressinfoid"></span><progress id="@_progressbarid" style="width: 150px; visibility: hidden;"></progress>
|
||||
<span class="float-right">
|
||||
<button type="button" class="btn btn-success" @onclick="UploadFile">Upload</button>
|
||||
@if (_showfiles && GetFileId() != -1)
|
||||
@if (ShowFiles && GetFileId() != -1)
|
||||
{
|
||||
<button type="button" class="btn btn-danger" @onclick="DeleteFile">Delete</button>
|
||||
}
|
||||
@ -89,7 +86,6 @@
|
||||
private string _id;
|
||||
private List<Folder> _folders;
|
||||
private List<File> _files = new List<File>();
|
||||
private bool _showfiles = true;
|
||||
private string _fileinputid = string.Empty;
|
||||
private string _progressinfoid = string.Empty;
|
||||
private string _progressbarid = string.Empty;
|
||||
@ -135,7 +131,7 @@
|
||||
|
||||
if (!string.IsNullOrEmpty(Folder))
|
||||
{
|
||||
_folders = new List<Folder> {new Folder {FolderId = -1, Name = Folder}};
|
||||
_folders = new List<Folder> { new Folder { FolderId = -1, Name = Folder } };
|
||||
FolderId = -1;
|
||||
}
|
||||
else
|
||||
@ -164,7 +160,7 @@
|
||||
|
||||
await GetFiles();
|
||||
|
||||
// create unique id for component
|
||||
// create unique id for component
|
||||
_guid = Guid.NewGuid().ToString("N");
|
||||
_fileinputid = _guid + "FileInput";
|
||||
_progressinfoid = _guid + "ProgressInfo";
|
||||
@ -212,7 +208,7 @@
|
||||
_message = string.Empty;
|
||||
try
|
||||
{
|
||||
FolderId = int.Parse((string) e.Value);
|
||||
FolderId = int.Parse((string)e.Value);
|
||||
await GetFiles();
|
||||
FileId = -1;
|
||||
_image = string.Empty;
|
||||
@ -228,7 +224,7 @@
|
||||
private async Task FileChanged(ChangeEventArgs e)
|
||||
{
|
||||
_message = string.Empty;
|
||||
FileId = int.Parse((string) e.Value);
|
||||
FileId = int.Parse((string)e.Value);
|
||||
|
||||
await SetImage();
|
||||
StateHasChanged();
|
||||
@ -245,8 +241,8 @@
|
||||
var maxwidth = 200;
|
||||
var maxheight = 200;
|
||||
|
||||
var ratioX = (double) maxwidth / (double) file.ImageWidth;
|
||||
var ratioY = (double) maxheight / (double) file.ImageHeight;
|
||||
var ratioX = (double)maxwidth / (double)file.ImageWidth;
|
||||
var ratioY = (double)maxheight / (double)file.ImageHeight;
|
||||
var ratio = ratioX < ratioY ? ratioX : ratioY;
|
||||
|
||||
_image = "<img src=\"" + ContentUrl(FileId) + "\" alt=\"" + file.Name +
|
||||
@ -258,7 +254,7 @@
|
||||
|
||||
private async Task UploadFile()
|
||||
{
|
||||
var interop = new Interop(JsRuntime);
|
||||
var interop = new Interop(JSRuntime);
|
||||
var upload = await interop.GetFiles(_fileinputid);
|
||||
if (upload.Length > 0)
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
@if (!string.IsNullOrEmpty(HelpText))
|
||||
{
|
||||
|
@ -1,10 +1,16 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@if (!string.IsNullOrEmpty(_message))
|
||||
{
|
||||
<div class="@_classname" role="alert">@_message</div>
|
||||
<div class="@_classname" role="alert">
|
||||
@_message
|
||||
@if (Type == MessageType.Error && UserSecurity.IsAuthorized(PageState.User, Constants.HostRole))
|
||||
{
|
||||
@((MarkupString)" ")<NavLink href="@NavigateUrl("admin/log")">View Details</NavLink>
|
||||
}
|
||||
</div>
|
||||
<br />
|
||||
}
|
||||
|
||||
|
@ -1,41 +1,39 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@typeparam TableItem
|
||||
|
||||
|
||||
<p>
|
||||
@if(Format == "Table")
|
||||
@if (Format == "Table")
|
||||
{
|
||||
<table class="@Class">
|
||||
<thead>
|
||||
<tr>@Header</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<table class="@Class">
|
||||
<thead>
|
||||
<tr>@Header</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var item in ItemList)
|
||||
{
|
||||
<tr>@Row(item)</tr>
|
||||
@if (Detail != null)
|
||||
{
|
||||
<tr>@Detail(item)</tr>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
@if (Format == "Grid")
|
||||
{
|
||||
<div class="@Class">
|
||||
<div class="row">@Header</div>
|
||||
@foreach (var item in ItemList)
|
||||
{
|
||||
<tr>@Row(item)</tr>
|
||||
<div class="row">@Row(item)</div>
|
||||
@if (Detail != null)
|
||||
{
|
||||
<tr>@Detail(item)</tr>
|
||||
<div class="row">@Detail(item)</div>
|
||||
}
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
@if(Format == "Grid")
|
||||
{
|
||||
<div class="@Class">
|
||||
<div class="row">@Header</div>
|
||||
@foreach (var item in ItemList)
|
||||
{
|
||||
<div class="row">@Row(item)</div>
|
||||
@if (Detail != null)
|
||||
{
|
||||
<div class="row">@Detail(item)</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="mx-auto text-center">
|
||||
@if (_page > _maxPages)
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
@inject IRoleService RoleService
|
||||
@inject IUserService UserService
|
||||
|
||||
@ -10,10 +9,10 @@
|
||||
<table class="table" style="width: 50%; min-width: 250px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Role</th>
|
||||
<th scope="col">Role</th>
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
<th style="text-align: center;">@permission.PermissionName</th>
|
||||
<th style="text-align: center; width: 1px;">@permission.PermissionName</th>
|
||||
}
|
||||
</tr>
|
||||
@foreach (Role role in _roles)
|
||||
@ -36,10 +35,10 @@
|
||||
<table class="table" style="width: 50%; min-width: 250px;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<th scope="col">User</th>
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
<th style="text-align: center;">@permission.PermissionName</th>
|
||||
<th style="text-align: center; width: 1px;">@permission.PermissionName</th>
|
||||
}
|
||||
</tr>
|
||||
</thead>
|
||||
@ -52,7 +51,7 @@
|
||||
@foreach (PermissionString permission in _permissions)
|
||||
{
|
||||
var p = permission;
|
||||
<td style="text-align: center;">
|
||||
<td style="text-align: center; width: 1px;">
|
||||
<TriStateCheckBox Value=@GetPermissionValue(p.Permissions, userid) Disabled=false OnChange="@(e => PermissionChanged(e, p.PermissionName, userid))" />
|
||||
</td>
|
||||
}
|
||||
@ -64,9 +63,10 @@
|
||||
<table class="table" style="width: 50%; min-width: 250px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="text-align: right;"><label for="Username" class="control-label">User: </label></td>
|
||||
<td><input type="text" name="Username" class="form-control" placeholder="Enter Username" @bind="@_username" /></td>
|
||||
<td style="text-align: left;"><button type="button" class="btn btn-primary" @onclick="AddUser">Add</button></td>
|
||||
<td class="input-group">
|
||||
<input type="text" name="Username" class="form-control" placeholder="Enter Username" @bind="@_username" />
|
||||
<button type="button" class="btn btn-primary" @onclick="AddUser">Add</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1,7 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<div class="row" style="margin-bottom: 50px;">
|
||||
<div class="col">
|
||||
@ -108,6 +106,13 @@
|
||||
[Parameter]
|
||||
public string DebugLevel { get; set; } = "info";
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill1.3.6.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
|
||||
};
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_content = Content; // raw HTML
|
||||
@ -117,8 +122,11 @@
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
await RichTextEditorInterop.CreateEditor(
|
||||
JsRuntime,
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
|
||||
await interop.CreateEditor(
|
||||
_editorElement,
|
||||
_toolBar,
|
||||
ReadOnly,
|
||||
@ -126,14 +134,10 @@
|
||||
Theme,
|
||||
DebugLevel);
|
||||
|
||||
await RichTextEditorInterop.LoadEditorContent(
|
||||
JsRuntime,
|
||||
_editorElement, Content);
|
||||
await interop.LoadEditorContent(_editorElement, Content);
|
||||
|
||||
// preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor )
|
||||
_original = await RichTextEditorInterop.GetHtml(
|
||||
JsRuntime,
|
||||
_editorElement);
|
||||
_original = await interop.GetHtml(_editorElement);
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,25 +150,22 @@
|
||||
|
||||
public async Task RefreshRichText()
|
||||
{
|
||||
await RichTextEditorInterop.LoadEditorContent(
|
||||
JsRuntime,
|
||||
_editorElement, _content);
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
await interop.LoadEditorContent(_editorElement, _content);
|
||||
}
|
||||
|
||||
public async Task RefreshRawHtml()
|
||||
{
|
||||
_content = await RichTextEditorInterop.GetHtml(
|
||||
JsRuntime,
|
||||
_editorElement);
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
_content = await interop.GetHtml(_editorElement);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
public async Task<string> GetHtml()
|
||||
{
|
||||
// get rich text content
|
||||
string content = await RichTextEditorInterop.GetHtml(
|
||||
JsRuntime,
|
||||
_editorElement);
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
string content = await interop.GetHtml(_editorElement);
|
||||
|
||||
if (_original != content)
|
||||
{
|
||||
@ -185,9 +186,8 @@
|
||||
var fileid = _fileManager.GetFileId();
|
||||
if (fileid != -1)
|
||||
{
|
||||
await RichTextEditorInterop.InsertImage(
|
||||
JsRuntime,
|
||||
_editorElement, ContentUrl(fileid));
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
await interop.InsertImage(_editorElement, ContentUrl(fileid));
|
||||
_filemanagervisible = false;
|
||||
_message = string.Empty;
|
||||
}
|
||||
@ -207,22 +207,19 @@
|
||||
// other rich text editor methods which can be used by developers
|
||||
public async Task<string> GetText()
|
||||
{
|
||||
return await RichTextEditorInterop.GetText(
|
||||
JsRuntime,
|
||||
_editorElement);
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
return await interop.GetText(_editorElement);
|
||||
}
|
||||
|
||||
public async Task<string> GetContent()
|
||||
{
|
||||
return await RichTextEditorInterop.GetContent(
|
||||
JsRuntime,
|
||||
_editorElement);
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
return await interop.GetContent(_editorElement);
|
||||
}
|
||||
|
||||
public async Task EnableEditor(bool mode)
|
||||
{
|
||||
await RichTextEditorInterop.EnableEditor(
|
||||
JsRuntime,
|
||||
_editorElement, mode);
|
||||
var interop = new RichTextEditorInterop(JSRuntime);
|
||||
await interop.EnableEditor(_editorElement, mode);
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,16 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.Modules.Controls
|
||||
{
|
||||
public static class RichTextEditorInterop
|
||||
public class RichTextEditorInterop
|
||||
{
|
||||
internal static ValueTask<object> CreateEditor(
|
||||
IJSRuntime jsRuntime,
|
||||
private readonly IJSRuntime _jsRuntime;
|
||||
|
||||
public RichTextEditorInterop(IJSRuntime jsRuntime)
|
||||
{
|
||||
_jsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async Task CreateEditor(
|
||||
ElementReference quillElement,
|
||||
ElementReference toolbar,
|
||||
bool readOnly,
|
||||
@ -15,66 +21,103 @@ namespace Oqtane.Modules.Controls
|
||||
string theme,
|
||||
string debugLevel)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<object>(
|
||||
"interop.createQuill",
|
||||
quillElement, toolbar, readOnly,
|
||||
placeholder, theme, debugLevel);
|
||||
try
|
||||
{
|
||||
await _jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.createQuill",
|
||||
quillElement, toolbar, readOnly, placeholder, theme, debugLevel);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// handle exception
|
||||
}
|
||||
}
|
||||
|
||||
internal static ValueTask<string> GetText(
|
||||
IJSRuntime jsRuntime,
|
||||
ElementReference quillElement)
|
||||
public ValueTask<string> GetText(ElementReference quillElement)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<string>(
|
||||
"interop.getQuillText",
|
||||
quillElement);
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"Oqtane.RichTextEditor.getQuillText",
|
||||
quillElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
internal static ValueTask<string> GetHtml(
|
||||
IJSRuntime jsRuntime,
|
||||
ElementReference quillElement)
|
||||
public ValueTask<string> GetHtml(ElementReference quillElement)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<string>(
|
||||
"interop.getQuillHTML",
|
||||
quillElement);
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"Oqtane.RichTextEditor.getQuillHTML",
|
||||
quillElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
internal static ValueTask<string> GetContent(
|
||||
IJSRuntime jsRuntime,
|
||||
ElementReference quillElement)
|
||||
public ValueTask<string> GetContent(ElementReference quillElement)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<string>(
|
||||
"interop.getQuillContent",
|
||||
quillElement);
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"Oqtane.RichTextEditor.getQuillContent",
|
||||
quillElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new ValueTask<string>(Task.FromResult(string.Empty));
|
||||
}
|
||||
}
|
||||
|
||||
internal static ValueTask<object> LoadEditorContent(
|
||||
IJSRuntime jsRuntime,
|
||||
ElementReference quillElement,
|
||||
string content)
|
||||
public Task LoadEditorContent(ElementReference quillElement, string content)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<object>(
|
||||
"interop.loadQuillContent",
|
||||
quillElement, content);
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.loadQuillContent",
|
||||
quillElement, content);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
internal static ValueTask<object> EnableEditor(
|
||||
IJSRuntime jsRuntime,
|
||||
ElementReference quillElement,
|
||||
bool mode)
|
||||
public Task EnableEditor(ElementReference quillElement, bool mode)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<object>(
|
||||
"interop.enableQuillEditor", quillElement, mode);
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.enableQuillEditor", quillElement, mode);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
internal static ValueTask<object> InsertImage(
|
||||
IJSRuntime jsRuntime,
|
||||
ElementReference quillElement,
|
||||
string imageUrl)
|
||||
public Task InsertImage(ElementReference quillElement, string imageUrl)
|
||||
{
|
||||
return jsRuntime.InvokeAsync<object>(
|
||||
"interop.insertQuillImage",
|
||||
quillElement, imageUrl);
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<object>(
|
||||
"Oqtane.RichTextEditor.insertQuillImage",
|
||||
quillElement, imageUrl);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,14 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<div class="d-flex">
|
||||
<div>
|
||||
<a data-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name">
|
||||
<a data-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
|
||||
<h5>@_heading</h5>
|
||||
</a>
|
||||
</div>
|
||||
<div class="ml-auto">
|
||||
<a data-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name">
|
||||
<a data-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
|
||||
<i class="oi oi-chevron-bottom"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
@if (Name == Parent.ActiveTab)
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<CascadingValue Value="this">
|
||||
<div class="container-fluid">
|
||||
@ -11,13 +10,13 @@
|
||||
<li class="nav-item">
|
||||
@if (tabPanel.Name == ActiveTab)
|
||||
{
|
||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab">
|
||||
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab">
|
||||
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
|
||||
@DisplayHeading(tabPanel.Name, tabPanel.Heading)
|
||||
</a>
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
|
||||
<img src="@_src" title="@_title" @onclick="SetValue" />
|
||||
|
||||
|
@ -27,12 +27,8 @@
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
||||
// the following resources should be declared in the RichTextEditor component however the framework currently only supports resource management for modules and themes
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.bubble.css" },
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css" },
|
||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill1.3.6.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill-blot-formatter.min.js" },
|
||||
new Resource { ResourceType = ResourceType.Script, Url = "js/quill-interop.js" }
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.6.snow.css" }
|
||||
};
|
||||
|
||||
private RichTextEditor RichTextEditorHtml;
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
@if (PageState.EditMode)
|
||||
{
|
||||
<br /><ActionLink Action="Edit" /><br /><br />
|
||||
<br /><ActionLink Action="Edit" EditMode="true" /><br /><br />
|
||||
}
|
||||
|
||||
@code {
|
||||
|
@ -21,23 +21,23 @@ namespace Oqtane.Modules.HtmlText.Services
|
||||
|
||||
public async Task<HtmlTextInfo> GetHtmlTextAsync(int moduleId)
|
||||
{
|
||||
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
||||
var htmltext = await GetJsonAsync<List<HtmlTextInfo>>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", moduleId));
|
||||
return htmltext.FirstOrDefault();
|
||||
}
|
||||
|
||||
public async Task AddHtmlTextAsync(HtmlTextInfo htmlText)
|
||||
{
|
||||
await PostJsonAsync($"{ApiUrl}?entityid={htmlText.ModuleId}", htmlText);
|
||||
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", htmlText.ModuleId), htmlText);
|
||||
}
|
||||
|
||||
public async Task UpdateHtmlTextAsync(HtmlTextInfo htmlText)
|
||||
{
|
||||
await PutJsonAsync($"{ApiUrl}/{htmlText.HtmlTextId}?entityid={htmlText.ModuleId}", htmlText);
|
||||
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", htmlText.ModuleId), htmlText);
|
||||
}
|
||||
|
||||
public async Task DeleteHtmlTextAsync(int moduleId)
|
||||
{
|
||||
await DeleteAsync($"{ApiUrl}/{moduleId}?entityid={moduleId}");
|
||||
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", moduleId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ using System;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.UI;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.JSInterop;
|
||||
using System.Linq;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
@ -19,6 +21,9 @@ namespace Oqtane.Modules
|
||||
[Inject]
|
||||
protected ILogService LoggingService { get; set; }
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
protected PageState PageState { get; set; }
|
||||
|
||||
@ -28,7 +33,6 @@ namespace Oqtane.Modules
|
||||
[CascadingParameter]
|
||||
protected ModuleInstance ModuleInstance { get; set; }
|
||||
|
||||
|
||||
// optional interface properties
|
||||
public virtual SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.View; } set { } } // default security
|
||||
|
||||
@ -40,6 +44,24 @@ namespace Oqtane.Modules
|
||||
|
||||
public virtual List<Resource> Resources { get; set; }
|
||||
|
||||
// base lifecycle method for handling JSInterop script registration
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
var scripts = new List<object>();
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "" });
|
||||
}
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// path method
|
||||
|
||||
@ -94,6 +116,54 @@ namespace Oqtane.Modules
|
||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||
}
|
||||
|
||||
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
||||
{
|
||||
var urlParameters = new Dictionary<string, string>();
|
||||
string[] templateSegments;
|
||||
var parameters = PageState.UrlParameters.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
var parameterId = 0;
|
||||
|
||||
if (string.IsNullOrEmpty(parametersTemplate))
|
||||
{
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
urlParameters.TryAdd("parameter" + i, parameters[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
templateSegments = parametersTemplate.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (parameters.Length == templateSegments.Length)
|
||||
{
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
if (parameters.Length > i)
|
||||
{
|
||||
if (templateSegments[i] == parameters[i])
|
||||
{
|
||||
urlParameters.TryAdd("parameter" + parameterId, parameters[i]);
|
||||
parameterId++;
|
||||
}
|
||||
else if (templateSegments[i].StartsWith("{") && templateSegments[i].EndsWith("}"))
|
||||
{
|
||||
var key = templateSegments[i].Replace("{", "");
|
||||
key = key.Replace("}", "");
|
||||
urlParameters.TryAdd(key, parameters[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = parameters.Length;
|
||||
urlParameters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return urlParameters;
|
||||
}
|
||||
|
||||
// user feedback methods
|
||||
public void AddModuleMessage(string message, MessageType type)
|
||||
{
|
||||
@ -132,12 +202,15 @@ namespace Oqtane.Modules
|
||||
case "add":
|
||||
logFunction = LogFunction.Create;
|
||||
break;
|
||||
|
||||
case "edit":
|
||||
logFunction = LogFunction.Update;
|
||||
break;
|
||||
|
||||
case "delete":
|
||||
logFunction = LogFunction.Delete;
|
||||
break;
|
||||
|
||||
default:
|
||||
logFunction = LogFunction.Read;
|
||||
break;
|
||||
|
10
Oqtane.Client/Modules/ModuleControlBase.cs
Normal file
10
Oqtane.Client/Modules/ModuleControlBase.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Modules
|
||||
{
|
||||
[OqtaneIgnore]
|
||||
public abstract class ModuleControlBase : ModuleBase
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>1.0.0</Version>
|
||||
<Version>1.0.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
@ -15,8 +15,9 @@
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/oqtane</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<PackageReleaseNotes>Not for production use.</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</PackageReleaseNotes>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -37,5 +38,4 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -170,6 +170,19 @@ namespace Oqtane.Services
|
||||
// can be used to override the default alias
|
||||
public Alias Alias { get; set; }
|
||||
|
||||
// add entityid parameter to url for custom authorization policy
|
||||
public string CreateAuthorizationPolicyUrl(string url, int entityId)
|
||||
{
|
||||
if (url.Contains("?"))
|
||||
{
|
||||
return url + "&entityid=" + entityId.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return url + "?entityid=" + entityId.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("This method is obsolete. Use CreateApiUrl(Alias alias, string serviceName) instead.", false)]
|
||||
public string CreateApiUrl(Alias alias, string absoluteUri, string serviceName)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ namespace Oqtane.Services
|
||||
public string GetSetting(Dictionary<string, string> settings, string settingName, string defaultValue)
|
||||
{
|
||||
string value = defaultValue;
|
||||
if (settings.ContainsKey(settingName))
|
||||
if (settings != null && settings.ContainsKey(settingName))
|
||||
{
|
||||
value = settings[settingName];
|
||||
}
|
||||
@ -162,6 +162,10 @@ namespace Oqtane.Services
|
||||
|
||||
public Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
settings = new Dictionary<string, string>();
|
||||
}
|
||||
if (settings.ContainsKey(settingName))
|
||||
{
|
||||
settings[settingName] = settingValue;
|
||||
|
@ -1,81 +1,54 @@
|
||||
using Oqtane.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Services
|
||||
{
|
||||
public class ThemeService : ServiceBase, IThemeService
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
private readonly SiteState _siteState;
|
||||
|
||||
public ThemeService(HttpClient http) : base(http)
|
||||
public ThemeService(HttpClient http, SiteState siteState) : base(http)
|
||||
{
|
||||
_http = http;
|
||||
_siteState = siteState;
|
||||
}
|
||||
|
||||
private string Apiurl => CreateApiUrl("Theme");
|
||||
private string ApiUrl => CreateApiUrl(_siteState.Alias, "Theme");
|
||||
|
||||
public async Task<List<Theme>> GetThemesAsync()
|
||||
{
|
||||
List<Theme> themes = await GetJsonAsync<List<Theme>>(Apiurl);
|
||||
List<Theme> themes = await GetJsonAsync<List<Theme>>(ApiUrl);
|
||||
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()
|
||||
{
|
||||
await GetJsonAsync<List<string>>($"{Apiurl}/install");
|
||||
await GetJsonAsync<List<string>>($"{ApiUrl}/install");
|
||||
}
|
||||
|
||||
public async Task DeleteThemeAsync(string themeName)
|
||||
{
|
||||
await DeleteAsync($"{Apiurl}/{themeName}");
|
||||
await DeleteAsync($"{ApiUrl}/{themeName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,11 @@
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" }
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css", Integrity = "sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.5.1.slim.min.js", Integrity = "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js", Integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" }
|
||||
};
|
||||
|
||||
}
|
@ -1,62 +1,12 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.UI;
|
||||
|
||||
namespace Oqtane.Themes
|
||||
{
|
||||
public class ContainerBase : ComponentBase, IContainerControl
|
||||
public abstract class ContainerBase : ThemeBase, IContainerControl
|
||||
{
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
protected PageState PageState { get; set; }
|
||||
|
||||
[CascadingParameter]
|
||||
protected Module ModuleState { get; set; }
|
||||
|
||||
|
||||
public string ThemePath()
|
||||
{
|
||||
return "Themes/" + GetType().Namespace + "/";
|
||||
}
|
||||
|
||||
public string NavigateUrl()
|
||||
{
|
||||
return NavigateUrl(PageState.Page.Path);
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path)
|
||||
{
|
||||
return NavigateUrl(path, "");
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path, string parameters)
|
||||
{
|
||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(string action, string parameters)
|
||||
{
|
||||
return EditUrl(ModuleState.ModuleId, action, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(int moduleid, string action)
|
||||
{
|
||||
return EditUrl(moduleid, action, "");
|
||||
}
|
||||
|
||||
public string EditUrl(int moduleid, string action, string parameters)
|
||||
{
|
||||
return EditUrl(PageState.Page.Path, moduleid, action, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(string path, int moduleid, string action, string parameters)
|
||||
{
|
||||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ThemeControlBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (BreadCrumbPages.Any())
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ThemeControlBase
|
||||
@attribute [OqtaneIgnore]
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject IUserService UserService
|
||||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@ -9,8 +8,9 @@
|
||||
@inject IPageService PageService
|
||||
@inject IPageModuleService PageModuleService
|
||||
@inject ILogService logger
|
||||
@inject ISettingService SettingService
|
||||
|
||||
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions))
|
||||
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||
{
|
||||
<div class="app-controlpanel" style="@_display">
|
||||
|
||||
@ -49,6 +49,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)
|
||||
@ -78,18 +93,18 @@
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<label for="Module" class="control-label">Module Management: </label>
|
||||
<select class="form-control" @bind="@_moduleType">
|
||||
<select class="form-control" @bind="@ModuleType">
|
||||
<option value="new">Add New Module</option>
|
||||
<option value="existing">Add Existing Module</option>
|
||||
</select>
|
||||
@if (_moduleType == "new")
|
||||
@if (ModuleType == "new")
|
||||
{
|
||||
@if (_moduleDefinitions != null)
|
||||
{
|
||||
<select class="form-control" @onchange="(e => CategoryChanged(e))">
|
||||
@foreach (var category in _categories)
|
||||
{
|
||||
if (category == _category)
|
||||
if (category == Category)
|
||||
{
|
||||
<option value="@category" selected>@category Modules</option>
|
||||
}
|
||||
@ -100,7 +115,7 @@
|
||||
}
|
||||
</select>
|
||||
<select class="form-control" @onchange="(e => ModuleChanged(e))">
|
||||
@if (_moduleDefinitionName == "-")
|
||||
@if (ModuleDefinitionName == "-")
|
||||
{
|
||||
<option value="-" selected><Select Module></option>
|
||||
}
|
||||
@ -112,11 +127,14 @@
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.Permissions))
|
||||
{
|
||||
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
||||
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
||||
{
|
||||
<option value="@moduledefinition.ModuleDefinitionName">@moduledefinition.Name</option>
|
||||
}
|
||||
}
|
||||
}
|
||||
</select>
|
||||
@((MarkupString)@_description)
|
||||
@((MarkupString) Description)
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -128,7 +146,7 @@
|
||||
<option value="@p.PageId">@p.Name</option>
|
||||
}
|
||||
</select>
|
||||
<select class="form-control" @bind="@_moduleId">
|
||||
<select class="form-control" @bind="@ModuleId">
|
||||
<option value="-"><Select Module></option>
|
||||
@foreach (Module module in _modules)
|
||||
{
|
||||
@ -141,28 +159,30 @@
|
||||
<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=""><Select Pane></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)
|
||||
<select class="form-control" @bind="@ContainerType">
|
||||
@foreach (var container in _containers)
|
||||
{
|
||||
<option value="@container.Key">@container.Value</option>
|
||||
<option value="@container.TypeName">@container.Name</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
@ -171,223 +191,201 @@
|
||||
<br />
|
||||
|
||||
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">Add Module To Page</button>
|
||||
@((MarkupString) _message)
|
||||
@((MarkupString) Message)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
|
||||
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions) || (PageState.Page.IsPersonalizable && PageState.User != null))
|
||||
{
|
||||
@if (PageState.Page.EditMode)
|
||||
if (PageState.EditMode)
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass active" aria-pressed="true" autocomplete="off">
|
||||
<button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (PageState.EditMode)
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass active" data-toggle="button" aria-pressed="true" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
<button type="button" class="btn @ButtonClass" data-toggle="button" aria-pressed="false" autocomplete="off" @onclick="(async () => await ToggleEditMode(PageState.EditMode))">
|
||||
<span class="oi oi-pencil"></span>
|
||||
</button>
|
||||
}
|
||||
}
|
||||
|
||||
@if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions))
|
||||
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||
{
|
||||
<button type="button" class="btn @ButtonClass" @onclick="ShowControlPanel">
|
||||
<span class="oi oi-cog"></span>
|
||||
</button>
|
||||
}
|
||||
|
||||
@code {
|
||||
@code{
|
||||
|
||||
private bool _deleteConfirmation = false;
|
||||
private string _moduleType = "new";
|
||||
private List<string> _categories = new List<string>();
|
||||
private List<ModuleDefinition> _allModuleDefinitions;
|
||||
private List<ModuleDefinition> _moduleDefinitions;
|
||||
private List<Page> _pages = new List<Page>();
|
||||
private string _pageId = "-";
|
||||
private string _moduleId = "-";
|
||||
private List<Module> _modules = new List<Module>();
|
||||
private Dictionary<string, string> _containers = new Dictionary<string, string>();
|
||||
private string _moduleDefinitionName = "-";
|
||||
private string _category = "Common";
|
||||
private string _description = "";
|
||||
private string _pane = "";
|
||||
private string _title = "";
|
||||
private string _containerType = "";
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _display = "display: none;";
|
||||
private string _message = "";
|
||||
private string _category = "Common";
|
||||
|
||||
[Parameter]
|
||||
public string ButtonClass { get; set; }
|
||||
protected string PageId { get; private set; } = "-";
|
||||
protected string ModuleId { get; private set; } = "-";
|
||||
protected string ModuleType { get; private set; } = "new";
|
||||
protected string ModuleDefinitionName { get; private set; } = "-";
|
||||
|
||||
[Parameter]
|
||||
public string CardClass { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string HeaderClass { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string BodyClass { get; set; }
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
protected string Category
|
||||
{
|
||||
if (string.IsNullOrEmpty(ButtonClass))
|
||||
get => _category;
|
||||
private set
|
||||
{
|
||||
ButtonClass = "btn-outline-secondary";
|
||||
if (_category != value)
|
||||
{
|
||||
_category = value;
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
||||
ModuleDefinitionName = "-";
|
||||
Description = "";
|
||||
StateHasChanged();
|
||||
_ = UpdateSettingsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(CardClass))
|
||||
protected string Pane
|
||||
{
|
||||
get => _pane;
|
||||
private set
|
||||
{
|
||||
CardClass = "card border-secondary mb-3";
|
||||
if (_pane != value)
|
||||
{
|
||||
_pane = value;
|
||||
_ = UpdateSettingsAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(HeaderClass))
|
||||
{
|
||||
HeaderClass = "card-header";
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(BodyClass))
|
||||
{
|
||||
BodyClass = "card-body";
|
||||
}
|
||||
protected string Description { get; private set; } = "";
|
||||
|
||||
if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions))
|
||||
protected string Title { get; private set; } = "";
|
||||
protected string ContainerType { get; private set; } = "";
|
||||
protected string Message { get; private set; } = "";
|
||||
|
||||
[Parameter]
|
||||
public string ButtonClass { get; set; } = "btn-outline-secondary";
|
||||
|
||||
[Parameter]
|
||||
public string CardClass { get; set; } = "card border-secondary mb-3";
|
||||
|
||||
[Parameter]
|
||||
public string HeaderClass { get; set; } = "card-header";
|
||||
|
||||
[Parameter]
|
||||
public string BodyClass { get; set; } = "card-body";
|
||||
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||
{
|
||||
_pages?.Clear();
|
||||
|
||||
foreach (Page p in PageState.Pages)
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.View, p.Permissions))
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
|
||||
{
|
||||
_pages.Add(p);
|
||||
}
|
||||
}
|
||||
await LoadSettingsAsync();
|
||||
|
||||
var panes = PageState.Page.Panes;
|
||||
_pane = panes.Count() == 1 ? panes.SingleOrDefault() : "";
|
||||
var themes = await ThemeService.GetThemesAsync();
|
||||
_containers = ThemeService.GetContainerTypes(themes);
|
||||
_containerType = PageState.Site.DefaultContainerType;
|
||||
|
||||
_containers = ThemeService.GetContainerControls(themes, PageState.Page.ThemeType);
|
||||
ContainerType = PageState.Site.DefaultContainerType;
|
||||
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||
|
||||
_categories = new List<string>();
|
||||
foreach (ModuleDefinition moduledefinition in _allModuleDefinitions)
|
||||
{
|
||||
if (moduledefinition.Categories != "")
|
||||
{
|
||||
foreach (string category in moduledefinition.Categories.Split(','))
|
||||
{
|
||||
if (!_categories.Contains(category))
|
||||
{
|
||||
_categories.Add(category);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_category = "Common";
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
||||
_moduleDefinitionName = "-";
|
||||
_description = "";
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
||||
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private void CategoryChanged(ChangeEventArgs e)
|
||||
{
|
||||
_category = (string) e.Value;
|
||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
||||
_moduleDefinitionName = "-";
|
||||
_description = "";
|
||||
StateHasChanged();
|
||||
Category = (string) e.Value;
|
||||
}
|
||||
|
||||
private void ModuleChanged(ChangeEventArgs e)
|
||||
{
|
||||
_moduleDefinitionName = (string)e.Value;
|
||||
if (_moduleDefinitionName != "-")
|
||||
ModuleDefinitionName = (string) e.Value;
|
||||
if (ModuleDefinitionName != "-")
|
||||
{
|
||||
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == _moduleDefinitionName);
|
||||
_description = "<br /><div class=\"alert alert-info\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
||||
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName);
|
||||
Description = "<br /><div class=\"alert alert-info\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
||||
}
|
||||
else
|
||||
{
|
||||
_description = "";
|
||||
Description = "";
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void PageChanged(ChangeEventArgs e)
|
||||
{
|
||||
_pageId = (string) e.Value;
|
||||
_modules?.Clear();
|
||||
|
||||
if (_pageId != "-")
|
||||
PageId = (string) e.Value;
|
||||
if (PageId != "-")
|
||||
{
|
||||
foreach (Module module in PageState.Modules.Where(item => item.PageId == int.Parse(_pageId) && !item.IsDeleted))
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.View, module.Permissions))
|
||||
{
|
||||
_modules.Add(module);
|
||||
}
|
||||
}
|
||||
_modules = PageState.Modules
|
||||
.Where(module => module.PageId == int.Parse(PageId)
|
||||
&& !module.IsDeleted
|
||||
&& UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
_moduleId = "-";
|
||||
ModuleId = "-";
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task AddModule()
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions))
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||
{
|
||||
if ((_moduleType == "new" && _moduleDefinitionName != "-") || (_moduleType != "new" && _moduleId != "-"))
|
||||
if ((ModuleType == "new" && ModuleDefinitionName != "-") || (ModuleType != "new" && ModuleId != "-"))
|
||||
{
|
||||
if (_moduleType == "new")
|
||||
if (ModuleType == "new")
|
||||
{
|
||||
Module module = new Module();
|
||||
module.SiteId = PageState.Site.SiteId;
|
||||
module.PageId = PageState.Page.PageId;
|
||||
module.ModuleDefinitionName = _moduleDefinitionName;
|
||||
module.ModuleDefinitionName = ModuleDefinitionName;
|
||||
module.AllPages = false;
|
||||
module.Permissions = PageState.Page.Permissions;
|
||||
module = await ModuleService.AddModuleAsync(module);
|
||||
_moduleId = module.ModuleId.ToString();
|
||||
ModuleId = module.ModuleId.ToString();
|
||||
}
|
||||
|
||||
var pageModule = new PageModule
|
||||
{
|
||||
PageId = PageState.Page.PageId,
|
||||
ModuleId = int.Parse(_moduleId),
|
||||
Title = _title
|
||||
ModuleId = int.Parse(ModuleId),
|
||||
Title = Title
|
||||
};
|
||||
if (pageModule.Title == "")
|
||||
{
|
||||
if (_moduleType == "new")
|
||||
if (ModuleType == "new")
|
||||
{
|
||||
pageModule.Title = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == _moduleDefinitionName)?.Name;
|
||||
pageModule.Title = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName)?.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
pageModule.Title = _modules.FirstOrDefault(item => item.ModuleId == int.Parse(_moduleId))?.Title;
|
||||
pageModule.Title = _modules.FirstOrDefault(item => item.ModuleId == int.Parse(ModuleId))?.Title;
|
||||
}
|
||||
}
|
||||
|
||||
pageModule.Pane = _pane;
|
||||
pageModule.Pane = Pane;
|
||||
pageModule.Order = int.MaxValue;
|
||||
pageModule.ContainerType = _containerType;
|
||||
pageModule.ContainerType = ContainerType;
|
||||
|
||||
if (pageModule.ContainerType == PageState.Site.DefaultContainerType)
|
||||
{
|
||||
@ -397,32 +395,23 @@
|
||||
await PageModuleService.AddPageModuleAsync(pageModule);
|
||||
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
||||
|
||||
_message = "<br /><div class=\"alert alert-success\" role=\"alert\">Module Added To Page</div>";
|
||||
|
||||
_moduleDefinitionName = "-";
|
||||
_description = "";
|
||||
_pane = "";
|
||||
_title = "";
|
||||
_containerType = "";
|
||||
_pageId = "-";
|
||||
_moduleId = "-";
|
||||
|
||||
Message = "<br /><div class=\"alert alert-success\" role=\"alert\">Module Added To Page</div>";
|
||||
NavigationManager.NavigateTo(NavigateUrl());
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select A Module</div>";
|
||||
Message = "<br /><div class=\"alert alert-warning\" role=\"alert\">You Must Select A Module</div>";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = "<br /><div class=\"alert alert-error\" role=\"alert\">Not Authorized</div>";
|
||||
Message = "<br /><div class=\"alert alert-error\" role=\"alert\">Not Authorized</div>";
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ToggleEditMode(bool EditMode)
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions))
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
|
||||
{
|
||||
if (EditMode)
|
||||
{
|
||||
@ -432,6 +421,7 @@
|
||||
{
|
||||
PageState.EditMode = true;
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "1" : "0")));
|
||||
}
|
||||
else
|
||||
@ -447,14 +437,14 @@
|
||||
|
||||
private void ShowControlPanel()
|
||||
{
|
||||
_message = "";
|
||||
Message = "";
|
||||
_display = "width: 25%; min-width: 375px;";
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void HideControlPanel()
|
||||
{
|
||||
_message = "";
|
||||
Message = "";
|
||||
_display = "width: 0%;";
|
||||
StateHasChanged();
|
||||
}
|
||||
@ -503,6 +493,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;
|
||||
@ -536,4 +581,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
private string settingCategory = "CP-category";
|
||||
private string settingPane = "CP-pane";
|
||||
private string _pane = "";
|
||||
|
||||
private async Task LoadSettingsAsync()
|
||||
{
|
||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||
_category = SettingService.GetSetting(settings, settingCategory, "Common");
|
||||
var pane = SettingService.GetSetting(settings, settingPane, "");
|
||||
_pane = PageState.Page.Panes.Contains(pane) ? pane : PageState.Page.Panes.FirstOrDefault();
|
||||
}
|
||||
|
||||
private async Task UpdateSettingsAsync()
|
||||
{
|
||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||
SettingService.SetSetting(settings, settingCategory, _category);
|
||||
SettingService.SetSetting(settings, settingPane, _pane);
|
||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits LoginBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
<span class="app-login">
|
||||
<AuthorizeView>
|
||||
|
@ -1,6 +1,5 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ThemeControlBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (PageState.Site.LogoFileId != null)
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits MenuBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (MenuPages.Any())
|
||||
{
|
||||
<span class="app-menu-toggler">
|
||||
@ -16,7 +16,7 @@
|
||||
if (p.PageId == PageState.Page.PageId)
|
||||
{
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="@NavigateUrl(p.Path)">
|
||||
<a class="nav-link" href="@GetUrl(p)" target="@GetTarget(p)" >
|
||||
@if (p.Icon != string.Empty)
|
||||
{
|
||||
<span class="oi oi-@p.Icon" aria-hidden="true"></span>
|
||||
@ -28,7 +28,7 @@
|
||||
else
|
||||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="@NavigateUrl(p.Path)">
|
||||
<a class="nav-link" href="@GetUrl(p)" target="@GetTarget(p)" >
|
||||
@if (p.Icon != string.Empty)
|
||||
{
|
||||
<span class="oi oi-@p.Icon" aria-hidden="true"></span>
|
||||
|
@ -1,6 +1,6 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits MenuBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (MenuPages.Any())
|
||||
{
|
||||
<span class="app-menu-toggler">
|
||||
|
@ -2,7 +2,7 @@
|
||||
@inherits ModuleActionsBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
||||
@if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, ModuleState.Permissions))
|
||||
{
|
||||
<div class="app-moduleactions">
|
||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false"></a>
|
||||
@ -15,7 +15,18 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">@action.Name</a>
|
||||
<a class="dropdown-item" @onclick="(async () => await ModuleAction(action))">
|
||||
@if (string.IsNullOrEmpty(action.Icon))
|
||||
{
|
||||
@((MarkupString) " ");
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="oi oi-@action.Icon" aria-hidden="true"></span>
|
||||
}
|
||||
|
||||
@action.Name
|
||||
</a>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
|
@ -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,8 +17,9 @@ 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;
|
||||
public List<ActionViewModel> Actions;
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
@ -29,42 +31,52 @@ namespace Oqtane.Themes.Controls
|
||||
var actionList = new List<ActionViewModel>();
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, ModuleState.Permissions))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.Cog, Name = "Manage Settings", Action = async (u, m) => await Settings(u, m)});
|
||||
|
||||
if (UserSecurity.GetPermissionStrings(ModuleState.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(Constants.AllUsersRole))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Icon=Icons.CircleX, Name = "Unpublish Module", Action = async (s, m) => await Unpublish(s, m) });
|
||||
}
|
||||
else
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Icon=Icons.CircleCheck, Name = "Publish Module", Action = async (s, m) => await Publish(s, m) });
|
||||
}
|
||||
actionList.Add(new ActionViewModel {Icon=Icons.Trash, Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m) });
|
||||
|
||||
if (ModuleState.ModuleDefinition != null && ModuleState.ModuleDefinition.ServerManagerType != "")
|
||||
{
|
||||
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 = "" });
|
||||
actionList.Add(new ActionViewModel {Icon=Icons.CloudUpload, Name = "Import Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Import")});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.CloudDownload, Name = "Export Content", Action = async (u, m) => await EditUrlAsync(u, m.ModuleId, "Export")});
|
||||
}
|
||||
|
||||
actionList.Add(new ActionViewModel {Name = "Delete Module", Action = async (u, m) => await DeleteModule(u, m)});
|
||||
actionList.Add(new ActionViewModel {Name = ""});
|
||||
|
||||
if (ModuleState.PaneModuleIndex > 0)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.DataTransferUpload ,Name = "Move To Top", Action = async (s, m) => await MoveTop(s, m)});
|
||||
}
|
||||
|
||||
if (ModuleState.PaneModuleIndex > 0)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickTop, Name = "Move Up", Action = async (s, m) => await MoveUp(s, m)});
|
||||
}
|
||||
|
||||
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.ArrowThickBottom, Name = "Move Down", Action = async (s, m) => await MoveDown(s, m)});
|
||||
}
|
||||
|
||||
if (ModuleState.PaneModuleIndex < (ModuleState.PaneModuleCount - 1))
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.DataTransferDownload, Name = "Move To Bottom", Action = async (s, m) => await MoveBottom(s, m)});
|
||||
}
|
||||
|
||||
foreach (string pane in PageState.Page.Panes)
|
||||
{
|
||||
if (pane != ModuleState.Pane)
|
||||
{
|
||||
actionList.Add(new ActionViewModel {Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||
actionList.Add(new ActionViewModel {Icon = Icons.AccountLogin, Name = "Move To " + pane + " Pane", Action = async (s, m) => await MoveToPane(s, pane, m)});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -121,6 +133,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;
|
||||
@ -155,8 +203,8 @@ namespace Oqtane.Themes.Controls
|
||||
|
||||
public class ActionViewModel
|
||||
{
|
||||
public string Icon { get; set; }
|
||||
public string Name { set; get; }
|
||||
|
||||
public Func<string, PageModule, Task<string>> Action { set; get; }
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
@namespace Oqtane.Themes.Controls
|
||||
@inherits ThemeControlBase
|
||||
@attribute [OqtaneIgnore]
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<span class="app-profile">
|
||||
|
@ -2,5 +2,6 @@
|
||||
{
|
||||
public interface IContainerControl
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
{
|
||||
public interface ILayoutControl
|
||||
{
|
||||
string Panes { get; } // identifies all panes in a theme ( delimited by ";" )
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,7 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.UI;
|
||||
|
||||
namespace Oqtane.Themes
|
||||
namespace Oqtane.Themes
|
||||
{
|
||||
public class LayoutBase : ComponentBase, ILayoutControl
|
||||
public abstract class LayoutBase : ThemeBase, ILayoutControl
|
||||
{
|
||||
[CascadingParameter]
|
||||
protected PageState PageState { get; set; }
|
||||
public virtual string Panes { get; set; }
|
||||
|
||||
public string LayoutPath()
|
||||
{
|
||||
return "Themes/" + GetType().Namespace + "/";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -13,3 +13,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "Standard Header";
|
||||
}
|
@ -17,14 +17,16 @@
|
||||
</main>
|
||||
|
||||
@code {
|
||||
public override string Name => "Default";
|
||||
|
||||
public override string Panes => string.Empty;
|
||||
|
||||
public override List<Resource> Resources => new List<Resource>()
|
||||
{
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "BootswatchCyborg.css" },
|
||||
// remote stylesheets can be linked using the format below, however we want the default theme to display properly in local development scenarios where an Internet connection is not available
|
||||
//new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css", Integrity = "sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" }
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.5.0/cyborg/bootstrap.min.css", Integrity = "sha384-GKugkVcT8wqoh3M8z1lqHbU+g6j498/ZT/zuXbepz7Dc09/otQZxTimkEMTkRWHP", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://code.jquery.com/jquery-3.5.1.slim.min.js", Integrity = "sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js", Integrity = "sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo", CrossOrigin = "anonymous" },
|
||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js", Integrity = "sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI", CrossOrigin = "anonymous" }
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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";
|
||||
}
|
@ -7,3 +7,7 @@
|
||||
}
|
||||
<ModuleInstance />
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "No Header";
|
||||
}
|
@ -6,5 +6,7 @@
|
||||
</div>
|
||||
|
||||
@code {
|
||||
public override string Name => "Single Pane";
|
||||
|
||||
public override string Panes => "Content";
|
||||
}
|
@ -4,11 +4,12 @@ using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.UI;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
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,9 +18,30 @@ 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; }
|
||||
|
||||
// base lifecycle method for handling JSInterop script registration
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
var scripts = new List<object>();
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "" });
|
||||
}
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// path method
|
||||
|
||||
public string ThemePath()
|
||||
@ -58,5 +80,10 @@ namespace Oqtane.Themes
|
||||
{
|
||||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
||||
}
|
||||
|
||||
public string ContentUrl(int fileid)
|
||||
{
|
||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,10 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Oqtane.Shared;
|
||||
using Oqtane.UI;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Themes
|
||||
{
|
||||
public class ThemeControlBase : ComponentBase
|
||||
[OqtaneIgnore]
|
||||
public abstract class ThemeControlBase : ThemeBase
|
||||
{
|
||||
[CascadingParameter]
|
||||
protected PageState PageState { get; set; }
|
||||
|
||||
public string NavigateUrl()
|
||||
{
|
||||
return NavigateUrl(PageState.Page.Path);
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path)
|
||||
{
|
||||
return NavigateUrl(path, "");
|
||||
}
|
||||
|
||||
public string NavigateUrl(string path, string parameters)
|
||||
{
|
||||
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(int moduleid, string action)
|
||||
{
|
||||
return EditUrl(moduleid, action, "");
|
||||
}
|
||||
|
||||
public string EditUrl(int moduleid, string action, string parameters)
|
||||
{
|
||||
return EditUrl(PageState.Page.Path, moduleid, action, parameters);
|
||||
}
|
||||
|
||||
public string EditUrl(string path, int moduleid, string action, string parameters)
|
||||
{
|
||||
return Utilities.EditUrl(PageState.Alias.Path, path, moduleid, action, parameters);
|
||||
}
|
||||
|
||||
public string ContentUrl(int fileid)
|
||||
{
|
||||
return Utilities.ContentUrl(PageState.Alias, fileid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
{
|
||||
_moduleState = Module; // passed in from Pane component
|
||||
string container = _moduleState.ContainerType;
|
||||
if (PageState.ModuleId != -1 && PageState.Action != "" && _moduleState.UseAdminContainer)
|
||||
if (PageState.ModuleId != -1 && _moduleState.UseAdminContainer)
|
||||
{
|
||||
container = Constants.DefaultAdminContainer;
|
||||
}
|
||||
@ -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();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
@inject IInstallationService InstallationService
|
||||
@inject ISiteService SiteService
|
||||
@inject IUserService UserService
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@ -138,6 +139,15 @@
|
||||
private string _integratedSecurityDisplay = "display: none;";
|
||||
private string _loadingDisplay = "display: none;";
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.IncludeLink("app-stylesheet", "stylesheet", "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css", "text/css", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", "anonymous", "");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetIntegratedSecurity(ChangeEventArgs e)
|
||||
{
|
||||
_integratedSecurityDisplay = Convert.ToBoolean((string)e.Value)
|
||||
|
@ -1,6 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using Microsoft.JSInterop;
|
||||
using Oqtane.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Oqtane.UI
|
||||
@ -18,9 +17,9 @@ namespace Oqtane.UI
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.setCookie",
|
||||
name, value, days);
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.setCookie",
|
||||
name, value, days);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -34,7 +33,7 @@ namespace Oqtane.UI
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"interop.getCookie",
|
||||
"Oqtane.Interop.getCookie",
|
||||
name);
|
||||
}
|
||||
catch
|
||||
@ -47,8 +46,8 @@ namespace Oqtane.UI
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.updateTitle",
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.updateTitle",
|
||||
title);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@ -58,13 +57,13 @@ namespace Oqtane.UI
|
||||
}
|
||||
}
|
||||
|
||||
public Task IncludeMeta(string id, string attribute, string name, string content)
|
||||
public Task IncludeMeta(string id, string attribute, string name, string content, string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.includeMeta",
|
||||
id, attribute, name, content);
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.includeMeta",
|
||||
id, attribute, name, content, key);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -73,13 +72,13 @@ namespace Oqtane.UI
|
||||
}
|
||||
}
|
||||
|
||||
public Task IncludeLink(string id, string rel, string url, string type, string integrity, string crossorigin)
|
||||
public Task IncludeLink(string id, string rel, string href, string type, string integrity, string crossorigin, string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.includeLink",
|
||||
id, rel, url, type, integrity, crossorigin);
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.includeLink",
|
||||
id, rel, href, type, integrity, crossorigin, key);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -88,13 +87,13 @@ namespace Oqtane.UI
|
||||
}
|
||||
}
|
||||
|
||||
public Task IncludeScript(string id, string src, string content, string location, string integrity, string crossorigin)
|
||||
public Task IncludeLinks(object[] links)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.includeScript",
|
||||
id, src, content, location, integrity, crossorigin);
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.includeLinks",
|
||||
(object) links);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -103,13 +102,13 @@ namespace Oqtane.UI
|
||||
}
|
||||
}
|
||||
|
||||
public Task IncludeCSS(string id, string url)
|
||||
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string content, string location, string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.includeLink",
|
||||
id, "stylesheet", url, "text/css");
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.includeScript",
|
||||
id, src, integrity, crossorigin, content, location, key);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -118,12 +117,26 @@ namespace Oqtane.UI
|
||||
}
|
||||
}
|
||||
|
||||
public async Task IncludeScripts(object[] scripts)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.includeScripts",
|
||||
(object)scripts);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignore exception
|
||||
}
|
||||
}
|
||||
|
||||
public Task RemoveElementsById(string prefix, string first, string last)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.removeElementsById",
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.removeElementsById",
|
||||
prefix, first, last);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
@ -133,13 +146,12 @@ namespace Oqtane.UI
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public ValueTask<string> GetElementByName(string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string>(
|
||||
"interop.getElementByName",
|
||||
"Oqtane.Interop.getElementByName",
|
||||
name);
|
||||
}
|
||||
catch
|
||||
@ -152,9 +164,9 @@ namespace Oqtane.UI
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.submitForm",
|
||||
path, fields);
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.submitForm",
|
||||
path, fields);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -168,7 +180,7 @@ namespace Oqtane.UI
|
||||
try
|
||||
{
|
||||
return _jsRuntime.InvokeAsync<string[]>(
|
||||
"interop.getFiles",
|
||||
"Oqtane.Interop.getFiles",
|
||||
id);
|
||||
}
|
||||
catch
|
||||
@ -181,9 +193,9 @@ namespace Oqtane.UI
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeAsync<string>(
|
||||
"interop.uploadFiles",
|
||||
posturl, folder, id);
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.uploadFiles",
|
||||
posturl, folder, id);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
@ -191,5 +203,36 @@ namespace Oqtane.UI
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task RefreshBrowser(bool force, int wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.refreshBrowser",
|
||||
force, wait);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
public Task RedirectBrowser(string url, int wait)
|
||||
{
|
||||
try
|
||||
{
|
||||
_jsRuntime.InvokeVoidAsync(
|
||||
"Oqtane.Interop.redirectBrowser",
|
||||
url, wait);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ namespace Oqtane.UI
|
||||
public List<Module> Modules { get; set; }
|
||||
public Uri Uri { get; set; }
|
||||
public Dictionary<string, string> QueryString { get; set; }
|
||||
public string UrlParameters { get; set; }
|
||||
public int ModuleId { get; set; }
|
||||
public string Action { get; set; }
|
||||
public bool EditMode { get; set; }
|
||||
|
@ -1,4 +1,5 @@
|
||||
@namespace Oqtane.UI
|
||||
@using Microsoft.AspNetCore.Components.Rendering
|
||||
@namespace Oqtane.UI
|
||||
@inject IUserService UserService
|
||||
@inject IModuleService ModuleService
|
||||
@inject IModuleDefinitionService ModuleDefinitionService
|
||||
@ -25,7 +26,7 @@
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (PageState.EditMode && !PageState.Page.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane)
|
||||
if (PageState.EditMode && UserSecurity.IsAuthorized(PageState.User,PermissionNames.Edit, PageState.Page.Permissions) && Name != Constants.AdminPane)
|
||||
{
|
||||
_paneadminborder = "app-pane-admin-border";
|
||||
_panetitle = "<div class=\"app-pane-admin-title\">" + Name + " Pane</div>";
|
||||
@ -38,12 +39,12 @@
|
||||
|
||||
DynamicComponent = builder =>
|
||||
{
|
||||
if (PageState.ModuleId != -1 && PageState.Action != "")
|
||||
if (PageState.ModuleId != -1 && PageState.Action != Constants.DefaultAction)
|
||||
{
|
||||
if (Name.ToLower() == Constants.AdminPane.ToLower())
|
||||
{
|
||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||
if (module != null)
|
||||
if (module != null && !module.IsDeleted)
|
||||
{
|
||||
var typename = module.ModuleType;
|
||||
// check for core module actions component
|
||||
@ -88,10 +89,7 @@
|
||||
{
|
||||
module.Title = module.ControlTitle;
|
||||
}
|
||||
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.CloseComponent();
|
||||
CreateComponent(builder, module);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -106,14 +104,12 @@
|
||||
if (PageState.ModuleId != -1)
|
||||
{
|
||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
||||
if (module != null && module.Pane.ToLower() == Name.ToLower())
|
||||
if (module != null && module.Pane.ToLower() == Name.ToLower() && !module.IsDeleted)
|
||||
{
|
||||
// check if user is authorized to view module
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||
{
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.CloseComponent();
|
||||
CreateComponent(builder, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,14 +120,19 @@
|
||||
// check if user is authorized to view module
|
||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.Permissions))
|
||||
{
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.SetKey(module.PageModuleId);
|
||||
builder.CloseComponent();
|
||||
CreateComponent(builder, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void CreateComponent(RenderTreeBuilder builder, Module module)
|
||||
{
|
||||
builder.OpenComponent(0, Type.GetType(Constants.ContainerComponent));
|
||||
builder.AddAttribute(1, "Module", module);
|
||||
builder.SetKey(module.PageModuleId);
|
||||
builder.CloseComponent();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
}
|
@ -76,7 +76,8 @@
|
||||
User user = null;
|
||||
List<Module> modules;
|
||||
var moduleid = -1;
|
||||
var action = "";
|
||||
var action = string.Empty;
|
||||
var urlparameters = string.Empty;
|
||||
var editmode = false;
|
||||
var reload = Reload.None;
|
||||
var lastsyncdate = DateTime.UtcNow;
|
||||
@ -90,7 +91,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;
|
||||
@ -173,27 +174,66 @@
|
||||
|
||||
if (alias.Path != "")
|
||||
{
|
||||
path = path.Replace(alias.Path + "/", "");
|
||||
path = path.Substring(alias.Path.Length + 1);
|
||||
}
|
||||
|
||||
// extract admin route elements from path
|
||||
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
int result;
|
||||
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
||||
if (segments.Length >= 2 && int.TryParse(segments[segments.Length - 2], out result))
|
||||
|
||||
int modIdPos = 0;
|
||||
int actionPos = 0;
|
||||
int urlParametersPos = 0;
|
||||
|
||||
for (int i = 0; i < segments.Length; i++)
|
||||
{
|
||||
action = segments[segments.Length - 1];
|
||||
moduleid = result;
|
||||
path = path.Replace(moduleid.ToString() + "/" + action + "/", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
// check if path has moduleid specification ie. pagename/moduleid/
|
||||
if (segments.Length >= 1 && int.TryParse(segments[segments.Length - 1], out result))
|
||||
|
||||
if (segments[i] == Constants.UrlParametersDelimiter)
|
||||
{
|
||||
moduleid = result;
|
||||
path = path.Replace(moduleid.ToString() + "/", "");
|
||||
urlParametersPos = i + 1;
|
||||
}
|
||||
|
||||
if (i >= urlParametersPos && urlParametersPos != 0)
|
||||
{
|
||||
urlparameters += "/" + segments[i];
|
||||
}
|
||||
|
||||
if (segments[i] == Constants.ModuleDelimiter)
|
||||
{
|
||||
modIdPos = i + 1;
|
||||
actionPos = modIdPos + 1;
|
||||
if (actionPos > segments.Length - 1)
|
||||
{
|
||||
action = Constants.DefaultAction;
|
||||
}
|
||||
else
|
||||
{
|
||||
action = segments[actionPos];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// check if path has moduleid and action specification ie. pagename/moduleid/action/
|
||||
if (modIdPos > 0)
|
||||
{
|
||||
int.TryParse(segments[modIdPos], out result);
|
||||
moduleid = result;
|
||||
if (actionPos > segments.Length - 1)
|
||||
{
|
||||
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
path = path.Replace(segments[modIdPos - 1] + "/" + segments[modIdPos] + "/" + segments[actionPos] + "/", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (urlParametersPos > 0)
|
||||
{
|
||||
path = path.Replace(segments[urlParametersPos - 1] + urlparameters + "/", "");
|
||||
}
|
||||
|
||||
// remove trailing slash so it can be used as a key for Pages
|
||||
@ -220,17 +260,14 @@
|
||||
{
|
||||
page = pages.Where(item => item.Path == path).FirstOrDefault();
|
||||
reload = Reload.Page;
|
||||
if (page != null)
|
||||
{
|
||||
editmode = page.EditMode;
|
||||
}
|
||||
editmode = false;
|
||||
}
|
||||
|
||||
if (page != null)
|
||||
{
|
||||
if (PageState == null)
|
||||
{
|
||||
editmode = page.EditMode;
|
||||
editmode = false;
|
||||
}
|
||||
|
||||
// check if user is authorized to view page
|
||||
@ -263,6 +300,7 @@
|
||||
Modules = modules,
|
||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||
QueryString = querystring,
|
||||
UrlParameters = urlparameters,
|
||||
ModuleId = moduleid,
|
||||
Action = action,
|
||||
EditMode = editmode,
|
||||
@ -277,7 +315,6 @@
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
await LogService.Log(null, null, null, GetType().AssemblyQualifiedName, Utilities.GetTypeNameLastSegment(GetType().AssemblyQualifiedName, 1), LogFunction.Security, LogLevel.Error, null, "Page Does Not Exist Or User Is Not Authorized To View Page {Path}", path);
|
||||
// redirect to login page
|
||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "login", "returnurl=" + path));
|
||||
}
|
||||
@ -361,20 +398,33 @@
|
||||
|
||||
string panes = "";
|
||||
Type themetype = Type.GetType(page.ThemeType);
|
||||
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
||||
if (themeobject != null)
|
||||
if (themetype == null)
|
||||
{
|
||||
panes = themeobject.Panes;
|
||||
page.Resources = ManagePageResources(page.Resources, themeobject.Resources);
|
||||
// fallback
|
||||
page.ThemeType = Constants.DefaultTheme;
|
||||
page.LayoutType = Constants.DefaultLayout;
|
||||
themetype = Type.GetType(Constants.DefaultTheme);
|
||||
}
|
||||
if (themetype != null)
|
||||
{
|
||||
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
||||
if (themeobject != null)
|
||||
{
|
||||
panes = themeobject.Panes;
|
||||
page.Resources = ManagePageResources(page.Resources, themeobject.Resources);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(page.LayoutType))
|
||||
{
|
||||
Type layouttype = Type.GetType(page.LayoutType);
|
||||
var layoutobject = Activator.CreateInstance(layouttype) as ILayoutControl;
|
||||
if (layoutobject != null)
|
||||
if (layouttype != null)
|
||||
{
|
||||
panes = layoutobject.Panes;
|
||||
var layoutobject = Activator.CreateInstance(layouttype) as IThemeControl;
|
||||
if (layoutobject != null)
|
||||
{
|
||||
panes = layoutobject.Panes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -396,7 +446,7 @@
|
||||
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
||||
{
|
||||
var typename = string.Empty;
|
||||
if (module.ModuleDefinition != null)
|
||||
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(GetRuntime().ToString())))
|
||||
{
|
||||
typename = module.ModuleDefinition.ControlTypeTemplate;
|
||||
}
|
||||
|
@ -13,6 +13,13 @@
|
||||
{
|
||||
var interop = new Interop(JsRuntime);
|
||||
|
||||
// handle page redirection
|
||||
if (!string.IsNullOrEmpty(PageState.Page.Url))
|
||||
{
|
||||
NavigationManager.NavigateTo(PageState.Page.Url);
|
||||
return;
|
||||
}
|
||||
|
||||
// set page title
|
||||
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
||||
{
|
||||
@ -23,31 +30,20 @@
|
||||
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
||||
}
|
||||
|
||||
// update page resources
|
||||
int stylesheet = 0;
|
||||
int script = 0;
|
||||
foreach (Resource resource in PageState.Page.Resources)
|
||||
// manage stylesheets for this page
|
||||
string batch = DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
||||
var links = new List<object>();
|
||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||
{
|
||||
switch (resource.ResourceType)
|
||||
{
|
||||
case ResourceType.Stylesheet:
|
||||
stylesheet += 1;
|
||||
await interop.IncludeLink("app-stylesheet" + stylesheet.ToString("00"), "stylesheet", resource.Url, "text/css", resource.Integrity ?? "", resource.CrossOrigin ?? "");
|
||||
break;
|
||||
case ResourceType.Script:
|
||||
script += 1;
|
||||
await interop.IncludeScript("app-script" + script.ToString("00"), resource.Url, "", "body", resource.Integrity ?? "", resource.CrossOrigin ?? "");
|
||||
break;
|
||||
}
|
||||
links.Add(new { id = "app-stylesheet-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = resource.Url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", key = "" });
|
||||
}
|
||||
// remove any page resources references which are no longer required for this page
|
||||
await interop.RemoveElementsById("app-stylesheet", "app-stylesheet" + (stylesheet + 1).ToString("00"), "");
|
||||
await interop.RemoveElementsById("app-script", "app-script" + (script + 1).ToString("00"), "");
|
||||
await interop.IncludeLinks(links.ToArray());
|
||||
await interop.RemoveElementsById("app-stylesheet", "", "app-stylesheet-" + batch + "-00");
|
||||
|
||||
// add favicon
|
||||
if (PageState.Site.FaviconFileId != null)
|
||||
{
|
||||
await interop.IncludeLink("fav-icon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "");
|
||||
await interop.IncludeLink("app-favicon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "", "id");
|
||||
}
|
||||
// add PWA support
|
||||
if (PageState.Site.PwaIsEnabled)
|
||||
@ -58,18 +54,8 @@
|
||||
DynamicComponent = builder =>
|
||||
{
|
||||
var themeType = Type.GetType(PageState.Page.ThemeType);
|
||||
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();
|
||||
}
|
||||
builder.OpenComponent(0, themeType);
|
||||
builder.CloseComponent();
|
||||
};
|
||||
}
|
||||
|
||||
@ -97,10 +83,10 @@
|
||||
"const serialized = JSON.stringify(manifest); " +
|
||||
"const blob = new Blob([serialized], {type: 'application/javascript'}); " +
|
||||
"const url = URL.createObjectURL(blob); " +
|
||||
"document.getElementById('pwa-manifest').setAttribute('href', url); " +
|
||||
"document.getElementById('app-manifest').setAttribute('href', url); " +
|
||||
"} " +
|
||||
", 1000);";
|
||||
await interop.IncludeScript("pwa-manifestscript", "", manifest, "body", "", "");
|
||||
await interop.IncludeScript("app-pwa", "", "", "", manifest, "body", "id");
|
||||
|
||||
// service worker must be in root of site
|
||||
string serviceworker = "if ('serviceWorker' in navigator) { " +
|
||||
@ -110,6 +96,6 @@
|
||||
"console.log('ServiceWorker Registration Failed ', err); " +
|
||||
"}); " +
|
||||
"}";
|
||||
await interop.IncludeScript("pwa-serviceworker", "", serviceworker, "body", "", "");
|
||||
await interop.IncludeScript("app-serviceworker", "", "", "", serviceworker, "body", "id");
|
||||
}
|
||||
}
|
||||
|
23
Oqtane.Package/Oqtane.Client.nuspec
Normal file
23
Oqtane.Package/Oqtane.Client.nuspec
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>1.0.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
<description>A modular application framework for Blazor</description>
|
||||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib\netstandard2.1" />
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.pdb" target="lib\netstandard2.1" />
|
||||
</files>
|
||||
</package>
|
@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>1.0.0</version>
|
||||
<version>1.0.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -13,13 +13,11 @@
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane framework</tags>
|
||||
<releaseNotes>Initial Release</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Client\bin\Release\netstandard2.1\Oqtane.Client.dll" target="lib" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Upgrade.dll" target="lib" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\*.*" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\wwwroot\**\*.*" target="wwwroot" />
|
||||
</files>
|
||||
</package>
|
23
Oqtane.Package/Oqtane.Server.nuspec
Normal file
23
Oqtane.Package/Oqtane.Server.nuspec
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>1.0.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
<description>A modular application framework for Blazor</description>
|
||||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.dll" target="lib\netcoreapp3.1" />
|
||||
<file src="..\Oqtane.Server\bin\Release\netcoreapp3.1\Oqtane.Server.pdb" target="lib\netcoreapp3.1" />
|
||||
</files>
|
||||
</package>
|
23
Oqtane.Package/Oqtane.Shared.nuspec
Normal file
23
Oqtane.Package/Oqtane.Shared.nuspec
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>1.0.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
<description>A modular application framework for Blazor</description>
|
||||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<iconUrl>https://www.oqtane.org/Portals/0/icon.jpg</iconUrl>
|
||||
<tags>oqtane</tags>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v1.0.3</releaseNotes>
|
||||
<summary>A modular application framework for Blazor</summary>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.dll" target="lib\netstandard2.1" />
|
||||
<file src="..\Oqtane.Shared\bin\Release\netstandard2.1\Oqtane.Shared.pdb" target="lib\netstandard2.1" />
|
||||
</files>
|
||||
</package>
|
1
Oqtane.Package/install.ps1
Normal file
1
Oqtane.Package/install.ps1
Normal file
@ -0,0 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.1.0.3.Install.zip" -Force
|
Binary file not shown.
@ -1,3 +0,0 @@
|
||||
DEL "*.nupkg"
|
||||
nuget.exe pack Oqtane.Framework.nuspec
|
||||
|
18
Oqtane.Package/release.cmd
Normal file
18
Oqtane.Package/release.cmd
Normal file
@ -0,0 +1,18 @@
|
||||
del "*.nupkg"
|
||||
dotnet clean -c Release ..\Oqtane.sln
|
||||
dotnet build -c Release ..\Oqtane.sln
|
||||
nuget.exe pack Oqtane.Client.nuspec
|
||||
nuget.exe pack Oqtane.Server.nuspec
|
||||
nuget.exe pack Oqtane.Shared.nuspec
|
||||
del /F/Q/S "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish" > NUL
|
||||
rmdir /Q/S "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish"
|
||||
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
|
||||
del "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\appsettings.json"
|
||||
ren "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\appsettings.release.json" "appsettings.json"
|
||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
||||
del "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\appsettings.json"
|
||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
|
||||
del "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\Oqtane.Upgrade.*"
|
||||
nuget.exe pack Oqtane.Framework.nuspec
|
||||
|
||||
|
1
Oqtane.Package/upgrade.ps1
Normal file
1
Oqtane.Package/upgrade.ps1
Normal file
@ -0,0 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\netcoreapp3.1\publish\*" -DestinationPath "..\Oqtane.Server\bin\Release\Oqtane.Framework.1.0.3.Upgrade.zip" -Force
|
@ -47,7 +47,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
|
||||
// GET api/<controller>/name/xxx?sync=yyyyMMddHHmmssfff
|
||||
[HttpGet("name/{name}")]
|
||||
[HttpGet("name/{**name}")]
|
||||
public Alias Get(string name, string sync)
|
||||
{
|
||||
List<Alias> aliases = _aliases.GetAliases().ToList(); // cached
|
||||
|
@ -1,4 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@ -483,7 +483,7 @@ namespace Oqtane.Controllers
|
||||
string[] folders = folderpath.Split(separators, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (string folder in folders)
|
||||
{
|
||||
path = Utilities.PathCombine(path, folder, "\\");
|
||||
path = Utilities.PathCombine(path, folder, Path.DirectorySeparatorChar.ToString());
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Oqtane.Models;
|
||||
@ -112,7 +113,7 @@ namespace Oqtane.Controllers
|
||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||
}
|
||||
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
||||
folder.Path = Utilities.PathCombine(folder.Path, Path.DirectorySeparatorChar.ToString());
|
||||
folder = _folders.AddFolder(folder);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Folder Added {Folder}", folder);
|
||||
}
|
||||
@ -147,7 +148,7 @@ namespace Oqtane.Controllers
|
||||
Folder parent = _folders.GetFolder(folder.ParentId.Value);
|
||||
folder.Path = Utilities.PathCombine(parent.Path, folder.Name);
|
||||
}
|
||||
folder.Path = Utilities.PathCombine(folder.Path, "\\");
|
||||
folder.Path = Utilities.PathCombine(folder.Path, Path.DirectorySeparatorChar.ToString());
|
||||
folder = _folders.UpdateFolder(folder);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Folder Updated {Folder}", folder);
|
||||
}
|
||||
|
@ -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");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user