Compare commits
317 Commits
Author | SHA1 | Date | |
---|---|---|---|
681321feeb | |||
a637b6d4d0 | |||
5161ade786 | |||
6dd62a164e | |||
3bece7599c | |||
b2f3a53980 | |||
cea31a8573 | |||
ce6647a84a | |||
d54ba9a5c6 | |||
1e18d913e0 | |||
0041c7d3b3 | |||
f6cca5cb35 | |||
fa5abbf96f | |||
2ff365765d | |||
ee31e4a411 | |||
ee4068d671 | |||
5e86c95db6 | |||
6126624631 | |||
a7c5841e76 | |||
0f242a94b4 | |||
8f8a0897e4 | |||
7c6b64123c | |||
55642093ed | |||
5660f40512 | |||
df7cd648ac | |||
2a5713ed67 | |||
de93281f3e | |||
86fbdced1b | |||
43bcfb9a4e | |||
0daf6af3b8 | |||
c3bccbade8 | |||
1e39f48235 | |||
05b5d9da9b | |||
db2aa920e2 | |||
8067b2e634 | |||
273c6d7dee | |||
d9f3db5bf3 | |||
c8a679ecce | |||
3abe47ae9e | |||
fcb05a7834 | |||
02e22df4d5 | |||
8bfca2f10a | |||
6bea9a087c | |||
3f4218f75f | |||
3849f59126 | |||
8ccee87378 | |||
9e518ffc4c | |||
e3233fd19f | |||
d3af9b0f14 | |||
08daca848b | |||
3b0ffde1fb | |||
6ca97e8d5d | |||
34a727b435 | |||
b1b9100600 | |||
bda0943d58 | |||
b21d202c7f | |||
3ea8ea1e3b | |||
ee897a9973 | |||
5f8cfb9977 | |||
d7928a70bf | |||
93568af5a9 | |||
9e86d97253 | |||
84bac0c462 | |||
3c18a258ff | |||
9759c68d58 | |||
f57a190405 | |||
d2eb203aa1 | |||
dd2c2dbe61 | |||
2529592b66 | |||
f248d2fe4e | |||
875bcd8ce2 | |||
726f9375e1 | |||
0c2e200245 | |||
a10db462eb | |||
6df28d8171 | |||
8367f15638 | |||
69456d3569 | |||
3b644338bc | |||
02e29aa22f | |||
88c489a585 | |||
706e73210d | |||
d52809c914 | |||
6058286577 | |||
a271f24157 | |||
2299375aaa | |||
c3290526a4 | |||
a9d871e9af | |||
5eb25796ca | |||
5d650bd276 | |||
b6be519537 | |||
160477d612 | |||
b2bc09be16 | |||
2f5d1cebb0 | |||
e4d144651e | |||
ce56dfc239 | |||
ad4f8fd7a0 | |||
c4070cb603 | |||
602fd7d658 | |||
818fd2fb43 | |||
e4912fcb09 | |||
3692ec49c1 | |||
9a1ea3f375 | |||
10a754642a | |||
bc9de5d094 | |||
9f93476167 | |||
f61492d353 | |||
50cf67546b | |||
41d83ec421 | |||
cc9377b37d | |||
7f986d5f60 | |||
d272bf8a29 | |||
ba5260f5b1 | |||
40c788fc33 | |||
8f147e7de2 | |||
85358c7dd4 | |||
87c7eafb87 | |||
613f4848da | |||
3cb06e4819 | |||
811701ef7f | |||
c14dc67d8a | |||
867767f009 | |||
640216d076 | |||
6b7c61f228 | |||
28ba2c00fc | |||
b56daae321 | |||
b57450398c | |||
c3d884e895 | |||
7a21f96552 | |||
4ccb4c636f | |||
0d5c3a3a0c | |||
b093cbff15 | |||
30cb8ec9c3 | |||
d5e51d6c38 | |||
6f0a6c7f69 | |||
549d71073e | |||
4ad5522f9e | |||
2145c1a48c | |||
0f093b1238 | |||
1aa3fd7056 | |||
cc4c47c3ee | |||
6e3f3fac9d | |||
261adefbc7 | |||
7eafcfd7ad | |||
6183d6a22e | |||
51d42692ba | |||
18a9c059f4 | |||
50a13ffd6d | |||
b360944742 | |||
59d1a47846 | |||
22969d8daa | |||
95ba87945b | |||
da11a86f99 | |||
98c2f012ee | |||
386c6144f8 | |||
666f9c2db9 | |||
f7c49588fb | |||
c0e6f06a5c | |||
31907f2d16 | |||
452d0af8c9 | |||
d13f26dc7e | |||
03374483e4 | |||
b1c0a865a0 | |||
7b0799a6f6 | |||
0de2976933 | |||
20c7bf3c48 | |||
55e090ba2a | |||
ded326c822 | |||
1ee9c2cf0e | |||
e41d9008b3 | |||
1ec24251a2 | |||
2be48c3847 | |||
2137b79f6d | |||
0b8086bd36 | |||
d16659890c | |||
076d150f72 | |||
62deffd017 | |||
f1ec70ff14 | |||
af27c763e0 | |||
7336417634 | |||
cde46c0889 | |||
5da4dadc31 | |||
e32ca089ec | |||
8d2f644177 | |||
a003010be5 | |||
89ada83012 | |||
65fbf6926c | |||
5e652364c9 | |||
8b7c3d6cfa | |||
3b214a0105 | |||
c0c4073bc4 | |||
dbe7324c7f | |||
9316255e87 | |||
7f7dff7019 | |||
961e004a49 | |||
02c1e4fb65 | |||
bcbc2a6e95 | |||
0c749a126c | |||
3698ebad7c | |||
f59a5c90a5 | |||
36e4a69891 | |||
19b560f7c1 | |||
0bec92e87e | |||
a0d02f16cd | |||
4a0f655e1c | |||
91bf65292d | |||
a69d52d688 | |||
79fe224cea | |||
757d8e59a2 | |||
53ec1416b4 | |||
d1b52534de | |||
35edc053b5 | |||
2aa8d3be0f | |||
ec0a5377b3 | |||
b876da069d | |||
f06063d7eb | |||
c6ba4f4bee | |||
89da4ab2a1 | |||
99ac0a3cab | |||
a964c30705 | |||
2334d0297d | |||
e444c6bcf0 | |||
601582fc98 | |||
e939dbe24e | |||
143ad85fd5 | |||
20377e9789 | |||
e4a24df7b4 | |||
e88ca00658 | |||
2312c612d7 | |||
3aee52482d | |||
32248e0be6 | |||
6c18c320bd | |||
e31f32e5aa | |||
a856390566 | |||
64b8291487 | |||
2ebd1310c9 | |||
09118fcb42 | |||
5d5167abbc | |||
bf43dea060 | |||
6ebab830c5 | |||
9a9a78e0bd | |||
418eff7d21 | |||
d39869ca8e | |||
7829168ea7 | |||
dd83e3ee67 | |||
c3ac0e365d | |||
2986625605 | |||
8beaeabf09 | |||
fa9b4b6112 | |||
d81fbe4585 | |||
536c044139 | |||
376531195e | |||
abf4ff71d7 | |||
d25debcea3 | |||
948c186cb5 | |||
ba27e70fe3 | |||
c93d2576af | |||
e0b0156640 | |||
a3ca6a3071 | |||
b20157450b | |||
7e4f0923d7 | |||
e0c2b2982f | |||
9a231c28af | |||
94a02b7bf9 | |||
22c8fb411a | |||
cf46210ff8 | |||
f32d988297 | |||
7fe4577158 | |||
8985dcb4c0 | |||
d346444c51 | |||
ef27a0d6b0 | |||
627158cb5d | |||
648edcabba | |||
0f34c6efc5 | |||
cc3cc55269 | |||
a503a9d5bc | |||
789baf99ff | |||
036279a54c | |||
481f18cf1c | |||
2f1e386554 | |||
1e0c7cf43d | |||
7978c89731 | |||
82221f54c5 | |||
2e23e6e4d5 | |||
3a79fa074a | |||
696c63c6d2 | |||
8f6dc52430 | |||
c8a9ad9807 | |||
a0933d07d8 | |||
6bf61e2008 | |||
36ecc55578 | |||
47065299ca | |||
0f707a7607 | |||
7590c5550f | |||
3d23a5c79a | |||
9aa0374dc2 | |||
058a191673 | |||
5fbb9160f1 | |||
2c3dad0592 | |||
00f039d31e | |||
497ef1750b | |||
7d4cd04ce9 | |||
04c0b9d37d | |||
b9c16c0727 | |||
0a30f2b7e8 | |||
dbb1d53202 | |||
2c88f36e3d | |||
d91dcad774 | |||
6eb4ea2a2d | |||
ff6187c336 | |||
1253dfe0c8 | |||
c1f2f9a970 | |||
8d5e7ed69f | |||
3d3540f090 | |||
61f1fcb99c | |||
c7b576d6d3 | |||
ab3b1d5e46 | |||
ddff3faba9 |
@ -1,6 +1,8 @@
|
|||||||
|
@using Microsoft.AspNetCore.Http
|
||||||
@inject IInstallationService InstallationService
|
@inject IInstallationService InstallationService
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
@inject SiteState SiteState
|
@inject SiteState SiteState
|
||||||
|
@inject IServiceProvider ServiceProvider
|
||||||
|
|
||||||
@if (_initialized)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
@ -54,12 +56,24 @@
|
|||||||
|
|
||||||
private PageState PageState { get; set; }
|
private PageState PageState { get; set; }
|
||||||
|
|
||||||
|
private IHttpContextAccessor accessor;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
SiteState.RemoteIPAddress = RemoteIPAddress;
|
SiteState.RemoteIPAddress = RemoteIPAddress;
|
||||||
SiteState.AntiForgeryToken = AntiForgeryToken;
|
SiteState.AntiForgeryToken = AntiForgeryToken;
|
||||||
SiteState.AuthorizationToken = AuthorizationToken;
|
SiteState.AuthorizationToken = AuthorizationToken;
|
||||||
|
|
||||||
|
accessor = (IHttpContextAccessor)ServiceProvider.GetService(typeof(IHttpContextAccessor));
|
||||||
|
if (accessor != null)
|
||||||
|
{
|
||||||
|
SiteState.IsPrerendering = !accessor.HttpContext.Response.HasStarted;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SiteState.IsPrerendering = true;
|
||||||
|
}
|
||||||
|
|
||||||
_installation = await InstallationService.IsInstalled();
|
_installation = await InstallationService.IsInstalled();
|
||||||
if (_installation.Alias != null)
|
if (_installation.Alias != null)
|
||||||
{
|
{
|
||||||
@ -72,6 +86,7 @@
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
|
// prevents flash on initial page load
|
||||||
_display = "";
|
_display = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
64
Oqtane.Client/Head.razor
Normal file
64
Oqtane.Client/Head.razor
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
@using System.ComponentModel
|
||||||
|
@using Oqtane.Shared
|
||||||
|
@inject SiteState SiteState
|
||||||
|
|
||||||
|
@if (!string.IsNullOrEmpty(_title))
|
||||||
|
{
|
||||||
|
@((MarkupString)_title)
|
||||||
|
}
|
||||||
|
@if (!string.IsNullOrEmpty(_content))
|
||||||
|
{
|
||||||
|
@((MarkupString)_content)
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private string _title = "";
|
||||||
|
private string _content = "";
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
((INotifyPropertyChanged)SiteState.Properties).PropertyChanged += PropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
switch (e.PropertyName)
|
||||||
|
{
|
||||||
|
case "PageTitle":
|
||||||
|
var title = "\n<title>" + SiteState.Properties.PageTitle + "</title>";
|
||||||
|
if (title != _title)
|
||||||
|
{
|
||||||
|
_title = title;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "HeadContent":
|
||||||
|
var content = RemoveScripts(SiteState.Properties.HeadContent) + "\n";
|
||||||
|
if (content != _content)
|
||||||
|
{
|
||||||
|
_content = content;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string RemoveScripts(string headcontent)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(headcontent))
|
||||||
|
{
|
||||||
|
var index = headcontent.IndexOf("<script");
|
||||||
|
while (index >= 0)
|
||||||
|
{
|
||||||
|
headcontent = headcontent.Remove(index, headcontent.IndexOf("</script>") + 9 - index);
|
||||||
|
index = headcontent.IndexOf("<script");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return headcontent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
((INotifyPropertyChanged)SiteState.Properties).PropertyChanged -= PropertyChanged;
|
||||||
|
}
|
||||||
|
}
|
@ -5,15 +5,17 @@
|
|||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IDatabaseService DatabaseService
|
@inject IDatabaseService DatabaseService
|
||||||
|
@inject ISiteTemplateService SiteTemplateService
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
@inject IStringLocalizer<Installer> Localizer
|
@inject IStringLocalizer<Installer> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
@inject SiteState SiteState
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mx-auto text-center">
|
<div class="mx-auto text-center">
|
||||||
<img src="oqtane-black.png" />
|
<img src="oqtane-black.png" />
|
||||||
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version</div>
|
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET 7)</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="app-rule" />
|
<hr class="app-rule" />
|
||||||
@ -77,7 +79,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordType" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
<input id="password" type="@_passwordType" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglePassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglePassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -86,7 +88,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_confirmPasswordType" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
<input id="confirm" type="@_confirmPasswordType" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@ToggleConfirmPassword">@_toggleConfirmPassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@ToggleConfirmPassword" tabindex="-1">@_toggleConfirmPassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -96,6 +98,20 @@
|
|||||||
<input type="text" class="form-control" @bind="@_hostEmail" />
|
<input type="text" class="form-control" @bind="@_hostEmail" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="template" HelpText="Select a site template" ResourceKey="Template">Template:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
@if (_templates != null)
|
||||||
|
{
|
||||||
|
<select id="template" class="form-select" @bind="@_template" required>
|
||||||
|
@foreach (var template in _templates)
|
||||||
|
{
|
||||||
|
<option value="@template.TypeName">@template.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -103,7 +119,13 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="mx-auto text-center">
|
<div class="mx-auto text-center">
|
||||||
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["InstallNow"]</button><br /><br />
|
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["InstallNow"]</button><br /><br />
|
||||||
<ModuleMessage Message="@_message" Type="MessageType.Error"></ModuleMessage>
|
@if (!string.IsNullOrEmpty(_message))
|
||||||
|
{
|
||||||
|
<div class="alert alert-danger alert-dismissible fade show mb-3" role="alert">
|
||||||
|
@((MarkupString)_message)
|
||||||
|
<button type="button" class="btn-close" aria-label="Close" @onclick="DismissModal"></button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
|
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -131,12 +153,18 @@
|
|||||||
private string _toggleConfirmPassword = string.Empty;
|
private string _toggleConfirmPassword = string.Empty;
|
||||||
private string _confirmPassword = string.Empty;
|
private string _confirmPassword = string.Empty;
|
||||||
private string _hostEmail = string.Empty;
|
private string _hostEmail = string.Empty;
|
||||||
|
private List<SiteTemplate> _templates;
|
||||||
|
private string _template = Constants.DefaultSiteTemplate;
|
||||||
private bool _register = true;
|
private bool _register = true;
|
||||||
private string _message = string.Empty;
|
private string _message = string.Empty;
|
||||||
private string _loadingDisplay = "display: none;";
|
private string _loadingDisplay = "display: none;";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
// include CSS
|
||||||
|
var content = "<link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css\" integrity=\"sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==\" crossorigin=\"anonymous\" type=\"text/css\"/>";
|
||||||
|
SiteState.AppendHeadContent(content);
|
||||||
|
|
||||||
_togglePassword = SharedLocalizer["ShowPassword"];
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
_toggleConfirmPassword = SharedLocalizer["ShowPassword"];
|
_toggleConfirmPassword = SharedLocalizer["ShowPassword"];
|
||||||
|
|
||||||
@ -150,6 +178,8 @@
|
|||||||
_databaseName = "LocalDB";
|
_databaseName = "LocalDB";
|
||||||
}
|
}
|
||||||
LoadDatabaseConfigComponent();
|
LoadDatabaseConfigComponent();
|
||||||
|
|
||||||
|
_templates = await SiteTemplateService.GetSiteTemplatesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DatabaseChanged(ChangeEventArgs eventArgs)
|
private void DatabaseChanged(ChangeEventArgs eventArgs)
|
||||||
@ -185,9 +215,9 @@
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
|
// include JavaScript
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
await interop.IncludeLink("", "stylesheet", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/css/bootstrap.min.css", "text/css", "sha512-XWTTruHZEYJsxV3W/lSXG1n3Q39YIWOstqvmFsdNEEQfHoZ6vm6E9GK2OrF6DSJSpIbRbi+Nn0WDPID9O7xB2Q==", "anonymous", "");
|
await interop.IncludeScript("", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js", "sha512-VK2zcvntEufaimc+efOYi622VN5ZacdnufnmX7zIhCPmjhKnOi9ZDMtg1/ug5l183f19gG1/cBstPO4D8N/Img==", "anonymous", "", "head");
|
||||||
await interop.IncludeScript("", "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/js/bootstrap.bundle.min.js", "sha512-9GacT4119eY3AcosfWtHMsT5JyZudrexyEVzTBWV3viP/YfB9e2pEy3N7WXL3SV6ASXpTU0vzzSxsbfsuUH4sQ==", "anonymous", "", "head");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +259,8 @@
|
|||||||
TenantName = TenantNames.Master,
|
TenantName = TenantNames.Master,
|
||||||
IsNewTenant = true,
|
IsNewTenant = true,
|
||||||
SiteName = Constants.DefaultSite,
|
SiteName = Constants.DefaultSite,
|
||||||
Register = _register
|
Register = _register,
|
||||||
|
SiteTemplate = _template
|
||||||
};
|
};
|
||||||
|
|
||||||
var installation = await InstallationService.Install(config);
|
var installation = await InstallationService.Install(config);
|
||||||
@ -291,4 +322,9 @@
|
|||||||
_showConnectionString = !_showConnectionString;
|
_showConnectionString = !_showConnectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DismissModal()
|
||||||
|
{
|
||||||
|
_message = "";
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
<div class="row">
|
@if (_pages != null)
|
||||||
|
{
|
||||||
|
<div class="row">
|
||||||
@foreach (var p in _pages)
|
@foreach (var p in _pages)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
@ -17,19 +19,20 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Page> _pages;
|
private List<Page> _pages;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
||||||
if (admin != null)
|
if (admin != null)
|
||||||
{
|
{
|
||||||
_pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList();
|
_pages = PageState.Pages.Where(item => item.ParentId == admin.PageId).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,6 @@ else
|
|||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="translated" HelpText="Specify If You Wish To Select Languages That Have Translations Installed" ResourceKey="Translated">Translated?</Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="translated" class="form-select" value="@_translated" @onchange="(e => TranslatedChanged(e))" required>
|
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
|
<Label Class="col-sm-3" For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="_code" class="form-select" @bind="@_code" required>
|
<select id="_code" class="form-select" @bind="@_code" required>
|
||||||
@ -57,13 +48,12 @@ else
|
|||||||
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
|
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" HelpText="Upload one or more translations. Once they are uploaded click Install to complete the installation." ResourceKey="LanguageUpload">Translation: </Label>
|
<Label Class="col-sm-3" HelpText="Upload one or more translations. Once they are uploaded click Install." ResourceKey="LanguageUpload">Translation: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
|
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" OnUpload="OnUpload" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
@ -73,7 +63,6 @@ else
|
|||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
|
|
||||||
private string _translated = "True";
|
|
||||||
private string _code = "-";
|
private string _code = "-";
|
||||||
private string _default = "False";
|
private string _default = "False";
|
||||||
private List<string> _languages;
|
private List<string> _languages;
|
||||||
@ -91,18 +80,11 @@ else
|
|||||||
|
|
||||||
private async Task LoadCultures()
|
private async Task LoadCultures()
|
||||||
{
|
{
|
||||||
_cultures = await LocalizationService.GetCulturesAsync(bool.Parse(_translated));
|
_cultures = await LocalizationService.GetCulturesAsync(false);
|
||||||
_cultures = _cultures.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !_languages.Contains(c.Name));
|
_cultures = _cultures.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !_languages.Contains(c.Name));
|
||||||
_code = "-";
|
_code = "-";
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TranslatedChanged(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
_translated = (string)e.Value;
|
|
||||||
await LoadCultures();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveLanguage()
|
private async Task SaveLanguage()
|
||||||
{
|
{
|
||||||
validated = true;
|
validated = true;
|
||||||
@ -142,19 +124,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallTranslations()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await PackageService.InstallPackagesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Language.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Translations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SetCultureAsync(string culture)
|
private async Task SetCultureAsync(string culture)
|
||||||
{
|
{
|
||||||
if (culture != CultureInfo.CurrentUICulture.Name)
|
if (culture != CultureInfo.CurrentUICulture.Name)
|
||||||
@ -166,4 +135,9 @@ else
|
|||||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnUpload()
|
||||||
|
{
|
||||||
|
AddModuleMessage(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,23 +35,27 @@ else
|
|||||||
{
|
{
|
||||||
<td>@((string.IsNullOrEmpty(context.Version)) ? "---" : context.Version)</td>
|
<td>@((string.IsNullOrEmpty(context.Version)) ? "---" : context.Version)</td>
|
||||||
<td>
|
<td>
|
||||||
@switch (TranslationAvailable(context.Code, context.Version))
|
@{
|
||||||
|
var translation = TranslationAvailable(context.Code, context.Version);
|
||||||
|
}
|
||||||
|
@if (translation != null)
|
||||||
{
|
{
|
||||||
case "install":
|
if (string.IsNullOrEmpty(context.Version))
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code))>@SharedLocalizer["Download"]</button>
|
{
|
||||||
break;
|
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code, translation.Version))>@SharedLocalizer["Download"]</button>
|
||||||
case "upgrade":
|
}
|
||||||
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code))>@SharedLocalizer["Upgrade"]</button>
|
else
|
||||||
break;
|
{
|
||||||
|
if (Version.Parse(translation.Version).CompareTo(Version.Parse(context.Version)) > 0)
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-success" @onclick=@(async () => await GetPackage(context.Code, translation.Version))>@SharedLocalizer["Upgrade"]</button>
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
}
|
}
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host) && _install)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_package != null)
|
@if (_package != null)
|
||||||
@ -98,7 +102,6 @@ else
|
|||||||
private List<Language> _languages;
|
private List<Language> _languages;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private Package _package;
|
private Package _package;
|
||||||
private bool _install = false;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
@ -134,38 +137,16 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string TranslationAvailable(string code, string version)
|
private Package TranslationAvailable(string code, string version)
|
||||||
{
|
{
|
||||||
if (_packages != null)
|
return _packages?.FirstOrDefault(item => item.PackageId == (Constants.PackageId + "." + code));
|
||||||
{
|
|
||||||
var package = _packages.Where(item => item.PackageId == (Constants.PackageId + "." + code)).FirstOrDefault();
|
|
||||||
if (package != null)
|
|
||||||
{
|
|
||||||
// package version needs to match current framework version
|
|
||||||
if (Version.Parse(package.Version).CompareTo(Version.Parse(Constants.Version)) == 0)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(version))
|
|
||||||
{
|
|
||||||
return "install";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0)
|
|
||||||
{
|
|
||||||
return "upgrade";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task GetPackage(string code)
|
private async Task GetPackage(string code, string version)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, Constants.Version);
|
_package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, version);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -181,9 +162,8 @@ else
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Language Package {Name} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
await logger.LogInformation("Language Package {Name} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
||||||
AddModuleMessage(Localizer["Success.Language.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_package = null;
|
_package = null;
|
||||||
_install = true;
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -198,19 +178,4 @@ else
|
|||||||
_package = null;
|
_package = null;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallTranslations()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await PackageService.InstallPackagesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Translation.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
_install = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Translations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<Label Class="control-label" For="password" HelpText="Please enter your Password" ResourceKey="Password">Password:</Label>
|
<Label Class="control-label" For="password" HelpText="Please enter your Password" ResourceKey="Password">Password:</Label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" name="Password" class="form-control" placeholder="@Localizer["Password.Placeholder"]" @bind="@_password" required />
|
<input id="password" type="@_passwordtype" name="Password" class="form-control" placeholder="@Localizer["Password.Placeholder"]" @bind="@_password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mt-2">
|
<div class="form-group mt-2">
|
||||||
|
@ -195,7 +195,7 @@ else
|
|||||||
if (_owner != "" && _module != "" && _template != "-")
|
if (_owner != "" && _module != "" && _template != "-")
|
||||||
{
|
{
|
||||||
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
||||||
_location = template.Location + _owner + "." + _module;
|
_location = template.Location + _owner + ".Module." + _module;
|
||||||
|
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
@ -65,13 +65,15 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<br />
|
||||||
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
<TabPanel Name="Upload" ResourceKey="Upload">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
|
<Label Class="col-sm-3" HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
|
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" OnUpload="OnUpload" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -111,13 +113,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallModules">@SharedLocalizer["Install"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
@ -236,7 +233,7 @@
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_packageid, _packageversion, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_packageid, _packageversion, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion);
|
||||||
AddModuleMessage(Localizer["Success.Module.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_productname = "";
|
_productname = "";
|
||||||
_packagelicense = "";
|
_packagelicense = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -248,16 +245,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallModules()
|
private void OnUpload()
|
||||||
{
|
{
|
||||||
try
|
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
{
|
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Modules");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,15 @@
|
|||||||
<input id="categories" class="form-control" @bind="@_categories" maxlength="200" required />
|
<input id="categories" class="form-control" @bind="@_categories" maxlength="200" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="isenabled" HelpText="Is module enabled for this site?" ResourceKey="IsEnabled">Enabled? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="isenabled" class="form-select" @bind="@_isenabled" required>
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<Section Name="Information" ResourceKey="Information">
|
<Section Name="Information" ResourceKey="Information">
|
||||||
@ -131,10 +140,6 @@
|
|||||||
</td>
|
</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@if (_install)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallTranslations">@SharedLocalizer["Install"]</button>
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -203,6 +208,7 @@
|
|||||||
private string _name;
|
private string _name;
|
||||||
private string _description = "";
|
private string _description = "";
|
||||||
private string _categories;
|
private string _categories;
|
||||||
|
private string _isenabled;
|
||||||
private string _moduledefinitionname = "";
|
private string _moduledefinitionname = "";
|
||||||
private string _version;
|
private string _version;
|
||||||
private string _packagename = "";
|
private string _packagename = "";
|
||||||
@ -224,7 +230,6 @@
|
|||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private List<Language> _languages;
|
private List<Language> _languages;
|
||||||
private Package _package;
|
private Package _package;
|
||||||
private bool _install = false;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
@ -239,6 +244,7 @@
|
|||||||
_name = moduleDefinition.Name;
|
_name = moduleDefinition.Name;
|
||||||
_description = moduleDefinition.Description;
|
_description = moduleDefinition.Description;
|
||||||
_categories = moduleDefinition.Categories;
|
_categories = moduleDefinition.Categories;
|
||||||
|
_isenabled = moduleDefinition.IsEnabled.ToString();
|
||||||
_moduledefinitionname = moduleDefinition.ModuleDefinitionName;
|
_moduledefinitionname = moduleDefinition.ModuleDefinitionName;
|
||||||
_version = moduleDefinition.Version;
|
_version = moduleDefinition.Version;
|
||||||
_packagename = moduleDefinition.PackageName;
|
_packagename = moduleDefinition.PackageName;
|
||||||
@ -285,6 +291,9 @@
|
|||||||
if (await interop.FormValid(form))
|
if (await interop.FormValid(form))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
var moduleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||||
|
if (!moduleDefinitions.Any(item => item.Name.ToLower() == _name.ToLower() && item.ModuleDefinitionId != _moduleDefinitionId))
|
||||||
{
|
{
|
||||||
var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
|
var moduledefinition = await ModuleDefinitionService.GetModuleDefinitionAsync(_moduleDefinitionId, ModuleState.SiteId);
|
||||||
if (moduledefinition.Name != _name)
|
if (moduledefinition.Name != _name)
|
||||||
@ -299,10 +308,16 @@
|
|||||||
{
|
{
|
||||||
moduledefinition.Categories = _categories;
|
moduledefinition.Categories = _categories;
|
||||||
}
|
}
|
||||||
|
moduledefinition.IsEnabled = (_isenabled == null ? true : bool.Parse(_isenabled));
|
||||||
moduledefinition.PermissionList = _permissionGrid.GetPermissionList();
|
moduledefinition.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
|
await ModuleDefinitionService.UpdateModuleDefinitionAsync(moduledefinition);
|
||||||
await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
|
await logger.LogInformation("ModuleDefinition Saved {ModuleDefinition}", moduledefinition);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.DuplicateName"], MessageType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -366,9 +381,8 @@
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _package.PackageId, _package.Version);
|
||||||
AddModuleMessage(Localizer["Success.Translation.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Translation.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_package = null;
|
_package = null;
|
||||||
_install = true;
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -377,19 +391,4 @@
|
|||||||
AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallTranslations()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await PackageService.InstallPackagesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Translation.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
_install = false;
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Translations");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ else
|
|||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
<th>@SharedLocalizer["Version"]</th>
|
<th>@SharedLocalizer["Version"]</th>
|
||||||
|
<th>@Localizer["Enabled"]</th>
|
||||||
<th>@Localizer["InUse"]</th>
|
<th>@Localizer["InUse"]</th>
|
||||||
<th>@SharedLocalizer["Expires"]</th>
|
<th>@SharedLocalizer["Expires"]</th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
@ -57,6 +58,16 @@ else
|
|||||||
</td>
|
</td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.Version</td>
|
<td>@context.Version</td>
|
||||||
|
<td>
|
||||||
|
@if (context.IsEnabled)
|
||||||
|
{
|
||||||
|
<span>@SharedLocalizer["Yes"]</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span>@SharedLocalizer["No"]</span>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName == Constants.ClientId || PageState.Modules.Where(m => m.ModuleDefinition?.ModuleDefinitionId == context.ModuleDefinitionId).FirstOrDefault() != null)
|
@if (context.AssemblyName == Constants.ClientId || PageState.Modules.Where(m => m.ModuleDefinition?.ModuleDefinitionId == context.ModuleDefinitionId).FirstOrDefault() != null)
|
||||||
{
|
{
|
||||||
@ -149,7 +160,6 @@ else
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
||||||
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -44,13 +44,21 @@
|
|||||||
<Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
|
<Label Class="col-sm-3" For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="page" class="form-select" @bind="@_pageId" required>
|
<select id="page" class="form-select" @bind="@_pageId" required>
|
||||||
@foreach (Page p in PageState.Pages)
|
@if (PageState.Page.UserId != null)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
<option value="@PageState.Page.PageId">@(PageState.Page.Name)</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (Page p in PageState.Pages)
|
||||||
|
{
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, p.PermissionList))
|
||||||
{
|
{
|
||||||
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
|
<option value="@p.PageId">@(new string('-', p.Level * 2))@(p.Name)</option>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -95,7 +103,6 @@
|
|||||||
|
|
||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
private List<Theme> _themes;
|
|
||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _title;
|
private string _title;
|
||||||
private string _containerType;
|
private string _containerType;
|
||||||
@ -116,11 +123,10 @@
|
|||||||
private string modifiedby;
|
private string modifiedby;
|
||||||
private DateTime modifiedon;
|
private DateTime modifiedon;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
_title = ModuleState.Title;
|
_title = ModuleState.Title;
|
||||||
_themes = await ThemeService.GetThemesAsync();
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||||
_containers = ThemeService.GetContainerControls(_themes, PageState.Page.ThemeType);
|
|
||||||
_containerType = ModuleState.ContainerType;
|
_containerType = ModuleState.ContainerType;
|
||||||
_allPages = ModuleState.AllPages.ToString();
|
_allPages = ModuleState.AllPages.ToString();
|
||||||
_permissions = ModuleState.PermissionList;
|
_permissions = ModuleState.PermissionList;
|
||||||
@ -165,7 +171,7 @@
|
|||||||
AddModuleMessage(string.Format(Localizer["Error.Module.Load"], ModuleState.ModuleDefinitionName), MessageType.Error);
|
AddModuleMessage(string.Format(Localizer["Error.Module.Load"], ModuleState.ModuleDefinitionName), MessageType.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
var theme = _themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType)));
|
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Containers.Any(themecontrol => themecontrol.TypeName.Equals(_containerType)));
|
||||||
if (theme != null && !string.IsNullOrEmpty(theme.ContainerSettingsType))
|
if (theme != null && !string.IsNullOrEmpty(theme.ContainerSettingsType))
|
||||||
{
|
{
|
||||||
_containerSettingsType = Type.GetType(theme.ContainerSettingsType);
|
_containerSettingsType = Type.GetType(theme.ContainerSettingsType);
|
||||||
|
@ -6,12 +6,11 @@
|
|||||||
@inject IStringLocalizer<Add> Localizer
|
@inject IStringLocalizer<Add> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
{
|
||||||
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
<TabStrip Refresh="@_refresh">
|
<TabStrip Refresh="@_refresh">
|
||||||
<TabPanel Name="Settings" ResourceKey="Settings">
|
<TabPanel Name="Settings" ResourceKey="Settings">
|
||||||
@if (_themeList != null)
|
|
||||||
{
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
|
<Label Class="col-sm-3" For="name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
|
||||||
@ -19,15 +18,20 @@
|
|||||||
<input id="name" class="form-control" @bind="@_name" required />
|
<input id="name" class="form-control" @bind="@_name" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
|
{
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
|
<Label Class="col-sm-3" For="parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="parent" class="form-select" @onchange="(e => ParentChanged(e))" required>
|
<select id="parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))" required>
|
||||||
<option value="-1"><@Localizer["SiteRoot"]></option>
|
<option value="-1"><@Localizer["SiteRoot"]></option>
|
||||||
@foreach (Page page in PageState.Pages)
|
@foreach (Page page in PageState.Pages)
|
||||||
|
{
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -55,6 +59,26 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="parent" class="form-select" @onchange="(e => ParentChanged(e))" required>
|
||||||
|
<option value="@(_parent.PageId)">@(new string('-', _parent.Level * 2))@(_parent.Name)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages" ResourceKey="Insert">Insert: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="insert" class="form-select" @bind="@_insert" required>
|
||||||
|
<option value=">>">@Localizer["AtEnd"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
|
<Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -85,45 +109,6 @@
|
|||||||
<input id="url" class="form-control" @bind="@_url" />
|
<input id="url" class="form-control" @bind="@_url" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<Section Name="Appearance" ResourceKey="Appearance">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="title" class="form-control" @bind="@_title" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="meta" HelpText="Optionally enter meta tags (in exactly the form you want them to be included in the page output)." ResourceKey="Meta">Meta: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<textarea id="meta" class="form-control" @bind="@_meta" rows="3"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
|
||||||
@foreach (var theme in _themes)
|
|
||||||
{
|
|
||||||
<option value="@theme.TypeName">@theme.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="container" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="container" class="form-select" @bind="@_containertype" required>
|
|
||||||
<option value="-"><@Localizer["Container.Select"]></option>
|
|
||||||
@foreach (var container in _containers)
|
|
||||||
{
|
|
||||||
<option value="@container.TypeName">@container.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
|
<Label Class="col-sm-3" For="icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -140,8 +125,55 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
|
||||||
|
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="title" class="form-control" @bind="@_title" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="theme" class="form-select" @bind="@_themetype" required>
|
||||||
|
@foreach (var theme in _themes)
|
||||||
|
{
|
||||||
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
}
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="container" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="container" class="form-select" @bind="@_containertype" required>
|
||||||
|
@foreach (var container in _containers)
|
||||||
|
{
|
||||||
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="bodycontent" HelpText="Optionally enter content to be included in the page body (ie. script tags)" ResourceKey="BodyContent">Body Content: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -160,54 +192,77 @@
|
|||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
||||||
</form>
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
|
|
||||||
private List<Theme> _themeList;
|
private bool _initialized = false;
|
||||||
|
private ElementReference form;
|
||||||
|
private bool validated = false;
|
||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
|
private int _pageId;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _title;
|
|
||||||
private string _meta;
|
|
||||||
private string _path = string.Empty;
|
|
||||||
private string _parentid = "-1";
|
private string _parentid = "-1";
|
||||||
private string _insert = ">>";
|
private string _insert = ">>";
|
||||||
private List<Page> _children;
|
private List<Page> _children;
|
||||||
private int _childid = -1;
|
private int _childid = -1;
|
||||||
private string _isnavigation = "True";
|
private string _isnavigation = "True";
|
||||||
private string _isclickable = "True";
|
private string _isclickable = "True";
|
||||||
|
private string _path = string.Empty;
|
||||||
private string _url;
|
private string _url;
|
||||||
private string _ispersonalizable = "False";
|
private string _ispersonalizable = "False";
|
||||||
|
private string _title;
|
||||||
|
private string _icon = string.Empty;
|
||||||
private string _themetype = string.Empty;
|
private string _themetype = string.Empty;
|
||||||
private string _containertype = string.Empty;
|
private string _containertype = string.Empty;
|
||||||
private string _icon = string.Empty;
|
private string _headcontent;
|
||||||
|
private string _bodycontent;
|
||||||
private string _permissions = null;
|
private string _permissions = null;
|
||||||
private PermissionGrid _permissionGrid;
|
private PermissionGrid _permissionGrid;
|
||||||
private Type _themeSettingsType;
|
private Type _themeSettingsType;
|
||||||
private object _themeSettings;
|
private object _themeSettings;
|
||||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||||
private bool _refresh = false;
|
private bool _refresh = false;
|
||||||
private ElementReference form;
|
protected Page _parent = null;
|
||||||
private bool validated = false;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themeList = await ThemeService.GetThemesAsync();
|
if (PageState.QueryString.ContainsKey("id"))
|
||||||
_themes = ThemeService.GetThemeControls(_themeList);
|
{
|
||||||
|
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||||
|
_parent = await PageService.GetPageAsync(_pageId);
|
||||||
|
if (_parent != null)
|
||||||
|
{
|
||||||
|
_parentid = _parent.PageId.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if admin or user has edit access to parent page
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin) || (_parent != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _parent.PermissionList)))
|
||||||
|
{
|
||||||
_themetype = PageState.Site.DefaultThemeType;
|
_themetype = PageState.Site.DefaultThemeType;
|
||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
_themes = ThemeService.GetThemeControls(PageState.Site.Themes, _themetype);
|
||||||
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||||
_containertype = PageState.Site.DefaultContainerType;
|
_containertype = PageState.Site.DefaultContainerType;
|
||||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||||
ThemeSettings();
|
ThemeSettings();
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await logger.LogWarning("Error Loading Page {ParentId}", _parentid);
|
||||||
|
AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Initializing Page {Error}", ex.Message);
|
await logger.LogError(ex, "Error Loading Page {Error}", ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.Page.Initialize"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,27 +301,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ThemeChanged(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_themetype = (string)e.Value;
|
|
||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
|
||||||
_containertype = "-";
|
|
||||||
ThemeSettings();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThemeSettings()
|
private void ThemeSettings()
|
||||||
{
|
{
|
||||||
_themeSettingsType = null;
|
_themeSettingsType = null;
|
||||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||||
{
|
{
|
||||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||||
@ -292,12 +330,11 @@
|
|||||||
Page page = null;
|
Page page = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
if (!string.IsNullOrEmpty(_themetype) && !string.IsNullOrEmpty(_containertype))
|
||||||
{
|
{
|
||||||
page = new Page();
|
page = new Page();
|
||||||
page.SiteId = PageState.Page.SiteId;
|
page.SiteId = PageState.Page.SiteId;
|
||||||
page.Name = _name;
|
page.Name = _name;
|
||||||
page.Title = _title;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_path))
|
if (string.IsNullOrEmpty(_path))
|
||||||
{
|
{
|
||||||
@ -366,33 +403,41 @@
|
|||||||
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
|
||||||
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
||||||
page.Url = _url;
|
page.Url = _url;
|
||||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
||||||
|
page.UserId = null;
|
||||||
|
|
||||||
|
// appearance
|
||||||
|
page.Title = _title;
|
||||||
|
page.Icon = (_icon == null ? string.Empty : _icon);
|
||||||
|
page.ThemeType = _themetype;
|
||||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
||||||
{
|
{
|
||||||
page.ThemeType = string.Empty;
|
page.ThemeType = string.Empty;
|
||||||
}
|
}
|
||||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
page.DefaultContainerType = _containertype;
|
||||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||||
{
|
{
|
||||||
page.DefaultContainerType = string.Empty;
|
page.DefaultContainerType = string.Empty;
|
||||||
}
|
}
|
||||||
page.Icon = (_icon == null ? string.Empty : _icon);
|
|
||||||
|
// page content
|
||||||
|
page.HeadContent = _headcontent;
|
||||||
|
page.BodyContent = _bodycontent;
|
||||||
|
|
||||||
|
// permissions
|
||||||
page.PermissionList = _permissionGrid.GetPermissionList();
|
page.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
|
||||||
page.UserId = null;
|
|
||||||
page.Meta = _meta;
|
|
||||||
|
|
||||||
page = await PageService.AddPageAsync(page);
|
page = await PageService.AddPageAsync(page);
|
||||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||||
|
|
||||||
await logger.LogInformation("Page Added {Page}", page);
|
await logger.LogInformation("Page Added {Page}", page);
|
||||||
if (PageState.QueryString.ContainsKey("cp"))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
|
NavigationManager.NavigateTo(page.Path); // redirect to new page
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(page.Path));
|
NavigationManager.NavigateTo(NavigateUrl()); // redirect to page management
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -415,9 +460,9 @@
|
|||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
if (PageState.QueryString.ContainsKey("cp"))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8,11 +8,13 @@
|
|||||||
@inject IStringLocalizer<Edit> Localizer
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
@if (_initialized)
|
||||||
|
{
|
||||||
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
|
@if (_page.UserId == null)
|
||||||
|
{
|
||||||
<TabStrip Refresh="@_refresh">
|
<TabStrip Refresh="@_refresh">
|
||||||
<TabPanel Name="Settings" ResourceKey="Settings" Heading=@Localizer["Settings.Heading"]>
|
<TabPanel Name="Settings" ResourceKey="Settings" Heading=@Localizer["Settings.Heading"]>
|
||||||
@if (_themeList != null)
|
|
||||||
{
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
|
<Label Class="col-sm-3" For="name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
|
||||||
@ -20,6 +22,8 @@
|
|||||||
<input id="name" class="form-control" @bind="@_name" maxlength="50" required />
|
<input id="name" class="form-control" @bind="@_name" maxlength="50" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
|
{
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
|
<Label Class="col-sm-3" For="parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -27,7 +31,7 @@
|
|||||||
<option value="-1"><@Localizer["SiteRoot"]></option>
|
<option value="-1"><@Localizer["SiteRoot"]></option>
|
||||||
@foreach (Page page in PageState.Pages)
|
@foreach (Page page in PageState.Pages)
|
||||||
{
|
{
|
||||||
if (page.PageId != _pageId)
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, page.PermissionList) && page.PageId != _pageId)
|
||||||
{
|
{
|
||||||
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
|
||||||
}
|
}
|
||||||
@ -63,6 +67,30 @@
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))" disabled>
|
||||||
|
<option value="-1"><@Localizer["SiteRoot"]></option>
|
||||||
|
@if (_parent != null)
|
||||||
|
{
|
||||||
|
<option value="@(_parent.PageId)">@(new string('-', _parent.Level * 2))@(_parent.Name)</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="move" HelpText="Select the location where you would like the page to be moved in relation to other pages" ResourceKey="Move">Move: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="move" class="form-select" @bind="@_insert" disabled>
|
||||||
|
<option value="="><@Localizer["ThisLocation.Keep"]></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
|
<Label Class="col-sm-3" For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -84,57 +112,19 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used. If the page is intended to be the root path specify '/'." ResourceKey="UrlPath">Url Path: </Label>
|
<Label Class="col-sm-3" For="path" HelpText="Optionally enter a url path for this page (ie. home ). If you do not provide a url path, the page name will be used. If the page is intended to be the root path specify '/'." ResourceKey="UrlPath">Url Path: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="path" class="form-control" @bind="@_path" maxlength="256"/>
|
<input id="path" class="form-control" @bind="@_path" maxlength="256" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it" ResourceKey="Redirect">Redirect: </Label>
|
<Label Class="col-sm-3" For="url" HelpText="Optionally enter a url which this page should redirect to when a user navigates to it" ResourceKey="Redirect">Redirect: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="url" class="form-control" @bind="@_url" maxlength="500"/>
|
<input id="url" class="form-control" @bind="@_url" maxlength="500" />
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Section Name="Appearance" ResourceKey="Appearance">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="title" class="form-control" @bind="@_title" maxlength="200"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="meta" HelpText="Optionally enter meta tags (in exactly the form you want them to be included in the page output)." ResourceKey="Meta">Meta: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<textarea id="meta" class="form-control" @bind="@_meta" rows="3"></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
|
||||||
@foreach (var theme in _themes)
|
|
||||||
{
|
|
||||||
<option value="@theme.TypeName">@theme.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="container" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="container" class="form-select" @bind="@_containertype" required>
|
|
||||||
<option value="-"><@Localizer["Container.Select"]></option>
|
|
||||||
@foreach (var container in _containers)
|
|
||||||
{
|
|
||||||
<option value="@container.TypeName">@container.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
|
<Label Class="col-sm-3" For="icon" HelpText="Optionally provide an icon class name for this page which will be displayed in the site navigation" ResourceKey="Icon">Icon: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="icon" class="form-control" @bind="@_icon" maxlength="50"/>
|
<input id="icon" class="form-control" @bind="@_icon" maxlength="50" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -147,25 +137,66 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Section Name="Appearance" ResourceKey="Appearance">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="title" class="form-control" @bind="@_title" maxlength="200" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="theme" class="form-select" @bind="@_themetype" required>
|
||||||
|
@foreach (var theme in _themes)
|
||||||
|
{
|
||||||
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="container" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="container" class="form-select" @bind="@_containertype" required>
|
||||||
|
@foreach (var container in _containers)
|
||||||
|
{
|
||||||
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="bodycontent" HelpText="Optionally enter content to be included in the page body (ie. script tags)" ResourceKey="BodyContent">Body Content: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
|
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
||||||
@if (_permissions != null)
|
|
||||||
{
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<PermissionGrid EntityName="@EntityNames.Page" PermissionList="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.Page" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="PageModules" Heading="Modules" ResourceKey="PageModules">
|
<TabPanel Name="PageModules" Heading="Modules" ResourceKey="PageModules">
|
||||||
@if(_pageModules != null)
|
|
||||||
{
|
|
||||||
<Pager Items="_pageModules">
|
<Pager Items="_pageModules">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
@ -180,7 +211,6 @@
|
|||||||
<td>@context.ModuleDefinition?.Name</td>
|
<td>@context.ModuleDefinition?.Name</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
@if (_themeSettingsType != null)
|
@if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
@ -190,25 +220,67 @@
|
|||||||
<br />
|
<br />
|
||||||
}
|
}
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<TabStrip Refresh="@_refresh">
|
||||||
|
<TabPanel Name="Settings" ResourceKey="Settings" Heading=@Localizer["Settings.Heading"]>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="title" HelpText="Optionally enter the page title. If you do not provide a page title, the page name will be used." ResourceKey="Title">Title: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="title" class="form-control" @bind="@_title" maxlength="200" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="theme" class="form-select" @bind="@_themetype" required>
|
||||||
|
@foreach (var theme in _themes)
|
||||||
|
{
|
||||||
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="container" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="container" class="form-select" @bind="@_containertype" required>
|
||||||
|
@foreach (var container in _containers)
|
||||||
|
{
|
||||||
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
@if (_themeSettingsType != null)
|
||||||
|
{
|
||||||
|
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
||||||
|
@ThemeSettingsComponent
|
||||||
|
</TabPanel>
|
||||||
|
<br />
|
||||||
|
}
|
||||||
|
</TabStrip>
|
||||||
|
}
|
||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
||||||
</form>
|
</form>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
|
|
||||||
|
private bool _initialized = false;
|
||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
private List<Theme> _themeList;
|
|
||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private List<Module> _pageModules;
|
|
||||||
private int _pageId;
|
private int _pageId;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _title;
|
|
||||||
private string _meta;
|
|
||||||
private string _path;
|
|
||||||
private string _currentparentid;
|
private string _currentparentid;
|
||||||
private string _parentid = "-1";
|
private string _parentid = "-1";
|
||||||
private string _insert = "=";
|
private string _insert = "=";
|
||||||
@ -216,44 +288,55 @@
|
|||||||
private int _childid = -1;
|
private int _childid = -1;
|
||||||
private string _isnavigation;
|
private string _isnavigation;
|
||||||
private string _isclickable;
|
private string _isclickable;
|
||||||
|
private string _path;
|
||||||
private string _url;
|
private string _url;
|
||||||
private string _ispersonalizable;
|
private string _ispersonalizable;
|
||||||
|
private string _title;
|
||||||
|
private string _icon;
|
||||||
private string _themetype;
|
private string _themetype;
|
||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
private string _icon;
|
private Type _themeSettingsType;
|
||||||
|
private object _themeSettings;
|
||||||
|
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||||
|
private string _headcontent;
|
||||||
|
private string _bodycontent;
|
||||||
private List<Permission> _permissions = null;
|
private List<Permission> _permissions = null;
|
||||||
|
private PermissionGrid _permissionGrid;
|
||||||
|
private List<Module> _pageModules;
|
||||||
private string _createdby;
|
private string _createdby;
|
||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
private string _modifiedby;
|
private string _modifiedby;
|
||||||
private DateTime _modifiedon;
|
private DateTime _modifiedon;
|
||||||
private string _deletedby;
|
private string _deletedby;
|
||||||
private DateTime? _deletedon;
|
private DateTime? _deletedon;
|
||||||
private PermissionGrid _permissionGrid;
|
|
||||||
private Type _themeSettingsType;
|
|
||||||
private object _themeSettings;
|
|
||||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
|
||||||
private bool _refresh = false;
|
private bool _refresh = false;
|
||||||
protected Page page;
|
protected Page _page = null;
|
||||||
|
protected Page _parent = null;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
||||||
_themeList = await ThemeService.GetThemesAsync();
|
|
||||||
_themes = ThemeService.GetThemeControls(_themeList);
|
|
||||||
|
|
||||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
_page = await PageService.GetPageAsync(_pageId);
|
||||||
|
|
||||||
if (page != null)
|
if (_page != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _page.PermissionList))
|
||||||
{
|
{
|
||||||
_name = page.Name;
|
_name = _page.Name;
|
||||||
_title = page.Title;
|
if (_page.ParentId == null)
|
||||||
_meta = page.Meta;
|
{
|
||||||
_path = page.Path;
|
_parentid = "-1";
|
||||||
_pageModules = PageState.Modules.Where(m => m.PageId == page.PageId).ToList();
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_parentid = _page.ParentId.ToString();
|
||||||
|
_parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId);
|
||||||
|
}
|
||||||
|
_currentparentid = _parentid;
|
||||||
|
_isnavigation = _page.IsNavigation.ToString();
|
||||||
|
_isclickable = _page.IsClickable.ToString();
|
||||||
|
_path = _page.Path;
|
||||||
if (string.IsNullOrEmpty(_path))
|
if (string.IsNullOrEmpty(_path))
|
||||||
{
|
{
|
||||||
_path = "/";
|
_path = "/";
|
||||||
@ -265,42 +348,50 @@
|
|||||||
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
_path = _path.Substring(_path.LastIndexOf("/") + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_url = _page.Url;
|
||||||
|
_icon = _page.Icon;
|
||||||
|
_ispersonalizable = _page.IsPersonalizable.ToString();
|
||||||
|
|
||||||
if (page.ParentId == null)
|
// appearance
|
||||||
{
|
_title = _page.Title;
|
||||||
_parentid = "-1";
|
_themetype = _page.ThemeType;
|
||||||
}
|
if (string.IsNullOrEmpty(_themetype) || ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName)
|
||||||
else
|
|
||||||
{
|
|
||||||
_parentid = page.ParentId.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
_currentparentid = _parentid;
|
|
||||||
_isnavigation = page.IsNavigation.ToString();
|
|
||||||
_isclickable = page.IsClickable.ToString();
|
|
||||||
_url = page.Url;
|
|
||||||
_ispersonalizable = page.IsPersonalizable.ToString();
|
|
||||||
_themetype = page.ThemeType;
|
|
||||||
if (string.IsNullOrEmpty(_themetype))
|
|
||||||
{
|
{
|
||||||
_themetype = PageState.Site.DefaultThemeType;
|
_themetype = PageState.Site.DefaultThemeType;
|
||||||
}
|
}
|
||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
_themes = ThemeService.GetThemeControls(PageState.Site.Themes, _themetype);
|
||||||
_containertype = page.DefaultContainerType;
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||||
|
_containertype = _page.DefaultContainerType;
|
||||||
if (string.IsNullOrEmpty(_containertype))
|
if (string.IsNullOrEmpty(_containertype))
|
||||||
{
|
{
|
||||||
_containertype = PageState.Site.DefaultContainerType;
|
_containertype = PageState.Site.DefaultContainerType;
|
||||||
}
|
}
|
||||||
_icon = page.Icon;
|
|
||||||
_permissions = page.PermissionList;
|
// page content
|
||||||
_createdby = page.CreatedBy;
|
_headcontent = _page.HeadContent;
|
||||||
_createdon = page.CreatedOn;
|
_bodycontent = _page.BodyContent;
|
||||||
_modifiedby = page.ModifiedBy;
|
|
||||||
_modifiedon = page.ModifiedOn;
|
// permissions
|
||||||
_deletedby = page.DeletedBy;
|
_permissions = _page.PermissionList;
|
||||||
_deletedon = page.DeletedOn;
|
|
||||||
|
// page modules
|
||||||
|
_pageModules = PageState.Modules.Where(m => m.PageId == _page.PageId).ToList();
|
||||||
|
|
||||||
|
// audit
|
||||||
|
_createdby = _page.CreatedBy;
|
||||||
|
_createdon = _page.CreatedOn;
|
||||||
|
_modifiedby = _page.ModifiedBy;
|
||||||
|
_modifiedon = _page.ModifiedOn;
|
||||||
|
_deletedby = _page.DeletedBy;
|
||||||
|
_deletedon = _page.DeletedOn;
|
||||||
|
|
||||||
ThemeSettings();
|
ThemeSettings();
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await logger.LogWarning("Error Loading Page {PageId}", _pageId);
|
||||||
|
AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -314,7 +405,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(page.PageId, module.ModuleId);
|
PageModule pagemodule = await PageModuleService.GetPageModuleAsync(_page.PageId, module.ModuleId);
|
||||||
pagemodule.IsDeleted = true;
|
pagemodule.IsDeleted = true;
|
||||||
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
await PageModuleService.UpdatePageModuleAsync(pagemodule);
|
||||||
await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title);
|
await logger.LogInformation(LogFunction.Update,"Module Deleted {Title}", module.Title);
|
||||||
@ -372,29 +463,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ThemeChanged(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_themetype = (string)e.Value;
|
|
||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
|
||||||
_containertype = "-";
|
|
||||||
ThemeSettings();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThemeSettings()
|
private void ThemeSettings()
|
||||||
{
|
{
|
||||||
_themeSettingsType = null;
|
_themeSettingsType = null;
|
||||||
if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel
|
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||||
{
|
|
||||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
|
||||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||||
{
|
{
|
||||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||||
@ -410,7 +482,6 @@
|
|||||||
_refresh = true;
|
_refresh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SavePage()
|
private async Task SavePage()
|
||||||
{
|
{
|
||||||
@ -418,16 +489,13 @@
|
|||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
if (await interop.FormValid(form))
|
if (await interop.FormValid(form))
|
||||||
{
|
{
|
||||||
Page page = null;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
||||||
{
|
{
|
||||||
page = PageState.Pages.FirstOrDefault(item => item.PageId == _pageId);
|
string currentPath = _page.Path;
|
||||||
string currentPath = page.Path;
|
|
||||||
|
|
||||||
page.Name = _name;
|
_page.Name = _name;
|
||||||
page.Title = _title;
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_path))
|
if (string.IsNullOrEmpty(_path))
|
||||||
{
|
{
|
||||||
@ -444,33 +512,33 @@
|
|||||||
|
|
||||||
if (_parentid == "-1")
|
if (_parentid == "-1")
|
||||||
{
|
{
|
||||||
page.ParentId = null;
|
_page.ParentId = null;
|
||||||
page.Path = Utilities.GetFriendlyUrl(_path);
|
_page.Path = Utilities.GetFriendlyUrl(_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
page.ParentId = Int32.Parse(_parentid);
|
_page.ParentId = Int32.Parse(_parentid);
|
||||||
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == page.ParentId);
|
Page parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId);
|
||||||
if (parent.Path == string.Empty)
|
if (parent.Path == string.Empty)
|
||||||
{
|
{
|
||||||
page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
_page.Path = Utilities.GetFriendlyUrl(parent.Name) + "/" + Utilities.GetFriendlyUrl(_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
_page.Path = parent.Path + "/" + Utilities.GetFriendlyUrl(_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
var _pages = await PageService.GetPagesAsync(PageState.Site.SiteId);
|
||||||
if (_pages.Any(item => item.Path == page.Path && item.PageId != page.PageId))
|
if (_pages.Any(item => item.Path == _page.Path && item.PageId != _page.PageId))
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
|
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page.ParentId == null && Constants.ReservedRoutes.Contains(page.Name.ToLower()))
|
if (_page.ParentId == null && Constants.ReservedRoutes.Contains(_page.Name.ToLower()))
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning);
|
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], _page.Name), MessageType.Warning);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,49 +548,59 @@
|
|||||||
switch (_insert)
|
switch (_insert)
|
||||||
{
|
{
|
||||||
case "<<":
|
case "<<":
|
||||||
page.Order = 0;
|
_page.Order = 0;
|
||||||
break;
|
break;
|
||||||
case "<":
|
case "<":
|
||||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||||
if (child != null) page.Order = child.Order - 1;
|
if (child != null) _page.Order = child.Order - 1;
|
||||||
break;
|
break;
|
||||||
case ">":
|
case ">":
|
||||||
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
child = PageState.Pages.FirstOrDefault(item => item.PageId == _childid);
|
||||||
if (child != null) page.Order = child.Order + 1;
|
if (child != null) _page.Order = child.Order + 1;
|
||||||
break;
|
break;
|
||||||
case ">>":
|
case ">>":
|
||||||
page.Order = int.MaxValue;
|
_page.Order = int.MaxValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
_page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
|
||||||
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
_page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
|
||||||
page.Url = _url;
|
_page.Url = _url;
|
||||||
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
|
_page.Icon = _icon ?? string.Empty;
|
||||||
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
|
_page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
||||||
{
|
|
||||||
page.ThemeType = string.Empty;
|
|
||||||
}
|
|
||||||
page.DefaultContainerType = (_containertype != "-") ? _containertype : string.Empty;
|
|
||||||
if (!string.IsNullOrEmpty(page.DefaultContainerType) && page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
|
||||||
{
|
|
||||||
page.DefaultContainerType = string.Empty;
|
|
||||||
}
|
|
||||||
page.Icon = _icon ?? string.Empty;
|
|
||||||
page.PermissionList = _permissionGrid.GetPermissionList();
|
|
||||||
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
|
||||||
page.UserId = null;
|
|
||||||
page.Meta = _meta;
|
|
||||||
|
|
||||||
page = await PageService.UpdatePageAsync(page);
|
// appearance
|
||||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
_page.Title = _title;
|
||||||
|
_page.ThemeType = _themetype;
|
||||||
|
if (!string.IsNullOrEmpty(_page.ThemeType) && _page.ThemeType == PageState.Site.DefaultThemeType)
|
||||||
|
{
|
||||||
|
_page.ThemeType = string.Empty;
|
||||||
|
}
|
||||||
|
_page.DefaultContainerType = _containertype;
|
||||||
|
if (!string.IsNullOrEmpty(_page.DefaultContainerType) && _page.DefaultContainerType == PageState.Site.DefaultContainerType)
|
||||||
|
{
|
||||||
|
_page.DefaultContainerType = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// page content
|
||||||
|
_page.HeadContent = _headcontent;
|
||||||
|
_page.BodyContent = _bodycontent;
|
||||||
|
|
||||||
|
// permissions
|
||||||
|
if (_page.UserId == null)
|
||||||
|
{
|
||||||
|
_page.PermissionList = _permissionGrid.GetPermissionList();
|
||||||
|
}
|
||||||
|
|
||||||
|
_page = await PageService.UpdatePageAsync(_page);
|
||||||
|
await PageService.UpdatePageOrderAsync(_page.SiteId, _page.PageId, _page.ParentId);
|
||||||
if (_currentparentid == string.Empty)
|
if (_currentparentid == string.Empty)
|
||||||
{
|
{
|
||||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, null);
|
await PageService.UpdatePageOrderAsync(_page.SiteId, _page.PageId, null);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, int.Parse(_currentparentid));
|
await PageService.UpdatePageOrderAsync(_page.SiteId, _page.PageId, int.Parse(_currentparentid));
|
||||||
}
|
}
|
||||||
|
|
||||||
// update child paths
|
// update child paths
|
||||||
@ -530,7 +608,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath)))
|
foreach (Page p in PageState.Pages.Where(item => item.Path.StartsWith(currentPath)))
|
||||||
{
|
{
|
||||||
p.Path = p.Path.Replace(currentPath, page.Path);
|
p.Path = p.Path.Replace(currentPath, _page.Path);
|
||||||
await PageService.UpdatePageAsync(p);
|
await PageService.UpdatePageAsync(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -540,14 +618,14 @@
|
|||||||
await themeSettingsControl.UpdateSettings();
|
await themeSettingsControl.UpdateSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
await logger.LogInformation("Page Saved {Page}", page);
|
await logger.LogInformation("Page Saved {Page}", _page);
|
||||||
if (PageState.QueryString.ContainsKey("cp"))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(page.Path));
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -557,7 +635,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
|
await logger.LogError(ex, "Error Saving Page {Page} {Error}", _page, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,9 +647,9 @@
|
|||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
if (PageState.QueryString.ContainsKey("cp"))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Pages.First(item => item.PageId == int.Parse(PageState.QueryString["cp"])).Path));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@if (PageState.Pages != null)
|
@if (PageState.Pages != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add Page" ResourceKey="AddPage" />
|
<ActionLink Action="Add" Text="Add Page" ResourceKey="AddPage" />
|
||||||
|
|
||||||
|
@ -64,6 +64,12 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="validation" HelpText="Optionally provide a regular expression (RegExp) for validating the value entered" ResourceKey="Validation">Validation: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="validation" class="form-control" @bind="@_validation" maxlength="200" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
|
<Label Class="col-sm-3" For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -97,6 +103,7 @@
|
|||||||
private string _maxlength = "0";
|
private string _maxlength = "0";
|
||||||
private string _defaultvalue = string.Empty;
|
private string _defaultvalue = string.Empty;
|
||||||
private string _options = string.Empty;
|
private string _options = string.Empty;
|
||||||
|
private string _validation = string.Empty;
|
||||||
private string _isrequired = "False";
|
private string _isrequired = "False";
|
||||||
private string _isprivate = "False";
|
private string _isprivate = "False";
|
||||||
private string createdby;
|
private string createdby;
|
||||||
@ -126,6 +133,7 @@
|
|||||||
_maxlength = profile.MaxLength.ToString();
|
_maxlength = profile.MaxLength.ToString();
|
||||||
_defaultvalue = profile.DefaultValue;
|
_defaultvalue = profile.DefaultValue;
|
||||||
_options = profile.Options;
|
_options = profile.Options;
|
||||||
|
_validation = profile.Validation;
|
||||||
_isrequired = profile.IsRequired.ToString();
|
_isrequired = profile.IsRequired.ToString();
|
||||||
_isprivate = profile.IsPrivate.ToString();
|
_isprivate = profile.IsPrivate.ToString();
|
||||||
createdby = profile.CreatedBy;
|
createdby = profile.CreatedBy;
|
||||||
@ -169,6 +177,7 @@
|
|||||||
profile.MaxLength = int.Parse(_maxlength);
|
profile.MaxLength = int.Parse(_maxlength);
|
||||||
profile.DefaultValue = _defaultvalue;
|
profile.DefaultValue = _defaultvalue;
|
||||||
profile.Options = _options;
|
profile.Options = _options;
|
||||||
|
profile.Validation = _validation;
|
||||||
profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
|
profile.IsRequired = (_isrequired == null ? false : Boolean.Parse(_isrequired));
|
||||||
profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
|
profile.IsPrivate = (_isprivate == null ? false : Boolean.Parse(_isprivate));
|
||||||
if (_profileid != -1)
|
if (_profileid != -1)
|
||||||
|
@ -184,13 +184,6 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
||||||
|
|
||||||
// check if there are any remaining module instances in the site
|
|
||||||
if (!_modules.Exists (item => item.ModuleId == module.ModuleId && item.PageModuleId != module.PageModuleId))
|
|
||||||
{
|
|
||||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
await logger.LogInformation("Module Permanently Deleted {Module}", module);
|
await logger.LogInformation("Module Permanently Deleted {Module}", module);
|
||||||
await Load();
|
await Load();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -210,16 +203,7 @@ else
|
|||||||
foreach (Module module in _modules.Where(item => item.IsDeleted).ToList())
|
foreach (Module module in _modules.Where(item => item.IsDeleted).ToList())
|
||||||
{
|
{
|
||||||
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
await PageModuleService.DeletePageModuleAsync(module.PageModuleId);
|
||||||
|
|
||||||
// DeletePageModuleAsync does not update _modules so remove it.
|
|
||||||
_modules.Remove(module);
|
|
||||||
// check if there are any remaining module instances in the site
|
|
||||||
if (!_modules.Exists(item => item.ModuleId == module.ModuleId && item.PageModuleId != module.PageModuleId))
|
|
||||||
{
|
|
||||||
await ModuleService.DeleteModuleAsync(module.ModuleId);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await logger.LogInformation("Modules Permanently Deleted");
|
await logger.LogInformation("Modules Permanently Deleted");
|
||||||
await Load();
|
await Load();
|
||||||
ModuleInstance.HideProgressIndicator();
|
ModuleInstance.HideProgressIndicator();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
@inject ISettingService SettingService
|
||||||
|
|
||||||
@if (PageState.Site.AllowRegistration)
|
@if (PageState.Site.AllowRegistration)
|
||||||
{
|
{
|
||||||
@ -15,7 +16,7 @@
|
|||||||
<ModuleMessage Message="@Localizer["Info.Registration.Exists"]" Type="MessageType.Info" />
|
<ModuleMessage Message="@Localizer["Info.Registration.Exists"]" Type="MessageType.Info" />
|
||||||
</Authorized>
|
</Authorized>
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
<ModuleMessage Message="@Localizer["Info.Registration.InvalidEmail"]" Type="MessageType.Info" />
|
<ModuleMessage Message="@_passwordconstruction" Type="MessageType.Info" />
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -29,7 +30,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -38,7 +39,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -78,11 +79,44 @@ else
|
|||||||
private string _email = string.Empty;
|
private string _email = string.Empty;
|
||||||
private string _displayname = string.Empty;
|
private string _displayname = string.Empty;
|
||||||
|
|
||||||
|
//Password construction
|
||||||
|
private string _minimumlength;
|
||||||
|
private string _uniquecharacters;
|
||||||
|
private bool _requiredigit;
|
||||||
|
private bool _requireupper;
|
||||||
|
private bool _requirelower;
|
||||||
|
private bool _requirepunctuation;
|
||||||
|
private string _passwordconstruction;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
|
||||||
|
_minimumlength = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredLength", "6");
|
||||||
|
_uniquecharacters = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", "1");
|
||||||
|
_requiredigit = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireDigit", "true"));
|
||||||
|
_requireupper = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireUppercase", "true"));
|
||||||
|
_requirelower = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireLowercase", "true"));
|
||||||
|
_requirepunctuation = bool.Parse(SettingService.GetSetting(settings, "IdentityOptions:Password:RequireNonAlphanumeric", "true"));
|
||||||
|
|
||||||
|
// Replace the placeholders with the actual values of the variables
|
||||||
|
string digitRequirement = _requiredigit ? Localizer["Password.DigitRequirement"] + ", " : "";
|
||||||
|
string uppercaseRequirement = _requireupper ? Localizer["Password.UppercaseRequirement"] + ", " : "";
|
||||||
|
string lowercaseRequirement = _requirelower ? Localizer["Password.LowercaseRequirement"] + ", " : "";
|
||||||
|
string punctuationRequirement = _requirepunctuation ? Localizer["Password.PunctuationRequirement"] + ", " : "";
|
||||||
|
|
||||||
|
// Replace the placeholders with the actual values of the variables
|
||||||
|
string passwordValidationCriteriaTemplate = Localizer["Password.ValidationCriteria"];
|
||||||
|
_passwordconstruction = Localizer["Info.Registration.InvalidEmail"] + ". " + string.Format(passwordValidationCriteriaTemplate,
|
||||||
|
_minimumlength, _uniquecharacters, digitRequirement, uppercaseRequirement, lowercaseRequirement, punctuationRequirement);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Register()
|
private async Task Register()
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,55 +22,6 @@
|
|||||||
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="favicon" HelpText="Specify a Favicon" ResourceKey="FavoriteIcon">Favicon: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<FileManager FileId="@_faviconfileid" Filter="ico" @ref="_faviconfilemanager" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
|
||||||
<option value="-"><@Localizer["Theme.Select"]></option>
|
|
||||||
@foreach (var theme in _themes)
|
|
||||||
{
|
|
||||||
<option value="@theme.TypeName">@theme.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="defaultContainer" class="form-select" @bind="@_containertype" required>
|
|
||||||
<option value="-"><@Localizer["Container.Select"]></option>
|
|
||||||
@foreach (var container in _containers)
|
|
||||||
{
|
|
||||||
<option value="@container.TypeName">@container.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="defaultAdminContainer" class="form-select" @bind="@_admincontainertype" required>
|
|
||||||
<option value="-"><@Localizer["Container.Select"]></option>
|
|
||||||
<option value="@Constants.DefaultAdminContainer"><@Localizer["DefaultAdminContainer"]></option>
|
|
||||||
@foreach (var container in _containers)
|
|
||||||
{
|
|
||||||
<option value="@container.TypeName">@container.Name</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="homepage" HelpText="Select the home page for the site (to be used if there is no page with a path of '/')" ResourceKey="HomePage">Home Page: </Label>
|
<Label Class="col-sm-3" For="homepage" HelpText="Select the home page for the site (to be used if there is no page with a path of '/')" ResourceKey="HomePage">Home Page: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -101,7 +52,80 @@
|
|||||||
<input id="sitemap" class="form-control" @bind="@_sitemap" required disabled />
|
<input id="sitemap" class="form-control" @bind="@_sitemap" required disabled />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="version" HelpText="The site version (for site content migrations)" ResourceKey="Version">Version: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="version" class="form-control" @bind="@_version" required disabled />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<Section Name="Appearance" ResourceKey="Appearance">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<FileManager FileId="@_logofileid" Filter="@Constants.ImageFiles" @ref="_logofilemanager" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="favicon" HelpText="Specify a Favicon" ResourceKey="FavoriteIcon">Favicon: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<FileManager FileId="@_faviconfileid" Filter="ico,png,gif" @ref="_faviconfilemanager" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
||||||
|
@foreach (var theme in _themes)
|
||||||
|
{
|
||||||
|
<option value="@theme.TypeName">@theme.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="defaultContainer" class="form-select" @bind="@_containertype" required>
|
||||||
|
@foreach (var container in _containers)
|
||||||
|
{
|
||||||
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="defaultAdminContainer" class="form-select" @bind="@_admincontainertype" required>
|
||||||
|
<option value="@Constants.DefaultAdminContainer"><@Localizer["DefaultAdminContainer"]></option>
|
||||||
|
@foreach (var container in _containers)
|
||||||
|
{
|
||||||
|
<option value="@container.TypeName">@container.Name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="headcontent" class="form-control" @bind="@_headcontent" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="bodycontent" HelpText="Optionally enter content to be included in the page body (ie. script tags)" ResourceKey="BodyContent">Body Content: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="bodycontent" class="form-control" @bind="@_bodycontent" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -124,9 +148,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="enabledSSl" HelpText="Specify if SSL is required for your SMTP server" ResourceKey="UseSsl">SSL Enabled: </Label>
|
<Label Class="col-sm-3" For="smtpssl" HelpText="Specify if SSL is required for your SMTP server" ResourceKey="UseSsl">SSL Enabled: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="enabledSSl" class="form-select" @bind="@_smtpssl" >
|
<select id="smtpssl" class="form-select" @bind="@_smtpssl" >
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
</select>
|
</select>
|
||||||
@ -143,7 +167,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_smtppasswordtype" class="form-control" @bind="@_smtppassword" />
|
<input id="password" type="@_smtppasswordtype" class="form-control" @bind="@_smtppassword" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@ToggleSMTPPassword">@_togglesmtppassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@ToggleSMTPPassword" tabindex="-1">@_togglesmtppassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -162,6 +186,15 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="smtpenabled" HelpText="Specify if SMTP is enabled for this site" ResourceKey="SMTPEnabled">Enabled? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="smtpenabled" class="form-select" @bind="@_smtpenabled">
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="retention" HelpText="Number of days of notifications to retain" ResourceKey="Retention">Retention (Days): </Label>
|
<Label Class="col-sm-3" For="retention" HelpText="Number of days of notifications to retain" ResourceKey="Retention">Retention (Days): </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -309,25 +342,22 @@
|
|||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
private bool _initialized = false;
|
private bool _initialized = false;
|
||||||
private List<Theme> _themeList;
|
|
||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private List<Alias> _aliases;
|
private string _homepageid = "-";
|
||||||
private int _aliasid = -1;
|
private string _isdeleted;
|
||||||
private string _aliasname;
|
private string _sitemap = "";
|
||||||
private string _defaultalias;
|
private string _version = "";
|
||||||
private string _runtime = "";
|
|
||||||
private string _prerender = "";
|
|
||||||
private int _logofileid = -1;
|
private int _logofileid = -1;
|
||||||
private FileManager _logofilemanager;
|
private FileManager _logofilemanager;
|
||||||
private int _faviconfileid = -1;
|
private int _faviconfileid = -1;
|
||||||
private FileManager _faviconfilemanager;
|
private FileManager _faviconfilemanager;
|
||||||
private string _themetype = "-";
|
private string _themetype = "";
|
||||||
private string _containertype = "-";
|
private string _containertype = "";
|
||||||
private string _admincontainertype = "-";
|
private string _admincontainertype = "";
|
||||||
private string _homepageid = "-";
|
private string _headcontent = string.Empty;
|
||||||
private string _sitemap = "";
|
private string _bodycontent = string.Empty;
|
||||||
private string _smtphost = string.Empty;
|
private string _smtphost = string.Empty;
|
||||||
private string _smtpport = string.Empty;
|
private string _smtpport = string.Empty;
|
||||||
private string _smtpssl = "False";
|
private string _smtpssl = "False";
|
||||||
@ -337,12 +367,19 @@
|
|||||||
private string _togglesmtppassword = string.Empty;
|
private string _togglesmtppassword = string.Empty;
|
||||||
private string _smtpsender = string.Empty;
|
private string _smtpsender = string.Empty;
|
||||||
private string _smtprelay = "False";
|
private string _smtprelay = "False";
|
||||||
|
private string _smtpenabled = "True";
|
||||||
private string _retention = string.Empty;
|
private string _retention = string.Empty;
|
||||||
private string _pwaisenabled;
|
private string _pwaisenabled;
|
||||||
private int _pwaappiconfileid = -1;
|
private int _pwaappiconfileid = -1;
|
||||||
private FileManager _pwaappiconfilemanager;
|
private FileManager _pwaappiconfilemanager;
|
||||||
private int _pwasplashiconfileid = -1;
|
private int _pwasplashiconfileid = -1;
|
||||||
private FileManager _pwasplashiconfilemanager;
|
private FileManager _pwasplashiconfilemanager;
|
||||||
|
private List<Alias> _aliases;
|
||||||
|
private int _aliasid = -1;
|
||||||
|
private string _aliasname;
|
||||||
|
private string _defaultalias;
|
||||||
|
private string _runtime = "";
|
||||||
|
private string _prerender = "";
|
||||||
private string _tenant = string.Empty;
|
private string _tenant = string.Empty;
|
||||||
private string _database = string.Empty;
|
private string _database = string.Empty;
|
||||||
private string _connectionstring = string.Empty;
|
private string _connectionstring = string.Empty;
|
||||||
@ -352,7 +389,6 @@
|
|||||||
private DateTime _modifiedon;
|
private DateTime _modifiedon;
|
||||||
private string _deletedby;
|
private string _deletedby;
|
||||||
private DateTime? _deletedon;
|
private DateTime? _deletedon;
|
||||||
private string _isdeleted;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
@ -360,18 +396,19 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themeList = await ThemeService.GetThemesAsync();
|
|
||||||
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
||||||
if (site != null)
|
if (site != null)
|
||||||
{
|
{
|
||||||
_name = site.Name;
|
_name = site.Name;
|
||||||
_runtime = site.Runtime;
|
if (site.HomePageId != null)
|
||||||
_prerender = site.RenderMode.Replace(_runtime, "");
|
{
|
||||||
|
_homepageid = site.HomePageId.Value.ToString();
|
||||||
|
}
|
||||||
_isdeleted = site.IsDeleted.ToString();
|
_isdeleted = site.IsDeleted.ToString();
|
||||||
_sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml";
|
_sitemap = PageState.Alias.Protocol + PageState.Alias.Name + "/pages/sitemap.xml";
|
||||||
|
_version = site.Version;
|
||||||
|
|
||||||
await GetAliases();
|
// appearance
|
||||||
|
|
||||||
if (site.LogoFileId != null)
|
if (site.LogoFileId != null)
|
||||||
{
|
{
|
||||||
_logofileid = site.LogoFileId.Value;
|
_logofileid = site.LogoFileId.Value;
|
||||||
@ -381,18 +418,17 @@
|
|||||||
{
|
{
|
||||||
_faviconfileid = site.FaviconFileId.Value;
|
_faviconfileid = site.FaviconFileId.Value;
|
||||||
}
|
}
|
||||||
|
_themes = ThemeService.GetThemeControls(PageState.Site.Themes);
|
||||||
_themes = ThemeService.GetThemeControls(_themeList);
|
|
||||||
_themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme;
|
_themetype = (!string.IsNullOrEmpty(site.DefaultThemeType)) ? site.DefaultThemeType : Constants.DefaultTheme;
|
||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||||
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
|
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
|
||||||
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
|
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
|
||||||
|
|
||||||
if (site.HomePageId != null)
|
// page content
|
||||||
{
|
_headcontent = site.HeadContent;
|
||||||
_homepageid = site.HomePageId.Value.ToString();
|
_bodycontent = site.BodyContent;
|
||||||
}
|
|
||||||
|
|
||||||
|
// PWA
|
||||||
_pwaisenabled = site.PwaIsEnabled.ToString();
|
_pwaisenabled = site.PwaIsEnabled.ToString();
|
||||||
if (site.PwaAppIconFileId != null)
|
if (site.PwaAppIconFileId != null)
|
||||||
{
|
{
|
||||||
@ -403,6 +439,7 @@
|
|||||||
_pwasplashiconfileid = site.PwaSplashIconFileId.Value;
|
_pwasplashiconfileid = site.PwaSplashIconFileId.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SMTP
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||||
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
|
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
|
||||||
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
|
_smtpport = SettingService.GetSetting(settings, "SMTPPort", string.Empty);
|
||||||
@ -412,8 +449,17 @@
|
|||||||
_togglesmtppassword = SharedLocalizer["ShowPassword"];
|
_togglesmtppassword = SharedLocalizer["ShowPassword"];
|
||||||
_smtpsender = SettingService.GetSetting(settings, "SMTPSender", string.Empty);
|
_smtpsender = SettingService.GetSetting(settings, "SMTPSender", string.Empty);
|
||||||
_smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False");
|
_smtprelay = SettingService.GetSetting(settings, "SMTPRelay", "False");
|
||||||
|
_smtpenabled = SettingService.GetSetting(settings, "SMTPEnabled", "True");
|
||||||
_retention = SettingService.GetSetting(settings, "NotificationRetention", "30");
|
_retention = SettingService.GetSetting(settings, "NotificationRetention", "30");
|
||||||
|
|
||||||
|
// aliases
|
||||||
|
await GetAliases();
|
||||||
|
|
||||||
|
// hosting model
|
||||||
|
_runtime = site.Runtime;
|
||||||
|
_prerender = site.RenderMode.Replace(_runtime, "");
|
||||||
|
|
||||||
|
// database
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
var tenants = await TenantService.GetTenantsAsync();
|
var tenants = await TenantService.GetTenantsAsync();
|
||||||
@ -427,6 +473,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// audit
|
||||||
_createdby = site.CreatedBy;
|
_createdby = site.CreatedBy;
|
||||||
_createdon = site.CreatedOn;
|
_createdon = site.CreatedOn;
|
||||||
_modifiedby = site.ModifiedBy;
|
_modifiedby = site.ModifiedBy;
|
||||||
@ -449,15 +496,8 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
if (_themetype != "-")
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||||
{
|
_containertype = _containers.First().TypeName;
|
||||||
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_containers = new List<ThemeControl>();
|
|
||||||
}
|
|
||||||
_containertype = "-";
|
|
||||||
_admincontainertype = Constants.DefaultAdminContainer;
|
_admincontainertype = Constants.DefaultAdminContainer;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@ -485,17 +525,10 @@
|
|||||||
bool reload = false;
|
bool reload = false;
|
||||||
|
|
||||||
site.Name = _name;
|
site.Name = _name;
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
|
||||||
{
|
|
||||||
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
|
|
||||||
{
|
|
||||||
site.Runtime = _runtime;
|
|
||||||
site.RenderMode = _runtime + _prerender;
|
|
||||||
reload = true; // needs to be reloaded on server
|
|
||||||
}
|
|
||||||
}
|
|
||||||
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
||||||
|
|
||||||
|
// appearance
|
||||||
site.LogoFileId = null;
|
site.LogoFileId = null;
|
||||||
var logofileid = _logofilemanager.GetFileId();
|
var logofileid = _logofilemanager.GetFileId();
|
||||||
if (logofileid != -1)
|
if (logofileid != -1)
|
||||||
@ -520,8 +553,20 @@
|
|||||||
refresh = true; // needs to be refreshed on client
|
refresh = true; // needs to be refreshed on client
|
||||||
}
|
}
|
||||||
site.AdminContainerType = _admincontainertype;
|
site.AdminContainerType = _admincontainertype;
|
||||||
site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
|
|
||||||
|
|
||||||
|
// page content
|
||||||
|
if (site.HeadContent != _headcontent)
|
||||||
|
{
|
||||||
|
site.HeadContent = _headcontent;
|
||||||
|
reload = true;
|
||||||
|
}
|
||||||
|
if (site.BodyContent != _bodycontent)
|
||||||
|
{
|
||||||
|
site.BodyContent = _bodycontent;
|
||||||
|
reload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// PWA
|
||||||
if (site.PwaIsEnabled.ToString() != _pwaisenabled)
|
if (site.PwaIsEnabled.ToString() != _pwaisenabled)
|
||||||
{
|
{
|
||||||
site.PwaIsEnabled = Boolean.Parse(_pwaisenabled);
|
site.PwaIsEnabled = Boolean.Parse(_pwaisenabled);
|
||||||
@ -542,8 +587,20 @@
|
|||||||
reload = true; // needs to be reloaded on server
|
reload = true; // needs to be reloaded on server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hosting model
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
|
{
|
||||||
|
if (site.Runtime != _runtime || site.RenderMode != _runtime + _prerender)
|
||||||
|
{
|
||||||
|
site.Runtime = _runtime;
|
||||||
|
site.RenderMode = _runtime + _prerender;
|
||||||
|
reload = true; // needs to be reloaded on server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
site = await SiteService.UpdateSiteAsync(site);
|
site = await SiteService.UpdateSiteAsync(site);
|
||||||
|
|
||||||
|
// SMTP
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||||
settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true);
|
settings = SettingService.SetSetting(settings, "SMTPHost", _smtphost, true);
|
||||||
settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true);
|
settings = SettingService.SetSetting(settings, "SMTPPort", _smtpport, true);
|
||||||
@ -552,6 +609,7 @@
|
|||||||
settings = SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true);
|
settings = SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true);
|
||||||
settings = SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true);
|
settings = SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true);
|
||||||
settings = SettingService.SetSetting(settings, "SMTPRelay", _smtprelay, true);
|
settings = SettingService.SetSetting(settings, "SMTPRelay", _smtprelay, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "SMTPEnabled", _smtpenabled, true);
|
||||||
settings = SettingService.SetSetting(settings, "NotificationRetention", _retention, true);
|
settings = SettingService.SetSetting(settings, "NotificationRetention", _retention, true);
|
||||||
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
||||||
|
|
||||||
@ -564,7 +622,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
|
AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
|
||||||
await interop.ScrollTo(0, 0, "smooth");
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -633,8 +691,7 @@
|
|||||||
|
|
||||||
await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly."));
|
await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly."));
|
||||||
AddModuleMessage(Localizer["Info.Smtp.SaveSettings"], MessageType.Info);
|
AddModuleMessage(Localizer["Info.Smtp.SaveSettings"], MessageType.Info);
|
||||||
var interop = new Interop(JSRuntime);
|
await ScrollToPageTop();
|
||||||
await interop.ScrollTo(0, 0, "smooth");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -65,13 +65,15 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
<br />
|
||||||
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
<TabPanel Name="Upload" ResourceKey="Upload">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
|
<Label Class="col-sm-3" HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" />
|
<FileManager Folder="@Constants.PackagesFolder" UploadMultiple="true" OnUpload="OnUpload" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -111,13 +113,8 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button type="button" class="btn btn-success" @onclick="InstallThemes">@SharedLocalizer["Install"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
@ -236,7 +233,7 @@
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
|
||||||
AddModuleMessage(Localizer["Success.Theme.Download"], MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_productname = "";
|
_productname = "";
|
||||||
_license = "";
|
_license = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -248,16 +245,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task InstallThemes()
|
private void OnUpload()
|
||||||
{
|
{
|
||||||
try
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
{
|
|
||||||
await ThemeService.InstallThemesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Installing Theme");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@
|
|||||||
if (_owner != "" && _theme != "" && _template != "-")
|
if (_owner != "" && _theme != "" && _template != "-")
|
||||||
{
|
{
|
||||||
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
||||||
_location = template.Location + _owner + "." + _theme;
|
_location = template.Location + _owner + ".Theme." + _theme;
|
||||||
|
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
162
Oqtane.Client/Modules/Admin/Themes/Edit.razor
Normal file
162
Oqtane.Client/Modules/Admin/Themes/Edit.razor
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Themes
|
||||||
|
@using System.Net
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject IThemeService ThemeService
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="name" class="form-control" @bind="@_name" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="isenabled" HelpText="Is theme enabled for this site?" ResourceKey="IsEnabled">Enabled? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="isenabled" class="form-select" @bind="@_isenabled" required>
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<Section Name="Information" ResourceKey="Information">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="themename" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="themename" class="form-control" @bind="@_themeName" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="version" HelpText="The version of the theme" ResourceKey="Version">Version: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="version" class="form-control" @bind="@_version" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the theme" ResourceKey="Owner">Owner: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="url" HelpText="The reference url of the theme" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="contact" HelpText="The contact for the theme" ResourceKey="Contact">Contact: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="license" HelpText="The license of the theme" ResourceKey="License">License: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
|
<br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="SaveTheme">@SharedLocalizer["Save"]</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
|
private ElementReference form;
|
||||||
|
private bool validated = false;
|
||||||
|
private int _themeId;
|
||||||
|
private string _themeName = "";
|
||||||
|
private string _isenabled;
|
||||||
|
private string _name;
|
||||||
|
private string _version;
|
||||||
|
private string _packagename;
|
||||||
|
private string _owner = "";
|
||||||
|
private string _url = "";
|
||||||
|
private string _contact = "";
|
||||||
|
private string _license = "";
|
||||||
|
private string _createdby;
|
||||||
|
private DateTime _createdon;
|
||||||
|
private string _modifiedby;
|
||||||
|
private DateTime _modifiedon;
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_themeId = Int32.Parse(PageState.QueryString["id"]);
|
||||||
|
var theme = await ThemeService.GetThemeAsync(_themeId, ModuleState.SiteId);
|
||||||
|
if (theme != null)
|
||||||
|
{
|
||||||
|
_name = theme.Name;
|
||||||
|
_isenabled =theme.IsEnabled.ToString();
|
||||||
|
_version = theme.Version;
|
||||||
|
_packagename = theme.PackageName;
|
||||||
|
_owner = theme.Owner;
|
||||||
|
_url = theme.Url;
|
||||||
|
_contact = theme.Contact;
|
||||||
|
_license = theme.License;
|
||||||
|
_createdby = theme.CreatedBy;
|
||||||
|
_createdon = theme.CreatedOn;
|
||||||
|
_modifiedby = theme.ModifiedBy;
|
||||||
|
_modifiedon = theme.ModifiedOn;
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Theme.Loading"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveTheme()
|
||||||
|
{
|
||||||
|
validated = true;
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
if (await interop.FormValid(form))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var theme = await ThemeService.GetThemeAsync(_themeId, ModuleState.SiteId);
|
||||||
|
theme.Name = _name;
|
||||||
|
theme.IsEnabled = (_isenabled == null ? true : bool.Parse(_isenabled));
|
||||||
|
await ThemeService.UpdateThemeAsync(theme);
|
||||||
|
await logger.LogInformation("Theme Saved {Theme}", theme);
|
||||||
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Saving Theme {ThemeId} {Error}", _themeId, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -23,11 +23,12 @@ else
|
|||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
<th>@SharedLocalizer["Version"]</th>
|
<th>@SharedLocalizer["Version"]</th>
|
||||||
|
<th>@Localizer["Enabled"]</th>
|
||||||
<th>@SharedLocalizer["Expires"]</th>
|
<th>@SharedLocalizer["Expires"]</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"name=" + WebUtility.UrlEncode(context.ThemeName))" ResourceKey="ViewTheme" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ThemeId.ToString())" ResourceKey="EditModule" /></td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName != Constants.ClientId)
|
@if (context.AssemblyName != Constants.ClientId)
|
||||||
{
|
{
|
||||||
@ -36,6 +37,16 @@ else
|
|||||||
</td>
|
</td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.Version</td>
|
<td>@context.Version</td>
|
||||||
|
<td>
|
||||||
|
@if (context.IsEnabled)
|
||||||
|
{
|
||||||
|
<span>@SharedLocalizer["Yes"]</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span>@SharedLocalizer["No"]</span>
|
||||||
|
}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@((MarkupString)PurchaseLink(context.PackageName))
|
@((MarkupString)PurchaseLink(context.PackageName))
|
||||||
</td>
|
</td>
|
||||||
@ -116,7 +127,6 @@ else
|
|||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
||||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
|
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
|
||||||
await ThemeService.InstallThemesAsync();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Themes
|
|
||||||
@using System.Net
|
|
||||||
@inherits ModuleBase
|
|
||||||
@inject IThemeService ThemeService
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
@inject IStringLocalizer<View> Localizer
|
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="name" HelpText="The name of the theme" ResourceKey="Name">Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="name" class="form-control" @bind="@_name" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="themename" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="themename" class="form-control" @bind="@_themeName" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="version" HelpText="The version of the theme" ResourceKey="Version">Version: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="version" class="form-control" @bind="@_version" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="owner" HelpText="The owner or creator of the theme" ResourceKey="Owner">Owner: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="owner" class="form-control" @bind="@_owner" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the theme" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="contact" HelpText="The contact for the theme" ResourceKey="Contact">Contact: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="contact" class="form-control" @bind="@_contact" disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="license" HelpText="The license of the theme" ResourceKey="License">License: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private string _themeName = "";
|
|
||||||
private string _name;
|
|
||||||
private string _version;
|
|
||||||
private string _packagename;
|
|
||||||
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;
|
|
||||||
_packagename = theme.PackageName;
|
|
||||||
_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(Localizer["Error.Theme.Loading"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Admin.UserProfile
|
@namespace Oqtane.Modules.Admin.UserProfile
|
||||||
|
@using System.Text.RegularExpressions;
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@ -34,7 +35,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +44,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -370,6 +371,8 @@ else
|
|||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -389,10 +392,15 @@ else
|
|||||||
}
|
}
|
||||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
||||||
|
{
|
||||||
|
Regex regex = new Regex(profile.Validation);
|
||||||
|
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Users
|
@namespace Oqtane.Modules.Admin.Users
|
||||||
|
@using System.Text.RegularExpressions;
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@ -23,7 +24,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +33,7 @@
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" required />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" required />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -195,10 +196,18 @@
|
|||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
|
{
|
||||||
|
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
||||||
|
{
|
||||||
|
Regex regex = new Regex(profile.Validation);
|
||||||
|
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Users
|
@namespace Oqtane.Modules.Admin.Users
|
||||||
|
@using System.Text.RegularExpressions;
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@ -32,7 +33,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -41,7 +42,7 @@ else
|
|||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -293,10 +294,18 @@ else
|
|||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
|
{
|
||||||
|
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
||||||
{
|
{
|
||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
|
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
||||||
|
{
|
||||||
|
Regex regex = new Regex(profile.Validation);
|
||||||
|
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,6 @@
|
|||||||
_haseditpermission = false;
|
_haseditpermission = false;
|
||||||
_files = new List<File>();
|
_files = new List<File>();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (_filter != "*")
|
if (_filter != "*")
|
||||||
{
|
{
|
||||||
List<File> filtered = new List<File>();
|
List<File> filtered = new List<File>();
|
||||||
@ -245,6 +244,7 @@
|
|||||||
_files = filtered;
|
_files = filtered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task FolderChanged(ChangeEventArgs e)
|
private async Task FolderChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
@ -370,6 +370,12 @@
|
|||||||
_messagetype = MessageType.Error;
|
_messagetype = MessageType.Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Folder == Constants.PackagesFolder)
|
||||||
|
{
|
||||||
|
await OnUpload.InvokeAsync(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// set FileId to first file in upload collection
|
// set FileId to first file in upload collection
|
||||||
await GetFiles();
|
await GetFiles();
|
||||||
var file = _files.Where(item => item.Name == uploads[0]).FirstOrDefault();
|
var file = _files.Where(item => item.Name == uploads[0]).FirstOrDefault();
|
||||||
@ -380,6 +386,7 @@
|
|||||||
await OnUpload.InvokeAsync(FileId);
|
await OnUpload.InvokeAsync(FileId);
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,6 @@
|
|||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.bubble.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.bubble.css" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.snow.css" }
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.snow.css" }
|
||||||
};
|
};
|
||||||
|
@ -15,11 +15,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
|
||||||
{
|
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
|
|
||||||
};
|
|
||||||
|
|
||||||
private string content = "";
|
private string content = "";
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Modules.HtmlText
|
namespace Oqtane.Modules.HtmlText
|
||||||
{
|
{
|
||||||
@ -13,7 +15,11 @@ namespace Oqtane.Modules.HtmlText
|
|||||||
Version = "1.0.1",
|
Version = "1.0.1",
|
||||||
ServerManagerType = "Oqtane.Modules.HtmlText.Manager.HtmlTextManager, Oqtane.Server",
|
ServerManagerType = "Oqtane.Modules.HtmlText.Manager.HtmlTextManager, Oqtane.Server",
|
||||||
ReleaseVersions = "1.0.0,1.0.1",
|
ReleaseVersions = "1.0.0,1.0.1",
|
||||||
SettingsType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client"
|
SettingsType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client",
|
||||||
|
Resources = new List<Resource>()
|
||||||
|
{
|
||||||
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Module.css" }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using Oqtane.UI;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Oqtane.Themes;
|
||||||
|
|
||||||
namespace Oqtane.Modules
|
namespace Oqtane.Modules
|
||||||
{
|
{
|
||||||
@ -70,17 +71,33 @@ namespace Oqtane.Modules
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
List<Resource> resources = null;
|
||||||
|
var type = GetType();
|
||||||
|
if (type.BaseType == typeof(ModuleBase))
|
||||||
|
{
|
||||||
|
if (PageState.Page.Resources != null)
|
||||||
|
{
|
||||||
|
resources = PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Script && item.Level != ResourceLevel.Site && item.Namespace == type.Namespace).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // modulecontrolbase
|
||||||
|
{
|
||||||
|
if (Resources != null)
|
||||||
|
{
|
||||||
|
resources = Resources.Where(item => item.ResourceType == ResourceType.Script).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resources != null &&resources.Any())
|
||||||
{
|
{
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
var scripts = new List<object>();
|
var scripts = new List<object>();
|
||||||
var inline = 0;
|
var inline = 0;
|
||||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
foreach (Resource resource in resources)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(resource.Url))
|
if (!string.IsNullOrEmpty(resource.Url))
|
||||||
{
|
{
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
||||||
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module });
|
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module, location = resource.Location.ToString().ToLower() });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -104,6 +121,7 @@ namespace Oqtane.Modules
|
|||||||
}
|
}
|
||||||
|
|
||||||
// url methods
|
// url methods
|
||||||
|
|
||||||
public string NavigateUrl()
|
public string NavigateUrl()
|
||||||
{
|
{
|
||||||
return NavigateUrl(PageState.Page.Path);
|
return NavigateUrl(PageState.Page.Path);
|
||||||
@ -273,6 +291,33 @@ namespace Oqtane.Modules
|
|||||||
SiteState.Properties.ModuleVisibility = obj;
|
SiteState.Properties.ModuleVisibility = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetPageTitle(string title)
|
||||||
|
{
|
||||||
|
SiteState.Properties.PageTitle = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note - only supports links and meta tags - not scripts
|
||||||
|
public void AddHeadContent(string content)
|
||||||
|
{
|
||||||
|
SiteState.AppendHeadContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddScript(Resource resource)
|
||||||
|
{
|
||||||
|
resource.ResourceType = ResourceType.Script;
|
||||||
|
if (Resources == null) Resources = new List<Resource>();
|
||||||
|
if (!Resources.Any(item => (!string.IsNullOrEmpty(resource.Url) && item.Url == resource.Url) || (!string.IsNullOrEmpty(resource.Content) && item.Content == resource.Content)))
|
||||||
|
{
|
||||||
|
Resources.Add(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ScrollToPageTop()
|
||||||
|
{
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.ScrollTo(0, 0, "smooth");
|
||||||
|
}
|
||||||
|
|
||||||
// logging methods
|
// logging methods
|
||||||
public async Task Log(Alias alias, LogLevel level, string function, Exception exception, string message, params object[] args)
|
public async Task Log(Alias alias, LogLevel level, string function, Exception exception, string message, params object[] args)
|
||||||
{
|
{
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RazorLangVersion>3.0</RazorLangVersion>
|
<RazorLangVersion>3.0</RazorLangVersion>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Version>3.4.0</Version>
|
<Version>4.0.0</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
<Description>Modular Application Framework for Blazor and MAUI</Description>
|
<Description>CMS and Application Framework for Blazor and .NET MAUI</Description>
|
||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
@ -22,13 +22,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="6.0.3" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="6.0.3" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.5" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
||||||
|
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.3" />
|
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -16,7 +16,6 @@ using Microsoft.JSInterop;
|
|||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Modules;
|
using Oqtane.Modules;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.UI;
|
using Oqtane.UI;
|
||||||
|
|
||||||
namespace Oqtane.Client
|
namespace Oqtane.Client
|
||||||
@ -198,6 +197,8 @@ namespace Oqtane.Client
|
|||||||
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
||||||
{
|
{
|
||||||
// dynamically register module scoped services
|
// dynamically register module scoped services
|
||||||
|
try
|
||||||
|
{
|
||||||
var implementationTypes = assembly.GetInterfaces<IService>();
|
var implementationTypes = assembly.GetInterfaces<IService>();
|
||||||
foreach (var implementationType in implementationTypes)
|
foreach (var implementationType in implementationTypes)
|
||||||
{
|
{
|
||||||
@ -208,8 +209,15 @@ namespace Oqtane.Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var startUps = assembly.GetInstances<IClientStartup>();
|
var startUps = assembly.GetInstances<IClientStartup>();
|
||||||
foreach (var startup in startUps)
|
foreach (var startup in startUps)
|
||||||
@ -217,6 +225,11 @@ namespace Oqtane.Client
|
|||||||
startup.ConfigureServices(services);
|
startup.ConfigureServices(services);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static async Task SetCultureFromLocalizationCookie(IServiceProvider serviceProvider)
|
private static async Task SetCultureFromLocalizationCookie(IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
<value>Database:</value>
|
<value>Database:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ApplicationAdmin" xml:space="preserve">
|
<data name="ApplicationAdmin" xml:space="preserve">
|
||||||
<value>Application Administrator</value>
|
<value>Application Administration</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InstallNow" xml:space="preserve">
|
<data name="InstallNow" xml:space="preserve">
|
||||||
<value>Install Now</value>
|
<value>Install Now</value>
|
||||||
@ -180,4 +180,7 @@
|
|||||||
<data name="EnterConnectionString" xml:space="preserve">
|
<data name="EnterConnectionString" xml:space="preserve">
|
||||||
<value>Enter Connection String</value>
|
<value>Enter Connection String</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Template" xml:space="preserve">
|
||||||
|
<value>Select a site template</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -120,29 +120,23 @@
|
|||||||
<data name="Error.Language.Add" xml:space="preserve">
|
<data name="Error.Language.Add" xml:space="preserve">
|
||||||
<value>Error Adding Language</value>
|
<value>Error Adding Language</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Translated.HelpText" xml:space="preserve">
|
|
||||||
<value>Specify If You Wish To Select Languages That Have Translations Installed</value>
|
|
||||||
</data>
|
|
||||||
<data name="Name.HelpText" xml:space="preserve">
|
<data name="Name.HelpText" xml:space="preserve">
|
||||||
<value>Name Of The Langauage</value>
|
<value>Name Of The Langauage</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsDefault.HelpText" xml:space="preserve">
|
<data name="IsDefault.HelpText" xml:space="preserve">
|
||||||
<value>Indicates Whether Or Not This Language Is The Default For The Site</value>
|
<value>Indicates Whether Or Not This Language Is The Default For The Site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Translated.Text" xml:space="preserve">
|
|
||||||
<value>Translated?</value>
|
|
||||||
</data>
|
|
||||||
<data name="Name.Text" xml:space="preserve">
|
<data name="Name.Text" xml:space="preserve">
|
||||||
<value>Name:</value>
|
<value>Name:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsDefault.Text" xml:space="preserve">
|
<data name="IsDefault.Text" xml:space="preserve">
|
||||||
<value>Default?</value>
|
<value>Default?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Language.Install" xml:space="preserve">
|
<data name="Success.Language.Download" xml:space="preserve">
|
||||||
<value>Translations Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
<value>Translation Package Saved Successfully. You Must <a href={0}>Restart</a> To Complete The Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LanguageUpload.HelpText" xml:space="preserve">
|
<data name="LanguageUpload.HelpText" xml:space="preserve">
|
||||||
<value>Upload one or more translation packages. Once they are uploaded click Install to complete the installation.</value>
|
<value>Upload one or more translation packages.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="LanguageUpload.Text" xml:space="preserve">
|
<data name="LanguageUpload.Text" xml:space="preserve">
|
||||||
<value>Translation</value>
|
<value>Translation</value>
|
||||||
|
@ -132,12 +132,12 @@
|
|||||||
<data name="DeleteLanguage.Header" xml:space="preserve">
|
<data name="DeleteLanguage.Header" xml:space="preserve">
|
||||||
<value>Delete Language</value>
|
<value>Delete Language</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Success.Language.Download" xml:space="preserve">
|
||||||
|
<value>Translation Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
|
</data>
|
||||||
<data name="Error.Language.Download" xml:space="preserve">
|
<data name="Error.Language.Download" xml:space="preserve">
|
||||||
<value>Error Downloading Translation</value>
|
<value>Error Downloading Translation</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Language.Install" xml:space="preserve">
|
|
||||||
<value>Translation Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Default" xml:space="preserve">
|
<data name="Default" xml:space="preserve">
|
||||||
<value>Default</value>
|
<value>Default</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -123,17 +123,14 @@
|
|||||||
<data name="Error.Package.Load" xml:space="preserve">
|
<data name="Error.Package.Load" xml:space="preserve">
|
||||||
<value>Error Loading Packages</value>
|
<value>Error Loading Packages</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Module.Install" xml:space="preserve">
|
|
||||||
<value>Module Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Success.Module.Download" xml:space="preserve">
|
<data name="Success.Module.Download" xml:space="preserve">
|
||||||
<value>Module Downloaded Successfully. Click Install To Complete Installation.</value>
|
<value>Module Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Module.Download" xml:space="preserve">
|
<data name="Error.Module.Download" xml:space="preserve">
|
||||||
<value>Error Downloading Module</value>
|
<value>Error Downloading Module</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Module.HelpText" xml:space="preserve">
|
<data name="Module.HelpText" xml:space="preserve">
|
||||||
<value>Upload one or more module packages. Once they are uploaded click Install to complete the installation.</value>
|
<value>Upload one or more module packages.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.NoResults" xml:space="preserve">
|
<data name="Search.NoResults" xml:space="preserve">
|
||||||
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
|
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
|
||||||
|
@ -211,12 +211,18 @@
|
|||||||
<value>No Translations Exist For This Module Or Package Service Is Disabled</value>
|
<value>No Translations Exist For This Module Or Package Service Is Disabled</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Translation.Download" xml:space="preserve">
|
<data name="Success.Translation.Download" xml:space="preserve">
|
||||||
<value>Translation Downloaded Successfully. Click Install To Complete Installation.</value>
|
<value>Translation Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
</data>
|
|
||||||
<data name="Success.Translation.Install" xml:space="preserve">
|
|
||||||
<value>Translation Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
</data>
|
||||||
<data name="Translations.Heading" xml:space="preserve">
|
<data name="Translations.Heading" xml:space="preserve">
|
||||||
<value>Translations</value>
|
<value>Translations</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.DuplicateName" xml:space="preserve">
|
||||||
|
<value>A Module With The Name Specified Already Exists</value>
|
||||||
|
</data>
|
||||||
|
<data name="IsEnabled.HelpText" xml:space="preserve">
|
||||||
|
<value>Is module enabled for this site?</value>
|
||||||
|
</data>
|
||||||
|
<data name="IsEnabled.Text" xml:space="preserve">
|
||||||
|
<value>Enabled?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -145,7 +145,7 @@
|
|||||||
<value>Delete Module</value>
|
<value>Delete Module</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="InUse" xml:space="preserve">
|
<data name="InUse" xml:space="preserve">
|
||||||
<value>In Use</value>
|
<value>In Use?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="EditModule.Text" xml:space="preserve">
|
<data name="EditModule.Text" xml:space="preserve">
|
||||||
<value>Edit</value>
|
<value>Edit</value>
|
||||||
@ -153,4 +153,7 @@
|
|||||||
<data name="Modules" xml:space="preserve">
|
<data name="Modules" xml:space="preserve">
|
||||||
<value>Modules</value>
|
<value>Modules</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Enabled" xml:space="preserve">
|
||||||
|
<value>Enabled?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -150,8 +150,8 @@
|
|||||||
<data name="Container.Select" xml:space="preserve">
|
<data name="Container.Select" xml:space="preserve">
|
||||||
<value>Select Container</value>
|
<value>Select Container</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Page.Initialize" xml:space="preserve">
|
<data name="Error.Page.Load" xml:space="preserve">
|
||||||
<value>Error Initializing Page</value>
|
<value>Error Loading Page</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.ChildPage.Load" xml:space="preserve">
|
<data name="Error.ChildPage.Load" xml:space="preserve">
|
||||||
<value>Error Loading Child Pages For Parent</value>
|
<value>Error Loading Child Pages For Parent</value>
|
||||||
@ -228,13 +228,22 @@
|
|||||||
<data name="Appearance.Name" xml:space="preserve">
|
<data name="Appearance.Name" xml:space="preserve">
|
||||||
<value>Appearance</value>
|
<value>Appearance</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Meta.HelpText" xml:space="preserve">
|
<data name="HeadContent.HelpText" xml:space="preserve">
|
||||||
<value>Optionally enter meta tags (in exactly the form you want them to be included in the page output).</value>
|
<value>Optionally enter content to be included in the page head (ie. meta, link, or script tags)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Meta.Text" xml:space="preserve">
|
<data name="HeadContent.Text" xml:space="preserve">
|
||||||
<value>Meta:</value>
|
<value>Head Content:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Page.Reserved" xml:space="preserve">
|
<data name="Message.Page.Reserved" xml:space="preserve">
|
||||||
<value>The page name {0} is reserved. Please enter a different name for your page.</value>
|
<value>The page name {0} is reserved. Please enter a different name for your page.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="BodyContent.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally enter content to be included in the page body (ie. script tags)</value>
|
||||||
|
</data>
|
||||||
|
<data name="BodyContent.Text" xml:space="preserve">
|
||||||
|
<value>Body Content:</value>
|
||||||
|
</data>
|
||||||
|
<data name="PageContent.Heading" xml:space="preserve">
|
||||||
|
<value>Page Content</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -264,13 +264,22 @@
|
|||||||
<data name="Clickable.Text" xml:space="preserve">
|
<data name="Clickable.Text" xml:space="preserve">
|
||||||
<value>Clickable?</value>
|
<value>Clickable?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Meta.HelpText" xml:space="preserve">
|
<data name="HeadContent.HelpText" xml:space="preserve">
|
||||||
<value>Optionally enter meta tags (in exactly the form you want them to be included in the page output).</value>
|
<value>Optionally enter content to be included in the page head (ie. meta, link, or script tags)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Meta.Text" xml:space="preserve">
|
<data name="HeadContent.Text" xml:space="preserve">
|
||||||
<value>Meta:</value>
|
<value>Head Content:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Page.Reserved" xml:space="preserve">
|
<data name="Message.Page.Reserved" xml:space="preserve">
|
||||||
<value>The page name {0} is reserved. Please enter a different name for your page.</value>
|
<value>The page name {0} is reserved. Please enter a different name for your page.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="BodyContent.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally enter content to be included in the page body (ie. script tags)</value>
|
||||||
|
</data>
|
||||||
|
<data name="BodyContent.Text" xml:space="preserve">
|
||||||
|
<value>Body Content:</value>
|
||||||
|
</data>
|
||||||
|
<data name="PageContent.Heading" xml:space="preserve">
|
||||||
|
<value>Page Content</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -183,4 +183,10 @@
|
|||||||
<data name="Private.Text" xml:space="preserve">
|
<data name="Private.Text" xml:space="preserve">
|
||||||
<value>Private? </value>
|
<value>Private? </value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Validation.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally provide a regular expression (RegExp) for validating the value entered</value>
|
||||||
|
</data>
|
||||||
|
<data name="Validation.Text" xml:space="preserve">
|
||||||
|
<value>Validation:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<root>
|
<root>
|
||||||
<!--
|
<!--
|
||||||
Microsoft ResX Schema
|
Microsoft ResX Schema
|
||||||
@ -166,7 +166,7 @@
|
|||||||
<value>Email:</value>
|
<value>Email:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Password.HelpText" xml:space="preserve">
|
<data name="Password.HelpText" xml:space="preserve">
|
||||||
<value>Please choose a sufficiently secure password and enter it here</value>
|
<value>Please enter a sufficiently secure password which meets the password complexity requirements</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Password.Text" xml:space="preserve">
|
<data name="Password.Text" xml:space="preserve">
|
||||||
<value>Password:</value>
|
<value>Password:</value>
|
||||||
@ -177,4 +177,19 @@
|
|||||||
<data name="Username.Text" xml:space="preserve">
|
<data name="Username.Text" xml:space="preserve">
|
||||||
<value>Username:</value>
|
<value>Username:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Password.ValidationCriteria" xml:space="preserve">
|
||||||
|
<value>Passwords Must Have A Minimum Length Of {0} Characters, Including At Least {1} Unique Character(s), {2}{3}{4}{5} To Satisfy Password Compexity Requirements For This Site.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.DigitRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Digit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.LowercaseRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Lowercase Letter</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.PunctuationRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Punctuation Mark</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.UppercaseRequirement" xml:space="preserve">
|
||||||
|
<value>At Least One Uppercase Letter</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -175,7 +175,7 @@
|
|||||||
<value>Specify a logo for the site</value>
|
<value>Specify a logo for the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FavoriteIcon.HelpText" xml:space="preserve">
|
<data name="FavoriteIcon.HelpText" xml:space="preserve">
|
||||||
<value>Specify a Favicon</value>
|
<value>Specify a Favicon. The format for the image must be 16×16, 32×32, 48×48, or 64×64 pixels in size, and 8-bit, 24-bit, or 32-bit in color depth. The format of the image must be ICO, PNG, or GIF.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DefaultTheme.HelpText" xml:space="preserve">
|
<data name="DefaultTheme.HelpText" xml:space="preserve">
|
||||||
<value>Select the sites default theme</value>
|
<value>Select the sites default theme</value>
|
||||||
@ -351,4 +351,34 @@
|
|||||||
<data name="SiteMap.Text" xml:space="preserve">
|
<data name="SiteMap.Text" xml:space="preserve">
|
||||||
<value>Site Map:</value>
|
<value>Site Map:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Appearance.Heading" xml:space="preserve">
|
||||||
|
<value>Appearance</value>
|
||||||
|
</data>
|
||||||
|
<data name="HeadContent.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally enter content to be included in the page head (ie. meta, link, or script tags)</value>
|
||||||
|
</data>
|
||||||
|
<data name="HeadContent.Text" xml:space="preserve">
|
||||||
|
<value>Head Content:</value>
|
||||||
|
</data>
|
||||||
|
<data name="BodyContent.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally enter content to be included in the page body (ie. script tags)</value>
|
||||||
|
</data>
|
||||||
|
<data name="BodyContent.Text" xml:space="preserve">
|
||||||
|
<value>Body Content:</value>
|
||||||
|
</data>
|
||||||
|
<data name="PageContent.Heading" xml:space="preserve">
|
||||||
|
<value>Page Content</value>
|
||||||
|
</data>
|
||||||
|
<data name="SMTPEnabled.HelpText" xml:space="preserve">
|
||||||
|
<value>Specify if SMTP is enabled for this site</value>
|
||||||
|
</data>
|
||||||
|
<data name="SMTPEnabled.Text" xml:space="preserve">
|
||||||
|
<value>Enabled?</value>
|
||||||
|
</data>
|
||||||
|
<data name="Version.HelpText" xml:space="preserve">
|
||||||
|
<value>The site version (for site content migrations)</value>
|
||||||
|
</data>
|
||||||
|
<data name="Version.Text" xml:space="preserve">
|
||||||
|
<value>Version:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -123,17 +123,14 @@
|
|||||||
<data name="Theme.Text" xml:space="preserve">
|
<data name="Theme.Text" xml:space="preserve">
|
||||||
<value>Theme: </value>
|
<value>Theme: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Theme.Install" xml:space="preserve">
|
|
||||||
<value>Theme Installed Successfully. You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Success.Theme.Download" xml:space="preserve">
|
<data name="Success.Theme.Download" xml:space="preserve">
|
||||||
<value>Theme Downloaded Successfully. Click Install To Complete Installation.</value>
|
<value>Theme Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Theme.Download" xml:space="preserve">
|
<data name="Error.Theme.Download" xml:space="preserve">
|
||||||
<value>Error Downloading Theme</value>
|
<value>Error Downloading Theme</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Theme.HelpText" xml:space="preserve">
|
<data name="Theme.HelpText" xml:space="preserve">
|
||||||
<value>Upload one or more theme packages. Once they are uploaded click Install to complete the installation.</value>
|
<value>Upload one or more theme packages.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.NoResults" xml:space="preserve">
|
<data name="Search.NoResults" xml:space="preserve">
|
||||||
<value>No Themes Match The Criteria Provided Or Package Service Is Disabled</value>
|
<value>No Themes Match The Criteria Provided Or Package Service Is Disabled</value>
|
||||||
|
@ -168,4 +168,13 @@
|
|||||||
<data name="PackageName.Text" xml:space="preserve">
|
<data name="PackageName.Text" xml:space="preserve">
|
||||||
<value>Package Name:</value>
|
<value>Package Name:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Information.Heading" xml:space="preserve">
|
||||||
|
<value>Information</value>
|
||||||
|
</data>
|
||||||
|
<data name="IsEnabled.HelpText" xml:space="preserve">
|
||||||
|
<value>Is theme enabled for this site?</value>
|
||||||
|
</data>
|
||||||
|
<data name="IsEnabled.Text" xml:space="preserve">
|
||||||
|
<value>Enabled?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -144,4 +144,7 @@
|
|||||||
<data name="ViewTheme.Text" xml:space="preserve">
|
<data name="ViewTheme.Text" xml:space="preserve">
|
||||||
<value>View</value>
|
<value>View</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Enabled" xml:space="preserve">
|
||||||
|
<value>Enabled?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -340,6 +340,48 @@
|
|||||||
<value>Visitor Management</value>
|
<value>Visitor Management</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Oqtane.Marketplace" xml:space="preserve">
|
<data name="Oqtane.Marketplace" xml:space="preserve">
|
||||||
<value>Please note that the third party extensions displayed above have been registered in the <a href="https://www.oqtane.net" target="_new">Oqtane Marketplace</a> which enables them to be seamlessly downloaded and installed into the framework.</value>
|
<value>Please note that third party extensions are registered in the <a href="https://www.oqtane.net" target="_new">Oqtane Marketplace</a> which enables them to be seamlessly downloaded and installed into the framework.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Home" xml:space="preserve">
|
||||||
|
<value>Home</value>
|
||||||
|
</data>
|
||||||
|
<data name="Close" xml:space="preserve">
|
||||||
|
<value>Close</value>
|
||||||
|
</data>
|
||||||
|
<data name="OK" xml:space="preserve">
|
||||||
|
<value>OK</value>
|
||||||
|
</data>
|
||||||
|
<data name="Apply" xml:space="preserve">
|
||||||
|
<value>Apply</value>
|
||||||
|
</data>
|
||||||
|
<data name="Select" xml:space="preserve">
|
||||||
|
<value>Select</value>
|
||||||
|
</data>
|
||||||
|
<data name="Next" xml:space="preserve">
|
||||||
|
<value>Next</value>
|
||||||
|
</data>
|
||||||
|
<data name="Previous" xml:space="preserve">
|
||||||
|
<value>Previous</value>
|
||||||
|
</data>
|
||||||
|
<data name="Submit" xml:space="preserve">
|
||||||
|
<value>Submit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Refresh" xml:space="preserve">
|
||||||
|
<value>Refresh</value>
|
||||||
|
</data>
|
||||||
|
<data name="Back" xml:space="preserve">
|
||||||
|
<value>Back</value>
|
||||||
|
</data>
|
||||||
|
<data name="Return" xml:space="preserve">
|
||||||
|
<value>Return</value>
|
||||||
|
</data>
|
||||||
|
<data name="New" xml:space="preserve">
|
||||||
|
<value>New</value>
|
||||||
|
</data>
|
||||||
|
<data name="View" xml:space="preserve">
|
||||||
|
<value>View</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirm" xml:space="preserve">
|
||||||
|
<value>Confirm</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -29,9 +30,9 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public async Task<List<File>> GetFilesAsync(int siteId, string folderPath)
|
public async Task<List<File>> GetFilesAsync(int siteId, string folderPath)
|
||||||
{
|
{
|
||||||
if (!(folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar)))
|
if (!(string.IsNullOrEmpty(folderPath) || folderPath.EndsWith(System.IO.Path.DirectorySeparatorChar) || folderPath.EndsWith(System.IO.Path.AltDirectorySeparatorChar)))
|
||||||
{
|
{
|
||||||
folderPath = Utilities.PathCombine(folderPath, System.IO.Path.DirectorySeparatorChar.ToString());
|
folderPath = Utilities.UrlCombine(folderPath) + "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = WebUtility.UrlEncode(folderPath);
|
var path = WebUtility.UrlEncode(folderPath);
|
||||||
|
@ -33,13 +33,6 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task UpdateModuleDefinitionAsync(ModuleDefinition moduleDefinition);
|
Task UpdateModuleDefinitionAsync(ModuleDefinition moduleDefinition);
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Installs all module definitions located in //TODO: 2dm where?
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task InstallModuleDefinitionsAsync();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a module definition
|
/// Deletes a module definition
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -23,14 +23,6 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Page> GetPageAsync(int pageId);
|
Task<Page> GetPageAsync(int pageId);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Returns a specific page personalized for the given user
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pageId"></param>
|
|
||||||
/// <param name="userId"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
Task<Page> GetPageAsync(int pageId, int userId);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a specific page by its defined path
|
/// Returns a specific page by its defined path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -16,6 +16,22 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<Theme>> GetThemesAsync();
|
Task<List<Theme>> GetThemesAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a specific thenme
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="themeId"></param>
|
||||||
|
/// <param name="siteId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<Theme> GetThemeAsync(int themeId, int siteId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a theme <see cref="ThemeControl"/>s containing a specific theme control type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="themes"></param>
|
||||||
|
/// <param name="themeControlType"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Theme GetTheme(List<Theme> themes, string themeControlType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a list of <see cref="ThemeControl"/>s from the given themes
|
/// Returns a list of <see cref="ThemeControl"/>s from the given themes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -24,26 +40,27 @@ namespace Oqtane.Services
|
|||||||
List<ThemeControl> GetThemeControls(List<Theme> themes);
|
List<ThemeControl> GetThemeControls(List<Theme> themes);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a list of layouts (<see cref="ThemeControl"/>) from the given themes with a matching theme name
|
/// Returns a list of <see cref="ThemeControl"/>s for a theme containing a specific theme control type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="themes"></param>
|
/// <param name="themes"></param>
|
||||||
/// <param name="themeName"></param>
|
/// <param name="themeControlType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName);
|
List<ThemeControl> GetThemeControls(List<Theme> themes, string themeControlType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a list of containers (<see cref="ThemeControl"/>) from the given themes with a matching theme name
|
/// Returns a list of containers (<see cref="ThemeControl"/>) for a theme containing a specific theme control type
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="themes"></param>
|
/// <param name="themes"></param>
|
||||||
/// <param name="themeName"></param>
|
/// <param name="themeControlType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName);
|
List<ThemeControl> GetContainerControls(List<Theme> themes, string themeControlType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Installs all themes located in //TODO: 2dm where?
|
/// Updates a existing theem
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="theme"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task InstallThemesAsync();
|
Task UpdateThemeAsync(Theme theme);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Deletes a theme
|
/// Deletes a theme
|
||||||
@ -64,5 +81,14 @@ namespace Oqtane.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<List<Template>> GetThemeTemplatesAsync();
|
Task<List<Template>> GetThemeTemplatesAsync();
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a list of layouts (<see cref="ThemeControl"/>) from the given themes with a matching theme name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="themes"></param>
|
||||||
|
/// <param name="themeName"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,11 +34,6 @@ namespace Oqtane.Services
|
|||||||
await PutJsonAsync($"{Apiurl}/{moduleDefinition.ModuleDefinitionId}", moduleDefinition);
|
await PutJsonAsync($"{Apiurl}/{moduleDefinition.ModuleDefinitionId}", moduleDefinition);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InstallModuleDefinitionsAsync()
|
|
||||||
{
|
|
||||||
await GetJsonAsync<List<string>>($"{Apiurl}/install");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId)
|
public async Task DeleteModuleDefinitionAsync(int moduleDefinitionId, int siteId)
|
||||||
{
|
{
|
||||||
await DeleteAsync($"{Apiurl}/{moduleDefinitionId}?siteid={siteId}");
|
await DeleteAsync($"{Apiurl}/{moduleDefinitionId}?siteid={siteId}");
|
||||||
|
@ -18,11 +18,7 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public async Task<List<Module>> GetModulesAsync(int siteId)
|
public async Task<List<Module>> GetModulesAsync(int siteId)
|
||||||
{
|
{
|
||||||
List<Module> modules = await GetJsonAsync<List<Module>>($"{Apiurl}?siteid={siteId}");
|
return await GetJsonAsync<List<Module>>($"{Apiurl}?siteid={siteId}");
|
||||||
modules = modules
|
|
||||||
.OrderBy(item => item.Order)
|
|
||||||
.ToList();
|
|
||||||
return modules;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Module> GetModuleAsync(int moduleId)
|
public async Task<Module> GetModuleAsync(int moduleId)
|
||||||
|
@ -25,11 +25,6 @@ namespace Oqtane.Services
|
|||||||
return await GetJsonAsync<Page>($"{Apiurl}/{pageId}");
|
return await GetJsonAsync<Page>($"{Apiurl}/{pageId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Page> GetPageAsync(int pageId, int userId)
|
|
||||||
{
|
|
||||||
return await GetJsonAsync<Page>($"{Apiurl}/{pageId}?userid={userId}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Page> GetPageAsync(string path, int siteId)
|
public async Task<Page> GetPageAsync(string path, int siteId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -5,6 +5,7 @@ using System.Threading.Tasks;
|
|||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
using Oqtane.UI;
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
@ -20,27 +21,35 @@ namespace Oqtane.Services
|
|||||||
List<Theme> themes = await GetJsonAsync<List<Theme>>(ApiUrl);
|
List<Theme> themes = await GetJsonAsync<List<Theme>>(ApiUrl);
|
||||||
return themes.OrderBy(item => item.Name).ToList();
|
return themes.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
public async Task<Theme> GetThemeAsync(int themeId, int siteId)
|
||||||
|
{
|
||||||
|
return await GetJsonAsync<Theme>($"{ApiUrl}/{themeId}?siteid={siteId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Theme GetTheme(List<Theme> themes, string themeControlType)
|
||||||
|
{
|
||||||
|
return themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == themeControlType));
|
||||||
|
}
|
||||||
|
|
||||||
public List<ThemeControl> GetThemeControls(List<Theme> themes)
|
public List<ThemeControl> GetThemeControls(List<Theme> themes)
|
||||||
{
|
{
|
||||||
return themes.SelectMany(item => item.Themes).ToList();
|
return themes.SelectMany(item => item.Themes).OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Obsolete("This method is deprecated.", false)]
|
public List<ThemeControl> GetThemeControls(List<Theme> themes, string themeControlType)
|
||||||
public List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName)
|
|
||||||
{
|
{
|
||||||
return null;
|
return GetTheme(themes, themeControlType)?.Themes.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ThemeControl> GetContainerControls(List<Theme> themes, string themeName)
|
|
||||||
|
public List<ThemeControl> GetContainerControls(List<Theme> themes, string themeControlType)
|
||||||
{
|
{
|
||||||
return themes.Where(item => Utilities.GetTypeName(themeName).StartsWith(Utilities.GetTypeName(item.ThemeName)))
|
return GetTheme(themes, themeControlType)?.Containers.OrderBy(item => item.Name).ToList();
|
||||||
.SelectMany(item => item.Containers).ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InstallThemesAsync()
|
public async Task UpdateThemeAsync(Theme theme)
|
||||||
{
|
{
|
||||||
await GetJsonAsync<List<string>>($"{ApiUrl}/install");
|
await PutJsonAsync($"{ApiUrl}/{theme.ThemeId}", theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task DeleteThemeAsync(string themeName)
|
public async Task DeleteThemeAsync(string themeName)
|
||||||
@ -58,5 +67,11 @@ namespace Oqtane.Services
|
|||||||
List<Template> templates = await GetJsonAsync<List<Template>>($"{ApiUrl}/templates");
|
List<Template> templates = await GetJsonAsync<List<Template>>($"{ApiUrl}/templates");
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//[Obsolete("This method is deprecated.", false)]
|
||||||
|
public List<ThemeControl> GetLayoutControls(List<Theme> themes, string themeName)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,9 @@
|
|||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
// obtained from https://cdnjs.com/libraries
|
// obtained from https://cdnjs.com/libraries
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/css/bootstrap.min.css", Integrity = "sha512-XWTTruHZEYJsxV3W/lSXG1n3Q39YIWOstqvmFsdNEEQfHoZ6vm6E9GK2OrF6DSJSpIbRbi+Nn0WDPID9O7xB2Q==", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css", Integrity = "sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/js/bootstrap.bundle.min.js", Integrity = "sha512-9GacT4119eY3AcosfWtHMsT5JyZudrexyEVzTBWV3viP/YfB9e2pEy3N7WXL3SV6ASXpTU0vzzSxsbfsuUH4sQ==", CrossOrigin = "anonymous" }
|
new Resource { ResourceType = ResourceType.Script, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js", Integrity = "sha512-VK2zcvntEufaimc+efOYi622VN5ZacdnufnmX7zIhCPmjhKnOi9ZDMtg1/ug5l183f19gG1/cBstPO4D8N/Img==", CrossOrigin = "anonymous" }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -2,12 +2,9 @@
|
|||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits ContainerBase
|
@inherits ContainerBase
|
||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
@inject SiteState SiteState
|
|
||||||
|
|
||||||
<span class="app-moduletitle">
|
<span class="app-moduletitle">
|
||||||
<a id="@ModuleState.PageModuleId.ToString()">
|
|
||||||
@((MarkupString)title)
|
@((MarkupString)title)
|
||||||
</a>
|
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@using System.Net
|
||||||
@namespace Oqtane.Themes.Controls
|
@namespace Oqtane.Themes.Controls
|
||||||
@inherits ThemeControlBase
|
@inherits ThemeControlBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@ -55,7 +56,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr class="app-rule" />
|
<hr class="app-rule" />
|
||||||
}
|
}
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
@if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.PermissionList))
|
||||||
{
|
{
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col text-center">
|
<div class="col text-center">
|
||||||
@ -64,7 +65,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row d-flex mb-2">
|
<div class="row d-flex mb-2">
|
||||||
<div class="col d-flex justify-content-between">
|
<div class="col d-flex justify-content-between">
|
||||||
|
@if (PageState.Page.UserId == null)
|
||||||
|
{
|
||||||
<button type="button" class="btn btn-secondary col me-1" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Add"))>@SharedLocalizer["Add"]</button>
|
<button type="button" class="btn btn-secondary col me-1" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Add"))>@SharedLocalizer["Add"]</button>
|
||||||
|
}
|
||||||
<button type="button" class="btn btn-secondary col" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Edit"))>@SharedLocalizer["Edit"]</button>
|
<button type="button" class="btn btn-secondary col" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Edit"))>@SharedLocalizer["Edit"]</button>
|
||||||
<button type="button" class="btn btn-danger col ms-1" @onclick="ConfirmDelete">@SharedLocalizer["Delete"]</button>
|
<button type="button" class="btn btn-danger col ms-1" @onclick="ConfirmDelete">@SharedLocalizer["Delete"]</button>
|
||||||
</div>
|
</div>
|
||||||
@ -144,7 +148,7 @@
|
|||||||
}
|
}
|
||||||
@foreach (var moduledefinition in _moduleDefinitions)
|
@foreach (var moduledefinition in _moduleDefinitions)
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.PermissionList))
|
if (moduledefinition.IsEnabled && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Utilize, moduledefinition.PermissionList))
|
||||||
{
|
{
|
||||||
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
if (moduledefinition.Runtimes == "" || moduledefinition.Runtimes.Contains(PageState.Runtime.ToString()))
|
||||||
{
|
{
|
||||||
@ -478,15 +482,19 @@
|
|||||||
PageState.EditMode = true;
|
PageState.EditMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "true" : "false")));
|
// preserve other querystring parameters
|
||||||
|
if (PageState.QueryString.ContainsKey("edit")) PageState.QueryString.Remove("edit");
|
||||||
|
PageState.QueryString.Add("edit", PageState.EditMode.ToString().ToLower());
|
||||||
|
var url = PageState.Route.AbsolutePath + Utilities.CreateQueryString(PageState.QueryString);
|
||||||
|
NavigationManager.NavigateTo(url);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (PageState.Page.IsPersonalizable && PageState.User != null)
|
if (PageState.Page.IsPersonalizable && PageState.User != null)
|
||||||
{
|
{
|
||||||
await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
var page = await PageService.AddPageAsync(PageState.Page.PageId, PageState.User.UserId);
|
||||||
PageState.EditMode = true;
|
PageState.EditMode = true;
|
||||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "edit=" + ((PageState.EditMode) ? "true" : "false")));
|
NavigationManager.NavigateTo(NavigateUrl(page.Path, "edit=" + ((PageState.EditMode) ? "true" : "false")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -501,7 +509,7 @@
|
|||||||
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.AdminDashboardModule);
|
module = PageState.Modules.FirstOrDefault(item => item.ModuleDefinitionName == Constants.AdminDashboardModule);
|
||||||
if (module != null)
|
if (module != null)
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, module.ModuleId, "Index", ""));
|
NavigationManager.NavigateTo(EditUrl("admin", module.ModuleId, "Index", "returnurl=" + WebUtility.UrlEncode(PageState.Route.PathAndQuery)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Add":
|
case "Add":
|
||||||
@ -515,10 +523,10 @@
|
|||||||
switch (location)
|
switch (location)
|
||||||
{
|
{
|
||||||
case "Add":
|
case "Add":
|
||||||
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "cp=" + PageState.Page.PageId);
|
url = EditUrl("admin/pages", module.ModuleId, location, $"id={PageState.Page.PageId}&returnurl={WebUtility.UrlEncode(PageState.Route.PathAndQuery)}");
|
||||||
break;
|
break;
|
||||||
case "Edit":
|
case "Edit":
|
||||||
url = EditUrl(PageState.Page.Path, module.ModuleId, location, "id=" + PageState.Page.PageId.ToString() + "&cp=" + PageState.Page.PageId);
|
url = EditUrl("admin/pages", module.ModuleId, location, $"id={PageState.Page.PageId}&returnurl={WebUtility.UrlEncode(PageState.Route.PathAndQuery)}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ namespace Oqtane.Themes.Controls
|
|||||||
[Inject] public IUserService UserService { get; set; }
|
[Inject] public IUserService UserService { get; set; }
|
||||||
[Inject] public IJSRuntime jsRuntime { get; set; }
|
[Inject] public IJSRuntime jsRuntime { get; set; }
|
||||||
[Inject] public IServiceProvider ServiceProvider { get; set; }
|
[Inject] public IServiceProvider ServiceProvider { get; set; }
|
||||||
[Inject] public SiteState SiteState { get; set; }
|
|
||||||
[Inject] public ILogService LoggingService { get; set; }
|
[Inject] public ILogService LoggingService { get; set; }
|
||||||
|
|
||||||
protected void LoginUser()
|
protected void LoginUser()
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
<div class="app-menu navbar-expand-md">
|
<div class="app-menu navbar-expand-md">
|
||||||
<div class="collapse navbar-collapse" id="Menu">
|
<div class="collapse navbar-collapse navbar-nav-scroll" id="Menu">
|
||||||
<MenuItemsHorizontal ParentPage="null" Pages="MenuPages" />
|
<MenuItemsHorizontal ParentPage="null" Pages="MenuPages" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Themes.OqtaneTheme
|
namespace Oqtane.Themes.OqtaneTheme
|
||||||
{
|
{
|
||||||
@ -11,7 +13,13 @@ namespace Oqtane.Themes.OqtaneTheme
|
|||||||
Name = "Oqtane Theme",
|
Name = "Oqtane Theme",
|
||||||
Version = "1.0.0",
|
Version = "1.0.0",
|
||||||
ThemeSettingsType = "Oqtane.Themes.OqtaneTheme.ThemeSettings, Oqtane.Client",
|
ThemeSettingsType = "Oqtane.Themes.OqtaneTheme.ThemeSettings, Oqtane.Client",
|
||||||
ContainerSettingsType = "Oqtane.Themes.OqtaneTheme.ContainerSettings, Oqtane.Client"
|
ContainerSettingsType = "Oqtane.Themes.OqtaneTheme.ContainerSettings, Oqtane.Client",
|
||||||
|
Resources = new List<Resource>()
|
||||||
|
{
|
||||||
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.0/cyborg/bootstrap.min.css", Integrity = "sha512-jwIqEv8o/kTBMJVtbNCBrDqhBojl0YSUam+EFpLjVOC86Ci6t4ZciTnIkelFNOik+dEQVymKGcQLiaJZNAfWRg==", CrossOrigin = "anonymous" },
|
||||||
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
||||||
|
new Resource { ResourceType = ResourceType.Script, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js", Integrity = "sha512-VK2zcvntEufaimc+efOYi622VN5ZacdnufnmX7zIhCPmjhKnOi9ZDMtg1/ug5l183f19gG1/cBstPO4D8N/Img==", CrossOrigin = "anonymous" }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,14 +110,6 @@
|
|||||||
|
|
||||||
public override string Panes => PaneNames.Default + ",Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width,Footer";
|
public override string Panes => PaneNames.Default + ",Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width,Footer";
|
||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
|
||||||
{
|
|
||||||
// obtained from https://cdnjs.com/libraries
|
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.2.0/cyborg/bootstrap.min.css", Integrity = "sha512-d6pZJl/sNcj0GFkp4kTjXtPE14deuUsOqFQtxkj0KyBJQl+4e0qsEyuIDcNqrYuGoauAW3sWyDCQp49mhF4Syw==", CrossOrigin = "anonymous" },
|
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.0/js/bootstrap.bundle.min.js", Integrity = "sha512-9GacT4119eY3AcosfWtHMsT5JyZudrexyEVzTBWV3viP/YfB9e2pEy3N7WXL3SV6ASXpTU0vzzSxsbfsuUH4sQ==", CrossOrigin = "anonymous" }
|
|
||||||
};
|
|
||||||
|
|
||||||
private bool _login = true;
|
private bool _login = true;
|
||||||
private bool _register = true;
|
private bool _register = true;
|
||||||
private bool _footer = false;
|
private bool _footer = false;
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private int pageId = -1;
|
||||||
private string resourceType = "Oqtane.Themes.OqtaneTheme.ThemeSettings, Oqtane.Client"; // for localization
|
private string resourceType = "Oqtane.Themes.OqtaneTheme.ThemeSettings, Oqtane.Client"; // for localization
|
||||||
private string _scope = "page";
|
private string _scope = "page";
|
||||||
private string _login = "-";
|
private string _login = "-";
|
||||||
@ -60,6 +61,11 @@
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
|
if (PageState.QueryString.ContainsKey("id"))
|
||||||
|
{
|
||||||
|
pageId = int.Parse(PageState.QueryString["id"]);
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await LoadSettings();
|
await LoadSettings();
|
||||||
@ -82,7 +88,8 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var settings = SettingService.MergeSettings(PageState.Site.Settings, PageState.Page.Settings);
|
var settings = await SettingService.GetPageSettingsAsync(pageId);
|
||||||
|
settings = SettingService.MergeSettings(PageState.Site.Settings, settings);
|
||||||
_login = SettingService.GetSetting(settings, GetType().Namespace + ":Login", "-");
|
_login = SettingService.GetSetting(settings, GetType().Namespace + ":Login", "-");
|
||||||
_register = SettingService.GetSetting(settings, GetType().Namespace + ":Register", "-");
|
_register = SettingService.GetSetting(settings, GetType().Namespace + ":Register", "-");
|
||||||
_footer = SettingService.GetSetting(settings, GetType().Namespace + ":Footer", "-");
|
_footer = SettingService.GetSetting(settings, GetType().Namespace + ":Footer", "-");
|
||||||
@ -128,7 +135,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var settings = await SettingService.GetPageSettingsAsync(PageState.Page.PageId);
|
var settings = await SettingService.GetPageSettingsAsync(pageId);
|
||||||
if (_login != "-")
|
if (_login != "-")
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
|
||||||
@ -141,7 +148,7 @@
|
|||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Footer", _footer);
|
||||||
}
|
}
|
||||||
await SettingService.UpdatePageSettingsAsync(settings, PageState.Page.PageId);
|
await SettingService.UpdatePageSettingsAsync(settings, pageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -6,6 +6,7 @@ using Oqtane.UI;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Oqtane.Themes
|
namespace Oqtane.Themes
|
||||||
@ -15,10 +16,13 @@ namespace Oqtane.Themes
|
|||||||
[Inject]
|
[Inject]
|
||||||
protected IJSRuntime JSRuntime { get; set; }
|
protected IJSRuntime JSRuntime { get; set; }
|
||||||
|
|
||||||
// optional interface properties
|
[Inject]
|
||||||
|
protected SiteState SiteState { get; set; }
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected PageState PageState { get; set; }
|
protected PageState PageState { get; set; }
|
||||||
|
|
||||||
|
// optional interface properties
|
||||||
public virtual string Name { get; set; }
|
public virtual string Name { get; set; }
|
||||||
public virtual string Thumbnail { get; set; }
|
public virtual string Thumbnail { get; set; }
|
||||||
public virtual string Panes { get; set; }
|
public virtual string Panes { get; set; }
|
||||||
@ -30,17 +34,33 @@ namespace Oqtane.Themes
|
|||||||
{
|
{
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
if (Resources != null && Resources.Exists(item => item.ResourceType == ResourceType.Script))
|
List<Resource> resources = null;
|
||||||
|
var type = GetType();
|
||||||
|
if (type.BaseType == typeof(ThemeBase))
|
||||||
|
{
|
||||||
|
if (PageState.Page.Resources != null)
|
||||||
|
{
|
||||||
|
resources = PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Script && item.Level != ResourceLevel.Site && item.Namespace == type.Namespace).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // themecontrolbase, containerbase
|
||||||
|
{
|
||||||
|
if (Resources != null)
|
||||||
|
{
|
||||||
|
resources = Resources.Where(item => item.ResourceType == ResourceType.Script).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resources != null && resources.Any())
|
||||||
{
|
{
|
||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
var scripts = new List<object>();
|
var scripts = new List<object>();
|
||||||
var inline = 0;
|
var inline = 0;
|
||||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
foreach (Resource resource in resources)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(resource.Url))
|
if (!string.IsNullOrEmpty(resource.Url))
|
||||||
{
|
{
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
||||||
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module });
|
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module, location = resource.Location.ToString().ToLower() });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -139,6 +159,33 @@ namespace Oqtane.Themes
|
|||||||
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate);
|
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetPageTitle(string title)
|
||||||
|
{
|
||||||
|
SiteState.Properties.PageTitle = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note - only supports links and meta tags - not scripts
|
||||||
|
public void AddHeadContent(string content)
|
||||||
|
{
|
||||||
|
SiteState.AppendHeadContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddScript(Resource resource)
|
||||||
|
{
|
||||||
|
resource.ResourceType = ResourceType.Script;
|
||||||
|
if (Resources == null) Resources = new List<Resource>();
|
||||||
|
if (!Resources.Any(item => (!string.IsNullOrEmpty(resource.Url) && item.Url == resource.Url) || (!string.IsNullOrEmpty(resource.Content) && item.Content == resource.Content)))
|
||||||
|
{
|
||||||
|
Resources.Add(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ScrollToPageTop()
|
||||||
|
{
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.ScrollTo(0, 0, "smooth");
|
||||||
|
}
|
||||||
|
|
||||||
[Obsolete("ContentUrl(int fileId) is deprecated. Use FileUrl(int fileId) instead.", false)]
|
[Obsolete("ContentUrl(int fileId) is deprecated. Use FileUrl(int fileId) instead.", false)]
|
||||||
public string ContentUrl(int fileid)
|
public string ContentUrl(int fileid)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
@if (_visible)
|
@if (_visible)
|
||||||
{
|
{
|
||||||
|
<a id="@ModuleState.PageModuleId.ToString()"></a>
|
||||||
<CascadingValue Value="@ModuleState">
|
<CascadingValue Value="@ModuleState">
|
||||||
@if (_useadminborder)
|
@if (_useadminborder)
|
||||||
{
|
{
|
||||||
@ -16,6 +17,7 @@
|
|||||||
@DynamicComponent
|
@DynamicComponent
|
||||||
}
|
}
|
||||||
</CascadingValue>
|
</CascadingValue>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@ -38,7 +40,7 @@
|
|||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
string container = ModuleState.ContainerType;
|
string container = ModuleState.ContainerType;
|
||||||
if (PageState.ModuleId != -1 && ModuleState.UseAdminContainer)
|
if (PageState.ModuleId != -1 && PageState.Route.Action != "" && ModuleState.UseAdminContainer)
|
||||||
{
|
{
|
||||||
container = (!string.IsNullOrEmpty(PageState.Site.AdminContainerType)) ? PageState.Site.AdminContainerType : Constants.DefaultAdminContainer;
|
container = (!string.IsNullOrEmpty(PageState.Site.AdminContainerType)) ? PageState.Site.AdminContainerType : Constants.DefaultAdminContainer;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ namespace Oqtane.UI
|
|||||||
{
|
{
|
||||||
_jsRuntime.InvokeVoidAsync(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"Oqtane.Interop.includeLinks",
|
"Oqtane.Interop.includeLinks",
|
||||||
(object) links);
|
(object)links);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@ -107,12 +107,17 @@ namespace Oqtane.UI
|
|||||||
|
|
||||||
// external scripts need to specify src, inline scripts need to specify id and content
|
// external scripts need to specify src, inline scripts need to specify id and content
|
||||||
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string content, string location)
|
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string content, string location)
|
||||||
|
{
|
||||||
|
return IncludeScript(id, src, integrity, crossorigin, "", content, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string type, string content, string location)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeVoidAsync(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"Oqtane.Interop.includeScript",
|
"Oqtane.Interop.includeScript",
|
||||||
id, src, integrity, crossorigin, content, location);
|
id, src, integrity, crossorigin, type, content, location);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -13,6 +13,7 @@ namespace Oqtane.UI
|
|||||||
public Page Page { get; set; }
|
public Page Page { get; set; }
|
||||||
public User User { get; set; }
|
public User User { get; set; }
|
||||||
public Uri Uri { get; set; }
|
public Uri Uri { get; set; }
|
||||||
|
public Route Route { get; set; }
|
||||||
public Dictionary<string, string> QueryString { get; set; }
|
public Dictionary<string, string> QueryString { get; set; }
|
||||||
public string UrlParameters { get; set; }
|
public string UrlParameters { get; set; }
|
||||||
public int ModuleId { get; set; }
|
public int ModuleId { get; set; }
|
||||||
@ -23,6 +24,7 @@ namespace Oqtane.UI
|
|||||||
public int VisitorId { get; set; }
|
public int VisitorId { get; set; }
|
||||||
public string RemoteIPAddress { get; set; }
|
public string RemoteIPAddress { get; set; }
|
||||||
public string ReturnUrl { get; set; }
|
public string ReturnUrl { get; set; }
|
||||||
|
public bool IsInternalNavigation { get; set; }
|
||||||
|
|
||||||
public List<Page> Pages
|
public List<Page> Pages
|
||||||
{
|
{
|
||||||
|
@ -43,10 +43,11 @@ else
|
|||||||
|
|
||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
if (PageState.ModuleId != -1 && PageState.Action != Constants.DefaultAction)
|
foreach (Module module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId))
|
||||||
|
{
|
||||||
|
var pane = module.Pane;
|
||||||
|
if (module.ModuleId == PageState.ModuleId && PageState.Action != Constants.DefaultAction)
|
||||||
{
|
{
|
||||||
// action route needs to inject module control into specific pane
|
|
||||||
string pane = "";
|
|
||||||
if (PageState.Page.Panes.FindIndex(item => item.Equals(PaneNames.Default, StringComparison.OrdinalIgnoreCase)) != -1)
|
if (PageState.Page.Panes.FindIndex(item => item.Equals(PaneNames.Default, StringComparison.OrdinalIgnoreCase)) != -1)
|
||||||
{
|
{
|
||||||
pane = PaneNames.Default;
|
pane = PaneNames.Default;
|
||||||
@ -54,12 +55,13 @@ else
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
pane = PaneNames.Admin;
|
pane = PaneNames.Admin;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pane matches current pane
|
||||||
if (Name.ToLower() == pane.ToLower())
|
if (Name.ToLower() == pane.ToLower())
|
||||||
{
|
{
|
||||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
if (module.ModuleId == PageState.ModuleId && PageState.Action != Constants.DefaultAction)
|
||||||
if (module != null)
|
|
||||||
{
|
{
|
||||||
var moduleType = Type.GetType(module.ModuleType);
|
var moduleType = Type.GetType(module.ModuleType);
|
||||||
if (moduleType != null)
|
if (moduleType != null)
|
||||||
@ -96,19 +98,10 @@ else
|
|||||||
CreateComponent(builder, module);
|
CreateComponent(builder, module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// module type does not exist
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (PageState.ModuleId != -1)
|
if (PageState.ModuleId == -1 || PageState.ModuleId == module.ModuleId)
|
||||||
{
|
|
||||||
Module module = PageState.Modules.FirstOrDefault(item => item.ModuleId == PageState.ModuleId);
|
|
||||||
if (module != null && module.Pane.ToLower() == Name.ToLower())
|
|
||||||
{
|
{
|
||||||
// check if user is authorized to view module
|
// check if user is authorized to view module
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList))
|
||||||
@ -117,16 +110,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (Module module in PageState.Modules.Where(item => item.PageId == PageState.Page.PageId && item.Pane.ToLower() == Name.ToLower()).OrderBy(x => x.Order).ToArray())
|
|
||||||
{
|
|
||||||
// check if user is authorized to view module
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, module.PermissionList))
|
|
||||||
{
|
|
||||||
CreateComponent(builder, module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _absoluteUri;
|
private string _absoluteUri;
|
||||||
|
private bool _isInternalNavigation = false;
|
||||||
private bool _navigationInterceptionEnabled;
|
private bool _navigationInterceptionEnabled;
|
||||||
private PageState _pagestate;
|
private PageState _pagestate;
|
||||||
private string _error = "";
|
private string _error = "";
|
||||||
@ -72,6 +73,23 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void LocationChanged(object sender, LocationChangedEventArgs args)
|
||||||
|
{
|
||||||
|
_absoluteUri = args.Location;
|
||||||
|
_isInternalNavigation = true;
|
||||||
|
await Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
Task IHandleAfterRender.OnAfterRenderAsync()
|
||||||
|
{
|
||||||
|
if (!_navigationInterceptionEnabled)
|
||||||
|
{
|
||||||
|
_navigationInterceptionEnabled = true;
|
||||||
|
return NavigationInterception.EnableNavigationInterceptionAsync();
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
[SuppressMessage("ReSharper", "StringIndexOfIsCultureSpecific.1")]
|
[SuppressMessage("ReSharper", "StringIndexOfIsCultureSpecific.1")]
|
||||||
private async Task Refresh()
|
private async Task Refresh()
|
||||||
{
|
{
|
||||||
@ -87,7 +105,7 @@
|
|||||||
Route route = new Route(_absoluteUri, SiteState.Alias.Path);
|
Route route = new Route(_absoluteUri, SiteState.Alias.Path);
|
||||||
int moduleid = (int.TryParse(route.ModuleId, out moduleid)) ? moduleid : -1;
|
int moduleid = (int.TryParse(route.ModuleId, out moduleid)) ? moduleid : -1;
|
||||||
var action = (!string.IsNullOrEmpty(route.Action)) ? route.Action : Constants.DefaultAction;
|
var action = (!string.IsNullOrEmpty(route.Action)) ? route.Action : Constants.DefaultAction;
|
||||||
var querystring = ParseQueryString(route.Query);
|
var querystring = Utilities.ParseQueryString(route.Query);
|
||||||
var returnurl = "";
|
var returnurl = "";
|
||||||
if (querystring.ContainsKey("returnurl"))
|
if (querystring.ContainsKey("returnurl"))
|
||||||
{
|
{
|
||||||
@ -203,6 +221,23 @@
|
|||||||
page = site.Pages.FirstOrDefault();
|
page = site.Pages.FirstOrDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
|
// look for personalized page
|
||||||
|
page = await PageService.GetPageAsync(route.PagePath, site.SiteId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (user != null && page.IsPersonalizable)
|
||||||
|
{
|
||||||
|
var personalized = await PageService.GetPageAsync(route.PagePath + "/" + user.Username, site.SiteId);
|
||||||
|
if (personalized != null)
|
||||||
|
{
|
||||||
|
// redirect to the personalized page
|
||||||
|
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, personalized.Path, ""), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (page != null)
|
if (page != null)
|
||||||
{
|
{
|
||||||
@ -210,10 +245,10 @@
|
|||||||
if (UserSecurity.IsAuthorized(user, PermissionNames.View, page.PermissionList))
|
if (UserSecurity.IsAuthorized(user, PermissionNames.View, page.PermissionList))
|
||||||
{
|
{
|
||||||
// load additional metadata for current page
|
// load additional metadata for current page
|
||||||
page = await ProcessPage(page, site, user);
|
page = ProcessPage(page, site, user, SiteState.Alias);
|
||||||
|
|
||||||
// load additional metadata for modules
|
// load additional metadata for modules
|
||||||
(page, site.Modules) = ProcessModules(page, site.Modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType);
|
(page, site.Modules) = ProcessModules(page, site.Modules, moduleid, action, (!string.IsNullOrEmpty(page.DefaultContainerType)) ? page.DefaultContainerType : site.DefaultContainerType, SiteState.Alias);
|
||||||
|
|
||||||
// populate page state (which acts as a client-side cache for subsequent requests)
|
// populate page state (which acts as a client-side cache for subsequent requests)
|
||||||
_pagestate = new PageState
|
_pagestate = new PageState
|
||||||
@ -223,6 +258,7 @@
|
|||||||
Page = page,
|
Page = page,
|
||||||
User = user,
|
User = user,
|
||||||
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
Uri = new Uri(_absoluteUri, UriKind.Absolute),
|
||||||
|
Route = route,
|
||||||
QueryString = querystring,
|
QueryString = querystring,
|
||||||
UrlParameters = route.UrlParameters,
|
UrlParameters = route.UrlParameters,
|
||||||
ModuleId = moduleid,
|
ModuleId = moduleid,
|
||||||
@ -232,7 +268,8 @@
|
|||||||
Runtime = runtime,
|
Runtime = runtime,
|
||||||
VisitorId = VisitorId,
|
VisitorId = VisitorId,
|
||||||
RemoteIPAddress = SiteState.RemoteIPAddress,
|
RemoteIPAddress = SiteState.RemoteIPAddress,
|
||||||
ReturnUrl = returnurl
|
ReturnUrl = returnurl,
|
||||||
|
IsInternalNavigation = _isInternalNavigation
|
||||||
};
|
};
|
||||||
|
|
||||||
OnStateChange?.Invoke(_pagestate);
|
OnStateChange?.Invoke(_pagestate);
|
||||||
@ -277,84 +314,34 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void LocationChanged(object sender, LocationChangedEventArgs args)
|
private Page ProcessPage(Page page, Site site, User user, Alias alias)
|
||||||
{
|
|
||||||
_absoluteUri = args.Location;
|
|
||||||
await Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
Task IHandleAfterRender.OnAfterRenderAsync()
|
|
||||||
{
|
|
||||||
if (!_navigationInterceptionEnabled)
|
|
||||||
{
|
|
||||||
_navigationInterceptionEnabled = true;
|
|
||||||
return NavigationInterception.EnableNavigationInterceptionAsync();
|
|
||||||
}
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dictionary<string, string> ParseQueryString(string query)
|
|
||||||
{
|
|
||||||
Dictionary<string, string> querystring = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); // case insensistive keys
|
|
||||||
if (!string.IsNullOrEmpty(query))
|
|
||||||
{
|
|
||||||
if (query.StartsWith("?"))
|
|
||||||
{
|
|
||||||
query = query.Substring(1); // ignore "?"
|
|
||||||
}
|
|
||||||
foreach (string kvp in query.Split('&', StringSplitOptions.RemoveEmptyEntries))
|
|
||||||
{
|
|
||||||
if (kvp != "")
|
|
||||||
{
|
|
||||||
if (kvp.Contains("="))
|
|
||||||
{
|
|
||||||
string[] pair = kvp.Split('=');
|
|
||||||
if (!querystring.ContainsKey(pair[0]))
|
|
||||||
{
|
|
||||||
querystring.Add(pair[0], pair[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!querystring.ContainsKey(kvp))
|
|
||||||
{
|
|
||||||
querystring.Add(kvp, "true"); // default parameter when no value is provided
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return querystring;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<Page> ProcessPage(Page page, Site site, User user)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (page.IsPersonalizable && user != null)
|
page.Panes = new List<string>();
|
||||||
{
|
page.Resources = new List<Resource>();
|
||||||
// load the personalized page
|
|
||||||
page = await PageService.GetPageAsync(page.PageId, user.UserId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// validate theme
|
||||||
if (string.IsNullOrEmpty(page.ThemeType))
|
if (string.IsNullOrEmpty(page.ThemeType))
|
||||||
{
|
{
|
||||||
page.ThemeType = site.DefaultThemeType;
|
page.ThemeType = site.DefaultThemeType;
|
||||||
}
|
}
|
||||||
|
var theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
||||||
page.Panes = new List<string>();
|
|
||||||
page.Resources = new List<Resource>();
|
|
||||||
|
|
||||||
string panes = "";
|
|
||||||
Type themetype = Type.GetType(page.ThemeType);
|
Type themetype = Type.GetType(page.ThemeType);
|
||||||
if (themetype == null)
|
if (themetype == null || theme == null)
|
||||||
{
|
{
|
||||||
// fallback
|
// fallback to default Oqtane theme
|
||||||
page.ThemeType = Constants.DefaultTheme;
|
page.ThemeType = Constants.DefaultTheme;
|
||||||
themetype = Type.GetType(Constants.DefaultTheme);
|
themetype = Type.GetType(Constants.DefaultTheme);
|
||||||
|
theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
||||||
}
|
}
|
||||||
if (themetype != null)
|
|
||||||
|
string panes = "";
|
||||||
|
if (themetype != null && theme != null)
|
||||||
{
|
{
|
||||||
|
// get resources for theme (ITheme)
|
||||||
|
page.Resources = ManagePageResources(page.Resources, theme.Resources, ResourceLevel.Page, alias, "Themes", Utilities.GetTypeName(theme.ThemeName));
|
||||||
|
|
||||||
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
var themeobject = Activator.CreateInstance(themetype) as IThemeControl;
|
||||||
if (themeobject != null)
|
if (themeobject != null)
|
||||||
{
|
{
|
||||||
@ -362,9 +349,11 @@
|
|||||||
{
|
{
|
||||||
panes = themeobject.Panes;
|
panes = themeobject.Panes;
|
||||||
}
|
}
|
||||||
page.Resources = ManagePageResources(page.Resources, themeobject.Resources, ResourceLevel.Page);
|
// get resources for theme control
|
||||||
|
page.Resources = ManagePageResources(page.Resources, themeobject.Resources, ResourceLevel.Page, alias, "Themes", themetype.Namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(panes))
|
if (!string.IsNullOrEmpty(panes))
|
||||||
{
|
{
|
||||||
page.Panes = panes.Replace(";", ",").Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
|
page.Panes = panes.Replace(";", ",").Split(',', StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||||
@ -387,7 +376,7 @@
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string action, string defaultcontainertype)
|
private (Page Page, List<Module> Modules) ProcessModules(Page page, List<Module> modules, int moduleid, string action, string defaultcontainertype, Alias alias)
|
||||||
{
|
{
|
||||||
var paneindex = new Dictionary<string, int>();
|
var paneindex = new Dictionary<string, int>();
|
||||||
foreach (Module module in modules)
|
foreach (Module module in modules)
|
||||||
@ -403,6 +392,7 @@
|
|||||||
if ((module.PageId == page.PageId || module.ModuleId == moduleid))
|
if ((module.PageId == page.PageId || module.ModuleId == moduleid))
|
||||||
{
|
{
|
||||||
var typename = Constants.ErrorModule;
|
var typename = Constants.ErrorModule;
|
||||||
|
|
||||||
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(Runtime)))
|
if (module.ModuleDefinition != null && (module.ModuleDefinition.Runtimes == "" || module.ModuleDefinition.Runtimes.Contains(Runtime)))
|
||||||
{
|
{
|
||||||
typename = module.ModuleDefinition.ControlTypeTemplate;
|
typename = module.ModuleDefinition.ControlTypeTemplate;
|
||||||
@ -424,6 +414,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get module resources
|
||||||
|
page.Resources = ManagePageResources(page.Resources, module.ModuleDefinition.Resources, ResourceLevel.Module, alias, "Modules", Utilities.GetTypeName(module.ModuleDefinition.ModuleDefinitionName));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure component exists and implements IModuleControl
|
// ensure component exists and implements IModuleControl
|
||||||
@ -447,7 +440,7 @@
|
|||||||
{
|
{
|
||||||
// retrieve module component resources
|
// retrieve module component resources
|
||||||
var moduleobject = Activator.CreateInstance(moduletype) as IModuleControl;
|
var moduleobject = Activator.CreateInstance(moduletype) as IModuleControl;
|
||||||
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module);
|
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module, alias, "Modules", moduletype.Namespace);
|
||||||
if (action.ToLower() == "settings" && module.ModuleDefinition != null)
|
if (action.ToLower() == "settings" && module.ModuleDefinition != null)
|
||||||
{
|
{
|
||||||
// settings components are embedded within a framework settings module
|
// settings components are embedded within a framework settings module
|
||||||
@ -455,7 +448,7 @@
|
|||||||
if (moduletype != null)
|
if (moduletype != null)
|
||||||
{
|
{
|
||||||
moduleobject = Activator.CreateInstance(moduletype) as IModuleControl;
|
moduleobject = Activator.CreateInstance(moduletype) as IModuleControl;
|
||||||
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module);
|
page.Resources = ManagePageResources(page.Resources, moduleobject.Resources, ResourceLevel.Module, alias, "Modules", moduletype.Namespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,20 +507,33 @@
|
|||||||
return (page, modules);
|
return (page, modules);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources, ResourceLevel level)
|
private List<Resource> ManagePageResources(List<Resource> pageresources, List<Resource> resources, ResourceLevel level, Alias alias, string type, string name)
|
||||||
{
|
{
|
||||||
if (resources != null)
|
if (resources != null)
|
||||||
{
|
{
|
||||||
foreach (var resource in resources)
|
foreach (var resource in resources)
|
||||||
{
|
{
|
||||||
|
if (resource.Level != ResourceLevel.Site)
|
||||||
|
{
|
||||||
|
if (resource.Url.StartsWith("~"))
|
||||||
|
{
|
||||||
|
resource.Url = resource.Url.Replace("~", "/" + type + "/" + name + "/").Replace("//", "/");
|
||||||
|
}
|
||||||
|
if (!resource.Url.Contains("://") && alias.BaseUrl != "" && !resource.Url.StartsWith(alias.BaseUrl))
|
||||||
|
{
|
||||||
|
resource.Url = alias.BaseUrl + resource.Url;
|
||||||
|
}
|
||||||
|
|
||||||
// ensure resource does not exist already
|
// ensure resource does not exist already
|
||||||
if (pageresources.Find(item => item.Url == resource.Url) == null)
|
if (!pageresources.Exists(item => item.Url.ToLower() == resource.Url.ToLower()))
|
||||||
{
|
{
|
||||||
resource.Level = level;
|
resource.Level = level;
|
||||||
|
resource.Namespace = name;
|
||||||
pageresources.Add(resource);
|
pageresources.Add(resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return pageresources;
|
return pageresources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
@namespace Oqtane.UI
|
@namespace Oqtane.UI
|
||||||
@inject IJSRuntime JsRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject SiteState SiteState
|
||||||
|
|
||||||
@DynamicComponent
|
@DynamicComponent
|
||||||
|
|
||||||
@ -18,6 +19,41 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set page title
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
||||||
|
{
|
||||||
|
SiteState.Properties.PageTitle = PageState.Page.Title;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SiteState.Properties.PageTitle = PageState.Site.Name + " - " + PageState.Page.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set page head content
|
||||||
|
var headcontent = "";
|
||||||
|
|
||||||
|
// favicon
|
||||||
|
var favicon = "favicon.ico";
|
||||||
|
var favicontype = "x-icon";
|
||||||
|
if (PageState.Site.FaviconFileId != null)
|
||||||
|
{
|
||||||
|
favicon = Utilities.FileUrl(PageState.Alias, PageState.Site.FaviconFileId.Value);
|
||||||
|
favicontype = favicon.Substring(favicon.LastIndexOf(".") + 1);
|
||||||
|
}
|
||||||
|
headcontent += $"<link id=\"app-favicon\" rel=\"shortcut icon\" type=\"image/{favicontype}\" href=\"{favicon}\" />\n";
|
||||||
|
|
||||||
|
// head content
|
||||||
|
AddHeadContent(headcontent, PageState.Site.HeadContent);
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Site.HeadContent))
|
||||||
|
{
|
||||||
|
headcontent = AddHeadContent(headcontent, PageState.Site.HeadContent);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Page.HeadContent))
|
||||||
|
{
|
||||||
|
headcontent = AddHeadContent(headcontent, PageState.Page.HeadContent);
|
||||||
|
}
|
||||||
|
SiteState.Properties.HeadContent = headcontent;
|
||||||
|
|
||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
var themeType = Type.GetType(PageState.Page.ThemeType);
|
var themeType = Type.GetType(PageState.Page.ThemeType);
|
||||||
@ -26,11 +62,44 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string AddHeadContent(string headcontent, string content)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(content))
|
||||||
|
{
|
||||||
|
// format head content, remove scripts, and filter duplicate elements
|
||||||
|
var elements = (">" + content.Replace("\n", "") + "<").Split("><");
|
||||||
|
foreach (var element in elements)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(element) && !element.Contains("script"))
|
||||||
|
{
|
||||||
|
if (!headcontent.Contains("<" + element + ">"))
|
||||||
|
{
|
||||||
|
headcontent += "<" + element + ">" + "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return headcontent;
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
var interop = new Interop(JsRuntime);
|
if (!firstRender)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
|
||||||
|
{
|
||||||
|
await InjectScripts(PageState.Page.HeadContent, ResourceLocation.Head);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Page.BodyContent) && PageState.Page.BodyContent.Contains("<script"))
|
||||||
|
{
|
||||||
|
await InjectScripts(PageState.Page.BodyContent, ResourceLocation.Body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// manage stylesheets for this page
|
// style sheets
|
||||||
|
if (PageState.Page.Resources != null && PageState.Page.Resources.Exists(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
|
{
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
||||||
var links = new List<object>();
|
var links = new List<object>();
|
||||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
@ -45,15 +114,73 @@
|
|||||||
}
|
}
|
||||||
await interop.RemoveElementsById("app-stylesheet-page-", "", "app-stylesheet-page-" + batch + "-00");
|
await interop.RemoveElementsById("app-stylesheet-page-", "", "app-stylesheet-page-" + batch + "-00");
|
||||||
await interop.RemoveElementsById("app-stylesheet-module-", "", "app-stylesheet-module-" + batch + "-00");
|
await interop.RemoveElementsById("app-stylesheet-module-", "", "app-stylesheet-module-" + batch + "-00");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set page title
|
private async Task InjectScripts(string content, ResourceLocation location)
|
||||||
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
|
||||||
{
|
{
|
||||||
await interop.UpdateTitle(PageState.Page.Title);
|
// inject scripts into page dynamically
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
var scripts = new List<object>();
|
||||||
|
var count = 0;
|
||||||
|
var index = content.IndexOf("<script");
|
||||||
|
while (index >= 0)
|
||||||
|
{
|
||||||
|
var script = content.Substring(index, content.IndexOf("</script>", index) + 9 - index);
|
||||||
|
// get script attributes
|
||||||
|
var attributes = script.Substring(0, script.IndexOf(">")).Replace("\"", "").Split(" ");
|
||||||
|
string id = "";
|
||||||
|
string src = "";
|
||||||
|
string integrity = "";
|
||||||
|
string crossorigin = "";
|
||||||
|
string type = "";
|
||||||
|
foreach (var attribute in attributes)
|
||||||
|
{
|
||||||
|
if (attribute.Contains("="))
|
||||||
|
{
|
||||||
|
var value = attribute.Split("=");
|
||||||
|
switch (value[0])
|
||||||
|
{
|
||||||
|
case "id":
|
||||||
|
id = value[1];
|
||||||
|
break;
|
||||||
|
case "src":
|
||||||
|
src = value[1];
|
||||||
|
break;
|
||||||
|
case "integrity":
|
||||||
|
integrity = value[1];
|
||||||
|
break;
|
||||||
|
case "crossorigin":
|
||||||
|
crossorigin = value[1];
|
||||||
|
break;
|
||||||
|
case "type":
|
||||||
|
type = value[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// inject script
|
||||||
|
if (!string.IsNullOrEmpty(src))
|
||||||
|
{
|
||||||
|
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
||||||
|
scripts.Add(new { href = src, bundle = "", integrity = integrity, crossorigin = crossorigin, es6module = (type == "module"), location = location });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
// inline script must have an id attribute
|
||||||
|
if (id == "")
|
||||||
|
{
|
||||||
|
count += 1;
|
||||||
|
id = $"page{PageState.Page.PageId}-script{count}";
|
||||||
|
}
|
||||||
|
index = script.IndexOf(">") + 1;
|
||||||
|
await interop.IncludeScript(id, "", "", "", "", script.Substring(index, script.IndexOf("</script>") - index), location.ToString().ToLower());
|
||||||
|
}
|
||||||
|
index = content.IndexOf("<script", index + 1);
|
||||||
|
}
|
||||||
|
if (scripts.Any())
|
||||||
|
{
|
||||||
|
await interop.IncludeScripts(scripts.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Version>3.4.0</Version>
|
<Version>4.0.0</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MySql.EntityFrameworkCore" Version="6.0.0" />
|
<PackageReference Include="MySql.EntityFrameworkCore" Version="7.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.MySQL</id>
|
<id>Oqtane.Database.MySQL</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane MySQL Provider</title>
|
<title>Oqtane MySQL Provider</title>
|
||||||
@ -12,15 +12,15 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="bin\net6.0\Oqtane.Database.MySQL.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.MySQL.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Oqtane.Database.MySQL.pdb" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.MySQL.pdb" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Mysql.EntityFrameworkCore.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Mysql.EntityFrameworkCore.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Mysql.Data.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Mysql.Data.dll" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -1,8 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Version>3.4.0</Version>
|
<Version>4.0.0</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
@ -29,9 +29,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="6.0.0" />
|
<PackageReference Include="EFCore.NamingConventions" Version="7.0.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.5" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.3" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.PostgreSQL</id>
|
<id>Oqtane.Database.PostgreSQL</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane PostgreSQL Provider</title>
|
<title>Oqtane PostgreSQL Provider</title>
|
||||||
@ -12,16 +12,16 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="bin\net6.0\Oqtane.Database.PostgreSQL.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.PostgreSQL.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Oqtane.Database.PostgreSQL.pdb" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.PostgreSQL.pdb" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\EFCore.NamingConventions.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\EFCore.NamingConventions.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Npgsql.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Npgsql.dll" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -1,8 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Version>3.4.0</Version>
|
<Version>4.0.0</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.SqlServer</id>
|
<id>Oqtane.Database.SqlServer</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane SQL Server Provider</title>
|
<title>Oqtane SQL Server Provider</title>
|
||||||
@ -12,14 +12,14 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="bin\net6.0\Oqtane.Database.SqlServer.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.SqlServer.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Oqtane.Database.SqlServer.pdb" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.SqlServer.pdb" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Microsoft.EntityFrameworkCore.SqlServer.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Microsoft.EntityFrameworkCore.SqlServer.dll" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -1,8 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<Version>3.4.0</Version>
|
<Version>4.0.0</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
@ -29,7 +29,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.3" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Database.Sqlite</id>
|
<id>Oqtane.Database.Sqlite</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane SQLite Provider</title>
|
<title>Oqtane SQLite Provider</title>
|
||||||
@ -12,14 +12,14 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="bin\net6.0\Oqtane.Database.Sqlite.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.Sqlite.dll" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Oqtane.Database.Sqlite.pdb" target="lib\net6.0" />
|
<file src="bin\net7.0\Oqtane.Database.Sqlite.pdb" target="lib\net7.0" />
|
||||||
<file src="bin\net6.0\Microsoft.EntityFrameworkCore.Sqlite.dll" target="lib\net6.0" />
|
<file src="bin\net7.0\Microsoft.EntityFrameworkCore.Sqlite.dll" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
6
Oqtane.Maui/Head.razor
Normal file
6
Oqtane.Maui/Head.razor
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<DynamicComponent Type="@ComponentType"></DynamicComponent>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
Type ComponentType = Type.GetType("Oqtane.Head, Oqtane.Client");
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<BlazorWebView HostPage="wwwroot/index.html">
|
<BlazorWebView HostPage="wwwroot/index.html">
|
||||||
<BlazorWebView.RootComponents>
|
<BlazorWebView.RootComponents>
|
||||||
|
<RootComponent Selector="head::after" ComponentType="{x:Type local:Head}" />
|
||||||
<RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
|
<RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
|
||||||
</BlazorWebView.RootComponents>
|
</BlazorWebView.RootComponents>
|
||||||
</BlazorWebView>
|
</BlazorWebView>
|
||||||
|
@ -12,8 +12,8 @@ namespace Oqtane.Maui;
|
|||||||
public static class MauiProgram
|
public static class MauiProgram
|
||||||
{
|
{
|
||||||
// the API service url
|
// the API service url
|
||||||
static string apiurl = "https://www.dnfprojects.com"; // for testing
|
//static string apiurl = "https://www.dnfprojects.com"; // for testing
|
||||||
//static string apiurl = "http://localhost:44357"; // for local development (Oqtane.Server must be already running for MAUI client to connect)
|
static string apiurl = "http://localhost:44357"; // for local development (Oqtane.Server must be already running for MAUI client to connect)
|
||||||
|
|
||||||
public static MauiApp CreateMauiApp()
|
public static MauiApp CreateMauiApp()
|
||||||
{
|
{
|
||||||
@ -212,6 +212,8 @@ public static class MauiProgram
|
|||||||
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
|
||||||
{
|
{
|
||||||
// dynamically register module scoped services
|
// dynamically register module scoped services
|
||||||
|
try
|
||||||
|
{
|
||||||
var implementationTypes = assembly.GetInterfaces<IService>();
|
var implementationTypes = assembly.GetInterfaces<IService>();
|
||||||
foreach (var implementationType in implementationTypes)
|
foreach (var implementationType in implementationTypes)
|
||||||
{
|
{
|
||||||
@ -222,8 +224,15 @@ public static class MauiProgram
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
var startUps = assembly.GetInstances<IClientStartup>();
|
var startUps = assembly.GetInstances<IClientStartup>();
|
||||||
foreach (var startup in startUps)
|
foreach (var startup in startUps)
|
||||||
@ -231,4 +240,9 @@ public static class MauiProgram
|
|||||||
startup.ConfigureServices(services);
|
startup.ConfigureServices(services);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// could not interrogate assembly - likely missing dependencies
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
|
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
|
||||||
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
|
|
||||||
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
|
||||||
<!-- <TargetFrameworks>$(TargetFrameworks);net6.0-tizen</TargetFrameworks> -->
|
<!-- <TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks> -->
|
||||||
|
<!-- <TargetFrameworks>$(TargetFrameworks);net7.0-tizen</TargetFrameworks> -->
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<Version>3.4.0</Version>
|
<Version>4.0.0</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<RootNamespace>Oqtane.Maui</RootNamespace>
|
<RootNamespace>Oqtane.Maui</RootNamespace>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
|
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
|
||||||
|
|
||||||
<!-- Versions -->
|
<!-- Versions -->
|
||||||
<ApplicationDisplayVersion>3.4.0</ApplicationDisplayVersion>
|
<ApplicationDisplayVersion>4.0.0</ApplicationDisplayVersion>
|
||||||
<ApplicationVersion>1</ApplicationVersion>
|
<ApplicationVersion>1</ApplicationVersion>
|
||||||
|
|
||||||
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
|
||||||
@ -65,14 +65,21 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="6.0.8" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="6.0.3" />
|
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="6.0.0" />
|
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
|
||||||
<PackageReference Include="Oqtane.Client" Version="3.4.0" />
|
</ItemGroup>
|
||||||
<PackageReference Include="Oqtane.Shared" Version="3.4.0" />
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Oqtane.Client">
|
||||||
|
<HintPath>..\Oqtane.Server\bin\Debug\net7.0\Oqtane.Client.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Oqtane.Shared">
|
||||||
|
<HintPath>..\Oqtane.Server\bin\Debug\net7.0\Oqtane.Shared.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
15
Oqtane.Maui/Resources/Raw/AboutAssets.txt
Normal file
15
Oqtane.Maui/Resources/Raw/AboutAssets.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Any raw assets you want to be deployed with your application can be placed in
|
||||||
|
this directory (and child directories). Deployment of the asset to your application
|
||||||
|
is automatically handled by the following `MauiAsset` Build Action within your `.csproj`.
|
||||||
|
|
||||||
|
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||||
|
|
||||||
|
These files will be deployed with you package and will be accessible using Essentials:
|
||||||
|
|
||||||
|
async Task LoadMauiAsset()
|
||||||
|
{
|
||||||
|
using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt");
|
||||||
|
using var reader = new StreamReader(stream);
|
||||||
|
|
||||||
|
var contents = reader.ReadToEnd();
|
||||||
|
}
|
@ -9,8 +9,8 @@
|
|||||||
<script src="js/app.js"></script>
|
<script src="js/app.js"></script>
|
||||||
<script src="js/loadjs.min.js"></script>
|
<script src="js/loadjs.min.js"></script>
|
||||||
<link rel="stylesheet" href="css/app.css" />
|
<link rel="stylesheet" href="css/app.css" />
|
||||||
<link id="app-stylesheet-page" rel="stylesheet" href="css/empty.css" disabled />
|
<link id="app-stylesheet-page" />
|
||||||
<link id="app-stylesheet-module" rel="stylesheet" href="css/empty.css" disabled />
|
<link id="app-stylesheet-module" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Client</id>
|
<id>Oqtane.Client</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,13 +12,13 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Oqtane.Client\bin\Release\net6.0\Oqtane.Client.dll" target="lib\net6.0" />
|
<file src="..\Oqtane.Client\bin\Release\net7.0\Oqtane.Client.dll" target="lib\net7.0" />
|
||||||
<file src="..\Oqtane.Client\bin\Release\net6.0\Oqtane.Client.pdb" target="lib\net6.0" />
|
<file src="..\Oqtane.Client\bin\Release\net7.0\Oqtane.Client.pdb" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Framework</id>
|
<id>Oqtane.Framework</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -11,8 +11,8 @@
|
|||||||
<copyright>.NET Foundation</copyright>
|
<copyright>.NET Foundation</copyright>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.4.0/Oqtane.Framework.3.4.0.Upgrade.zip</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v4.0.0/Oqtane.Framework.4.0.0.Upgrade.zip</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane framework</tags>
|
<tags>oqtane framework</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Server</id>
|
<id>Oqtane.Server</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,13 +12,13 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Oqtane.Server\bin\Release\net6.0\Oqtane.Server.dll" target="lib\net6.0" />
|
<file src="..\Oqtane.Server\bin\Release\net7.0\Oqtane.Server.dll" target="lib\net7.0" />
|
||||||
<file src="..\Oqtane.Server\bin\Release\net6.0\Oqtane.Server.pdb" target="lib\net6.0" />
|
<file src="..\Oqtane.Server\bin\Release\net7.0\Oqtane.Server.pdb" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Shared</id>
|
<id>Oqtane.Shared</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,13 +12,13 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Oqtane.Shared\bin\Release\net6.0\Oqtane.Shared.dll" target="lib\net6.0" />
|
<file src="..\Oqtane.Shared\bin\Release\net7.0\Oqtane.Shared.dll" target="lib\net7.0" />
|
||||||
<file src="..\Oqtane.Shared\bin\Release\net6.0\Oqtane.Shared.pdb" target="lib\net6.0" />
|
<file src="..\Oqtane.Shared\bin\Release\net7.0\Oqtane.Shared.pdb" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -2,7 +2,7 @@
|
|||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>Oqtane.Updater</id>
|
<id>Oqtane.Updater</id>
|
||||||
<version>3.4.0</version>
|
<version>4.0.0</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,12 +12,12 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.4.0</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.0</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Oqtane.Updater\bin\Release\net6.0\publish\*.*" target="lib\net6.0" />
|
<file src="..\Oqtane.Updater\bin\Release\net7.0\publish\*.*" target="lib\net7.0" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
</package>
|
</package>
|
@ -1 +1 @@
|
|||||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.4.0.Install.zip" -Force
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.0.Install.zip" -Force
|
@ -8,14 +8,14 @@ nuget.exe pack Oqtane.Client.nuspec
|
|||||||
nuget.exe pack Oqtane.Server.nuspec
|
nuget.exe pack Oqtane.Server.nuspec
|
||||||
nuget.exe pack Oqtane.Shared.nuspec
|
nuget.exe pack Oqtane.Shared.nuspec
|
||||||
nuget.exe pack Oqtane.Framework.nuspec
|
nuget.exe pack Oqtane.Framework.nuspec
|
||||||
del /F/Q/S "..\Oqtane.Server\bin\Release\net6.0\publish" > NUL
|
del /F/Q/S "..\Oqtane.Server\bin\Release\net7.0\publish" > NUL
|
||||||
rmdir /Q/S "..\Oqtane.Server\bin\Release\net6.0\publish"
|
rmdir /Q/S "..\Oqtane.Server\bin\Release\net7.0\publish"
|
||||||
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
|
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
|
||||||
del /F/Q/S "..\Oqtane.Server\bin\Release\net6.0\publish\wwwroot\Content" > NUL
|
del /F/Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content" > NUL
|
||||||
rmdir /Q/S "..\Oqtane.Server\bin\Release\net6.0\publish\wwwroot\Content"
|
rmdir /Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content"
|
||||||
setlocal ENABLEDELAYEDEXPANSION
|
setlocal ENABLEDELAYEDEXPANSION
|
||||||
set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText,Templates
|
set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText,Templates
|
||||||
for /D %%i in ("..\Oqtane.Server\bin\Release\net6.0\publish\wwwroot\Modules\*") do (
|
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Modules\*") do (
|
||||||
set /A found=0
|
set /A found=0
|
||||||
for %%j in (%retain%) do (
|
for %%j in (%retain%) do (
|
||||||
if "%%~nxi" == "%%j" set /A found=1
|
if "%%~nxi" == "%%j" set /A found=1
|
||||||
@ -23,18 +23,18 @@ if "%%~nxi" == "%%j" set /A found=1
|
|||||||
if not !found! == 1 rmdir /Q/S "%%i"
|
if not !found! == 1 rmdir /Q/S "%%i"
|
||||||
)
|
)
|
||||||
set retain=Oqtane.Themes.BlazorTheme,Oqtane.Themes.OqtaneTheme,Templates
|
set retain=Oqtane.Themes.BlazorTheme,Oqtane.Themes.OqtaneTheme,Templates
|
||||||
for /D %%i in ("..\Oqtane.Server\bin\Release\net6.0\publish\wwwroot\Themes\*") do (
|
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Themes\*") do (
|
||||||
set /A found=0
|
set /A found=0
|
||||||
for %%j in (%retain%) do (
|
for %%j in (%retain%) do (
|
||||||
if "%%~nxi" == "%%j" set /A found=1
|
if "%%~nxi" == "%%j" set /A found=1
|
||||||
)
|
)
|
||||||
if not !found! == 1 rmdir /Q/S "%%i"
|
if not !found! == 1 rmdir /Q/S "%%i"
|
||||||
)
|
)
|
||||||
del "..\Oqtane.Server\bin\Release\net6.0\publish\appsettings.json"
|
del "..\Oqtane.Server\bin\Release\net7.0\publish\appsettings.json"
|
||||||
ren "..\Oqtane.Server\bin\Release\net6.0\publish\appsettings.release.json" "appsettings.json"
|
ren "..\Oqtane.Server\bin\Release\net7.0\publish\appsettings.release.json" "appsettings.json"
|
||||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
||||||
del "..\Oqtane.Server\bin\Release\net6.0\publish\appsettings.json"
|
del "..\Oqtane.Server\bin\Release\net7.0\publish\appsettings.json"
|
||||||
del "..\Oqtane.Server\bin\Release\net6.0\publish\web.config"
|
del "..\Oqtane.Server\bin\Release\net7.0\publish\web.config"
|
||||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
|
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
|
||||||
dotnet clean -c Release ..\Oqtane.Updater.sln
|
dotnet clean -c Release ..\Oqtane.Updater.sln
|
||||||
dotnet build -c Release ..\Oqtane.Updater.sln
|
dotnet build -c Release ..\Oqtane.Updater.sln
|
||||||
|
@ -1 +1 @@
|
|||||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.4.0.Upgrade.zip" -Force
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.0.Upgrade.zip" -Force
|
@ -33,8 +33,10 @@ namespace Oqtane.Controllers
|
|||||||
private readonly IHttpContextAccessor _accessor;
|
private readonly IHttpContextAccessor _accessor;
|
||||||
private readonly IAliasRepository _aliases;
|
private readonly IAliasRepository _aliases;
|
||||||
private readonly ILogger<InstallationController> _filelogger;
|
private readonly ILogger<InstallationController> _filelogger;
|
||||||
|
private readonly ITenantManager _tenantManager;
|
||||||
|
private readonly ServerStateManager _serverState;
|
||||||
|
|
||||||
public InstallationController(IConfigManager configManager, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager, IMemoryCache cache, IHttpContextAccessor accessor, IAliasRepository aliases, ILogger<InstallationController> filelogger)
|
public InstallationController(IConfigManager configManager, IInstallationManager installationManager, IDatabaseManager databaseManager, ILocalizationManager localizationManager, IMemoryCache cache, IHttpContextAccessor accessor, IAliasRepository aliases, ILogger<InstallationController> filelogger, ITenantManager tenantManager, ServerStateManager serverState)
|
||||||
{
|
{
|
||||||
_configManager = configManager;
|
_configManager = configManager;
|
||||||
_installationManager = installationManager;
|
_installationManager = installationManager;
|
||||||
@ -44,6 +46,8 @@ namespace Oqtane.Controllers
|
|||||||
_accessor = accessor;
|
_accessor = accessor;
|
||||||
_aliases = aliases;
|
_aliases = aliases;
|
||||||
_filelogger = filelogger;
|
_filelogger = filelogger;
|
||||||
|
_tenantManager = tenantManager;
|
||||||
|
_serverState = serverState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST api/<controller>
|
// POST api/<controller>
|
||||||
@ -115,35 +119,51 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
private List<ClientAssembly> GetAssemblyList()
|
private List<ClientAssembly> GetAssemblyList()
|
||||||
{
|
{
|
||||||
return _cache.GetOrCreate("assemblieslist", entry =>
|
int siteId = _tenantManager.GetAlias().SiteId;
|
||||||
|
|
||||||
|
return _cache.GetOrCreate($"assemblieslist:{siteId}", entry =>
|
||||||
{
|
{
|
||||||
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
var binFolder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||||
var assemblyList = new List<ClientAssembly>();
|
var assemblyList = new List<ClientAssembly>();
|
||||||
|
|
||||||
// get list of assemblies which should be downloaded to client
|
// testmode setting is used for validating that the API is downloading the appropriate assemblies to the client
|
||||||
var assemblies = AppDomain.CurrentDomain.GetOqtaneClientAssemblies();
|
bool hashfilename = true;
|
||||||
var list = assemblies.Select(a => a.GetName().Name).ToList();
|
if (_configManager.GetSetting($"{SettingKeys.TestModeKey}", "false") == "true")
|
||||||
|
|
||||||
// populate assemblies
|
|
||||||
for (int i = 0; i < list.Count; i++)
|
|
||||||
{
|
{
|
||||||
assemblyList.Add(new ClientAssembly(Path.Combine(binFolder, list[i] + ".dll")));
|
hashfilename = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get site assemblies which should be downloaded to client
|
||||||
|
var assemblies = _serverState.GetServerState(siteId).Assemblies;
|
||||||
|
|
||||||
|
// populate assembly list
|
||||||
|
foreach (var assembly in assemblies)
|
||||||
|
{
|
||||||
|
if (assembly != Constants.ClientId)
|
||||||
|
{
|
||||||
|
var filepath = Path.Combine(binFolder, assembly) + ".dll";
|
||||||
|
if (System.IO.File.Exists(filepath))
|
||||||
|
{
|
||||||
|
assemblyList.Add(new ClientAssembly(Path.Combine(binFolder, assembly + ".dll"), hashfilename));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert satellite assemblies at beginning of list
|
// insert satellite assemblies at beginning of list
|
||||||
foreach (var culture in _localizationManager.GetInstalledCultures())
|
foreach (var culture in _localizationManager.GetInstalledCultures())
|
||||||
{
|
{
|
||||||
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
if (culture != Constants.DefaultCulture)
|
||||||
if (culture == Constants.DefaultCulture)
|
|
||||||
{
|
{
|
||||||
continue;
|
var assembliesFolderPath = Path.Combine(binFolder, culture);
|
||||||
}
|
|
||||||
|
|
||||||
if (Directory.Exists(assembliesFolderPath))
|
if (Directory.Exists(assembliesFolderPath))
|
||||||
{
|
{
|
||||||
foreach (var resourceFile in Directory.EnumerateFiles(assembliesFolderPath))
|
foreach (var assembly in assemblies)
|
||||||
{
|
{
|
||||||
assemblyList.Insert(0, new ClientAssembly(resourceFile));
|
var filepath = Path.Combine(assembliesFolderPath, assembly) + ".resources.dll";
|
||||||
|
if (System.IO.File.Exists(filepath))
|
||||||
|
{
|
||||||
|
assemblyList.Insert(0, new ClientAssembly(Path.Combine(assembliesFolderPath, assembly + ".resources.dll"), hashfilename));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -151,48 +171,6 @@ namespace Oqtane.Controllers
|
|||||||
_filelogger.LogError(Utilities.LogMessage(this, $"The Satellite Assembly Folder For {culture} Does Not Exist"));
|
_filelogger.LogError(Utilities.LogMessage(this, $"The Satellite Assembly Folder For {culture} Does Not Exist"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert module and theme dependencies at beginning of list
|
|
||||||
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).Reverse())
|
|
||||||
{
|
|
||||||
var filepath = Path.Combine(binFolder, name + ".dll");
|
|
||||||
if (System.IO.File.Exists(filepath))
|
|
||||||
{
|
|
||||||
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
|
||||||
{
|
|
||||||
assemblyList.Insert(0, new ClientAssembly(filepath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filelogger.LogError(Utilities.LogMessage(this, $"Module {instance.ModuleDefinition.ModuleDefinitionName} Dependency {name}.dll Does Not Exist"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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).Reverse())
|
|
||||||
{
|
|
||||||
var filepath = Path.Combine(binFolder, name + ".dll");
|
|
||||||
if (System.IO.File.Exists(filepath))
|
|
||||||
{
|
|
||||||
if (!assemblyList.Exists(item => item.FilePath == filepath))
|
|
||||||
{
|
|
||||||
assemblyList.Insert(0, new ClientAssembly(filepath));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_filelogger.LogError(Utilities.LogMessage(this, $"Theme {instance.Theme.ThemeName} Dependency {name}.dll Does Not Exist"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return assemblyList;
|
return assemblyList;
|
||||||
@ -232,6 +210,8 @@ namespace Oqtane.Controllers
|
|||||||
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||||
{
|
{
|
||||||
foreach (var assembly in assemblies)
|
foreach (var assembly in assemblies)
|
||||||
|
{
|
||||||
|
if (Path.GetFileNameWithoutExtension(assembly.FilePath) != Constants.ClientId)
|
||||||
{
|
{
|
||||||
if (System.IO.File.Exists(assembly.FilePath))
|
if (System.IO.File.Exists(assembly.FilePath))
|
||||||
{
|
{
|
||||||
@ -252,6 +232,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return memoryStream.ToArray();
|
return memoryStream.ToArray();
|
||||||
}
|
}
|
||||||
@ -285,12 +266,19 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
public struct ClientAssembly
|
public struct ClientAssembly
|
||||||
{
|
{
|
||||||
public ClientAssembly(string filepath)
|
public ClientAssembly(string filepath, bool hashfilename)
|
||||||
{
|
{
|
||||||
FilePath = filepath;
|
FilePath = filepath;
|
||||||
DateTime lastwritetime = System.IO.File.GetLastWriteTime(filepath);
|
DateTime lastwritetime = System.IO.File.GetLastWriteTime(filepath);
|
||||||
|
if (hashfilename)
|
||||||
|
{
|
||||||
HashedName = GetDeterministicHashCode(filepath).ToString("X8") + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
HashedName = GetDeterministicHashCode(filepath).ToString("X8") + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HashedName = Path.GetFileNameWithoutExtension(filepath) + "." + lastwritetime.ToString("yyyyMMddHHmmss") + Path.GetExtension(filepath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public string FilePath { get; private set; }
|
public string FilePath { get; private set; }
|
||||||
public string HashedName { get; private set; }
|
public string HashedName { get; private set; }
|
||||||
|
@ -9,6 +9,7 @@ using Oqtane.Infrastructure;
|
|||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Security.Policy;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -75,7 +76,7 @@ namespace Oqtane.Controllers
|
|||||||
module.Order = pagemodule.Order;
|
module.Order = pagemodule.Order;
|
||||||
module.ContainerType = pagemodule.ContainerType;
|
module.ContainerType = pagemodule.ContainerType;
|
||||||
|
|
||||||
module.ModuleDefinition = FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||||
|
|
||||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.PermissionList))
|
||||||
@ -83,6 +84,7 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
modules.Add(module);
|
modules.Add(module);
|
||||||
}
|
}
|
||||||
|
modules = modules.OrderBy(item => item.PageId).ThenBy(item => item.Pane).ThenBy(item => item.Order).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -95,29 +97,6 @@ namespace Oqtane.Controllers
|
|||||||
return modules;
|
return modules;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModuleDefinition FilterModuleDefinition(ModuleDefinition moduleDefinition)
|
|
||||||
{
|
|
||||||
if (moduleDefinition != null)
|
|
||||||
{
|
|
||||||
moduleDefinition.Description = "";
|
|
||||||
moduleDefinition.Categories = "";
|
|
||||||
moduleDefinition.Version = "";
|
|
||||||
moduleDefinition.Owner = "";
|
|
||||||
moduleDefinition.Url = "";
|
|
||||||
moduleDefinition.Contact = "";
|
|
||||||
moduleDefinition.License = "";
|
|
||||||
moduleDefinition.Dependencies = "";
|
|
||||||
moduleDefinition.PermissionNames = "";
|
|
||||||
moduleDefinition.ServerManagerType = "";
|
|
||||||
moduleDefinition.ReleaseVersions = "";
|
|
||||||
moduleDefinition.PackageName = "";
|
|
||||||
moduleDefinition.AssemblyName = "";
|
|
||||||
moduleDefinition.PermissionList = null;
|
|
||||||
moduleDefinition.Template = "";
|
|
||||||
}
|
|
||||||
return moduleDefinition;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET api/<controller>/5
|
// GET api/<controller>/5
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public Module Get(int id)
|
public Module Get(int id)
|
||||||
@ -126,7 +105,7 @@ namespace Oqtane.Controllers
|
|||||||
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, module.PermissionList))
|
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, module.PermissionList))
|
||||||
{
|
{
|
||||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||||
module.ModuleDefinition = FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
module.ModuleDefinition = _moduleDefinitions.FilterModuleDefinition(moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName));
|
||||||
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, module.PermissionList))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, module.PermissionList))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
@ -123,14 +123,14 @@ namespace Oqtane.Controllers
|
|||||||
if (moduleDefinition.Template.ToLower().Contains("internal"))
|
if (moduleDefinition.Template.ToLower().Contains("internal"))
|
||||||
{
|
{
|
||||||
rootPath = Utilities.PathCombine(rootFolder.FullName, Path.DirectorySeparatorChar.ToString());
|
rootPath = Utilities.PathCombine(rootFolder.FullName, Path.DirectorySeparatorChar.ToString());
|
||||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", Oqtane.Client";
|
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + ".Module." + moduleDefinition.Name + ", Oqtane.Client";
|
||||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
|
moduleDefinition.ServerManagerType = moduleDefinition.Owner + ".Module." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, Oqtane.Server";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName, moduleDefinition.Owner + "." + moduleDefinition.Name, Path.DirectorySeparatorChar.ToString());
|
rootPath = Utilities.PathCombine(rootFolder.Parent.FullName, moduleDefinition.Owner + ".Module." + moduleDefinition.Name, Path.DirectorySeparatorChar.ToString());
|
||||||
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + "." + moduleDefinition.Name + ", " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Client.Oqtane";
|
moduleDefinition.ModuleDefinitionName = moduleDefinition.Owner + ".Module." + moduleDefinition.Name + ", " + moduleDefinition.Owner + ".Module." + moduleDefinition.Name + ".Client.Oqtane";
|
||||||
moduleDefinition.ServerManagerType = moduleDefinition.Owner + "." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + "." + moduleDefinition.Name + ".Server.Oqtane";
|
moduleDefinition.ServerManagerType = moduleDefinition.Owner + ".Module." + moduleDefinition.Name + ".Manager." + moduleDefinition.Name + "Manager, " + moduleDefinition.Owner + ".Module." + moduleDefinition.Name + ".Server.Oqtane";
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition);
|
ProcessTemplatesRecursively(new DirectoryInfo(templatePath), rootPath, rootFolder.Name, templatePath, moduleDefinition);
|
||||||
@ -255,10 +255,10 @@ namespace Oqtane.Controllers
|
|||||||
_modules.DeleteModule(moduleToRemove.ModuleId);
|
_modules.DeleteModule(moduleToRemove.ModuleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove module definition
|
// remove module definition
|
||||||
_moduleDefinitions.DeleteModuleDefinition(id);
|
_moduleDefinitions.DeleteModuleDefinition(id);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, SyncEventActions.Delete);
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.ModuleDefinition, moduledefinition.ModuleDefinitionId, SyncEventActions.Delete);
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, moduledefinition.SiteId, SyncEventActions.Refresh);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name);
|
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "Module Definition {ModuleDefinitionName} Deleted", moduledefinition.Name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -268,14 +268,6 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("install")]
|
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
|
||||||
public void InstallModules()
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "Modules Installed");
|
|
||||||
_installationManager.InstallPackages();
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET: api/<controller>/templates
|
// GET: api/<controller>/templates
|
||||||
[HttpGet("templates")]
|
[HttpGet("templates")]
|
||||||
[Authorize(Roles = RoleNames.Host)]
|
[Authorize(Roles = RoleNames.Host)]
|
||||||
@ -339,9 +331,9 @@ namespace Oqtane.Controllers
|
|||||||
if (moduleDefinition.Version == "local")
|
if (moduleDefinition.Version == "local")
|
||||||
{
|
{
|
||||||
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
||||||
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Client.dll</HintPath></Reference>");
|
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Client.dll</HintPath></Reference>");
|
||||||
text = text.Replace("[ServerReference]", $"<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Server.dll</HintPath></Reference>");
|
text = text.Replace("[ServerReference]", $"<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Server.dll</HintPath></Reference>");
|
||||||
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net6.0\\Oqtane.Shared.dll</HintPath></Reference>");
|
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Shared.dll</HintPath></Reference>");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,8 @@ using Oqtane.Enums;
|
|||||||
using Oqtane.Extensions;
|
using Oqtane.Extensions;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
|
using Oqtane.Modules.Admin.Users;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -73,20 +75,12 @@ namespace Oqtane.Controllers
|
|||||||
return pages;
|
return pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET api/<controller>/5?userid=x
|
// GET api/<controller>/5
|
||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public Page Get(int id, string userid)
|
public Page Get(int id)
|
||||||
{
|
{
|
||||||
Page page = null;
|
var page = _pages.GetPage(id);
|
||||||
if (string.IsNullOrEmpty(userid))
|
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, page.PermissionList))
|
||||||
{
|
|
||||||
page = _pages.GetPage(id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
page = _pages.GetPage(id, int.Parse(userid));
|
|
||||||
}
|
|
||||||
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, page.PermissionList))
|
|
||||||
{
|
{
|
||||||
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
||||||
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.PermissionList))
|
||||||
@ -95,7 +89,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {PageId} {UserId}", id, userid);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {PageId}", id);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -140,7 +134,7 @@ namespace Oqtane.Controllers
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_userPermissions.IsAuthorized(User,PermissionNames.Edit, permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.Edit, permissions))
|
||||||
{
|
{
|
||||||
page = _pages.AddPage(page);
|
page = _pages.AddPage(page);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Page, page.PageId, SyncEventActions.Create);
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Page, page.PageId, SyncEventActions.Create);
|
||||||
@ -180,29 +174,30 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
Page page = null;
|
Page page = null;
|
||||||
Page parent = _pages.GetPage(id);
|
Page parent = _pages.GetPage(id);
|
||||||
if (parent != null && parent.SiteId == _alias.SiteId && parent.IsPersonalizable && _userPermissions.GetUser(User).UserId == int.Parse(userid))
|
User user = _userPermissions.GetUser(User);
|
||||||
|
if (parent != null && parent.SiteId == _alias.SiteId && parent.IsPersonalizable && user.UserId == int.Parse(userid))
|
||||||
{
|
{
|
||||||
page = new Page();
|
page = new Page();
|
||||||
page.SiteId = parent.SiteId;
|
page.SiteId = parent.SiteId;
|
||||||
page.Name = parent.Name;
|
|
||||||
page.Title = parent.Title;
|
|
||||||
page.Path = parent.Path;
|
|
||||||
page.ParentId = parent.PageId;
|
page.ParentId = parent.PageId;
|
||||||
|
page.Name = user.Username;
|
||||||
|
page.Path = parent.Path + "/" + page.Name;
|
||||||
|
page.Title = parent.Name + " - " + page.Name;
|
||||||
page.Order = 0;
|
page.Order = 0;
|
||||||
page.IsNavigation = false;
|
page.IsNavigation = false;
|
||||||
page.Url = "";
|
page.Url = "";
|
||||||
page.ThemeType = parent.ThemeType;
|
page.ThemeType = parent.ThemeType;
|
||||||
page.DefaultContainerType = parent.DefaultContainerType;
|
page.DefaultContainerType = parent.DefaultContainerType;
|
||||||
page.Icon = parent.Icon;
|
page.Icon = parent.Icon;
|
||||||
page.PermissionList = new List<Permission> {
|
page.PermissionList = new List<Permission>()
|
||||||
|
{
|
||||||
new Permission(PermissionNames.View, int.Parse(userid), true),
|
new Permission(PermissionNames.View, int.Parse(userid), true),
|
||||||
|
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||||
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
||||||
};
|
};
|
||||||
page.IsPersonalizable = false;
|
page.IsPersonalizable = false;
|
||||||
page.UserId = int.Parse(userid);
|
page.UserId = int.Parse(userid);
|
||||||
page = _pages.AddPage(page);
|
page = _pages.AddPage(page);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Page, page.PageId, SyncEventActions.Create);
|
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, page.SiteId, SyncEventActions.Refresh);
|
|
||||||
|
|
||||||
// copy modules
|
// copy modules
|
||||||
List<PageModule> pagemodules = _pageModules.GetPageModules(page.SiteId).ToList();
|
List<PageModule> pagemodules = _pageModules.GetPageModules(page.SiteId).ToList();
|
||||||
@ -213,8 +208,10 @@ namespace Oqtane.Controllers
|
|||||||
module.PageId = page.PageId;
|
module.PageId = page.PageId;
|
||||||
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
|
module.ModuleDefinitionName = pm.Module.ModuleDefinitionName;
|
||||||
module.AllPages = false;
|
module.AllPages = false;
|
||||||
module.PermissionList = new List<Permission> {
|
module.PermissionList = new List<Permission>()
|
||||||
|
{
|
||||||
new Permission(PermissionNames.View, int.Parse(userid), true),
|
new Permission(PermissionNames.View, int.Parse(userid), true),
|
||||||
|
new Permission(PermissionNames.View, RoleNames.Everyone, true),
|
||||||
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
new Permission(PermissionNames.Edit, int.Parse(userid), true)
|
||||||
};
|
};
|
||||||
module = _modules.AddModule(module);
|
module = _modules.AddModule(module);
|
||||||
@ -235,6 +232,9 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
_pageModules.AddPageModule(pagemodule);
|
_pageModules.AddPageModule(pagemodule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Page, page.PageId, SyncEventActions.Create);
|
||||||
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, page.SiteId, SyncEventActions.Refresh);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -284,7 +284,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
var modulePermissions = _permissionRepository.GetPermissions(pageModule.Module.SiteId, EntityNames.Module, pageModule.Module.ModuleId).ToList();
|
var modulePermissions = _permissionRepository.GetPermissions(pageModule.Module.SiteId, EntityNames.Module, pageModule.Module.ModuleId).ToList();
|
||||||
// permissions added
|
// permissions added
|
||||||
foreach(Permission permission in added)
|
foreach (Permission permission in added)
|
||||||
{
|
{
|
||||||
if (!modulePermissions.Any(item => item.PermissionName == permission.PermissionName
|
if (!modulePermissions.Any(item => item.PermissionName == permission.PermissionName
|
||||||
&& item.RoleId == permission.RoleId && item.UserId == permission.UserId && item.IsAuthorized == permission.IsAuthorized))
|
&& item.RoleId == permission.RoleId && item.UserId == permission.UserId && item.IsAuthorized == permission.IsAuthorized))
|
||||||
@ -345,7 +345,7 @@ namespace Oqtane.Controllers
|
|||||||
[Authorize(Roles = RoleNames.Registered)]
|
[Authorize(Roles = RoleNames.Registered)]
|
||||||
public void Put(int siteid, int pageid, int? parentid)
|
public void Put(int siteid, int pageid, int? parentid)
|
||||||
{
|
{
|
||||||
if (siteid == _alias.SiteId && siteid == _alias.SiteId && _pages.GetPage(pageid, false) != null && _userPermissions.IsAuthorized(User, siteid, EntityNames.Page, pageid, PermissionNames.Edit))
|
if (siteid == _alias.SiteId && _pages.GetPage(pageid, false) != null && _userPermissions.IsAuthorized(User, siteid, EntityNames.Page, pageid, PermissionNames.Edit))
|
||||||
{
|
{
|
||||||
int order = 1;
|
int order = 1;
|
||||||
List<Page> pages = _pages.GetPages(siteid).ToList();
|
List<Page> pages = _pages.GetPages(siteid).ToList();
|
||||||
|
@ -200,6 +200,8 @@ namespace Oqtane.Controllers
|
|||||||
case EntityNames.Tenant:
|
case EntityNames.Tenant:
|
||||||
case EntityNames.ModuleDefinition:
|
case EntityNames.ModuleDefinition:
|
||||||
case EntityNames.Host:
|
case EntityNames.Host:
|
||||||
|
case EntityNames.Job:
|
||||||
|
case EntityNames.Theme:
|
||||||
if (permissionName == PermissionNames.Edit)
|
if (permissionName == PermissionNames.Edit)
|
||||||
{
|
{
|
||||||
authorized = User.IsInRole(RoleNames.Host);
|
authorized = User.IsInRole(RoleNames.Host);
|
||||||
@ -262,6 +264,8 @@ namespace Oqtane.Controllers
|
|||||||
case EntityNames.Tenant:
|
case EntityNames.Tenant:
|
||||||
case EntityNames.ModuleDefinition:
|
case EntityNames.ModuleDefinition:
|
||||||
case EntityNames.Host:
|
case EntityNames.Host:
|
||||||
|
case EntityNames.Job:
|
||||||
|
case EntityNames.Theme:
|
||||||
filter = !User.IsInRole(RoleNames.Host);
|
filter = !User.IsInRole(RoleNames.Host);
|
||||||
break;
|
break;
|
||||||
case EntityNames.Site:
|
case EntityNames.Site:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user