Compare commits
501 Commits
Author | SHA1 | Date | |
---|---|---|---|
1872a1a77c | |||
cf57bad7fa | |||
7e956894ee | |||
f78046d4c1 | |||
beb09cbf4a | |||
6b2a5d7777 | |||
4b0d368222 | |||
5ab2f6ea3a | |||
f845bf5b25 | |||
bb10d64d58 | |||
62472b97e6 | |||
10b89ff00b | |||
2d8339343f | |||
9ddd88b5d0 | |||
614ec645c6 | |||
893ffc48dc | |||
7bddb70f11 | |||
9d4a38e560 | |||
9d20b31585 | |||
fb8838375f | |||
dead4e3f85 | |||
9c833a8a95 | |||
0b90794bca | |||
fd89757814 | |||
5eedc312c8 | |||
36c1cc5e0c | |||
0b4cdea9dd | |||
12172168f6 | |||
c79aa49252 | |||
b869308bf4 | |||
7a748bd142 | |||
d11669e613 | |||
b5108b938c | |||
049d510536 | |||
113f7b18a6 | |||
65b248c3cf | |||
1698996ac3 | |||
2ae47f2375 | |||
6733d12e81 | |||
8b5109e32f | |||
7b651d56b1 | |||
23b9b8aaf6 | |||
8d9fb43828 | |||
0d1be72fdb | |||
ce102a2af6 | |||
dda6071bbc | |||
0c4809bb16 | |||
4b87c5e80e | |||
b8fe9b9074 | |||
bc8b18cea8 | |||
20fdd3e891 | |||
ff9147487f | |||
af494f3b5e | |||
f68d26317d | |||
5b881f7c77 | |||
fe5efff255 | |||
46d18a642c | |||
c00012f28b | |||
d0050f7d59 | |||
f3a4881261 | |||
1728909964 | |||
f6e7460b24 | |||
351829888f | |||
e520c30ade | |||
99267ac2f0 | |||
6f1f7ef7fc | |||
d647e947e2 | |||
adef45c30f | |||
8b80859023 | |||
907fff89c8 | |||
ca532ffdaf | |||
64ee842dc4 | |||
9c0754a88d | |||
3dac9e3dae | |||
6963e667aa | |||
af292b291b | |||
918f75704e | |||
6e258e5d0c | |||
a8ea4ec085 | |||
2f894af028 | |||
dd400e1214 | |||
f8a183bfdf | |||
2404193b61 | |||
3ef11f5b26 | |||
30419cec12 | |||
162841feb8 | |||
f910f63f8d | |||
860cb75f8f | |||
293be93b93 | |||
976e77b31e | |||
9f28ee2982 | |||
e6c1e48b86 | |||
2c2880199d | |||
c7f8737eeb | |||
f3aea3108d | |||
e4f8ad0f05 | |||
8b80f72313 | |||
06ebce31ca | |||
59db8ba997 | |||
df37d4aa7f | |||
fd9935c800 | |||
c057430488 | |||
767fa78e22 | |||
a0e289dcd6 | |||
c62d147254 | |||
f739bee353 | |||
db4dfb69fb | |||
9729a5ef16 | |||
6f12818352 | |||
75fc318da0 | |||
acf71cc2c2 | |||
42efe10473 | |||
b77e72880b | |||
297c1524b4 | |||
6140743769 | |||
d5ca700828 | |||
a7e1fe76c3 | |||
f6c55279d1 | |||
826f4835bb | |||
119a28def1 | |||
c1ffb8bc33 | |||
60cc9d14af | |||
7cf4f8fdaa | |||
1b84e83061 | |||
b0d2ee8760 | |||
2022432d35 | |||
c0ed335d84 | |||
4964562866 | |||
f78dc443ad | |||
56b47db778 | |||
2d4bf17b28 | |||
3b1819c68d | |||
575bbdb53b | |||
2fa7482028 | |||
e5062317e2 | |||
543f4fa3c2 | |||
49cdf69815 | |||
04196a1a19 | |||
b8622b8708 | |||
a2feca0ba3 | |||
ae6c6a75b2 | |||
bd987e9531 | |||
24d69fd820 | |||
9e2fa8d7f1 | |||
74ba2f7283 | |||
7603b5c63f | |||
03566afe66 | |||
3c2e314e2d | |||
1fcf08b5cd | |||
c13db89ed4 | |||
e68ae9e8a6 | |||
fb252d6db3 | |||
df959353d6 | |||
fbc443483d | |||
00f1dbc3dd | |||
c6021ff012 | |||
7a8cfcee35 | |||
c15586a1c4 | |||
be1d124e78 | |||
6fabf84d05 | |||
3299275da2 | |||
5539243bf3 | |||
c3d330f500 | |||
8c9e886136 | |||
cfde9944f8 | |||
b35d778abe | |||
1e9ee81df3 | |||
545d5730b6 | |||
28e645f9ca | |||
5b5c8a4beb | |||
6178be974a | |||
7771c3159b | |||
fc1e9c5d71 | |||
359de5b85e | |||
68dc4904cf | |||
057fd02e26 | |||
5c86ef6682 | |||
7c14bd799f | |||
edac046fcd | |||
8b23b386f7 | |||
e9bed59032 | |||
54077be32c | |||
30ad442dd1 | |||
b0c677d5a7 | |||
abe1b93e3c | |||
fd699cbb73 | |||
6f93ca11de | |||
916663b493 | |||
dbf2cddd87 | |||
d3c248cf5c | |||
bd93a94bb7 | |||
a46836e2a6 | |||
a1d88b4faa | |||
29741c0ec8 | |||
0b5fb92452 | |||
65782e87c1 | |||
6403df3330 | |||
c6a8f5305a | |||
d354e63267 | |||
836b174d15 | |||
4435f25ee6 | |||
4ab4bf4a3a | |||
d2f1d3c86c | |||
98257de005 | |||
5ea5c6ff7d | |||
441324d354 | |||
44f093b2fa | |||
38a16d1ae2 | |||
6b9de40442 | |||
d9c9eb9799 | |||
e88c8eee0f | |||
a6ca843ced | |||
6967a5cc14 | |||
e0ebf70907 | |||
53d0202f3b | |||
8daf38654d | |||
17337440f2 | |||
8e5e79a799 | |||
5c1cf14303 | |||
f2ad796104 | |||
886df69058 | |||
703aa95e60 | |||
7919e14d90 | |||
c8ef191660 | |||
840b656d1c | |||
d28516b6b1 | |||
5797bf549c | |||
e1ea721ea9 | |||
5ed1284baf | |||
e507023a03 | |||
2b328b9bb2 | |||
d155e13399 | |||
6993d4782d | |||
9267efce01 | |||
8c88cec863 | |||
b4b9976567 | |||
3cbd820d9c | |||
edd77b0222 | |||
c0991df9a2 | |||
26921c899e | |||
a1e5912d37 | |||
037f1ec887 | |||
89ab44590b | |||
4a20be8b34 | |||
32a401ba67 | |||
138c01aef8 | |||
3e54bc9c77 | |||
9966fc4651 | |||
c9ed5ec98f | |||
1f4ae5dbfb | |||
d0d3cc8faa | |||
7513ae28f0 | |||
c151c6f55a | |||
d491aeeba6 | |||
ab93d0acea | |||
f40f3f934f | |||
4d57adb393 | |||
e91db18677 | |||
9a88d65ff7 | |||
211d8c7f19 | |||
763cdca114 | |||
0d56d35646 | |||
d1e80cb86a | |||
2e116489c8 | |||
a94daa1216 | |||
ad57d665cc | |||
db2c42f0f4 | |||
b713cf86c7 | |||
11d02ccf44 | |||
54f3c8beac | |||
2ed51bf1f3 | |||
9f859f024c | |||
d47175df8a | |||
d6a80d36b1 | |||
a857e3f31e | |||
918dfb05cd | |||
f22e0c4384 | |||
daa08626ae | |||
45592e6acd | |||
6944eb3392 | |||
85f20aca58 | |||
ca8d8b3587 | |||
74921a0686 | |||
be4296f288 | |||
836de56276 | |||
ef60ac3836 | |||
bdd1ba05e8 | |||
f0a22d5517 | |||
417c8d7874 | |||
5a111cdb2a | |||
ef2f779f71 | |||
f0fd0db7bb | |||
b4ab45d2e7 | |||
73c4bcee30 | |||
d4daf098e1 | |||
95de1fff69 | |||
96480b4382 | |||
14ae553557 | |||
4de809e275 | |||
a383382529 | |||
d2b3061ed9 | |||
073b10929a | |||
6a2cfcab34 | |||
00c85ae7d3 | |||
d1b1e88389 | |||
5679ff5df9 | |||
3f28b39da0 | |||
ee21536742 | |||
6fafeedeb9 | |||
d86c53858e | |||
0a22f80942 | |||
fb247197e8 | |||
261ed05fa3 | |||
f5ce48a7c2 | |||
82d128974c | |||
34ae731959 | |||
030a92d048 | |||
a327358b7a | |||
9bd078d3e9 | |||
412405e22c | |||
2b20b34a74 | |||
f269a07463 | |||
d9948e8ee0 | |||
ddb2fe4b03 | |||
471f7184fb | |||
92ea5da358 | |||
09f1d3ca15 | |||
3729b8eac2 | |||
ca5f345414 | |||
15cf1e8a53 | |||
da74b0ece1 | |||
f50fe6f22f | |||
542eec2a9e | |||
4c5460fc9e | |||
394b8f1ce6 | |||
abeeda1a2b | |||
9e6ea3f486 | |||
2777a0946c | |||
7f43c2659a | |||
a4fa11c881 | |||
8230e51c05 | |||
6e62d4791c | |||
ce8abdb8cd | |||
941bb7edaa | |||
1acbdf8b9e | |||
530804c847 | |||
b00b426e9c | |||
128f1753c0 | |||
1922629d27 | |||
283a03a7cc | |||
cdab26a97b | |||
5d3311c46b | |||
7cbc21671b | |||
d14d820e25 | |||
b567d02df2 | |||
dbb58541f2 | |||
5a42caf4f8 | |||
c2acd010ce | |||
4a8bcc6f71 | |||
89e4dc7a08 | |||
c344eedb12 | |||
0aeb1a62b9 | |||
316e0f5a68 | |||
6f9314f76f | |||
6ef21795ba | |||
e44855493e | |||
101a3c8af5 | |||
8fbbbce4ec | |||
1de8bb850f | |||
25d09186fe | |||
9552b7c6f9 | |||
3d692e4198 | |||
215ca9f755 | |||
7dbcb24f3d | |||
18b4bd62f7 | |||
20f3cf5327 | |||
c1d35e8af5 | |||
e1cd318f61 | |||
4da0952091 | |||
a60f75f0a9 | |||
3814009ad9 | |||
fe7bb00112 | |||
2356753dfc | |||
bd23ec268b | |||
1d5f23c3c7 | |||
f424bf53b3 | |||
efbdf0006e | |||
625b173ee4 | |||
0a8d9bc3d3 | |||
0d0909a461 | |||
ebb0a538f8 | |||
337a566617 | |||
fecee7a12b | |||
282ec99ce8 | |||
17a4985ebe | |||
13b17d91a9 | |||
5782005007 | |||
258f2dbe8f | |||
e7b35bd0c2 | |||
176bd229e6 | |||
c12f1251b0 | |||
0710736661 | |||
51ebe520f4 | |||
1ef566c824 | |||
96cf06fe8d | |||
38ebfdcd0c | |||
b5649e2a6f | |||
5fc6dadeae | |||
22cfec9276 | |||
0a82ec5f0a | |||
3bdd1f6c4f | |||
1e466dc1fe | |||
3b302d2f86 | |||
7f108eebf9 | |||
9d41fee2fe | |||
bef686f95a | |||
4bdcb974bd | |||
af042bd23c | |||
19e3cef7dd | |||
085ab4bfb4 | |||
f7bd03d051 | |||
b48d751717 | |||
92a4a1b210 | |||
6a57fcc04a | |||
749e11762f | |||
61817726c3 | |||
808354e969 | |||
d2f594ff4a | |||
fa18467cdd | |||
4c940d02ef | |||
04202a6b70 | |||
4483901270 | |||
f02d894697 | |||
2bc130856a | |||
aa3a4dca65 | |||
4f65931f51 | |||
93be61e483 | |||
cb7fe364bc | |||
9cdcb4b22c | |||
c49072f9b6 | |||
61df26b667 | |||
25c935f1db | |||
6b982bc0c7 | |||
caccc803d3 | |||
5be640632b | |||
40912f0ffd | |||
d518860a34 | |||
185617ed9e | |||
5ba96b627e | |||
edf955f4cd | |||
8d0b04668e | |||
a72e5e02da | |||
4740404c2e | |||
34253916ea | |||
1d77ba2694 | |||
765041c587 | |||
8c6bca7666 | |||
c1b1cef590 | |||
507f7804c3 | |||
453bacf9bd | |||
25778458c6 | |||
7a42646bed | |||
755b7034d2 | |||
122fcfd701 | |||
2c905eddc2 | |||
3e8eb9abb5 | |||
d2df3b2d9a | |||
2a0c983c2e | |||
1319432fde | |||
02e2aeb6d1 | |||
5e35edd976 | |||
4d63c6266c | |||
48f8d41993 | |||
0b41ccad83 | |||
f994afbc11 | |||
5dea783677 | |||
347ef9a1d0 | |||
739aa5311c | |||
805018286c | |||
45f2a47ba5 | |||
fe503b7bee | |||
6736570ee7 | |||
88c06eea6e | |||
13693ef9e5 | |||
3a54326e73 | |||
941c1c8a45 | |||
d328058075 | |||
9108eb5616 | |||
ea45044dc7 | |||
6b16808207 | |||
4071b285ce | |||
7bc80f0814 | |||
6b57202421 | |||
ca3edb6687 | |||
7428f87899 | |||
02481560a9 | |||
2d66063763 | |||
9158e24295 | |||
118e177756 | |||
88ac82a013 | |||
c025013ca8 |
@ -2,7 +2,6 @@
|
|||||||
@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)
|
||||||
{
|
{
|
||||||
@ -50,29 +49,21 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string AuthorizationToken { get; set; }
|
public string AuthorizationToken { get; set; }
|
||||||
|
|
||||||
|
[CascadingParameter]
|
||||||
|
HttpContext HttpContext { get; set; }
|
||||||
|
|
||||||
private bool _initialized = false;
|
private bool _initialized = false;
|
||||||
private string _display = "display: none;";
|
private string _display = "display: none;";
|
||||||
private Installation _installation = new Installation { Success = false, Message = "" };
|
private Installation _installation = new Installation { Success = false, Message = "" };
|
||||||
|
|
||||||
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;
|
||||||
|
SiteState.IsPrerendering = (HttpContext != null) ? true : false;
|
||||||
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)
|
||||||
|
14
Oqtane.Client/IconResources.cs
Normal file
14
Oqtane.Client/IconResources.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
namespace Oqtane
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Dummy class used to collect shared resource strings for this application
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class is mostly used with IStringLocalizer and IHtmlLocalizer interfaces.
|
||||||
|
/// The class must reside at the project root.
|
||||||
|
/// </remarks>
|
||||||
|
public class IconResources
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
@namespace Oqtane.Installer.Controls
|
@namespace Oqtane.Installer.Controls
|
||||||
@implements Oqtane.Interfaces.IDatabaseConfigControl
|
@implements Oqtane.Interfaces.IDatabaseConfigControl
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="server" HelpText="Enter the database server" ResourceKey="Server">Server:</Label>
|
<Label Class="col-sm-3" For="server" HelpText="Enter the database server" ResourceKey="Server">Server:</Label>
|
||||||
@ -28,7 +29,10 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="pwd" type="password" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
<div class="input-group">
|
||||||
|
<input id="pwd" type="@_passwordType" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglePassword</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -38,6 +42,13 @@
|
|||||||
private string _database = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
|
private string _database = "Oqtane-" + DateTime.UtcNow.ToString("yyyyMMddHHmm");
|
||||||
private string _uid = String.Empty;
|
private string _uid = String.Empty;
|
||||||
private string _pwd = String.Empty;
|
private string _pwd = String.Empty;
|
||||||
|
private string _passwordType = "password";
|
||||||
|
private string _togglePassword = string.Empty;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
|
}
|
||||||
|
|
||||||
public string GetConnectionString()
|
public string GetConnectionString()
|
||||||
{
|
{
|
||||||
@ -55,4 +66,18 @@
|
|||||||
|
|
||||||
return connectionString;
|
return connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TogglePassword()
|
||||||
|
{
|
||||||
|
if (_passwordType == "password")
|
||||||
|
{
|
||||||
|
_passwordType = "text";
|
||||||
|
_togglePassword = SharedLocalizer["HidePassword"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_passwordType = "password";
|
||||||
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
@namespace Oqtane.Installer.Controls
|
@namespace Oqtane.Installer.Controls
|
||||||
@implements Oqtane.Interfaces.IDatabaseConfigControl
|
@implements Oqtane.Interfaces.IDatabaseConfigControl
|
||||||
@inject IStringLocalizer<PostgreSQLConfig> Localizer
|
@inject IStringLocalizer<PostgreSQLConfig> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="server" HelpText="Enter the database server" ResourceKey="Server">Server:</Label>
|
<Label Class="col-sm-3" For="server" HelpText="Enter the database server" ResourceKey="Server">Server:</Label>
|
||||||
@ -40,7 +41,10 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="pwd" type="password" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
<div class="input-group">
|
||||||
|
<input id="pwd" type="@_passwordType" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglePassword</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -52,6 +56,13 @@
|
|||||||
private string _security = "integrated";
|
private string _security = "integrated";
|
||||||
private string _uid = String.Empty;
|
private string _uid = String.Empty;
|
||||||
private string _pwd = String.Empty;
|
private string _pwd = String.Empty;
|
||||||
|
private string _passwordType = "password";
|
||||||
|
private string _togglePassword = string.Empty;
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
|
}
|
||||||
|
|
||||||
public string GetConnectionString()
|
public string GetConnectionString()
|
||||||
{
|
{
|
||||||
@ -80,4 +91,18 @@
|
|||||||
|
|
||||||
return connectionString;
|
return connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TogglePassword()
|
||||||
|
{
|
||||||
|
if (_passwordType == "password")
|
||||||
|
{
|
||||||
|
_passwordType = "text";
|
||||||
|
_togglePassword = SharedLocalizer["HidePassword"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_passwordType = "password";
|
||||||
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -35,7 +35,10 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="pwd" type="password" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
<div class="input-group">
|
||||||
|
<input id="pwd" type="@_passwordType" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglePassword</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -67,9 +70,16 @@
|
|||||||
private string _security = "integrated";
|
private string _security = "integrated";
|
||||||
private string _uid = String.Empty;
|
private string _uid = String.Empty;
|
||||||
private string _pwd = String.Empty;
|
private string _pwd = String.Empty;
|
||||||
|
private string _passwordType = "password";
|
||||||
|
private string _togglePassword = string.Empty;
|
||||||
private string _encryption = "false";
|
private string _encryption = "false";
|
||||||
private string _trustservercertificate = "false";
|
private string _trustservercertificate = "false";
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
|
}
|
||||||
|
|
||||||
public string GetConnectionString()
|
public string GetConnectionString()
|
||||||
{
|
{
|
||||||
var connectionString = String.Empty;
|
var connectionString = String.Empty;
|
||||||
@ -92,4 +102,18 @@
|
|||||||
|
|
||||||
return connectionString;
|
return connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TogglePassword()
|
||||||
|
{
|
||||||
|
if (_passwordType == "password")
|
||||||
|
{
|
||||||
|
_passwordType = "text";
|
||||||
|
_togglePassword = SharedLocalizer["HidePassword"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_passwordType = "password";
|
||||||
|
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -15,7 +15,7 @@
|
|||||||
<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 (.NET 7)</div>
|
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET 8)</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr class="app-rule" />
|
<hr class="app-rule" />
|
||||||
|
@ -12,11 +12,12 @@
|
|||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
string url = NavigateUrl(p.Path);
|
string url = NavigateUrl(p.Path);
|
||||||
<div class="col-md-2 mx-auto text-center mb-3">
|
<p class="col-md-2 mx-auto text-center mb-3">
|
||||||
<NavLink class="nav-link text-primary" href="@url" Match="NavLinkMatch.All">
|
<NavLink class="nav-link text-primary" href="@url" Match="NavLinkMatch.All">
|
||||||
<h2><span class="@p.Icon" aria-hidden="true"></span></h2>@SharedLocalizer[p.Name]
|
<h2><span class="@p.Icon" aria-hidden="true"></span></h2>
|
||||||
|
<p class="lead">@((MarkupString)SharedLocalizer[p.Name].ToString().Replace(" ", "<br />"))</p>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</p>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
</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="imagesizes" HelpText="Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,x200,200x)" ResourceKey="ImageSizes">Image Sizes: </Label>
|
<Label Class="col-sm-3" For="imagesizes" HelpText="Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes." ResourceKey="ImageSizes">Image Sizes: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="imagesizes" class="form-control" @bind="@_imagesizes" maxlength="512" />
|
<input id="imagesizes" class="form-control" @bind="@_imagesizes" maxlength="512" />
|
||||||
</div>
|
</div>
|
||||||
@ -67,6 +67,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
@if (!_isSystem)
|
@if (!_isSystem)
|
||||||
{
|
{
|
||||||
@ -79,8 +80,7 @@
|
|||||||
@((MarkupString)" ")
|
@((MarkupString)" ")
|
||||||
<ActionDialog Header="Delete Folder" Message="Are You Sure You Wish To Delete This Folder?" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFolder())" ResourceKey="DeleteFolder" />
|
<ActionDialog Header="Delete Folder" Message="Are You Sure You Wish To Delete This Folder?" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFolder())" ResourceKey="DeleteFolder" />
|
||||||
}
|
}
|
||||||
<br />
|
<br /><br />
|
||||||
<br />
|
|
||||||
@if (PageState.QueryString.ContainsKey("id"))
|
@if (PageState.QueryString.ContainsKey("id"))
|
||||||
{
|
{
|
||||||
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
|
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
|
||||||
|
@ -8,27 +8,28 @@
|
|||||||
|
|
||||||
@if (_files != null)
|
@if (_files != null)
|
||||||
{
|
{
|
||||||
<div class="container">
|
<div class="row">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="col-md mb-1">
|
||||||
<div class="col-sm-2">
|
<ActionLink Action="Edit" Text="Add Folder" Class="btn btn-secondary" ResourceKey="AddFolder" />
|
||||||
<label class="control-label">@Localizer["Folder"] </label>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-md-8 mb-1">
|
||||||
|
<div class="input-group">
|
||||||
|
<span class="input-group-text">@Localizer["Folder"]:</span>
|
||||||
<select class="form-select" @onchange="(e => FolderChanged(e))">
|
<select class="form-select" @onchange="(e => FolderChanged(e))">
|
||||||
@foreach (Folder folder in _folders)
|
@foreach (Folder folder in _folders)
|
||||||
{
|
{
|
||||||
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<ActionLink Action="Edit" Text="Edit Folder" Class="btn btn-secondary" Parameters="@($"id=" + _folderId.ToString())" ResourceKey="EditFolder" />
|
<ActionLink Action="Edit" Text="Edit Folder" Class="btn btn-secondary" Parameters="@($"id=" + _folderId.ToString())" ResourceKey="EditFolder" />
|
||||||
<ActionLink Action="Edit" Text="Add Folder" Class="btn btn-secondary" ResourceKey="AddFolder" />
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md mb-1 text-end">
|
||||||
<ActionLink Action="Add" Text="Upload Files" Parameters="@($"id=" + _folderId.ToString())" ResourceKey="UploadFiles" />
|
<ActionLink Action="Add" Text="Upload Files" Parameters="@($"id=" + _folderId.ToString())" ResourceKey="UploadFiles" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<Pager Items="@_files">
|
<Pager Items="@_files" SearchProperties="Name">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
@ -56,7 +56,7 @@
|
|||||||
<input id="starting" type="date" class="form-control" @bind="@_startDate" />
|
<input id="starting" type="date" class="form-control" @bind="@_startDate" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<input id="starting" type="text" class="form-control" placeholder="hh:mm" @bind="@_startTime" />
|
<input id="starting" type="time" class="form-control" placeholder="hh:mm" @bind="@_startTime" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -69,7 +69,7 @@
|
|||||||
<input id="ending" type="date" class="form-control" @bind="@_endDate" />
|
<input id="ending" type="date" class="form-control" @bind="@_endDate" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<input id="ending" type="text" class="form-control" placeholder="hh:mm" @bind="@_endTime" />
|
<input id="ending" type="time" class="form-control" placeholder="hh:mm" @bind="@_endTime" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,7 +82,7 @@
|
|||||||
<input id="next" type="date" class="form-control" @bind="@_nextDate" />
|
<input id="next" type="date" class="form-control" @bind="@_nextDate" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<input id="next" type="text" class="form-control" placeholder="hh:mm" @bind="@_nextTime" />
|
<input id="next" type="time" class="form-control" placeholder="hh:mm" @bind="@_nextTime" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -106,12 +106,12 @@
|
|||||||
private string _interval = string.Empty;
|
private string _interval = string.Empty;
|
||||||
private string _frequency = string.Empty;
|
private string _frequency = string.Empty;
|
||||||
private DateTime? _startDate = null;
|
private DateTime? _startDate = null;
|
||||||
private string _startTime = string.Empty;
|
private DateTime? _startTime = null;
|
||||||
private DateTime? _endDate = null;
|
private DateTime? _endDate = null;
|
||||||
private string _endTime = string.Empty;
|
private DateTime? _endTime = null;
|
||||||
private string _retentionHistory = string.Empty;
|
private string _retentionHistory = string.Empty;
|
||||||
private DateTime? _nextDate = null;
|
private DateTime? _nextDate = null;
|
||||||
private string _nextTime = string.Empty;
|
private DateTime? _nextTime = null;
|
||||||
private string createdby;
|
private string createdby;
|
||||||
private DateTime createdon;
|
private DateTime createdon;
|
||||||
private string modifiedby;
|
private string modifiedby;
|
||||||
@ -132,10 +132,13 @@
|
|||||||
_isEnabled = job.IsEnabled.ToString();
|
_isEnabled = job.IsEnabled.ToString();
|
||||||
_interval = job.Interval.ToString();
|
_interval = job.Interval.ToString();
|
||||||
_frequency = job.Frequency;
|
_frequency = job.Frequency;
|
||||||
(_startDate, _startTime) = Utilities.UtcAsLocalDateAndTime(job.StartDate);
|
_startDate = Utilities.UtcAsLocalDate(job.StartDate);
|
||||||
(_endDate, _endTime) = Utilities.UtcAsLocalDateAndTime(job.EndDate);
|
_startTime = Utilities.UtcAsLocalDateTime(job.StartDate);
|
||||||
|
_endDate = Utilities.UtcAsLocalDate(job.EndDate);
|
||||||
|
_endTime = Utilities.UtcAsLocalDateTime(job.EndDate);
|
||||||
_retentionHistory = job.RetentionHistory.ToString();
|
_retentionHistory = job.RetentionHistory.ToString();
|
||||||
(_nextDate, _nextTime) = Utilities.UtcAsLocalDateAndTime(job.NextExecution);
|
_nextDate = Utilities.UtcAsLocalDate(job.NextExecution);
|
||||||
|
_nextTime = Utilities.UtcAsLocalDateTime(job.NextExecution);
|
||||||
createdby = job.CreatedBy;
|
createdby = job.CreatedBy;
|
||||||
createdon = job.CreatedOn;
|
createdon = job.CreatedOn;
|
||||||
modifiedby = job.ModifiedBy;
|
modifiedby = job.ModifiedBy;
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<ActionLink Action="Log" Class="btn btn-secondary" Text="View Logs" ResourceKey="ViewJobs" />
|
<ActionLink Action="Log" Class="btn btn-secondary" Text="View Logs" ResourceKey="ViewJobs" />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="(async () => await Refresh())">Refresh</button>
|
<button type="button" class="btn btn-secondary" @onclick="(async () => await Refresh())">@Localizer["Refresh.Text"]</button>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<Pager Items="@_jobs">
|
<Pager Items="@_jobs" SearchProperties="Name">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Manage" ResourceKey="Manage">
|
<TabPanel Name="Manage" ResourceKey="Manage" Heading="Manage">
|
||||||
<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">
|
||||||
@ -45,7 +45,7 @@ else
|
|||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
</form>
|
</form>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
|
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host" Heading="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 translations. Once they are uploaded click Install." 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>
|
||||||
|
@ -14,7 +14,7 @@ else
|
|||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add Language" ResourceKey="AddLanguage" />
|
<ActionLink Action="Add" Text="Add Language" ResourceKey="AddLanguage" />
|
||||||
|
|
||||||
<Pager Items="@_languages">
|
<Pager Items="@_languages" SearchProperties="Name,Code">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
@ -146,7 +146,7 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, version);
|
_package = await PackageService.GetPackageAsync(Constants.PackageId + "." + code, version, false);
|
||||||
if (_package != null)
|
if (_package != null)
|
||||||
{
|
{
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -168,7 +168,7 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version);
|
||||||
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(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Language.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_package = null;
|
_package = null;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
@inject ISettingService SettingService
|
||||||
@inject IServiceProvider ServiceProvider
|
@inject IServiceProvider ServiceProvider
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
@ -11,9 +12,6 @@
|
|||||||
<Authorizing>
|
<Authorizing>
|
||||||
<text>...</text>
|
<text>...</text>
|
||||||
</Authorizing>
|
</Authorizing>
|
||||||
<Authorized>
|
|
||||||
<div>@Localizer["Info.SignedIn"]</div>
|
|
||||||
</Authorized>
|
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
@if (!twofactor)
|
@if (!twofactor)
|
||||||
{
|
{
|
||||||
@ -38,10 +36,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mt-2">
|
<div class="form-group mt-2">
|
||||||
|
@if (!_alwaysremember)
|
||||||
|
{
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input id="remember" type="checkbox" class="form-check-input" @bind="@_remember" />
|
<input id="remember" type="checkbox" class="form-check-input" @bind="@_remember" />
|
||||||
<Label Class="control-label" For="remember" HelpText="Specify if you would like to be signed back in automatically the next time you visit this site" ResourceKey="Remember">Remember Me?</Label>
|
<Label Class="control-label" For="remember" HelpText="Specify if you would like to be signed back in automatically the next time you visit this site" ResourceKey="Remember">Remember Me?</Label>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-primary" @onclick="Login">@SharedLocalizer["Login"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Login">@SharedLocalizer["Login"]</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>
|
||||||
@ -80,6 +81,7 @@
|
|||||||
private string _passwordtype = "password";
|
private string _passwordtype = "password";
|
||||||
private string _togglepassword = string.Empty;
|
private string _togglepassword = string.Empty;
|
||||||
private bool _remember = false;
|
private bool _remember = false;
|
||||||
|
private bool _alwaysremember = false;
|
||||||
private string _code = string.Empty;
|
private string _code = string.Empty;
|
||||||
|
|
||||||
private string _returnUrl = string.Empty;
|
private string _returnUrl = string.Empty;
|
||||||
@ -95,18 +97,11 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_allowexternallogin = (SettingService.GetSetting(PageState.Site.Settings, "ExternalLogin:ProviderType", "") != "") ? true : false;
|
||||||
|
_allowsitelogin = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:AllowSiteLogin", "true"));
|
||||||
|
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
|
|
||||||
if (PageState.Site.Settings.ContainsKey("LoginOptions:AllowSiteLogin") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]))
|
|
||||||
{
|
|
||||||
_allowsitelogin = bool.Parse(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.Site.Settings.ContainsKey("ExternalLogin:ProviderType") && !string.IsNullOrEmpty(PageState.Site.Settings["ExternalLogin:ProviderType"]))
|
|
||||||
{
|
|
||||||
_allowexternallogin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
if (PageState.QueryString.ContainsKey("returnurl"))
|
||||||
{
|
{
|
||||||
_returnUrl = PageState.QueryString["returnurl"];
|
_returnUrl = PageState.QueryString["returnurl"];
|
||||||
@ -160,6 +155,10 @@
|
|||||||
AddModuleMessage(Localizer["ExternalLoginStatus." + PageState.QueryString["status"]], MessageType.Info);
|
AddModuleMessage(Localizer["ExternalLoginStatus." + PageState.QueryString["status"]], MessageType.Info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (PageState.Site.Settings.TryGetValue("LoginOptions:AlwaysRemember", out string alwaysRememberStr))
|
||||||
|
{
|
||||||
|
_alwaysremember = Convert.ToBoolean(alwaysRememberStr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -170,10 +169,16 @@
|
|||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (firstRender && PageState.User == null)
|
if (firstRender && PageState.User == null && _allowsitelogin)
|
||||||
{
|
{
|
||||||
await username.FocusAsync();
|
await username.FocusAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redirect logged in user to specified page
|
||||||
|
if (PageState.User != null)
|
||||||
|
{
|
||||||
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Login()
|
private async Task Login()
|
||||||
@ -189,6 +194,13 @@
|
|||||||
|
|
||||||
if (!twofactor)
|
if (!twofactor)
|
||||||
{
|
{
|
||||||
|
bool alwaysRemember = false;
|
||||||
|
if (PageState.Site.Settings.TryGetValue("LoginOptions:AlwaysRemember", out string alwaysRememberStr))
|
||||||
|
{
|
||||||
|
alwaysRemember = Convert.ToBoolean(alwaysRememberStr);
|
||||||
|
}
|
||||||
|
bool remember = alwaysRemember || _remember;
|
||||||
|
_remember = remember;
|
||||||
user = await UserService.LoginUserAsync(user, hybrid, _remember);
|
user = await UserService.LoginUserAsync(user, hybrid, _remember);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -203,8 +215,7 @@
|
|||||||
if (hybrid)
|
if (hybrid)
|
||||||
{
|
{
|
||||||
// hybrid apps utilize an interactive login
|
// hybrid apps utilize an interactive login
|
||||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider
|
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||||
.GetService(typeof(IdentityAuthenticationStateProvider));
|
|
||||||
authstateprovider.NotifyAuthenticationChanged();
|
authstateprovider.NotifyAuthenticationChanged();
|
||||||
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
|
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
|
||||||
}
|
}
|
||||||
@ -218,7 +229,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((PageState.Site.Settings.ContainsKey("LoginOptions:TwoFactor") && PageState.Site.Settings["LoginOptions:TwoFactor"] == "required") || user.TwoFactorRequired)
|
if (SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:TwoFactor", "false") == "required" || user.TwoFactorRequired)
|
||||||
{
|
{
|
||||||
twofactor = true;
|
twofactor = true;
|
||||||
validated = false;
|
validated = false;
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
@namespace Oqtane.Modules.Admin.ModuleCreator
|
|
||||||
@inherits ModuleBase
|
|
||||||
@using System.Text.RegularExpressions
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
@inject IModuleDefinitionService ModuleDefinitionService
|
|
||||||
@inject IModuleService ModuleService
|
|
||||||
@inject ISettingService SettingService
|
|
||||||
@inject IStringLocalizer<Index> Localizer
|
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
|
||||||
|
|
||||||
@if (string.IsNullOrEmpty(_moduledefinitionname) && _templates != null)
|
|
||||||
{
|
|
||||||
<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="owner" HelpText="Enter the name of the organization who is developing this module. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="owner" class="form-control" @bind="@_owner" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="module" HelpText="Enter a name for this module. It should not contain spaces or punctuation." ResourceKey="ModuleName">Module Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="module" class="form-control" @bind="@_module" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="description" HelpText="Enter a short description for the module" ResourceKey="Description">Description: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<textarea id="description" class="form-control" @bind="@_description" rows="3" ></textarea>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="template" class="form-select" @onchange="(e => TemplateChanged(e))" required>
|
|
||||||
<option value="-"><@Localizer["Template.Select"]></option>
|
|
||||||
@foreach (Template template in _templates)
|
|
||||||
{
|
|
||||||
<option value="@template.Name">@template.Title</option>
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="reference" class="form-select" @bind="@_reference" required>
|
|
||||||
@foreach (string version in _versions)
|
|
||||||
{
|
|
||||||
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
|
|
||||||
{
|
|
||||||
<option value="@(version)">@(version)</option>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
<option value="local">@SharedLocalizer["LocalVersion"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@if (!string.IsNullOrEmpty(_location))
|
|
||||||
{
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="location" HelpText="Location where the module will be created" ResourceKey="Location">Location: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="module" class="form-control" @bind="@_location" readonly />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["Module.Create"]</button>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-success" @onclick="ActivateModule">@Localizer["Module.Activate"]</button>
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private ElementReference form;
|
|
||||||
private bool validated = false;
|
|
||||||
private string _moduledefinitionname = string.Empty;
|
|
||||||
private string _owner = string.Empty;
|
|
||||||
private string _module = string.Empty;
|
|
||||||
private string _description = string.Empty;
|
|
||||||
private List<Template> _templates;
|
|
||||||
private string _template = "-";
|
|
||||||
private string[] _versions;
|
|
||||||
private string _reference = "local";
|
|
||||||
private string _minversion = "2.0.0";
|
|
||||||
private string _location = string.Empty;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
_moduledefinitionname = SettingService.GetSetting(ModuleState.Settings, "ModuleDefinitionName", "");
|
|
||||||
if (string.IsNullOrEmpty(_moduledefinitionname))
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Info.Module.Creator"], MessageType.Info);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Info.Module.Activate"], MessageType.Info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
|
|
||||||
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading Module Creator");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task CreateModule()
|
|
||||||
{
|
|
||||||
validated = true;
|
|
||||||
var interop = new Interop(JSRuntime);
|
|
||||||
if (await interop.FormValid(form))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-")
|
|
||||||
{
|
|
||||||
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
|
|
||||||
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
|
|
||||||
|
|
||||||
var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
|
||||||
settings = SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName);
|
|
||||||
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
|
||||||
|
|
||||||
GetLocation();
|
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Creating Module");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ActivateModule()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(_moduledefinitionname))
|
|
||||||
{
|
|
||||||
Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId);
|
|
||||||
module.ModuleDefinitionName = _moduledefinitionname;
|
|
||||||
await ModuleService.UpdateModuleAsync(module);
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Activating Module");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsValid(string name)
|
|
||||||
{
|
|
||||||
// must contain letters, underscores and digits and first character must be letter or underscore
|
|
||||||
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void TemplateChanged(ChangeEventArgs e)
|
|
||||||
{
|
|
||||||
_template = (string)e.Value;
|
|
||||||
_minversion = "2.0.0";
|
|
||||||
if (_template != "-")
|
|
||||||
{
|
|
||||||
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
|
||||||
_minversion = template.Version;
|
|
||||||
}
|
|
||||||
GetLocation();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetLocation()
|
|
||||||
{
|
|
||||||
_location = string.Empty;
|
|
||||||
if (_owner != "" && _module != "" && _template != "-")
|
|
||||||
{
|
|
||||||
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
|
||||||
_location = template.Location + _owner + ".Module." + _module;
|
|
||||||
|
|
||||||
}
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
using Oqtane.Documentation;
|
|
||||||
using Oqtane.Models;
|
|
||||||
|
|
||||||
namespace Oqtane.Modules.Admin.ModuleCreator
|
|
||||||
{
|
|
||||||
[PrivateApi("Mark this as private, since it's not very useful in the public docs")]
|
|
||||||
public class ModuleInfo : IModule
|
|
||||||
{
|
|
||||||
public ModuleDefinition ModuleDefinition => new ModuleDefinition
|
|
||||||
{
|
|
||||||
Name = "Module Creator",
|
|
||||||
Description = "Enables software developers to quickly create modules by automating many of the initial module creation tasks",
|
|
||||||
Version = "1.0.0",
|
|
||||||
Categories = "Developer"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,67 +8,121 @@
|
|||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Download" ResourceKey="Download">
|
<TabPanel Name="Download" ResourceKey="Download" Heading="Download">
|
||||||
<div class="row justify-content-center mb-3">
|
<div class="row justify-content-center mb-3">
|
||||||
<div class="col-sm-6">
|
<div class="text-center">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="free" class="form-check-input" type="radio" checked="@(_price == "free")" name="Price" @onchange="@(() => PriceChanged("free"))" />
|
||||||
|
<label class="form-check-label" for="free">@SharedLocalizer["Free"]</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="paid" class="form-check-input" type="radio" checked="@(_price == "paid")" name="Price" @onchange="@(() => PriceChanged("paid"))" />
|
||||||
|
<label class="form-check-label" for="paid">@SharedLocalizer["Paid"]</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center mb-3">
|
||||||
|
<div class="col">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select id="price" class="form-select custom-select" @onchange="(e => PriceChanged(e))">
|
<span class="input-group-text">@Localizer["Product"]</span>
|
||||||
<option value="free">@SharedLocalizer["Free"]</option>
|
|
||||||
<option value="paid">@SharedLocalizer["Paid"]</option>
|
|
||||||
</select>
|
|
||||||
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
||||||
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||||
|
<button type="button" class="btn btn-primary ms-2" @onclick="Refresh"><span class="@Icons.Reload" aria-hidden="true"></span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
@if (_packages != null)
|
<div class="col">
|
||||||
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
if (_packages.Count > 0)
|
<br />
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<h3>@((_packages != null) ? _packages.Count : 0) @SharedLocalizer["Search.Results"]</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-select" value="@_sort" @onchange="(e => SortChanged(e))">
|
||||||
|
<option value="popularity">@SharedLocalizer["Search.Popularity"]</option>
|
||||||
|
<option value="alphabetical">@SharedLocalizer["Search.Alphabetical"]</option>
|
||||||
|
@if (_price == "free")
|
||||||
{
|
{
|
||||||
<Pager Items="@_packages">
|
<option value="downloads">@SharedLocalizer["Search.Downloads"]</option>
|
||||||
<Row>
|
|
||||||
<td>
|
|
||||||
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3> by: <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
|
||||||
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
|
||||||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
|
||||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
|
||||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
|
||||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
|
||||||
</td>
|
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
|
||||||
}
|
}
|
||||||
</td>
|
<option value="recent">@SharedLocalizer["Search.RecentlyReleased"]</option>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
@if (_price == "paid")
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
<option value="price">@SharedLocalizer["Search.Price"]</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Pager Format="Grid" Items="@_packages" DisplayPages="1" PageSize="9" Toolbar="Both" Class="container-fluid px-0" RowClass="row g-0" ColumnClass="col-lg-4 col-md-6" CurrentPage="@_page.ToString()" OnPageChange="OnPageChange">
|
||||||
|
<Row>
|
||||||
|
<div class="m-2 p-2 d-flex justify-content-center">
|
||||||
|
<div class="container-fluid px-0">
|
||||||
|
<div class="row g-0 mb-2">
|
||||||
|
<div class="col-4">
|
||||||
|
<a href="@context.ProductUrl" target="_blank">
|
||||||
|
@if (context.LogoUrl != null)
|
||||||
|
{
|
||||||
|
<img src="@context.LogoUrl" class="img-fluid" alt="@context.Name" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
<img src="/package.png" class="img-fluid" alt="@context.Name" />
|
||||||
|
}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 text-end">
|
||||||
|
<small>@SharedLocalizer["Search.Version"]:</small> <strong>@context.Version</strong>
|
||||||
|
<br /><small>@SharedLocalizer["Search.Released"]:</small> <strong>@context.ReleaseDate.ToString("MM/dd/yyyy")</strong>
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["Search.Source"]:</small> <strong>@(new Uri(context.PackageUrl).Host)</strong>
|
||||||
|
}
|
||||||
|
@if (context.Price == null)
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["Search.Downloads"]:</small> <strong>@(String.Format("{0:n0}", context.Downloads))</strong>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["From"]:</small> <strong>@context.Price.Value.ToString("$#,##0.00")</strong>
|
||||||
|
@((MarkupString)(context.TrialPeriod > 0 ? " <strong>(" + context.TrialPeriod + " Day Trial)</strong>" : ""))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col">
|
||||||
|
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_blank">@context.Name</a></h3><br />
|
||||||
|
<small>@SharedLocalizer["Search.By"]:</small> <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
||||||
|
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
||||||
|
<br />
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
|
{
|
||||||
|
<a class="btn btn-success ms-2" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@SharedLocalizer["Buy"]</a>
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<br />
|
|
||||||
<div class="mx-auto text-center">
|
|
||||||
@Localizer["Search.NoResults"]
|
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
}
|
|
||||||
<br />
|
<br />
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
<TabPanel Name="Upload" ResourceKey="Upload" Heading="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>
|
||||||
@ -116,8 +170,11 @@
|
|||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
|
private int _page = 1;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
|
private string _sort = "popularity";
|
||||||
private string _search = "";
|
private string _search = "";
|
||||||
private string _productname = "";
|
private string _productname = "";
|
||||||
private string _packageid = "";
|
private string _packageid = "";
|
||||||
@ -131,6 +188,7 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await LoadModuleDefinitions();
|
await LoadModuleDefinitions();
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -141,8 +199,10 @@
|
|||||||
|
|
||||||
private async Task LoadModuleDefinitions()
|
private async Task LoadModuleDefinitions()
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
|
||||||
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||||
_packages = await PackageService.GetPackagesAsync("module", _search, _price, "");
|
_packages = await PackageService.GetPackagesAsync("module", _search, _price, "", _sort);
|
||||||
|
|
||||||
if (_packages != null)
|
if (_packages != null)
|
||||||
{
|
{
|
||||||
@ -154,46 +214,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HideProgressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void PriceChanged(ChangeEventArgs e)
|
private async void PriceChanged(string price)
|
||||||
{
|
{
|
||||||
try
|
_price = price;
|
||||||
{
|
_sort = "popularity";
|
||||||
_price = (string)e.Value;
|
|
||||||
_search = "";
|
|
||||||
await LoadModuleDefinitions();
|
await LoadModuleDefinitions();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On PriceChanged");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Search()
|
private async Task Search()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
await LoadModuleDefinitions();
|
await LoadModuleDefinitions();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On Search");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Reset()
|
private async Task Reset()
|
||||||
{
|
{
|
||||||
try
|
_page = 1;
|
||||||
{
|
|
||||||
_search = "";
|
_search = "";
|
||||||
await LoadModuleDefinitions();
|
await LoadModuleDefinitions();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
private async Task Refresh()
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error On Reset");
|
await LoadModuleDefinitions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPageChange(int page)
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SortChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
_sort = (string)e.Value;
|
||||||
|
await LoadModuleDefinitions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HideModal()
|
private void HideModal()
|
||||||
@ -207,7 +265,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var package = await PackageService.GetPackageAsync(packageid, version);
|
var package = await PackageService.GetPackageAsync(packageid, version, false);
|
||||||
if (package != null)
|
if (package != null)
|
||||||
{
|
{
|
||||||
_productname = package.Name;
|
_productname = package.Name;
|
||||||
@ -236,7 +294,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_packageid, _packageversion, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_packageid, _packageversion);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _packageversion);
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_productname = "";
|
_productname = "";
|
||||||
|
@ -88,9 +88,12 @@
|
|||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
if (!NavigationManager.BaseUri.Contains("localhost:"))
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Info.Module.Development"], MessageType.Info);
|
AddModuleMessage(Localizer["Info.Module.Development"], MessageType.Info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
@ -115,12 +118,20 @@
|
|||||||
{
|
{
|
||||||
if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-")
|
if (IsValid(_owner) && IsValid(_module) && _owner != _module && _template != "-")
|
||||||
{
|
{
|
||||||
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
|
if (IsValidXML(_description))
|
||||||
|
{
|
||||||
|
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
||||||
|
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference, ModuleDefinitionName = template.Namespace };
|
||||||
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
|
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
|
||||||
GetLocation();
|
GetLocation();
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Require.ValidDescription"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
@ -142,6 +153,12 @@
|
|||||||
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
return !string.IsNullOrEmpty(name) && name.ToLower() != "module" && !name.ToLower().Contains("oqtane") && Regex.IsMatch(name, "^[A-Za-z_][A-Za-z0-9_]*$");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsValidXML(string description)
|
||||||
|
{
|
||||||
|
// must contain letters, digits, or spaces
|
||||||
|
return Regex.IsMatch(description, "^[A-Za-z0-9 .,!?]+$");
|
||||||
|
}
|
||||||
|
|
||||||
private void TemplateChanged(ChangeEventArgs e)
|
private void TemplateChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_template = (string)e.Value;
|
_template = (string)e.Value;
|
||||||
@ -160,8 +177,14 @@
|
|||||||
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;
|
if (!string.IsNullOrEmpty(template.Namespace))
|
||||||
|
{
|
||||||
|
_location = template.Location + template.Namespace.Replace("[Owner]", _owner).Replace("[Module]", _module);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_location = template.Location + _owner + ".Module." + _module;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
@if (_initialized)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Definition" ResourceKey="Definition">
|
<TabPanel Name="Definition" ResourceKey="Definition" Heading="Definition">
|
||||||
<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">
|
||||||
@ -59,9 +59,26 @@
|
|||||||
</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="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this module was installed. This value must be specified within the module's IModule interface specification." ResourceKey="PackageName">Package Name: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
@if (!string.IsNullOrEmpty(_packagename))
|
||||||
|
{
|
||||||
|
<div class="input-group">
|
||||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||||
|
@if (string.IsNullOrEmpty(_packageurl))
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="ValidatePackage">@Localizer["Validate"]</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<a href="@_packageurl" target="_blank" class="btn btn-primary">@SharedLocalizer["Download"]</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -85,13 +102,14 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="license" HelpText="The module license terms" ResourceKey="License">License: </Label>
|
<Label Class="col-sm-3" For="license" HelpText="The module license terms" ResourceKey="License">License: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
@if (_license.StartsWith("http") || _license.StartsWith("/") || _license.StartsWith("~"))
|
||||||
|
{
|
||||||
|
<a href="@_license.Replace("~", PageState?.Alias.BaseUrl + "/Modules/" + Utilities.GetTypeName(_moduledefinitionname))" class="btn btn-info" style="text-decoration: none !important" target="_new">@Localizer["View License"]</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||||
</div>
|
}
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="runtimes" HelpText="The Blazor runtimes which this module supports" ResourceKey="Runtimes">Runtimes: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="runtimes" class="form-control" @bind="@_runtimes" disabled />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -103,7 +121,7 @@
|
|||||||
<br />
|
<br />
|
||||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
<TabPanel Name="Permissions" ResourceKey="Permissions" Heading="Permissions">
|
||||||
<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.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" PermissionList="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.ModuleDefinition" PermissionNames="@PermissionNames.Utilize" PermissionList="@_permissions" @ref="_permissionGrid" />
|
||||||
@ -113,7 +131,7 @@
|
|||||||
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Translations" ResourceKey="Translations">
|
<TabPanel Name="Translations" ResourceKey="Translations" Heading="Translations">
|
||||||
@if (_languages != null && _languages.Count > 0)
|
@if (_languages != null && _languages.Count > 0)
|
||||||
{
|
{
|
||||||
<Pager Items="@_languages">
|
<Pager Items="@_languages">
|
||||||
@ -190,7 +208,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-success" @onclick="DownloadPackage">@SharedLocalizer["Accept"]</button>
|
<button type="button" class="btn btn-success" @onclick="DownloadTranslation">@SharedLocalizer["Accept"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="HideModal">@SharedLocalizer["Cancel"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="HideModal">@SharedLocalizer["Cancel"]</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -212,11 +230,11 @@
|
|||||||
private string _moduledefinitionname = "";
|
private string _moduledefinitionname = "";
|
||||||
private string _version;
|
private string _version;
|
||||||
private string _packagename = "";
|
private string _packagename = "";
|
||||||
|
private string _packageurl = "";
|
||||||
private string _owner = "";
|
private string _owner = "";
|
||||||
private string _url = "";
|
private string _url = "";
|
||||||
private string _contact = "";
|
private string _contact = "";
|
||||||
private string _license = "";
|
private string _license = "";
|
||||||
private string _runtimes = "";
|
|
||||||
private List<Permission> _permissions = null;
|
private List<Permission> _permissions = null;
|
||||||
private string _createdby;
|
private string _createdby;
|
||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
@ -252,7 +270,6 @@
|
|||||||
_url = moduleDefinition.Url;
|
_url = moduleDefinition.Url;
|
||||||
_contact = moduleDefinition.Contact;
|
_contact = moduleDefinition.Contact;
|
||||||
_license = moduleDefinition.License;
|
_license = moduleDefinition.License;
|
||||||
_runtimes = moduleDefinition.Runtimes;
|
|
||||||
_permissions = moduleDefinition.PermissionList;
|
_permissions = moduleDefinition.PermissionList;
|
||||||
_createdby = moduleDefinition.CreatedBy;
|
_createdby = moduleDefinition.CreatedBy;
|
||||||
_createdon = moduleDefinition.CreatedOn;
|
_createdon = moduleDefinition.CreatedOn;
|
||||||
@ -365,7 +382,7 @@
|
|||||||
var version = _packages.Where(item => item.PackageId == packagename).FirstOrDefault().Version;
|
var version = _packages.Where(item => item.PackageId == packagename).FirstOrDefault().Version;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_package = await PackageService.GetPackageAsync(packagename, version);
|
_package = await PackageService.GetPackageAsync(packagename, version, false);
|
||||||
if (_package != null)
|
if (_package != null)
|
||||||
{
|
{
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@ -383,11 +400,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DownloadPackage()
|
private async Task DownloadTranslation()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_package.PackageId, _package.Version);
|
||||||
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(string.Format(Localizer["Success.Translation.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Translation.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_package = null;
|
_package = null;
|
||||||
@ -399,4 +416,28 @@
|
|||||||
AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Translation.Download"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ValidatePackage()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var package = await PackageService.GetPackageAsync(_packagename, _version, true);
|
||||||
|
if (package == null || string.IsNullOrEmpty(package.PackageUrl))
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Validate"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_packageurl = package.PackageUrl;
|
||||||
|
AddModuleMessage(Localizer["Message.Download"], MessageType.Info);
|
||||||
|
}
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Downloading Package {PackageId} {Version}", _packagename, _version);
|
||||||
|
AddModuleMessage(Localizer["Error.Validate"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Pager Items="@_moduleDefinitions.Where(item => item.Categories.Contains(_category))">
|
<Pager Items="@_moduleDefinitions">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
@ -80,7 +80,7 @@ else
|
|||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@((MarkupString)SupportLink(context.PackageName))
|
@((MarkupString)SupportLink(context.PackageName, context.Version))
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@((MarkupString)PurchaseLink(context.PackageName))
|
@((MarkupString)PurchaseLink(context.PackageName))
|
||||||
@ -99,6 +99,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private List<ModuleDefinition> _allModuleDefinitions;
|
||||||
private List<ModuleDefinition> _moduleDefinitions;
|
private List<ModuleDefinition> _moduleDefinitions;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private List<string> _categories = new List<string>();
|
private List<string> _categories = new List<string>();
|
||||||
@ -110,9 +111,9 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_moduleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
_allModuleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||||
_packages = await PackageService.GetPackagesAsync("module");
|
_categories = _allModuleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
|
||||||
_categories = _moduleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
|
await LoadModuleDefinitions();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -124,6 +125,12 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task LoadModuleDefinitions()
|
||||||
|
{
|
||||||
|
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(_category)).ToList();
|
||||||
|
_packages = await PackageService.GetPackageUpdatesAsync("module");
|
||||||
|
}
|
||||||
|
|
||||||
private string PurchaseLink(string packagename)
|
private string PurchaseLink(string packagename)
|
||||||
{
|
{
|
||||||
string link = "";
|
string link = "";
|
||||||
@ -134,10 +141,13 @@ else
|
|||||||
{
|
{
|
||||||
if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
|
if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
|
||||||
{
|
{
|
||||||
link += "<span>" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</span><br />";
|
if (string.IsNullOrEmpty(package.PaymentUrl))
|
||||||
if (!string.IsNullOrEmpty(package.PaymentUrl))
|
|
||||||
{
|
{
|
||||||
link += " <a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + SharedLocalizer["Extend"] + "</a>";
|
link = "<span>" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</span>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
link = "<a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</a>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,7 +155,7 @@ else
|
|||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string SupportLink(string packagename)
|
private string SupportLink(string packagename, string version)
|
||||||
{
|
{
|
||||||
string link = "";
|
string link = "";
|
||||||
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
||||||
@ -153,7 +163,7 @@ else
|
|||||||
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
||||||
if (package != null && !string.IsNullOrEmpty(package.SupportUrl))
|
if (package != null && !string.IsNullOrEmpty(package.SupportUrl))
|
||||||
{
|
{
|
||||||
link += "<a class=\"btn btn-success\" style=\"text-decoration: none !important\" href=\"" + package.SupportUrl + "\" target=\"_new\">" + SharedLocalizer["Help"] + "</a>";
|
link += "<a class=\"btn btn-info\" style=\"text-decoration: none !important\" href=\"" + package.SupportUrl.Replace("{Version}", version) + "\" target=\"_new\">" + SharedLocalizer["Help"] + "</a>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return link;
|
return link;
|
||||||
@ -176,7 +186,7 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packagename, version);
|
||||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
@ -202,9 +212,9 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CategoryChanged(ChangeEventArgs e)
|
private async Task CategoryChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_category = (string)e.Value;
|
_category = (string)e.Value;
|
||||||
StateHasChanged();
|
await LoadModuleDefinitions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||||
public override string Title => "Export Content";
|
public override string Title => "Export Content";
|
||||||
|
|
||||||
|
|
||||||
private async Task ExportModule()
|
private async Task ExportModule()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -26,6 +26,17 @@
|
|||||||
<input id="title" type="text" class="form-control" @bind="@_title" required />
|
<input id="title" type="text" class="form-control" @bind="@_title" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="pane" HelpText="The pane where the module will be displayed" ResourceKey="Pane">Pane: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select class="form-select" @bind="@_pane">
|
||||||
|
@foreach (string pane in PageState.Page.Panes)
|
||||||
|
{
|
||||||
|
<option value="@pane">@pane Pane</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="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
|
<Label Class="col-sm-3" For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -112,6 +123,7 @@
|
|||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _module;
|
private string _module;
|
||||||
private string _title;
|
private string _title;
|
||||||
|
private string _pane;
|
||||||
private string _containerType;
|
private string _containerType;
|
||||||
private string _allPages = "false";
|
private string _allPages = "false";
|
||||||
private string _permissionNames = "";
|
private string _permissionNames = "";
|
||||||
@ -134,6 +146,7 @@
|
|||||||
{
|
{
|
||||||
_module = ModuleState.ModuleDefinition.Name;
|
_module = ModuleState.ModuleDefinition.Name;
|
||||||
_title = ModuleState.Title;
|
_title = ModuleState.Title;
|
||||||
|
_pane = ModuleState.Pane;
|
||||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, PageState.Page.ThemeType);
|
||||||
_containerType = ModuleState.ContainerType;
|
_containerType = ModuleState.ContainerType;
|
||||||
_allPages = ModuleState.AllPages.ToString();
|
_allPages = ModuleState.AllPages.ToString();
|
||||||
@ -206,6 +219,7 @@
|
|||||||
var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
var pagemodule = await PageModuleService.GetPageModuleAsync(ModuleState.PageModuleId);
|
||||||
pagemodule.PageId = int.Parse(_pageId);
|
pagemodule.PageId = int.Parse(_pageId);
|
||||||
pagemodule.Title = _title;
|
pagemodule.Title = _title;
|
||||||
|
pagemodule.Pane = _pane;
|
||||||
pagemodule.ContainerType = (_containerType != "-") ? _containerType : string.Empty;
|
pagemodule.ContainerType = (_containerType != "-") ? _containerType : string.Empty;
|
||||||
if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Page.DefaultContainerType)
|
if (!string.IsNullOrEmpty(pagemodule.ContainerType) && pagemodule.ContainerType == PageState.Page.DefaultContainerType)
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IPageService PageService
|
@inject IPageService PageService
|
||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
|
@inject ISystemService SystemService
|
||||||
@inject IStringLocalizer<Add> Localizer
|
@inject IStringLocalizer<Add> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@ -10,7 +11,7 @@
|
|||||||
{
|
{
|
||||||
<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" Heading="Settings">
|
||||||
<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>
|
||||||
@ -39,9 +40,9 @@
|
|||||||
<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>
|
<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">
|
<div class="col-sm-9">
|
||||||
<select id="insert" class="form-select" @bind="@_insert" required>
|
<select id="insert" class="form-select" @bind="@_insert" required>
|
||||||
<option value="<<">@Localizer["AtBeginning"]</option>
|
|
||||||
@if (_children != null && _children.Count > 0)
|
@if (_children != null && _children.Count > 0)
|
||||||
{
|
{
|
||||||
|
<option value="<<">@Localizer["AtBeginning"]</option>
|
||||||
<option value="<">@Localizer["Before"]</option>
|
<option value="<">@Localizer["Before"]</option>
|
||||||
<option value=">">@Localizer["After"]</option>
|
<option value=">">@Localizer["After"]</option>
|
||||||
}
|
}
|
||||||
@ -111,8 +112,11 @@
|
|||||||
</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-8">
|
||||||
<input id="icon" class="form-control" @bind="@_icon" />
|
<InputList Value="@_icon" ValueChanged="IconChanged" DataList="@_icons" ResourceKey="Icon" ResourceType="@_iconresources" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<i class="@_icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -126,7 +130,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
<Section Name="Appearance" ResourceKey="Appearance" Heading=@Localizer["Appearance.Name"]>
|
||||||
<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="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>
|
<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>
|
||||||
@ -158,7 +162,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
<Section Name="PageContent" Heading="Page Content" ResourceKey="PageContent">
|
<Section Name="PageContent" ResourceKey="PageContent" Heading=@Localizer["PageContent.Heading"]>
|
||||||
<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="headcontent" HelpText="Optionally enter content to be included in the page head (ie. meta, link, or script tags)" ResourceKey="HeadContent">Head Content: </Label>
|
<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>
|
||||||
@ -175,7 +179,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Permissions" ResourceKey="Permissions">
|
<TabPanel Name="Permissions" ResourceKey="Permissions" Heading=@Localizer["Permissions.Heading"]>
|
||||||
<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" Permissions="@_permissions" @ref="_permissionGrid" />
|
<PermissionGrid EntityName="@EntityNames.Page" Permissions="@_permissions" @ref="_permissionGrid" />
|
||||||
@ -184,7 +188,7 @@
|
|||||||
</TabPanel>
|
</TabPanel>
|
||||||
@if (_themeSettingsType != null)
|
@if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
<TabPanel Name="ThemeSettings" Heading=@Localizer["Theme.Heading"] ResourceKey="ThemeSettings">
|
||||||
@ThemeSettingsComponent
|
@ThemeSettingsComponent
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
}
|
}
|
||||||
@ -227,6 +231,8 @@
|
|||||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
private RenderFragment ThemeSettingsComponent { get; set; }
|
||||||
private bool _refresh = false;
|
private bool _refresh = false;
|
||||||
protected Page _parent = null;
|
protected Page _parent = null;
|
||||||
|
protected Dictionary<string, string> _icons;
|
||||||
|
private string _iconresources = "";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
@ -241,6 +247,8 @@
|
|||||||
_parentid = _parent.PageId.ToString();
|
_parentid = _parent.PageId.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_icons = await SystemService.GetIconsAsync();
|
||||||
|
_iconresources = typeof(IconResources).FullName;
|
||||||
|
|
||||||
// if admin or user has edit access to parent page
|
// 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)))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin) || (_parent != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _parent.PermissionList)))
|
||||||
@ -249,7 +257,14 @@
|
|||||||
_themes = ThemeService.GetThemeControls(PageState.Site.Themes);
|
_themes = ThemeService.GetThemeControls(PageState.Site.Themes);
|
||||||
_containers = ThemeService.GetContainerControls(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 = new List<Page>();
|
||||||
|
foreach (Page p in PageState.Pages.Where(item => (_parentid == "-1" && item.ParentId == null) || (item.ParentId == int.Parse(_parentid))))
|
||||||
|
{
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
|
{
|
||||||
|
_children.Add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
ThemeSettings();
|
ThemeSettings();
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
@ -272,26 +287,13 @@
|
|||||||
{
|
{
|
||||||
_parentid = (string)e.Value;
|
_parentid = (string)e.Value;
|
||||||
_children = new List<Page>();
|
_children = new List<Page>();
|
||||||
if (_parentid == "-1")
|
foreach (Page p in PageState.Pages.Where(item => (_parentid == "-1" && item.ParentId == null) || (item.ParentId == int.Parse(_parentid))))
|
||||||
{
|
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
|
||||||
{
|
{
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
{
|
||||||
_children.Add(p);
|
_children.Add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
|
||||||
{
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
|
||||||
{
|
|
||||||
_children.Add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -482,4 +484,8 @@
|
|||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void IconChanged(string NewIcon)
|
||||||
|
{
|
||||||
|
_icon = NewIcon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
@inject IPageService PageService
|
@inject IPageService PageService
|
||||||
@inject IPageModuleService PageModuleService
|
@inject IPageModuleService PageModuleService
|
||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
|
@inject ISystemService SystemService
|
||||||
@inject IStringLocalizer<Edit> Localizer
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@ -14,7 +15,7 @@
|
|||||||
@if (_page.UserId == null)
|
@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="Settings">
|
||||||
<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>
|
||||||
@ -47,13 +48,16 @@
|
|||||||
{
|
{
|
||||||
<option value="="><@Localizer["ThisLocation.Keep"]></option>
|
<option value="="><@Localizer["ThisLocation.Keep"]></option>
|
||||||
}
|
}
|
||||||
<option value="<<">@Localizer["ToBeginning"]</option>
|
|
||||||
@if (_children != null && _children.Count > 0)
|
@if (_children != null && _children.Count > 0)
|
||||||
{
|
{
|
||||||
|
<option value="<<">@Localizer["ToBeginning"]</option>
|
||||||
<option value="<">@Localizer["Before"]</option>
|
<option value="<">@Localizer["Before"]</option>
|
||||||
<option value=">">@Localizer["After"]</option>
|
<option value=">">@Localizer["After"]</option>
|
||||||
}
|
}
|
||||||
|
@if (_parentid != _currentparentid)
|
||||||
|
{
|
||||||
<option value=">>">@Localizer["ToEnd"]</option>
|
<option value=">>">@Localizer["ToEnd"]</option>
|
||||||
|
}
|
||||||
</select>
|
</select>
|
||||||
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
|
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
|
||||||
{
|
{
|
||||||
@ -123,8 +127,11 @@
|
|||||||
</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-8">
|
||||||
<input id="icon" class="form-control" @bind="@_icon" maxlength="50" />
|
<InputList Value="@_icon" ValueChanged="IconChanged" DataList="@_icons" ResourceKey="Icon" ResourceType="@_iconresources" />
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-1">
|
||||||
|
<i class="@_icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -137,7 +144,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Section Name="Appearance" ResourceKey="Appearance">
|
<Section Name="Appearance" ResourceKey="Appearance" Heading="Appearance">
|
||||||
<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="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>
|
<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>
|
||||||
@ -189,7 +196,7 @@
|
|||||||
<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" Heading="Permissions">
|
||||||
<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" />
|
||||||
@ -205,7 +212,7 @@
|
|||||||
<th>@Localizer["ModuleDefinition"]</th>
|
<th>@Localizer["ModuleDefinition"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Settings" Text="Edit" ModuleId="@context.ModuleId" Security="SecurityAccessLevel.Edit" PermissionList="@context.PermissionList" ResourceKey="ModuleSettings" /></td>
|
<td><ActionLink Action="Settings" Text="Edit" Path="@_actualpath" ModuleId="@context.ModuleId" Security="SecurityAccessLevel.Edit" PermissionList="@context.PermissionList" ResourceKey="ModuleSettings" /></td>
|
||||||
<td><ActionDialog Header="Delete Module" Message="Are You Sure You Wish To Delete This Module?" Action="Delete" Security="SecurityAccessLevel.Edit" PermissionList="@context.PermissionList" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
|
<td><ActionDialog Header="Delete Module" Message="Are You Sure You Wish To Delete This Module?" Action="Delete" Security="SecurityAccessLevel.Edit" PermissionList="@context.PermissionList" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
|
||||||
<td>@context.Title</td>
|
<td>@context.Title</td>
|
||||||
<td>@context.ModuleDefinition?.Name</td>
|
<td>@context.ModuleDefinition?.Name</td>
|
||||||
@ -224,7 +231,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<TabStrip Refresh="@_refresh">
|
<TabStrip Refresh="@_refresh">
|
||||||
<TabPanel Name="Settings" ResourceKey="Settings" Heading=@Localizer["Settings.Heading"]>
|
<TabPanel Name="Settings" ResourceKey="Settings" Heading="Settings">
|
||||||
<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="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>
|
<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>
|
||||||
@ -288,6 +295,7 @@
|
|||||||
private int _childid = -1;
|
private int _childid = -1;
|
||||||
private string _isnavigation;
|
private string _isnavigation;
|
||||||
private string _isclickable;
|
private string _isclickable;
|
||||||
|
private string _actualpath;
|
||||||
private string _path;
|
private string _path;
|
||||||
private string _url;
|
private string _url;
|
||||||
private string _ispersonalizable;
|
private string _ispersonalizable;
|
||||||
@ -312,14 +320,17 @@
|
|||||||
private bool _refresh = false;
|
private bool _refresh = false;
|
||||||
protected Page _page = null;
|
protected Page _page = null;
|
||||||
protected Page _parent = null;
|
protected Page _parent = null;
|
||||||
|
protected Dictionary<string, string> _icons;
|
||||||
|
private string _iconresources = "";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_children = PageState.Pages.Where(item => item.ParentId == null).ToList();
|
|
||||||
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
_pageId = Int32.Parse(PageState.QueryString["id"]);
|
||||||
_page = await PageService.GetPageAsync(_pageId);
|
_page = await PageService.GetPageAsync(_pageId);
|
||||||
|
_icons = await SystemService.GetIconsAsync();
|
||||||
|
_iconresources = Utilities.GetFullTypeName(typeof(IconResources).AssemblyQualifiedName);
|
||||||
|
|
||||||
if (_page != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _page.PermissionList))
|
if (_page != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, _page.PermissionList))
|
||||||
{
|
{
|
||||||
@ -333,10 +344,19 @@
|
|||||||
_parentid = _page.ParentId.ToString();
|
_parentid = _page.ParentId.ToString();
|
||||||
_parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId);
|
_parent = PageState.Pages.FirstOrDefault(item => item.PageId == _page.ParentId);
|
||||||
}
|
}
|
||||||
|
_children = new List<Page>();
|
||||||
|
foreach (Page p in PageState.Pages.Where(item => (_parentid == "-1" && item.ParentId == null) || (item.ParentId == int.Parse(_parentid))))
|
||||||
|
{
|
||||||
|
if (p.PageId != _pageId && UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
|
{
|
||||||
|
_children.Add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
_currentparentid = _parentid;
|
_currentparentid = _parentid;
|
||||||
_isnavigation = _page.IsNavigation.ToString();
|
_isnavigation = _page.IsNavigation.ToString();
|
||||||
_isclickable = _page.IsClickable.ToString();
|
_isclickable = _page.IsClickable.ToString();
|
||||||
_path = _page.Path;
|
_actualpath = _page.Path;
|
||||||
|
_path = _actualpath;
|
||||||
if (string.IsNullOrEmpty(_path))
|
if (string.IsNullOrEmpty(_path))
|
||||||
{
|
{
|
||||||
_path = "/";
|
_path = "/";
|
||||||
@ -355,7 +375,7 @@
|
|||||||
// appearance
|
// appearance
|
||||||
_title = _page.Title;
|
_title = _page.Title;
|
||||||
_themetype = _page.ThemeType;
|
_themetype = _page.ThemeType;
|
||||||
if (string.IsNullOrEmpty(_themetype) || ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName)
|
if (string.IsNullOrEmpty(_themetype))
|
||||||
{
|
{
|
||||||
_themetype = PageState.Site.DefaultThemeType;
|
_themetype = PageState.Site.DefaultThemeType;
|
||||||
}
|
}
|
||||||
@ -407,34 +427,14 @@
|
|||||||
{
|
{
|
||||||
_parentid = (string)e.Value;
|
_parentid = (string)e.Value;
|
||||||
_children = new List<Page>();
|
_children = new List<Page>();
|
||||||
if (_parentid == "-1")
|
foreach (Page p in PageState.Pages.Where(item => (_parentid == "-1" && item.ParentId == null) || (item.ParentId == int.Parse(_parentid))))
|
||||||
{
|
{
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == null))
|
if (p.PageId != _pageId && UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
||||||
{
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
|
||||||
{
|
{
|
||||||
_children.Add(p);
|
_children.Add(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
_insert = (_parentid == _currentparentid) ? "=" : ">>";
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (Page p in PageState.Pages.Where(item => item.ParentId == int.Parse(_parentid)))
|
|
||||||
{
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.PermissionList))
|
|
||||||
{
|
|
||||||
_children.Add(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (_parentid == _currentparentid)
|
|
||||||
{
|
|
||||||
_insert = "=";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_insert = ">>";
|
|
||||||
}
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -660,4 +660,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void IconChanged(string NewIcon)
|
||||||
|
{
|
||||||
|
_icon = NewIcon;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add Page" ResourceKey="AddPage" />
|
<ActionLink Action="Add" Text="Add Page" ResourceKey="AddPage" />
|
||||||
|
|
||||||
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)">
|
<Pager Items="@PageState.Pages.Where(item => !item.IsDeleted)" SearchProperties="Name">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
|
<Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea id="description" class="form-control" @bind="@_description" rows="5" maxlength="256" required ></textarea>
|
<textarea id="description" class="form-control" @bind="@_description" rows="3" maxlength="256" required></textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -34,13 +34,19 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label>
|
<Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="order" class="form-control" @bind="@_vieworder" maxlength="4" required />
|
<input id="order" class="form-control" @bind="@_vieworder" min="0" max="99" type="number" required />
|
||||||
</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="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label>
|
<Label Class="col-sm-3" For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="length" class="form-control" @bind="@_maxlength" maxlength="4" required />
|
<input id="length" class="form-control" @bind="@_maxlength" min="0" max="524288" type="number" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="rows" HelpText="The number of rows for text entry (one is the default)" ResourceKey="Rows">Rows: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="rows" class="form-control" @bind="@_rows" min="1" max="10" type="number" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -101,6 +107,7 @@
|
|||||||
private string _category = string.Empty;
|
private string _category = string.Empty;
|
||||||
private string _vieworder = "0";
|
private string _vieworder = "0";
|
||||||
private string _maxlength = "0";
|
private string _maxlength = "0";
|
||||||
|
private string _rows = "1";
|
||||||
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 _validation = string.Empty;
|
||||||
@ -131,6 +138,7 @@
|
|||||||
_category = profile.Category;
|
_category = profile.Category;
|
||||||
_vieworder = profile.ViewOrder.ToString();
|
_vieworder = profile.ViewOrder.ToString();
|
||||||
_maxlength = profile.MaxLength.ToString();
|
_maxlength = profile.MaxLength.ToString();
|
||||||
|
_rows = profile.Rows.ToString();
|
||||||
_defaultvalue = profile.DefaultValue;
|
_defaultvalue = profile.DefaultValue;
|
||||||
_options = profile.Options;
|
_options = profile.Options;
|
||||||
_validation = profile.Validation;
|
_validation = profile.Validation;
|
||||||
@ -175,6 +183,7 @@
|
|||||||
profile.Category = _category;
|
profile.Category = _category;
|
||||||
profile.ViewOrder = int.Parse(_vieworder);
|
profile.ViewOrder = int.Parse(_vieworder);
|
||||||
profile.MaxLength = int.Parse(_maxlength);
|
profile.MaxLength = int.Parse(_maxlength);
|
||||||
|
profile.Rows = int.Parse(_rows);
|
||||||
profile.DefaultValue = _defaultvalue;
|
profile.DefaultValue = _defaultvalue;
|
||||||
profile.Options = _options;
|
profile.Options = _options;
|
||||||
profile.Validation = _validation;
|
profile.Validation = _validation;
|
||||||
|
@ -12,16 +12,22 @@ else
|
|||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add Profile" Security="SecurityAccessLevel.Edit" ResourceKey="AddProfile" />
|
<ActionLink Action="Add" Text="Add Profile" Security="SecurityAccessLevel.Edit" ResourceKey="AddProfile" />
|
||||||
|
|
||||||
<Pager Items="@_profiles">
|
<Pager Items="@_profiles" SearchProperties="Title,Category">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
|
<th>@Localizer["Title"]</th>
|
||||||
|
<th>@Localizer["Category"]</th>
|
||||||
|
<th>@Localizer["Order"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ProfileId.ToString())" Security="SecurityAccessLevel.Edit" ResourceKey="EditProfile" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ProfileId.ToString())" Security="SecurityAccessLevel.Edit" ResourceKey="EditProfile" /></td>
|
||||||
<td><ActionDialog Header="Delete Profile" Message="@string.Format(Localizer["Confirm.Profile.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await DeleteProfile(context.ProfileId))" ResourceKey="DeleteProfile" /></td>
|
<td><ActionDialog Header="Delete Profile" Message="@string.Format(Localizer["Confirm.Profile.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await DeleteProfile(context.ProfileId))" ResourceKey="DeleteProfile" /></td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
|
<td>@context.Title</td>
|
||||||
|
<td>@context.Category</td>
|
||||||
|
<td>@context.ViewOrder</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Pages" ResourceKey="Pages">
|
<TabPanel Name="Pages" ResourceKey="Pages" Heading="Pages">
|
||||||
@if (!_pages.Where(item => item.IsDeleted).Any())
|
@if (!_pages.Where(item => item.IsDeleted).Any())
|
||||||
{
|
{
|
||||||
<br />
|
<br />
|
||||||
@ -31,7 +31,7 @@ else
|
|||||||
<th>@Localizer["DeletedOn"]</th>
|
<th>@Localizer["DeletedOn"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><button type="button" @onclick="@(() => RestorePage(context))" class="btn btn-success" title="Restore">Restore</button></td>
|
<td><button type="button" @onclick="@(() => RestorePage(context))" class="btn btn-success" title="Restore">@Localizer["Restore"]</button></td>
|
||||||
<td><ActionDialog Header="Delete Page" Message="@string.Format(Localizer["Confirm.Page.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
|
<td><ActionDialog Header="Delete Page" Message="@string.Format(Localizer["Confirm.Page.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.DeletedBy</td>
|
<td>@context.DeletedBy</td>
|
||||||
@ -42,7 +42,7 @@ else
|
|||||||
<ActionDialog Header="Remove All Deleted Pages" Message="Are You Sure You Wish To Permanently Remove All Deleted Pages?" Action="Remove All Deleted Pages" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllPages())" ResourceKey="DeleteAllPages" />
|
<ActionDialog Header="Remove All Deleted Pages" Message="Are You Sure You Wish To Permanently Remove All Deleted Pages?" Action="Remove All Deleted Pages" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllPages())" ResourceKey="DeleteAllPages" />
|
||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Modules" ResourceKey="Modules">
|
<TabPanel Name="Modules" ResourceKey="Modules" Heading="Modules">
|
||||||
@if (!_modules.Where(item => item.IsDeleted).Any())
|
@if (!_modules.Where(item => item.IsDeleted).Any())
|
||||||
{
|
{
|
||||||
<br />
|
<br />
|
||||||
|
@ -16,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="@_passwordconstruction" Type="MessageType.Info" />
|
<ModuleMessage Message="@_passwordrequirements" 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">
|
||||||
@ -69,6 +69,7 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string _passwordrequirements;
|
||||||
private string _username = string.Empty;
|
private string _username = string.Empty;
|
||||||
private ElementReference form;
|
private ElementReference form;
|
||||||
private bool validated = false;
|
private bool validated = false;
|
||||||
@ -79,44 +80,16 @@ 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()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(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()
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
|
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
|
||||||
<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="username" HelpText="Your username will be populated from the link you received in the password reset notification" ResourceKey="Username">Username: </Label>
|
<Label Class="col-sm-3" For="username" HelpText="Your username will be populated from the link you received in the password reset notification" ResourceKey="Username">Username: </Label>
|
||||||
@ -45,12 +46,14 @@
|
|||||||
private string _passwordtype = "password";
|
private string _passwordtype = "password";
|
||||||
private string _togglepassword = string.Empty;
|
private string _togglepassword = string.Empty;
|
||||||
private string _confirm = string.Empty;
|
private string _confirm = string.Empty;
|
||||||
|
private string _passwordrequirements;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token"))
|
if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token"))
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@ else
|
|||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add Role" Security="SecurityAccessLevel.Edit" ResourceKey="AddRole" />
|
<ActionLink Action="Add" Text="Add Role" Security="SecurityAccessLevel.Edit" ResourceKey="AddRole" />
|
||||||
|
|
||||||
<Pager Items="@_roles">
|
<Pager Items="@_roles" SearchProperties="Name">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<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">
|
||||||
<select id="homepage" class="form-select" @bind="@_homepageid" required>
|
<select id="homepage" class="form-select" @bind="@_homepageid" required>
|
||||||
<option value="-"><@Localizer["Not Specified"]></option>
|
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
||||||
@foreach (Page page in PageState.Pages)
|
@foreach (Page page in PageState.Pages)
|
||||||
{
|
{
|
||||||
if (UserSecurity.ContainsRole(page.PermissionList, PermissionNames.View, RoleNames.Everyone))
|
if (UserSecurity.ContainsRole(page.PermissionList, PermissionNames.View, RoleNames.Everyone))
|
||||||
@ -49,7 +49,16 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing" ResourceKey="SiteMap">Site Map: </Label>
|
<Label Class="col-sm-3" For="sitemap" HelpText="The site map url for this site which can be submitted to search engines for indexing" ResourceKey="SiteMap">Site Map: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="sitemap" class="form-control" @bind="@_sitemap" required disabled />
|
<div class="input-group">
|
||||||
|
<input id="sitemap" class="form-control" @bind="@_sitemap" disabled />
|
||||||
|
<a href="@_sitemap" class="btn btn-secondary" target="_new">@Localizer["Browse"]</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="siteguid" HelpText="The Unique Identifier For The Site" ResourceKey="SiteGuid">ID: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="siteguid" class="form-control" @bind="@_siteguid" required disabled />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -60,7 +69,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<Section Name="Appearance" ResourceKey="Appearance">
|
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
||||||
<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="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||||
@ -257,7 +266,7 @@
|
|||||||
<td>
|
<td>
|
||||||
@if (_aliasid == -1)
|
@if (_aliasid == -1)
|
||||||
{
|
{
|
||||||
<ActionDialog Action="Delete" OnClick="@(async () => await DeleteAlias(context))" ResourceKey="DeleteModule" Class="btn btn-danger" Header="Delete Alias" Message="@string.Format(Localizer["Confirm.Alias.Delete", context.Name])" />
|
<ActionDialog Action="Delete" OnClick="@(async () => await DeleteAlias(context))" ResourceKey="DeleteAlias" Class="btn btn-danger" Header="Delete Alias" Message="@string.Format(Localizer["Confirm.Alias.Delete", context.Name])" />
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
@ -348,6 +357,7 @@
|
|||||||
private string _homepageid = "-";
|
private string _homepageid = "-";
|
||||||
private string _isdeleted;
|
private string _isdeleted;
|
||||||
private string _sitemap = "";
|
private string _sitemap = "";
|
||||||
|
private string _siteguid = "";
|
||||||
private string _version = "";
|
private string _version = "";
|
||||||
private int _logofileid = -1;
|
private int _logofileid = -1;
|
||||||
private FileManager _logofilemanager;
|
private FileManager _logofilemanager;
|
||||||
@ -406,6 +416,7 @@
|
|||||||
}
|
}
|
||||||
_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";
|
||||||
|
_siteguid = site.SiteGuid;
|
||||||
_version = site.Version;
|
_version = site.Version;
|
||||||
|
|
||||||
// appearance
|
// appearance
|
||||||
@ -610,6 +621,7 @@
|
|||||||
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, "SMTPEnabled", _smtpenabled, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "SiteGuid", _siteguid, 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);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ else
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the default theme for the website" ResourceKey="DefaultTheme">Default Theme: </Label>
|
<Label Class="col-sm-3" For="defaultTheme" HelpText="Select the default theme for the website" ResourceKey="DefaultTheme">Default Theme: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="defaultTheme" class="form-select" @onchange="(e => ThemeChanged(e))" required>
|
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))" required>
|
||||||
<option value="-"><@Localizer["Theme.Select"]></option>
|
<option value="-"><@Localizer["Theme.Select"]></option>
|
||||||
@foreach (var theme in _themes)
|
@foreach (var theme in _themes)
|
||||||
{
|
{
|
||||||
@ -58,19 +58,6 @@ else
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="adminContainer" HelpText="Select the admin container for the site" ResourceKey="AdminContainer">Admin Container: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="adminContainer" class="form-select" @bind="@_admincontainertype" required>
|
|
||||||
<option value="-"><@Localizer["Container.Select"]></option>
|
|
||||||
<option value=""><@Localizer["DefaultContainer.Admin"]></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="siteTemplate" HelpText="Select the site template" ResourceKey="SiteTemplate">Site Template: </Label>
|
<Label Class="col-sm-3" For="siteTemplate" HelpText="Select the site template" ResourceKey="SiteTemplate">Site Template: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -105,7 +92,7 @@ else
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="tenant" HelpText="Select the database for the site" ResourceKey="Tenant">Database: </Label>
|
<Label Class="col-sm-3" For="tenant" HelpText="Select the database for the site" ResourceKey="Tenant">Database: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="tenant" class="form-select" @onchange="(e => TenantChanged(e))" required>
|
<select id="tenant" class="form-select" value="@_tenantid" @onchange="(e => TenantChanged(e))" required>
|
||||||
<option value="-"><@Localizer["Tenant.Select"]></option>
|
<option value="-"><@Localizer["Tenant.Select"]></option>
|
||||||
<option value="+"><@Localizer["Tenant.Add"]></option>
|
<option value="+"><@Localizer["Tenant.Add"]></option>
|
||||||
@foreach (Tenant tenant in _tenants)
|
@foreach (Tenant tenant in _tenants)
|
||||||
@ -214,7 +201,6 @@ else
|
|||||||
private string _urls = string.Empty;
|
private string _urls = string.Empty;
|
||||||
private string _themetype = "-";
|
private string _themetype = "-";
|
||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
private string _admincontainertype = "";
|
|
||||||
private string _sitetemplatetype = "-";
|
private string _sitetemplatetype = "-";
|
||||||
private string _runtime = "Server";
|
private string _runtime = "Server";
|
||||||
private string _prerender = "Prerendered";
|
private string _prerender = "Prerendered";
|
||||||
@ -224,10 +210,24 @@ else
|
|||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_tenants = await TenantService.GetTenantsAsync();
|
_tenants = await TenantService.GetTenantsAsync();
|
||||||
|
if (_tenants.Any(item => item.Name == TenantNames.Master))
|
||||||
|
{
|
||||||
|
_tenantid = _tenants.First(item => item.Name == TenantNames.Master).TenantId.ToString();
|
||||||
|
}
|
||||||
_urls = PageState.Alias.Name;
|
_urls = PageState.Alias.Name;
|
||||||
_themeList = await ThemeService.GetThemesAsync();
|
_themeList = await ThemeService.GetThemesAsync();
|
||||||
_themes = ThemeService.GetThemeControls(_themeList);
|
_themes = ThemeService.GetThemeControls(_themeList);
|
||||||
|
if (_themes.Any(item => item.TypeName == Constants.DefaultTheme))
|
||||||
|
{
|
||||||
|
_themetype = Constants.DefaultTheme;
|
||||||
|
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
|
||||||
|
_containertype = _containers.First().TypeName;
|
||||||
|
}
|
||||||
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
|
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
|
||||||
|
if (_siteTemplates.Any(item => item.TypeName == Constants.DefaultSiteTemplate))
|
||||||
|
{
|
||||||
|
_sitetemplatetype = Constants.DefaultSiteTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
_databases = await DatabaseService.GetDatabasesAsync();
|
_databases = await DatabaseService.GetDatabasesAsync();
|
||||||
if (_databases.Exists(item => item.IsDefault))
|
if (_databases.Exists(item => item.IsDefault))
|
||||||
@ -295,7 +295,6 @@ else
|
|||||||
_containers = new List<ThemeControl>();
|
_containers = new List<ThemeControl>();
|
||||||
_containertype = "-";
|
_containertype = "-";
|
||||||
}
|
}
|
||||||
_admincontainertype = "";
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -399,7 +398,7 @@ else
|
|||||||
config.Aliases = _urls;
|
config.Aliases = _urls;
|
||||||
config.DefaultTheme = _themetype;
|
config.DefaultTheme = _themetype;
|
||||||
config.DefaultContainer = _containertype;
|
config.DefaultContainer = _containertype;
|
||||||
config.DefaultAdminContainer = _admincontainertype;
|
config.DefaultAdminContainer = "";
|
||||||
config.SiteTemplate = _sitetemplatetype;
|
config.SiteTemplate = _sitetemplatetype;
|
||||||
config.Runtime = _runtime;
|
config.Runtime = _runtime;
|
||||||
config.RenderMode = _runtime + _prerender;
|
config.RenderMode = _runtime + _prerender;
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
@if (_sites == null)
|
@if (_sites == null)
|
||||||
{
|
{
|
||||||
<p><em>Loading...</em></p>
|
<p><em>@SharedLocalizer["Loading"]</em></p>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Add Site" ResourceKey="AddSite" />
|
<ActionLink Action="Add" Text="Add Site" ResourceKey="AddSite" />
|
||||||
|
|
||||||
<Pager Items="@_sites">
|
<Pager Items="@_sites" SearchProperties="Name">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
@ -133,12 +133,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="packageservice" HelpText="Specify If The Package Service Is Enabled For Installing Modules, Themes, And Translations" ResourceKey="PackageService">Enable Package Service? </Label>
|
<Label Class="col-sm-3" For="packageregistryurl" HelpText="Specify The Package Manager Service For Installing Modules, Themes, And Translations. If This Field Is Blank It Means The Package Manager Service Is Disabled For This Installation." ResourceKey="PackageManager">Package Manager: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="packageservice" class="form-select" @bind="@_packageservice">
|
<input id="packageregistryurl" class="form-control" @bind="@_packageregistryurl" />
|
||||||
<option value="true">@SharedLocalizer["True"]</option>
|
|
||||||
<option value="false">@SharedLocalizer["False"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -182,7 +179,7 @@
|
|||||||
private string _logginglevel = string.Empty;
|
private string _logginglevel = string.Empty;
|
||||||
private string _notificationlevel = string.Empty;
|
private string _notificationlevel = string.Empty;
|
||||||
private string _swagger = string.Empty;
|
private string _swagger = string.Empty;
|
||||||
private string _packageservice = string.Empty;
|
private string _packageregistryurl = string.Empty;
|
||||||
|
|
||||||
private string _log = string.Empty;
|
private string _log = string.Empty;
|
||||||
|
|
||||||
@ -213,7 +210,7 @@
|
|||||||
_logginglevel = systeminfo["Logging:LogLevel:Default"].ToString();
|
_logginglevel = systeminfo["Logging:LogLevel:Default"].ToString();
|
||||||
_notificationlevel = systeminfo["Logging:LogLevel:Notify"].ToString();
|
_notificationlevel = systeminfo["Logging:LogLevel:Notify"].ToString();
|
||||||
_swagger = systeminfo["UseSwagger"].ToString();
|
_swagger = systeminfo["UseSwagger"].ToString();
|
||||||
_packageservice = systeminfo["PackageService"].ToString();
|
_packageregistryurl = systeminfo["PackageRegistryUrl"].ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
systeminfo = await SystemService.GetSystemInfoAsync("log");
|
systeminfo = await SystemService.GetSystemInfoAsync("log");
|
||||||
@ -232,7 +229,7 @@
|
|||||||
settings.Add("Logging:LogLevel:Default", _logginglevel);
|
settings.Add("Logging:LogLevel:Default", _logginglevel);
|
||||||
settings.Add("Logging:LogLevel:Notify", _notificationlevel);
|
settings.Add("Logging:LogLevel:Notify", _notificationlevel);
|
||||||
settings.Add("UseSwagger", _swagger);
|
settings.Add("UseSwagger", _swagger);
|
||||||
settings.Add("PackageService", _packageservice);
|
settings.Add("PackageRegistryUrl", _packageregistryurl);
|
||||||
await SystemService.UpdateSystemInfoAsync(settings);
|
await SystemService.UpdateSystemInfoAsync(settings);
|
||||||
AddModuleMessage(Localizer["Success.UpdateConfig.Restart"], MessageType.Success);
|
AddModuleMessage(Localizer["Success.UpdateConfig.Restart"], MessageType.Success);
|
||||||
}
|
}
|
||||||
|
@ -10,61 +10,115 @@
|
|||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Download" ResourceKey="Download">
|
<TabPanel Name="Download" ResourceKey="Download">
|
||||||
<div class="row justify-content-center mb-3">
|
<div class="row justify-content-center mb-3">
|
||||||
<div class="col-sm-6">
|
<div class="text-center">
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="free" class="form-check-input" type="radio" checked="@(_price == "free")" name="Price" @onchange="@(() => PriceChanged("free"))" />
|
||||||
|
<label class="form-check-label" for="free">@SharedLocalizer["Free"]</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input id="paid" class="form-check-input" type="radio" checked="@(_price == "paid")" name="Price" @onchange="@(() => PriceChanged("paid"))" />
|
||||||
|
<label class="form-check-label" for="paid">@SharedLocalizer["Paid"]</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row justify-content-center mb-3">
|
||||||
|
<div class="col">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<select id="price" class="form-select custom-select" @onchange="(e => PriceChanged(e))">
|
<span class="input-group-text">@Localizer["Product"]</span>
|
||||||
<option value="free">@SharedLocalizer["Free"]</option>
|
|
||||||
<option value="paid">@SharedLocalizer["Paid"]</option>
|
|
||||||
</select>
|
|
||||||
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
|
||||||
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||||
|
<button type="button" class="btn btn-primary ms-2" @onclick="Refresh"><span class="@Icons.Reload" aria-hidden="true"></span></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-3">
|
||||||
@if (_packages != null)
|
<div class="col">
|
||||||
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
if (_packages.Count > 0)
|
<br />
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<h3>@((_packages != null) ? _packages.Count : 0) @SharedLocalizer["Search.Results"]</h3>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select class="form-select" value="@_sort" @onchange="(e => SortChanged(e))">
|
||||||
|
<option value="popularity">@SharedLocalizer["Search.Popularity"]</option>
|
||||||
|
<option value="alphabetical">@SharedLocalizer["Search.Alphabetical"]</option>
|
||||||
|
@if (_price == "free")
|
||||||
{
|
{
|
||||||
<Pager Items="@_packages">
|
<option value="downloads">@SharedLocalizer["Search.Downloads"]</option>
|
||||||
<Row>
|
|
||||||
<td>
|
|
||||||
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3> @SharedLocalizer["Search.By"]: <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
|
||||||
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
|
||||||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
|
||||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
|
||||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
|
||||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
|
||||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
|
||||||
</td>
|
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PackageUrl))
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
|
||||||
}
|
}
|
||||||
</td>
|
<option value="recent">@SharedLocalizer["Search.RecentlyReleased"]</option>
|
||||||
<td style="width: 1px; vertical-align: middle;">
|
@if (_price == "paid")
|
||||||
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
|
||||||
{
|
{
|
||||||
<a class="btn btn-primary" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@context.Price.Value.ToString("$#,##0.00")</a>
|
<option value="price">@SharedLocalizer["Search.Price"]</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Pager Format="Grid" Items="@_packages" DisplayPages="1" PageSize="9" Toolbar="Both" Class="container-fluid px-0" RowClass="row g-0" ColumnClass="col-lg-4 col-md-6">
|
||||||
|
<Row>
|
||||||
|
<div class="m-2 p-2 d-flex justify-content-center">
|
||||||
|
<div class="container-fluid px-0">
|
||||||
|
<div class="row g-0 mb-2">
|
||||||
|
<div class="col-4">
|
||||||
|
<a href="@context.ProductUrl" target="_blank">
|
||||||
|
@if (context.LogoUrl != null)
|
||||||
|
{
|
||||||
|
<img src="@context.LogoUrl" class="img-fluid" alt="@context.Name" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
<img src="/package.png" class="img-fluid" alt="@context.Name" />
|
||||||
|
}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-8 text-end">
|
||||||
|
<small>@SharedLocalizer["Search.Version"]:</small> <strong>@context.Version</strong>
|
||||||
|
<br /><small>@SharedLocalizer["Search.Released"]:</small> <strong>@context.ReleaseDate.ToString("MM/dd/yyyy")</strong>
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["Search.Source"]:</small> <strong>@(new Uri(context.PackageUrl).Host)</strong>
|
||||||
|
}
|
||||||
|
@if (context.Price == null)
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["Search.Downloads"]:</small> <strong>@(String.Format("{0:n0}", context.Downloads))</strong>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<br /><small>@SharedLocalizer["From"]:</small> <strong>@context.Price.Value.ToString("$#,##0.00")</strong>
|
||||||
|
@((MarkupString)(context.TrialPeriod > 0 ? " <strong>(" + context.TrialPeriod + " Day Trial)</strong>" : ""))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row g-0">
|
||||||
|
<div class="col">
|
||||||
|
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_blank">@context.Name</a></h3><br />
|
||||||
|
<small>@SharedLocalizer["Search.By"]:</small> <strong><a href="@context.OwnerUrl" target="new">@context.Owner</a></strong><br />
|
||||||
|
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)<br />
|
||||||
|
<br />
|
||||||
|
@if (!string.IsNullOrEmpty(context.PackageUrl))
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
<button type="button" class="btn btn-primary" @onclick=@(async () => await GetPackage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
|
||||||
}
|
}
|
||||||
</td>
|
@if (context.Price != null && !string.IsNullOrEmpty(context.PaymentUrl))
|
||||||
|
{
|
||||||
|
<a class="btn btn-success ms-2" style="text-decoration: none !important" href="@context.PaymentUrl" target="_new">@SharedLocalizer["Buy"]</a>
|
||||||
|
}
|
||||||
|
<br />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
<br />
|
|
||||||
<div class="mx-auto text-center">
|
|
||||||
@Localizer["Search.NoResults"]
|
|
||||||
</div>
|
</div>
|
||||||
}
|
</div>
|
||||||
}
|
|
||||||
<br />
|
<br />
|
||||||
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
<ModuleMessage Type="MessageType.Info" Message="@SharedLocalizer["Oqtane.Marketplace"]" />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
@ -116,8 +170,11 @@
|
|||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
|
private int _page = 1;
|
||||||
private List<Package> _packages;
|
private List<Package> _packages;
|
||||||
private string _price = "free";
|
private string _price = "free";
|
||||||
|
private string _sort = "popularity";
|
||||||
private string _search = "";
|
private string _search = "";
|
||||||
private string _productname = "";
|
private string _productname = "";
|
||||||
private string _license = "";
|
private string _license = "";
|
||||||
@ -131,6 +188,7 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await LoadThemes();
|
await LoadThemes();
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -141,8 +199,10 @@
|
|||||||
|
|
||||||
private async Task LoadThemes()
|
private async Task LoadThemes()
|
||||||
{
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
|
||||||
var themes = await ThemeService.GetThemesAsync();
|
var themes = await ThemeService.GetThemesAsync();
|
||||||
_packages = await PackageService.GetPackagesAsync("theme", _search, _price, "");
|
_packages = await PackageService.GetPackagesAsync("theme", _search, _price, "", _sort);
|
||||||
|
|
||||||
if (_packages != null)
|
if (_packages != null)
|
||||||
{
|
{
|
||||||
@ -154,46 +214,44 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HideProgressIndicator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void PriceChanged(ChangeEventArgs e)
|
private async void PriceChanged(string price)
|
||||||
{
|
{
|
||||||
try
|
_price = price;
|
||||||
{
|
_sort = "popularity";
|
||||||
_price = (string)e.Value;
|
|
||||||
_search = "";
|
|
||||||
await LoadThemes();
|
await LoadThemes();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On PriceChanged");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Search()
|
private async Task Search()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
await LoadThemes();
|
await LoadThemes();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error On Search");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Reset()
|
private async Task Reset()
|
||||||
{
|
{
|
||||||
try
|
_page = 1;
|
||||||
{
|
|
||||||
_search = "";
|
_search = "";
|
||||||
await LoadThemes();
|
await LoadThemes();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
|
private async Task Refresh()
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error On Reset");
|
await LoadThemes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPageChange(int page)
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void SortChanged(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
_sort = (string)e.Value;
|
||||||
|
await LoadThemes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HideModal()
|
private void HideModal()
|
||||||
@ -207,7 +265,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var package = await PackageService.GetPackageAsync(packageid, version);
|
var package = await PackageService.GetPackageAsync(packageid, version, false);
|
||||||
if (package != null)
|
if (package != null)
|
||||||
{
|
{
|
||||||
_productname = package.Name;
|
_productname = package.Name;
|
||||||
@ -236,7 +294,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(_packageid, _version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(_packageid, _version);
|
||||||
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
|
await logger.LogInformation("Package {PackageId} {Version} Downloaded Successfully", _packageid, _version);
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Download"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
_productname = "";
|
_productname = "";
|
||||||
|
@ -79,9 +79,12 @@
|
|||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
if (!NavigationManager.BaseUri.Contains("localhost:"))
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Info.Theme.CreatorIntent"], MessageType.Info);
|
AddModuleMessage(Localizer["Info.Theme.CreatorIntent"], MessageType.Info);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
@ -102,7 +105,8 @@
|
|||||||
{
|
{
|
||||||
if (IsValid(_owner) && IsValid(_theme) && _owner != _theme && _template != "-")
|
if (IsValid(_owner) && IsValid(_theme) && _owner != _theme && _template != "-")
|
||||||
{
|
{
|
||||||
var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference };
|
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
||||||
|
var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference, ThemeName = template.Namespace };
|
||||||
theme = await ThemeService.CreateThemeAsync(theme);
|
theme = await ThemeService.CreateThemeAsync(theme);
|
||||||
GetLocation();
|
GetLocation();
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Create"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Create"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
@ -142,8 +146,14 @@
|
|||||||
if (_owner != "" && _theme != "" && _template != "-")
|
if (_owner != "" && _theme != "" && _template != "-")
|
||||||
{
|
{
|
||||||
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
var template = _templates.FirstOrDefault(item => item.Name == _template);
|
||||||
|
if (!string.IsNullOrEmpty(template.Namespace))
|
||||||
|
{
|
||||||
|
_location = template.Location + template.Namespace.Replace("[Owner]", _owner).Replace("[Theme]", _theme);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_location = template.Location + _owner + ".Theme." + _theme;
|
_location = template.Location + _owner + ".Theme." + _theme;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
@using System.Net
|
@using System.Net
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject IThemeService ThemeService
|
@inject IThemeService ThemeService
|
||||||
|
@inject IPackageService PackageService
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IStringLocalizer<Edit> Localizer
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
@ -27,7 +28,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<Section Name="Information" ResourceKey="Information">
|
<Section Name="Information" ResourceKey="Information" Heading="Information">
|
||||||
<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="themename" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
<Label Class="col-sm-3" For="themename" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
|
||||||
@ -42,9 +43,26 @@
|
|||||||
</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="packagename" HelpText="The unique name of the package from which this module was installed" ResourceKey="PackageName">Package Name: </Label>
|
<Label Class="col-sm-3" For="packagename" HelpText="The unique name of the package from which this theme was installed. This value must be specified within the theme's ITheme interface specification." ResourceKey="PackageName">Package Name: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
@if (!string.IsNullOrEmpty(_packagename))
|
||||||
|
{
|
||||||
|
<div class="input-group">
|
||||||
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||||
|
@if (string.IsNullOrEmpty(_packageurl))
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="ValidatePackage">@Localizer["Validate"]</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<a href="@_packageurl" target="_blank" class="btn btn-primary">@SharedLocalizer["Download"]</a>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input id="packagename" class="form-control" @bind="@_packagename" disabled />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -68,7 +86,14 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<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>
|
<Label Class="col-sm-3" For="license" HelpText="The license of the theme" ResourceKey="License">License: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
@if (_license.StartsWith("http") || _license.StartsWith("/") || _license.StartsWith("~"))
|
||||||
|
{
|
||||||
|
<a href="@_license.Replace("~", PageState?.Alias.BaseUrl + "/Themes/" + Utilities.GetTypeName(_themeName))" class="btn btn-info" style="text-decoration: none !important" target="_new">@Localizer["View License"]</a>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
<textarea id="license" class="form-control" @bind="@_license" rows="5" disabled></textarea>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -90,7 +115,8 @@
|
|||||||
private string _isenabled;
|
private string _isenabled;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _version;
|
private string _version;
|
||||||
private string _packagename;
|
private string _packagename = "";
|
||||||
|
private string _packageurl = "";
|
||||||
private string _owner = "";
|
private string _owner = "";
|
||||||
private string _url = "";
|
private string _url = "";
|
||||||
private string _contact = "";
|
private string _contact = "";
|
||||||
@ -159,4 +185,27 @@
|
|||||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ValidatePackage()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var package = await PackageService.GetPackageAsync(_packagename, _version, true);
|
||||||
|
if (package == null || string.IsNullOrEmpty(package.PackageUrl))
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Validate"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_packageurl = package.PackageUrl;
|
||||||
|
AddModuleMessage(Localizer["Message.Download"], MessageType.Info);
|
||||||
|
}
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Downloading Package {PackageId} {Version}", _packagename, _version);
|
||||||
|
AddModuleMessage(Localizer["Error.Validate"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<ActionLink Action="Add" Text="Install Theme" />
|
<ActionLink Action="Add" Text="Install Theme" ResourceKey="InstallTheme" />
|
||||||
@((MarkupString)" ")
|
@((MarkupString)" ")
|
||||||
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" Class="btn btn-secondary" />
|
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" Class="btn btn-secondary" />
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ else
|
|||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ThemeId.ToString())" ResourceKey="EditModule" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ThemeId.ToString())" ResourceKey="EditTheme" /></td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.AssemblyName != Constants.ClientId)
|
@if (context.AssemblyName != Constants.ClientId)
|
||||||
{
|
{
|
||||||
@ -49,7 +49,7 @@ else
|
|||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@((MarkupString)SupportLink(context.PackageName))
|
@((MarkupString)SupportLink(context.PackageName, context.Version))
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@((MarkupString)PurchaseLink(context.PackageName))
|
@((MarkupString)PurchaseLink(context.PackageName))
|
||||||
@ -79,7 +79,7 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
_themes = await ThemeService.GetThemesAsync();
|
_themes = await ThemeService.GetThemesAsync();
|
||||||
_packages = await PackageService.GetPackagesAsync("theme");
|
_packages = await PackageService.GetPackageUpdatesAsync("theme");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -101,10 +101,13 @@ else
|
|||||||
{
|
{
|
||||||
if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
|
if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
|
||||||
{
|
{
|
||||||
link += "<span>" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</span><br />";
|
if (string.IsNullOrEmpty(package.PaymentUrl))
|
||||||
if (!string.IsNullOrEmpty(package.PaymentUrl))
|
|
||||||
{
|
{
|
||||||
link += " <a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + SharedLocalizer["Extend"] + "</a>";
|
link = "<span>" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</span>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
link = "<a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</a>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,7 +115,7 @@ else
|
|||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string SupportLink(string packagename)
|
private string SupportLink(string packagename, string version)
|
||||||
{
|
{
|
||||||
string link = "";
|
string link = "";
|
||||||
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
||||||
@ -120,7 +123,7 @@ else
|
|||||||
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
||||||
if (package != null && !string.IsNullOrEmpty(package.SupportUrl))
|
if (package != null && !string.IsNullOrEmpty(package.SupportUrl))
|
||||||
{
|
{
|
||||||
link += "<a class=\"btn btn-success\" style=\"text-decoration: none !important\" href=\"" + package.SupportUrl + "\" target=\"_new\">" + SharedLocalizer["Help"] + "</a>";
|
link += "<a class=\"btn btn-info\" style=\"text-decoration: none !important\" href=\"" + package.SupportUrl.Replace("{Version}", version) + "\" target=\"_new\">" + SharedLocalizer["Help"] + "</a>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return link;
|
return link;
|
||||||
@ -143,7 +146,7 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packagename, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packagename, version);
|
||||||
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
|
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
|
||||||
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Download" ResourceKey="Download">
|
<TabPanel Name="Download" ResourceKey="Download">
|
||||||
@if (_package != null && _upgradeavailable)
|
@if (_package != null && _upgradeavailable)
|
||||||
@ -17,11 +19,11 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage>
|
<ModuleMessage Type="MessageType.Info" Message=@Localizer["Message.Text"]></ModuleMessage>
|
||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
<TabPanel Name="Upload" ResourceKey="Upload">
|
||||||
<ModuleMessage Type="MessageType.Info" Message="Upload A Framework Package (Oqtane.Framework.version.nupkg) And Then Select Upgrade"></ModuleMessage>
|
<ModuleMessage Type="MessageType.Info" Message=@Localizer["MessageUpgrade.Text"]></ModuleMessage>
|
||||||
<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 A Framework Package And Then Select Upgrade" ResourceKey="Framework">Framework: </Label>
|
<Label Class="col-sm-3" HelpText="Upload A Framework Package And Then Select Upgrade" ResourceKey="Framework">Framework: </Label>
|
||||||
@ -33,8 +35,10 @@
|
|||||||
<button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
|
<button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private Package _package;
|
private Package _package;
|
||||||
private bool _upgradeavailable = false;
|
private bool _upgradeavailable = false;
|
||||||
|
|
||||||
@ -43,6 +47,12 @@
|
|||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (NavigationManager.BaseUri.Contains("localhost:"))
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Localhost.Text"], MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
List<Package> packages = await PackageService.GetPackagesAsync("framework", "", "", "");
|
List<Package> packages = await PackageService.GetPackagesAsync("framework", "", "", "");
|
||||||
if (packages != null)
|
if (packages != null)
|
||||||
@ -57,6 +67,8 @@
|
|||||||
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
_package = new Package { Name = Constants.PackageId, Version = Constants.Version };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_initialized = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
@ -85,8 +97,8 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await PackageService.DownloadPackageAsync(packageid, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(packageid, version);
|
||||||
await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version, Constants.PackagesFolder);
|
await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version);
|
||||||
AddModuleMessage(Localizer["Success.Framework.Download"], MessageType.Success);
|
AddModuleMessage(Localizer["Success.Framework.Download"], MessageType.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -28,7 +28,7 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<Pager Items="@_urlMappings">
|
<Pager Items="@_urlMappings" SearchProperties="Url">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
@inject IUserRoleService UserRoleService
|
||||||
@inject INotificationService NotificationService
|
@inject INotificationService NotificationService
|
||||||
@inject IStringLocalizer<Add> Localizer
|
@inject IStringLocalizer<Add> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
@ -10,9 +11,9 @@
|
|||||||
{
|
{
|
||||||
<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="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
|
<Label Class="col-sm-3" For="to" HelpText="Enter the user you wish to send a message to" ResourceKey="To">To: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="to" class="form-control" @bind="@username" />
|
<AutoComplete OnSearch="GetUsers" Placeholder="@Localizer["Username.Enter"]" @ref="username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -30,11 +31,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string username = "";
|
private AutoComplete username;
|
||||||
private string subject = "";
|
private string subject = "";
|
||||||
private string body = "";
|
private string body = "";
|
||||||
|
|
||||||
@ -42,23 +43,37 @@
|
|||||||
|
|
||||||
public override string Title => "Send Notification";
|
public override string Title => "Send Notification";
|
||||||
|
|
||||||
|
private async Task<Dictionary<string, string>> GetUsers(string filter)
|
||||||
|
{
|
||||||
|
var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
||||||
|
return users.Where(item => item.User.Username.Contains(filter, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToDictionary(item => item.UserId.ToString(), item => item.User.Username);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task Send()
|
private async Task Send()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
|
if (!string.IsNullOrEmpty(username.Key) && !string.IsNullOrEmpty(subject))
|
||||||
|
{
|
||||||
|
var user = await UserService.GetUserAsync(int.Parse(username.Key), ModuleState.SiteId);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body);
|
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body);
|
||||||
notification = await NotificationService.AddNotificationAsync(notification);
|
notification = await NotificationService.AddNotificationAsync(notification);
|
||||||
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
|
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Required"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
|
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
@if (PageState.User != null && photo != null)
|
@if (PageState.User != null && photo != null)
|
||||||
{
|
{
|
||||||
<img src="@ImageUrl(photofileid, 400, 400)" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
<img src="@ImageUrl(photofileid, 400, 400)" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
||||||
@ -21,8 +23,7 @@ else
|
|||||||
}
|
}
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Identity" ResourceKey="Identity">
|
<TabPanel Name="Identity" ResourceKey="Identity">
|
||||||
@if (profiles != null && settings != null)
|
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
|
||||||
{
|
|
||||||
<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="username" HelpText="Your username. Note that this field can not be modified." ResourceKey="Username"></Label>
|
<Label Class="col-sm-3" For="username" HelpText="Your username. Note that this field can not be modified." ResourceKey="Username"></Label>
|
||||||
@ -82,11 +83,8 @@ else
|
|||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="Save">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="Save">@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>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Profile" ResourceKey="Profile">
|
<TabPanel Name="Profile" ResourceKey="Profile">
|
||||||
@if (profiles != null && settings != null)
|
|
||||||
{
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@foreach (Profile profile in profiles)
|
@foreach (Profile profile in profiles)
|
||||||
@ -121,6 +119,8 @@ else
|
|||||||
</select>
|
</select>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
@if (p.Rows == 1)
|
||||||
{
|
{
|
||||||
@if (p.IsRequired)
|
@if (p.IsRequired)
|
||||||
{
|
{
|
||||||
@ -131,6 +131,18 @@ else
|
|||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@if (p.IsRequired)
|
||||||
|
{
|
||||||
|
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@ -139,19 +151,19 @@ else
|
|||||||
</div>
|
</div>
|
||||||
<button type="button" class="btn btn-success" @onclick="Save">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="Save">@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>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Notifications" ResourceKey="Notifications">
|
<TabPanel Name="Notifications" ResourceKey="Notifications">
|
||||||
@if (notifications != null)
|
<ActionLink Action="Add" Text="Send Notification" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="SendNotification" ReturnUrl="@NavigateUrl(PageState.Page.Path, "tab=Notifications")" />
|
||||||
{
|
<br />
|
||||||
|
<br />
|
||||||
<select class="form-select" @onchange="(e => FilterChanged(e))">
|
<select class="form-select" @onchange="(e => FilterChanged(e))">
|
||||||
<option value="to">@Localizer["Inbox"]</option>
|
<option value="to">@Localizer["Inbox"]</option>
|
||||||
<option value="from">@Localizer["Items.Sent"]</option>
|
<option value="from">@Localizer["Items.Sent"]</option>
|
||||||
</select>
|
</select>
|
||||||
<br />
|
<br />
|
||||||
<ActionLink Action="Add" Text="Send Notification" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="SendNotification" />
|
|
||||||
<br /><br />
|
|
||||||
@if (filter == "to")
|
@if (filter == "to")
|
||||||
|
{
|
||||||
|
@if (notifications.Any())
|
||||||
{
|
{
|
||||||
<Pager Items="@notifications">
|
<Pager Items="@notifications">
|
||||||
<Header>
|
<Header>
|
||||||
@ -162,7 +174,7 @@ else
|
|||||||
<th>@Localizer["Received"]</th>
|
<th>@Localizer["Received"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" ReturnUrl="@NavigateUrl(PageState.Page.Path, "tab=Notifications")" /></td>
|
||||||
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
|
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
|
||||||
|
|
||||||
@if (context.IsRead)
|
@if (context.IsRead)
|
||||||
@ -202,19 +214,30 @@ else
|
|||||||
</td>
|
</td>
|
||||||
</Detail>
|
</Detail>
|
||||||
</Pager>
|
</Pager>
|
||||||
|
<br />
|
||||||
|
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
<div class="no-notifications-text">
|
||||||
|
@Localizer["NoNotificationsReceived.Text"]
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@if (notifications.Any())
|
||||||
{
|
{
|
||||||
<Pager Items="@notifications">
|
<Pager Items="@notifications">
|
||||||
<Header>
|
<Header>
|
||||||
<th> </th>
|
<th style="width: 1px;"></th>
|
||||||
<th> </th>
|
<th style="width: 1px;"></th>
|
||||||
<th>@Localizer["To"]</th>
|
<th>@Localizer["To"]</th>
|
||||||
<th>@Localizer["Subject"]</th>
|
<th>@Localizer["Subject"]</th>
|
||||||
<th>@Localizer["Sent"]</th>
|
<th>@Localizer["Sent"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
|
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" ReturnUrl="@NavigateUrl(PageState.Page.Path, "tab=Notifications")" /></td>
|
||||||
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
|
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
|
||||||
|
|
||||||
@if (context.IsRead)
|
@if (context.IsRead)
|
||||||
@ -255,18 +278,25 @@ else
|
|||||||
</td>
|
</td>
|
||||||
</Detail>
|
</Detail>
|
||||||
</Pager>
|
</Pager>
|
||||||
}
|
|
||||||
@if (notifications.Any())
|
|
||||||
{
|
|
||||||
<br />
|
<br />
|
||||||
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
|
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="no-notifications-text">
|
||||||
|
@Localizer["NoNotificationsSent.Text"]
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
<br /><br />
|
<br />
|
||||||
|
<br />
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
|
private string _passwordrequirements;
|
||||||
private string username = string.Empty;
|
private string username = string.Empty;
|
||||||
private string _password = string.Empty;
|
private string _password = string.Empty;
|
||||||
private string _passwordtype = "password";
|
private string _passwordtype = "password";
|
||||||
@ -280,25 +310,25 @@ else
|
|||||||
private int folderid = -1;
|
private int folderid = -1;
|
||||||
private int photofileid = -1;
|
private int photofileid = -1;
|
||||||
private File photo = null;
|
private File photo = null;
|
||||||
|
|
||||||
private List<Profile> profiles;
|
private List<Profile> profiles;
|
||||||
private Dictionary<string, string> settings;
|
private Dictionary<string, string> settings;
|
||||||
private string category = string.Empty;
|
private string category = string.Empty;
|
||||||
|
|
||||||
private string filter = "to";
|
private string filter = "to";
|
||||||
private List<Notification> notifications;
|
private List<Notification> notifications;
|
||||||
private string notificationSummary = string.Empty;
|
private string notificationSummary = string.Empty;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
|
allowtwofactor = (SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:TwoFactor", "false") == "true");
|
||||||
if (PageState.Site.Settings.ContainsKey("LoginOptions:TwoFactor") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:TwoFactor"]))
|
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
||||||
{
|
|
||||||
allowtwofactor = (PageState.Site.Settings["LoginOptions:TwoFactor"] == "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.User != null)
|
if (PageState.User != null)
|
||||||
{
|
{
|
||||||
@ -325,10 +355,11 @@ else
|
|||||||
photo = null;
|
photo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
|
||||||
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
||||||
|
|
||||||
await LoadNotificationsAsync();
|
await LoadNotificationsAsync();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -362,9 +393,11 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
if (username != string.Empty && email != string.Empty)
|
||||||
{
|
{
|
||||||
if (_password == confirm)
|
if (_password == confirm)
|
||||||
|
{
|
||||||
|
if (ValidateProfiles())
|
||||||
{
|
{
|
||||||
var user = PageState.User;
|
var user = PageState.User;
|
||||||
user.Username = username;
|
user.Username = username;
|
||||||
@ -402,6 +435,7 @@ else
|
|||||||
AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error);
|
AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning);
|
||||||
@ -423,27 +457,33 @@ else
|
|||||||
|
|
||||||
private bool ValidateProfiles()
|
private bool ValidateProfiles()
|
||||||
{
|
{
|
||||||
bool valid = true;
|
|
||||||
foreach (Profile profile in profiles)
|
foreach (Profile profile in profiles)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
var value = GetProfileValue(profile.Name, string.Empty);
|
||||||
|
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
if (profile.IsRequired && string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
valid = false;
|
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
if (!string.IsNullOrEmpty(profile.Validation))
|
||||||
{
|
{
|
||||||
Regex regex = new Regex(profile.Validation);
|
Regex regex = new Regex(profile.Validation);
|
||||||
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
bool valid = regex.Match(value).Success;
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
@ -485,7 +525,6 @@ else
|
|||||||
private async void FilterChanged(ChangeEventArgs e)
|
private async void FilterChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
filter = (string)e.Value;
|
filter = (string)e.Value;
|
||||||
|
|
||||||
await LoadNotificationsAsync();
|
await LoadNotificationsAsync();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
@ -7,95 +7,72 @@
|
|||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@if (PageState.User != null)
|
@if (PageState.User != null)
|
||||||
|
{
|
||||||
|
@if (title == "From")
|
||||||
{
|
{
|
||||||
<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">@Localizer["Title"] </label>
|
<Label Class="col-sm-3" For="username" HelpText="The user who sent the message" ResourceKey="From">From:</Label>
|
||||||
@if (title == "From")
|
|
||||||
{
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<input class="form-control" @bind="@username" readonly />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (title == "To")
|
|
||||||
{
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<input class="form-control" @bind="@username" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<label Class="col-sm-3">@Localizer["Subject"] </label>
|
|
||||||
@if (title == "From")
|
|
||||||
{
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<input class="form-control" @bind="@subject" readonly />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
@if (title == "To")
|
|
||||||
{
|
|
||||||
<div class="col-sm-3">
|
|
||||||
<input class="form-control" @bind="@subject" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
|
||||||
@if (title == "From")
|
|
||||||
{
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<label class="col-sm-3">@Localizer["Date"] </label>
|
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input class="form-control" @bind="@createdon" readonly />
|
<input id="username" class="form-control" @bind="@username" readonly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
@if (title == "From")
|
|
||||||
{
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<label class="col-sm-3">@Localizer["Message"] </label>
|
<Label Class="col-sm-3" For="subject" HelpText="The subject of the message" ResourceKey="Subject">Subject:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea class="form-control" @bind="@body" rows="5" readonly />
|
<input id="subject" class="form-control" @bind="@subject" readonly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
|
||||||
@if (title == "To")
|
|
||||||
{
|
|
||||||
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<label class="col-sm-3">@Localizer["Message"] </label>
|
<Label class="col-sm-3" For="date" HelpText="The date the message was sent" ResourceKey="Date">Sent:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea class="form-control" @bind="@body" rows="5" readonly />
|
<input id="date" class="form-control" @bind="@createdon" readonly />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label class="col-sm-3" For="message" HelpText="The contents of the message" ResourceKey="Message">Message:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="message" class="form-control" @bind="@body" rows="5" readonly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
@if (reply != string.Empty)
|
|
||||||
{
|
|
||||||
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (title == "From")
|
<div class="container">
|
||||||
{
|
<div class="row mb-1 align-items-center">
|
||||||
<button type="button" class="btn btn-primary" @onclick="Reply">@Localizer["Reply"]</button>
|
<Label Class="col-sm-3" For="username" HelpText="The user who will be the recipient of the message" ResourceKey="To">To:</Label>
|
||||||
}
|
<div class="col-sm-9">
|
||||||
}
|
<input id="username" class="form-control" @bind="@username" readonly />
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
</div>
|
||||||
<br />
|
</div>
|
||||||
<br />
|
<div class="row mb-1 align-items-center">
|
||||||
@if (title == "To")
|
<Label Class="col-sm-3" For="subject" HelpText="The subject of the message" ResourceKey="Subject">Subject:</Label>
|
||||||
{
|
<div class="col-sm-9">
|
||||||
<div class="control-group">
|
<input id="subject" class="form-control" @bind="@subject" readonly="@(!reply)" />
|
||||||
<label class="control-label">@Localizer["OriginalMessage"] </label>
|
</div>
|
||||||
<textarea class="form-control" @bind="@reply" rows="5" readonly />
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label class="col-sm-3" For="message" HelpText="The content of the message" ResourceKey="Message">Message:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="message" class="form-control" @bind="@body" rows="5" readonly="@(!reply)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@if (reply)
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-primary me-2" @onclick="Send">@SharedLocalizer["Send"]</button>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (title == "From" && username != Localizer["System"])
|
||||||
|
{
|
||||||
|
<button type="button" class="btn btn-primary me-2" @onclick="Reply">@Localizer["Reply"]</button>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@ -105,7 +82,7 @@
|
|||||||
private string subject = string.Empty;
|
private string subject = string.Empty;
|
||||||
private string createdon = string.Empty;
|
private string createdon = string.Empty;
|
||||||
private string body = string.Empty;
|
private string body = string.Empty;
|
||||||
private string reply = string.Empty;
|
private bool reply = false;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
|
||||||
public override string Title => "View Notification";
|
public override string Title => "View Notification";
|
||||||
@ -118,9 +95,6 @@
|
|||||||
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
|
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
|
||||||
if (notification != null)
|
if (notification != null)
|
||||||
{
|
{
|
||||||
notification.IsRead = true;
|
|
||||||
notification = await NotificationService.UpdateNotificationAsync(notification);
|
|
||||||
|
|
||||||
int userid = -1;
|
int userid = -1;
|
||||||
if (notification.ToUserId == PageState.User.UserId)
|
if (notification.ToUserId == PageState.User.UserId)
|
||||||
{
|
{
|
||||||
@ -148,11 +122,17 @@
|
|||||||
}
|
}
|
||||||
if (username == "")
|
if (username == "")
|
||||||
{
|
{
|
||||||
username = "System";
|
username = Localizer["System"];
|
||||||
}
|
}
|
||||||
subject = notification.Subject;
|
subject = notification.Subject;
|
||||||
createdon = notification.CreatedOn.ToString();
|
createdon = notification.CreatedOn.ToString();
|
||||||
body = notification.Body;
|
body = notification.Body;
|
||||||
|
|
||||||
|
if (title == "From")
|
||||||
|
{
|
||||||
|
notification.IsRead = true;
|
||||||
|
notification = await NotificationService.UpdateNotificationAsync(notification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -165,12 +145,16 @@
|
|||||||
private void Reply()
|
private void Reply()
|
||||||
{
|
{
|
||||||
title = "To";
|
title = "To";
|
||||||
if (!subject.Contains("RE:"))
|
if (!subject.Contains(Localizer["RE:"]))
|
||||||
{
|
{
|
||||||
subject = "RE: " + subject;
|
subject = Localizer["RE"] + " " + subject;
|
||||||
}
|
}
|
||||||
reply = body;
|
body = $"\n\n____________________________________________\n" +
|
||||||
body = "\n\n____________________________________________\nSent: " + createdon + "\nSubject: " + subject + "\n\n" + body;
|
$"{Localizer["From.Text"]} {username}\n" +
|
||||||
|
$"{Localizer["Date.Text"]} {createdon}\n" +
|
||||||
|
$"{Localizer["Subject.Text"]} {subject}\n\n" +
|
||||||
|
body;
|
||||||
|
reply = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +168,7 @@
|
|||||||
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
|
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
|
||||||
notification = await NotificationService.AddNotificationAsync(notification);
|
notification = await NotificationService.AddNotificationAsync(notification);
|
||||||
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
|
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8,15 +8,18 @@
|
|||||||
@inject IStringLocalizer<Add> Localizer
|
@inject IStringLocalizer<Add> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Identity" ResourceKey="Identity">
|
<TabPanel Name="Identity" ResourceKey="Identity">
|
||||||
@if (profiles != null)
|
@if (profiles != null)
|
||||||
{
|
{
|
||||||
|
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
|
||||||
<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="username" HelpText="A unique username for a user. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
|
<Label Class="col-sm-3" For="username" HelpText="A unique username for a user. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="username" class="form-control" @bind="@username" />
|
<input id="username" class="form-control" @bind="@_username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -32,7 +35,7 @@
|
|||||||
<Label Class="col-sm-3" For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
|
<Label Class="col-sm-3" For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
|
||||||
<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" tabindex="-1">@_togglepassword</button>
|
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -40,22 +43,28 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
|
<Label Class="col-sm-3" For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="email" class="form-control" @bind="@email" />
|
<input id="email" class="form-control" @bind="@_email" />
|
||||||
</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="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
|
<Label Class="col-sm-3" For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="displayname" class="form-control" @bind="@displayname" />
|
<input id="displayname" class="form-control" @bind="@_displayname" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="notify" HelpText="Indicate if new users should receive an email notification" ResourceKey="Notify">Notify? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="notify" class="form-select" @bind="@_notify" required>
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Profile" ResourceKey="Profile">
|
<TabPanel Name="Profile" ResourceKey="Profile">
|
||||||
@if (profiles != null)
|
|
||||||
{
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@foreach (Profile profile in profiles)
|
@foreach (Profile profile in profiles)
|
||||||
@ -71,36 +80,58 @@
|
|||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@if (p.IsRequired)
|
@if (!string.IsNullOrEmpty(p.Options))
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
|
||||||
|
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
|
||||||
|
{
|
||||||
|
<option value="@option" selected>@option</option>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
<option value="@option">@option</option>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@if (p.Rows == 1)
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||||
|
}
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string username = string.Empty;
|
private bool _initialized = false;
|
||||||
|
private string _passwordrequirements;
|
||||||
|
private string _username = string.Empty;
|
||||||
private string _password = string.Empty;
|
private string _password = string.Empty;
|
||||||
private string _passwordtype = "password";
|
private string _passwordtype = "password";
|
||||||
private string _togglepassword = string.Empty;
|
private string _togglepassword = string.Empty;
|
||||||
private string confirm = string.Empty;
|
private string _confirm = string.Empty;
|
||||||
private string email = string.Empty;
|
private string _email = string.Empty;
|
||||||
private string displayname = string.Empty;
|
private string _displayname = string.Empty;
|
||||||
|
private string _notify = "True";
|
||||||
private List<Profile> profiles;
|
private List<Profile> profiles;
|
||||||
private Dictionary<string, string> settings;
|
private Dictionary<string, string> settings;
|
||||||
private string category = string.Empty;
|
private string category = string.Empty;
|
||||||
@ -111,9 +142,11 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
|
||||||
settings = new Dictionary<string, string>();
|
settings = new Dictionary<string, string>();
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -136,20 +169,20 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (username != string.Empty && _password != string.Empty && confirm != string.Empty && email != string.Empty && ValidateProfiles())
|
if (_username != string.Empty && _password != string.Empty && _confirm != string.Empty && _email != string.Empty)
|
||||||
{
|
{
|
||||||
if (_password == confirm)
|
if (_password == _confirm)
|
||||||
{
|
{
|
||||||
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
|
if (ValidateProfiles())
|
||||||
if (user == null)
|
|
||||||
{
|
{
|
||||||
user = new User();
|
var user = new User();
|
||||||
user.SiteId = PageState.Site.SiteId;
|
user.SiteId = PageState.Site.SiteId;
|
||||||
user.Username = username;
|
user.Username = _username;
|
||||||
user.Password = _password;
|
user.Password = _password;
|
||||||
user.Email = email;
|
user.Email = _email;
|
||||||
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
user.DisplayName = string.IsNullOrWhiteSpace(_displayname) ? _username : _displayname;
|
||||||
user.PhotoFileId = null;
|
user.PhotoFileId = null;
|
||||||
|
user.SuppressNotification = !bool.Parse(_notify);
|
||||||
|
|
||||||
user = await UserService.AddUserAsync(user);
|
user = await UserService.AddUserAsync(user);
|
||||||
|
|
||||||
@ -161,14 +194,10 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await logger.LogError("Error Adding User {Username} {Email}", username, email);
|
await logger.LogError("Error Adding User {Username} {Email}", _username, _email);
|
||||||
AddModuleMessage(Localizer["Error.User.AddCheckPass"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.User.AddCheckPass"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Message.Username.Exists"], MessageType.Warning);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -182,34 +211,40 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", username, email, ex.Message);
|
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", _username, _email, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ValidateProfiles()
|
private bool ValidateProfiles()
|
||||||
{
|
{
|
||||||
bool valid = true;
|
|
||||||
foreach (Profile profile in profiles)
|
foreach (Profile profile in profiles)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
var value = GetProfileValue(profile.Name, string.Empty);
|
||||||
|
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
if (profile.IsRequired && string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
valid = false;
|
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
if (!string.IsNullOrEmpty(profile.Validation))
|
||||||
{
|
{
|
||||||
Regex regex = new Regex(profile.Validation);
|
Regex regex = new Regex(profile.Validation);
|
||||||
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
bool valid = regex.Match(value).Success;
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
|
@ -9,18 +9,11 @@
|
|||||||
@inject IStringLocalizer<Edit> Localizer
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@if (PageState.User != null && photo != null)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<img src="@photo.Url" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<br />
|
|
||||||
}
|
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Identity" ResourceKey="Identity">
|
<TabPanel Name="Identity" ResourceKey="Identity">
|
||||||
@if (profiles != null)
|
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
|
||||||
{
|
|
||||||
<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="username" HelpText="The unique username for a user. Note that this field can not be modified." ResourceKey="Username"></Label>
|
<Label Class="col-sm-3" For="username" HelpText="The unique username for a user. Note that this field can not be modified." ResourceKey="Username"></Label>
|
||||||
@ -58,12 +51,6 @@ else
|
|||||||
<input id="displayname" class="form-control" @bind="@displayname" />
|
<input id="displayname" class="form-control" @bind="@displayname" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="@photofileid.ToString()" HelpText="A photo of the user" ResourceKey="Photo"></Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<FileManager FileId="@photofileid" @ref="filemanager" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="isdeleted" HelpText="Indicate if the user is active" ResourceKey="IsDeleted"></Label>
|
<Label Class="col-sm-3" For="isdeleted" HelpText="Indicate if the user is active" ResourceKey="IsDeleted"></Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -86,11 +73,8 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel Name="Profile" ResourceKey="Profile">
|
<TabPanel Name="Profile" ResourceKey="Profile">
|
||||||
@if (profiles != null)
|
|
||||||
{
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@foreach (Profile profile in profiles)
|
@foreach (Profile profile in profiles)
|
||||||
@ -124,21 +108,20 @@ else
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@if (p.IsRequired)
|
@if (p.Rows == 1)
|
||||||
{
|
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
|
|
||||||
@ -147,8 +130,11 @@ else
|
|||||||
<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>
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
|
private string _passwordrequirements;
|
||||||
private int userid;
|
private int userid;
|
||||||
private string username = string.Empty;
|
private string username = string.Empty;
|
||||||
private string _password = string.Empty;
|
private string _password = string.Empty;
|
||||||
@ -157,9 +143,6 @@ else
|
|||||||
private string confirm = string.Empty;
|
private string confirm = string.Empty;
|
||||||
private string email = string.Empty;
|
private string email = string.Empty;
|
||||||
private string displayname = string.Empty;
|
private string displayname = string.Empty;
|
||||||
private FileManager filemanager;
|
|
||||||
private int photofileid = -1;
|
|
||||||
private File photo = null;
|
|
||||||
private string isdeleted;
|
private string isdeleted;
|
||||||
private string lastlogin;
|
private string lastlogin;
|
||||||
private string lastipaddress;
|
private string lastipaddress;
|
||||||
@ -177,31 +160,23 @@ else
|
|||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (PageState.QueryString.ContainsKey("id"))
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
||||||
{
|
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
|
||||||
userid = Int32.Parse(PageState.QueryString["id"]);
|
|
||||||
|
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int UserId))
|
||||||
|
{
|
||||||
|
userid = UserId;
|
||||||
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
username = user.Username;
|
username = user.Username;
|
||||||
email = user.Email;
|
email = user.Email;
|
||||||
displayname = user.DisplayName;
|
displayname = user.DisplayName;
|
||||||
if (user.PhotoFileId != null)
|
|
||||||
{
|
|
||||||
photofileid = user.PhotoFileId.Value;
|
|
||||||
photo = await FileService.GetFileAsync(photofileid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
photofileid = -1;
|
|
||||||
photo = null;
|
|
||||||
}
|
|
||||||
isdeleted = user.IsDeleted.ToString();
|
isdeleted = user.IsDeleted.ToString();
|
||||||
lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn);
|
lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn);
|
||||||
lastipaddress = user.LastIPAddress;
|
lastipaddress = user.LastIPAddress;
|
||||||
@ -215,6 +190,8 @@ else
|
|||||||
deletedon = user.DeletedOn;
|
deletedon = user.DeletedOn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -237,9 +214,11 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (username != string.Empty && email != string.Empty && ValidateProfiles())
|
if (username != string.Empty && email != string.Empty)
|
||||||
{
|
{
|
||||||
if (_password == confirm)
|
if (_password == confirm)
|
||||||
|
{
|
||||||
|
if (ValidateProfiles())
|
||||||
{
|
{
|
||||||
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||||
user.SiteId = PageState.Site.SiteId;
|
user.SiteId = PageState.Site.SiteId;
|
||||||
@ -248,7 +227,6 @@ else
|
|||||||
user.Email = email;
|
user.Email = email;
|
||||||
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
user.DisplayName = string.IsNullOrWhiteSpace(displayname) ? username : displayname;
|
||||||
user.PhotoFileId = null;
|
user.PhotoFileId = null;
|
||||||
user.PhotoFileId = filemanager.GetFileId();
|
|
||||||
if (user.PhotoFileId == -1)
|
if (user.PhotoFileId == -1)
|
||||||
{
|
{
|
||||||
user.PhotoFileId = null;
|
user.PhotoFileId = null;
|
||||||
@ -268,6 +246,7 @@ else
|
|||||||
AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error);
|
AddModuleMessage(Localizer["Message.Password.Complexity"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
|
||||||
@ -287,27 +266,33 @@ else
|
|||||||
|
|
||||||
private bool ValidateProfiles()
|
private bool ValidateProfiles()
|
||||||
{
|
{
|
||||||
bool valid = true;
|
|
||||||
foreach (Profile profile in profiles)
|
foreach (Profile profile in profiles)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
|
var value = GetProfileValue(profile.Name, string.Empty);
|
||||||
|
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
if (valid == true && profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
|
if (profile.IsRequired && string.IsNullOrEmpty(value))
|
||||||
{
|
{
|
||||||
valid = false;
|
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (valid == true && !string.IsNullOrEmpty(profile.Validation))
|
if (!string.IsNullOrEmpty(profile.Validation))
|
||||||
{
|
{
|
||||||
Regex regex = new Regex(profile.Validation);
|
Regex regex = new Regex(profile.Validation);
|
||||||
valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
|
bool valid = regex.Match(value).Success;
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return valid;
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
|
@ -17,27 +17,18 @@ else
|
|||||||
{
|
{
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Users" Heading="Users" ResourceKey="Users">
|
<TabPanel Name="Users" Heading="Users" ResourceKey="Users">
|
||||||
<div class="container">
|
<ActionLink Action="Add" Text="Add User" Security="SecurityAccessLevel.Edit" ResourceKey="AddUser" />
|
||||||
<div class="row mb-1 align-items-center">
|
<ActionLink Text="Import Users" Class="btn btn-secondary ms-2" Action="Users" Security="SecurityAccessLevel.Admin" ResourceKey="ImportUsers"/>
|
||||||
<div class="col-sm-4">
|
|
||||||
<ActionLink Action="Add" Text="Add User" Security="SecurityAccessLevel.Edit" ResourceKey="AddUser" />
|
<Pager Items="@users" RowClass="align-middle" SearchProperties="User.Username,User.Email,User.DisplayName">
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<input class="form-control" @bind="@_search" />
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<button type="button" class="btn btn-secondary" @onclick="OnSearch">@SharedLocalizer["Search"]</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Pager Items="@users" RowClass="align-middle">
|
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th class="app-sort-th" @onclick="@(() => SortTable("Username"))">@Localizer["Username"]<i class="@(SetSortIcon("Username"))"></i></th>
|
<th class="app-sort-th link-primary text-decoration-underline" @onclick="@(() => SortTable("Username"))">@Localizer["Username"]<i class="@(SetSortIcon("Username"))"></i></th>
|
||||||
<th class="app-sort-th" @onclick="@(() => SortTable("DisplayName"))">@Localizer["Name"]<i class="@(SetSortIcon("DisplayName"))"></i></th>
|
<th class="app-sort-th link-primary text-decoration-underline" @onclick="@(() => SortTable("DisplayName"))">@Localizer["Name"]<i class="@(SetSortIcon("DisplayName"))"></i></th>
|
||||||
<th class="app-sort-th" @onclick="@(() => SortTable("LastLoginOn"))">@Localizer["LastLoginOn"]<i class="@(SetSortIcon("LastLoginOn"))"></i></th>
|
<th class="app-sort-th link-primary text-decoration-underline" @onclick="@(() => SortTable("Email"))">@Localizer["Email"]<i class="@(SetSortIcon("Email"))"></i></th>
|
||||||
|
<th class="app-sort-th link-primary text-decoration-underline" @onclick="@(() => SortTable("LastLoginOn"))">@Localizer["LastLoginOn"]<i class="@(SetSortIcon("LastLoginOn"))"></i></th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>
|
<td>
|
||||||
@ -50,7 +41,8 @@ else
|
|||||||
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" Security="SecurityAccessLevel.Edit" ResourceKey="Roles" />
|
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" Security="SecurityAccessLevel.Edit" ResourceKey="Roles" />
|
||||||
</td>
|
</td>
|
||||||
<td>@context.User.Username</td>
|
<td>@context.User.Username</td>
|
||||||
<td>@((MarkupString)string.Format("<a href=\"mailto:{0}\">{1}</a>", @context.User.Email, @context.User.DisplayName))</td>
|
<td>@context.User.DisplayName</td>
|
||||||
|
<td>@((MarkupString)string.Format("<a href=\"mailto:{0}\">{1}</a>", @context.User.Email, @context.User.Email))</td>
|
||||||
<td>@((context.User.LastLoginOn != DateTime.MinValue) ? string.Format("{0:dd-MMM-yyyy HH:mm:ss}", context.User.LastLoginOn) : "")</td>
|
<td>@((context.User.LastLoginOn != DateTime.MinValue) ? string.Format("{0:dd-MMM-yyyy HH:mm:ss}", context.User.LastLoginOn) : "")</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
@ -106,6 +98,21 @@ else
|
|||||||
<input id="cookiename" class="form-control" @bind="@_cookiename" />
|
<input id="cookiename" class="form-control" @bind="@_cookiename" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="cookieexpiration" HelpText="You can choose to use a custom authentication cookie expiration timespan for each site (e.g. '08:00:00' for 8 hours). The default is 14 days if not specified." ResourceKey="CookieExpiration">Cookie Expiration Timespan:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="cookieexpiration" class="form-control" @bind="@_cookieexpiration" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="alwaysremember" HelpText="Enabling this option will set a permanent cookie in conjunction with the Cookie Expiration Timespan, which will automatically sign in users the next time they visit the site. By default the site will use session cookies." ResourceKey="AlwaysRemember">Always Remember User?</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="alwaysremember" class="form-select" @bind="@_alwaysremember">
|
||||||
|
<option value="true">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="false">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</Section>
|
</Section>
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
@ -259,6 +266,21 @@ else
|
|||||||
<input id="parameters" class="form-control" @bind="@_parameters" />
|
<input id="parameters" class="form-control" @bind="@_parameters" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="authresponsetype" HelpText="Specify the authorization response type" ResourceKey="AuthResponseType">Authorization Response Type</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="authresponsetype" class="form-select" @bind="@_authresponsetype" required>
|
||||||
|
<option value="code">@Localizer["AuthFlow.Code"]</option>
|
||||||
|
<option value="code id_token">@Localizer["AuthFlow.CodeIdToken"]</option>
|
||||||
|
<option value="code id_token token">@Localizer["AuthFlow.CodeIdTokenToken"]</option>
|
||||||
|
<option value="code token">@Localizer["AuthFlow.CodeToken"]</option>
|
||||||
|
<option value="id_token">@Localizer["AuthFlow.IdToken"]</option>
|
||||||
|
<option value="id_token token">@Localizer["AuthFlow.IdTokenToken"]</option>
|
||||||
|
<option value="token">@Localizer["AuthFlow.Token"]</option>
|
||||||
|
<option value="none">@Localizer["AuthFlow.None"]</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="pkce" HelpText="Indicate if the provider supports Proof Key for Code Exchange (PKCE)" ResourceKey="PKCE">Use PKCE?</Label>
|
<Label Class="col-sm-3" For="pkce" HelpText="Indicate if the provider supports Proof Key for Code Exchange (PKCE)" ResourceKey="PKCE">Use PKCE?</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -316,6 +338,15 @@ else
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="verifyusers" HelpText="Do you want existing users to perform an additional email verification step to link their external login? If you disable this option, existing users will be linked automatically." ResourceKey="VerifyUsers">Verify Existing Users?</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="verifyusers" class="form-select" @bind="@_verifyusers">
|
||||||
|
<option value="true">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="false">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
</Section>
|
</Section>
|
||||||
<Section Name="Token" Heading="Token Settings" ResourceKey="TokenSettings">
|
<Section Name="Token" Heading="Token Settings" ResourceKey="TokenSettings">
|
||||||
@ -365,14 +396,14 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<UserRole> allusers;
|
|
||||||
private List<UserRole> users;
|
private List<UserRole> users;
|
||||||
private string _search = "";
|
|
||||||
|
|
||||||
private string _allowregistration;
|
private string _allowregistration;
|
||||||
private string _allowsitelogin;
|
private string _allowsitelogin;
|
||||||
private string _twofactor;
|
private string _twofactor;
|
||||||
private string _cookiename;
|
private string _cookiename;
|
||||||
|
private string _cookieexpiration;
|
||||||
|
private string _alwaysremember;
|
||||||
|
|
||||||
private string _minimumlength;
|
private string _minimumlength;
|
||||||
private string _uniquecharacters;
|
private string _uniquecharacters;
|
||||||
@ -397,6 +428,7 @@ else
|
|||||||
private string _scopes;
|
private string _scopes;
|
||||||
private string _parameters;
|
private string _parameters;
|
||||||
private string _pkce;
|
private string _pkce;
|
||||||
|
private string _authresponsetype;
|
||||||
private string _redirecturl;
|
private string _redirecturl;
|
||||||
private string _identifierclaimtype;
|
private string _identifierclaimtype;
|
||||||
private string _emailclaimtype;
|
private string _emailclaimtype;
|
||||||
@ -404,6 +436,7 @@ else
|
|||||||
private string _profileclaimtypes;
|
private string _profileclaimtypes;
|
||||||
private string _domainfilter;
|
private string _domainfilter;
|
||||||
private string _createusers;
|
private string _createusers;
|
||||||
|
private string _verifyusers;
|
||||||
|
|
||||||
private string _secret;
|
private string _secret;
|
||||||
private string _secrettype = "password";
|
private string _secrettype = "password";
|
||||||
@ -420,7 +453,6 @@ else
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
await LoadUserSettingsAsync();
|
|
||||||
await LoadUsersAsync(true);
|
await LoadUsersAsync(true);
|
||||||
|
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
@ -431,6 +463,8 @@ else
|
|||||||
{
|
{
|
||||||
_twofactor = SettingService.GetSetting(settings, "LoginOptions:TwoFactor", "false");
|
_twofactor = SettingService.GetSetting(settings, "LoginOptions:TwoFactor", "false");
|
||||||
_cookiename = SettingService.GetSetting(settings, "LoginOptions:CookieName", ".AspNetCore.Identity.Application");
|
_cookiename = SettingService.GetSetting(settings, "LoginOptions:CookieName", ".AspNetCore.Identity.Application");
|
||||||
|
_cookieexpiration = SettingService.GetSetting(settings, "LoginOptions:CookieExpiration", "");
|
||||||
|
_alwaysremember = SettingService.GetSetting(settings, "LoginOptions:AlwaysRemember", "false");
|
||||||
|
|
||||||
_minimumlength = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredLength", "6");
|
_minimumlength = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredLength", "6");
|
||||||
_uniquecharacters = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", "1");
|
_uniquecharacters = SettingService.GetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", "1");
|
||||||
@ -455,6 +489,7 @@ else
|
|||||||
_scopes = SettingService.GetSetting(settings, "ExternalLogin:Scopes", "");
|
_scopes = SettingService.GetSetting(settings, "ExternalLogin:Scopes", "");
|
||||||
_parameters = SettingService.GetSetting(settings, "ExternalLogin:Parameters", "");
|
_parameters = SettingService.GetSetting(settings, "ExternalLogin:Parameters", "");
|
||||||
_pkce = SettingService.GetSetting(settings, "ExternalLogin:PKCE", "false");
|
_pkce = SettingService.GetSetting(settings, "ExternalLogin:PKCE", "false");
|
||||||
|
_authresponsetype = SettingService.GetSetting(settings, "ExternalLogin:AuthResponseType", "code");
|
||||||
_redirecturl = PageState.Uri.Scheme + "://" + PageState.Alias.Name + "/signin-" + _providertype;
|
_redirecturl = PageState.Uri.Scheme + "://" + PageState.Alias.Name + "/signin-" + _providertype;
|
||||||
_identifierclaimtype = SettingService.GetSetting(settings, "ExternalLogin:IdentifierClaimType", "sub");
|
_identifierclaimtype = SettingService.GetSetting(settings, "ExternalLogin:IdentifierClaimType", "sub");
|
||||||
_emailclaimtype = SettingService.GetSetting(settings, "ExternalLogin:EmailClaimType", "email");
|
_emailclaimtype = SettingService.GetSetting(settings, "ExternalLogin:EmailClaimType", "email");
|
||||||
@ -462,6 +497,7 @@ else
|
|||||||
_profileclaimtypes = SettingService.GetSetting(settings, "ExternalLogin:ProfileClaimTypes", "");
|
_profileclaimtypes = SettingService.GetSetting(settings, "ExternalLogin:ProfileClaimTypes", "");
|
||||||
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
|
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
|
||||||
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
|
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
|
||||||
|
_verifyusers = SettingService.GetSetting(settings, "ExternalLogin:VerifyUsers", "true");
|
||||||
|
|
||||||
_secret = SettingService.GetSetting(settings, "JwtOptions:Secret", "");
|
_secret = SettingService.GetSetting(settings, "JwtOptions:Secret", "");
|
||||||
_togglesecret = SharedLocalizer["ShowPassword"];
|
_togglesecret = SharedLocalizer["ShowPassword"];
|
||||||
@ -475,32 +511,14 @@ else
|
|||||||
{
|
{
|
||||||
if (load)
|
if (load)
|
||||||
{
|
{
|
||||||
allusers = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
var hosts = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Host);
|
var hosts = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Host);
|
||||||
allusers.AddRange(hosts);
|
users.AddRange(hosts);
|
||||||
allusers = allusers.OrderBy(u => u.User.DisplayName).ToList();
|
users = users.OrderBy(u => u.User.DisplayName).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
users = allusers;
|
|
||||||
if (!string.IsNullOrEmpty(_search))
|
|
||||||
{
|
|
||||||
users = users.Where(item =>
|
|
||||||
(
|
|
||||||
item.User.Username.Contains(_search, StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
item.User.Email.Contains(_search, StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
item.User.DisplayName.Contains(_search, StringComparison.OrdinalIgnoreCase)
|
|
||||||
)
|
|
||||||
).ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task OnSearch()
|
|
||||||
{
|
|
||||||
await UpdateUserSettingsAsync();
|
|
||||||
await LoadUsersAsync(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteUser(UserRole UserRole)
|
private async Task DeleteUser(UserRole UserRole)
|
||||||
@ -523,21 +541,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string settingSearch = "AU-search";
|
|
||||||
|
|
||||||
private async Task LoadUserSettingsAsync()
|
|
||||||
{
|
|
||||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
|
||||||
_search = SettingService.GetSetting(settings, settingSearch, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task UpdateUserSettingsAsync()
|
|
||||||
{
|
|
||||||
Dictionary<string, string> settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
|
||||||
settings = SettingService.SetSetting(settings, settingSearch, _search);
|
|
||||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task SaveSiteSettings()
|
private async Task SaveSiteSettings()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -553,6 +556,8 @@ else
|
|||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:TwoFactor", _twofactor, false);
|
settings = SettingService.SetSetting(settings, "LoginOptions:TwoFactor", _twofactor, false);
|
||||||
settings = SettingService.SetSetting(settings, "LoginOptions:CookieName", _cookiename, true);
|
settings = SettingService.SetSetting(settings, "LoginOptions:CookieName", _cookiename, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "LoginOptions:CookieExpiration", _cookieexpiration, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "LoginOptions:AlwaysRemember", _alwaysremember, false);
|
||||||
|
|
||||||
settings = SettingService.SetSetting(settings, "IdentityOptions:Password:RequiredLength", _minimumlength, true);
|
settings = SettingService.SetSetting(settings, "IdentityOptions:Password:RequiredLength", _minimumlength, true);
|
||||||
settings = SettingService.SetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", _uniquecharacters, true);
|
settings = SettingService.SetSetting(settings, "IdentityOptions:Password:RequiredUniqueChars", _uniquecharacters, true);
|
||||||
@ -576,12 +581,14 @@ else
|
|||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:Scopes", _scopes, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:Scopes", _scopes, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:Parameters", _parameters, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:Parameters", _parameters, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:PKCE", _pkce, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:PKCE", _pkce, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "ExternalLogin:AuthResponseType", _authresponsetype, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:IdentifierClaimType", _identifierclaimtype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:IdentifierClaimType", _identifierclaimtype, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:EmailClaimType", _emailclaimtype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:EmailClaimType", _emailclaimtype, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:RoleClaimType", _roleclaimtype, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:RoleClaimType", _roleclaimtype, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:ProfileClaimTypes", _profileclaimtypes, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:ProfileClaimTypes", _profileclaimtypes, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
|
||||||
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
|
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "ExternalLogin:VerifyUsers", _verifyusers, true);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(_secret) && _secret.Length < 16) _secret = (_secret + "????????????????").Substring(0, 16);
|
if (!string.IsNullOrEmpty(_secret) && _secret.Length < 16) _secret = (_secret + "????????????????").Substring(0, 16);
|
||||||
settings = SettingService.SetSetting(settings, "JwtOptions:Secret", _secret, true);
|
settings = SettingService.SetSetting(settings, "JwtOptions:Secret", _secret, true);
|
||||||
|
69
Oqtane.Client/Modules/Admin/Users/Users.razor
Normal file
69
Oqtane.Client/Modules/Admin/Users/Users.razor
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
@namespace Oqtane.Modules.Admin.Users
|
||||||
|
@inherits ModuleBase
|
||||||
|
@inject NavigationManager NavigationManager
|
||||||
|
@inject IUserService UserService
|
||||||
|
@inject IStringLocalizer<Users> Localizer
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="importfile" HelpText="Upload or select a tab delimited text file containing user information. The file must be in the Template format specified (Roles can be specified as a comma delimited list)." ResourceKey="ImportFile">Import File:</Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<FileManager Id="importfile" @ref="_filemanager" Filter="txt" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="notify" HelpText="Indicate if new users should receive an email notification" ResourceKey="Notify">Notify? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="notify" class="form-select" @bind="@_notify" required>
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="ImportUsers">@Localizer["Import"]</button>
|
||||||
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
<a class="btn btn-info" href="/users.txt" target="_new">@Localizer["Template"]</a>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private FileManager _filemanager;
|
||||||
|
|
||||||
|
public override string Title => "Import Users";
|
||||||
|
|
||||||
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
|
private string _notify = "True";
|
||||||
|
|
||||||
|
private async Task ImportUsers()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fileid = _filemanager.GetFileId();
|
||||||
|
if (fileid != -1)
|
||||||
|
{
|
||||||
|
ShowProgressIndicator();
|
||||||
|
var results = await UserService.ImportUsersAsync(PageState.Site.SiteId, fileid, bool.Parse(_notify));
|
||||||
|
if (bool.Parse(results["Success"]))
|
||||||
|
{
|
||||||
|
AddModuleMessage(string.Format(Localizer["Message.Import.Success"], results["Users"]), MessageType.Success);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Import.Failure"], MessageType.Error);
|
||||||
|
}
|
||||||
|
HideProgressIndicator();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Import.Validation"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Importing Users {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Import"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@using System.Text.Json
|
@using System.Text.Json
|
||||||
@inherits LocalizableComponent
|
@inherits LocalizableComponent
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@if (_visible)
|
@if (_visible)
|
||||||
{
|
{
|
||||||
@ -20,7 +21,7 @@
|
|||||||
{
|
{
|
||||||
<button type="button" class="@Class" @onclick="Confirm">@((MarkupString)_iconSpan) @Text</button>
|
<button type="button" class="@Class" @onclick="Confirm">@((MarkupString)_iconSpan) @Text</button>
|
||||||
}
|
}
|
||||||
<button type="button" class="btn btn-secondary" @onclick="DisplayModal">@Localize("Cancel")</button>
|
<button type="button" class="btn btn-secondary" @onclick="DisplayModal">@SharedLocalizer["Cancel"]</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _text = string.Empty;
|
private string _text = string.Empty;
|
||||||
|
private int _moduleId = -1;
|
||||||
|
private string _path = string.Empty;
|
||||||
private string _parameters = string.Empty;
|
private string _parameters = string.Empty;
|
||||||
private string _url = string.Empty;
|
private string _url = string.Empty;
|
||||||
private List<Permission> _permissions;
|
private List<Permission> _permissions;
|
||||||
@ -41,10 +43,13 @@
|
|||||||
public string Text { get; set; } // optional - defaults to Action if not specified
|
public string Text { get; set; } // optional - defaults to Action if not specified
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Parameters { get; set; } // optional - querystring parameters should be in the form of "id=x&name=y"
|
public int ModuleId { get; set; } = -1; // optional - allows the link to target a specific moduleid
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public int ModuleId { get; set; } = -1; // optional - allows the link to target a specific moduleid
|
public string Path { get; set; } = null; // optional - allows the link to target a specific page
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Parameters { get; set; } // optional - querystring parameters should be in the form of "id=x&name=y"
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Action OnClick { get; set; } = null; // optional - executes a method in the calling component
|
public Action OnClick { get; set; } = null; // optional - executes a method in the calling component
|
||||||
@ -79,6 +84,7 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string ReturnUrl { get; set; } // optional - used to set a url to redirect to
|
public string ReturnUrl { get; set; } // optional - used to set a url to redirect to
|
||||||
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Permissions))
|
if (!string.IsNullOrEmpty(Permissions))
|
||||||
@ -102,6 +108,18 @@
|
|||||||
_text = string.Empty;
|
_text = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_moduleId = ModuleState.ModuleId;
|
||||||
|
if (ModuleId != -1)
|
||||||
|
{
|
||||||
|
_moduleId = ModuleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
_path = PageState.Page.Path;
|
||||||
|
if (Path != null)
|
||||||
|
{
|
||||||
|
_path = Path;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Parameters))
|
if (!string.IsNullOrEmpty(Parameters))
|
||||||
{
|
{
|
||||||
_parameters = Parameters;
|
_parameters = Parameters;
|
||||||
@ -133,7 +151,8 @@
|
|||||||
|
|
||||||
_permissions = (PermissionList == null) ? ModuleState.PermissionList : PermissionList;
|
_permissions = (PermissionList == null) ? ModuleState.PermissionList : PermissionList;
|
||||||
_text = Localize(nameof(Text), _text);
|
_text = Localize(nameof(Text), _text);
|
||||||
_url = (ModuleId == -1) ? EditUrl(Action, _parameters) : EditUrl(ModuleId, Action, _parameters);
|
|
||||||
|
_url = EditUrl(_path, _moduleId, Action, _parameters);
|
||||||
if (!string.IsNullOrEmpty(ReturnUrl))
|
if (!string.IsNullOrEmpty(ReturnUrl))
|
||||||
{
|
{
|
||||||
_url += ((_url.Contains("?")) ? "&" : "?") + $"returnurl={WebUtility.UrlEncode(ReturnUrl)}";
|
_url += ((_url.Contains("?")) ? "&" : "?") + $"returnurl={WebUtility.UrlEncode(ReturnUrl)}";
|
||||||
|
@ -64,12 +64,12 @@
|
|||||||
|
|
||||||
if (!String.IsNullOrEmpty(ModifiedBy))
|
if (!String.IsNullOrEmpty(ModifiedBy))
|
||||||
{
|
{
|
||||||
_text += $" {Localizer["by"]} <b>{ModifiedBy}</b>";
|
_text += $" {Localizer["By"]} <b>{ModifiedBy}</b>";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ModifiedOn != null)
|
if (ModifiedOn != null)
|
||||||
{
|
{
|
||||||
_text += $" {Localizer["on"]} <b>{ModifiedOn.Value.ToString(DateTimeFormat)}</b>";
|
_text += $" {Localizer["On"]} <b>{ModifiedOn.Value.ToString(DateTimeFormat)}</b>";
|
||||||
}
|
}
|
||||||
|
|
||||||
_text += "</p>";
|
_text += "</p>";
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
@inherits LocalizableComponent
|
@inherits LocalizableComponent
|
||||||
|
|
||||||
<div class="app-autocomplete">
|
<div class="app-autocomplete">
|
||||||
<input class="form-control" value="@Value" @oninput="OnInput" @onkeyup="OnKeyUp" placeholder="@Placeholder" autocomplete="off" />
|
<input class="form-control" value="@Value" @oninput="OnInput" @onkeyup="OnKeyUp" placeholder="@Placeholder" autocomplete="off" @attributes="InputAttributes" />
|
||||||
@if (_results != null)
|
@if (_results != null)
|
||||||
{
|
{
|
||||||
<select class="form-select" style="position: relative;" value="@Value" size="@Rows" @onkeyup="OnKeyUp" @onchange="(e => OnChange(e))">
|
<select class="form-select" style="position: relative;" value="@Value" size="@Rows" @onkeyup="OnKeyUp" @onchange="(e => OnChange(e))">
|
||||||
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
Dictionary<string, string> _results;
|
Dictionary<string, string> _results;
|
||||||
|
Dictionary<string, object> InputAttributes { get; set; } = new();
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public Func<string, Task<Dictionary<string, string>>> OnSearch { get; set; } // required - an async delegate method which accepts a filter string parameter and returns a dictionary
|
public Func<string, Task<Dictionary<string, string>>> OnSearch { get; set; } // required - an async delegate method which accepts a filter string parameter and returns a dictionary
|
||||||
@ -49,6 +50,26 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string Key { get; set; } // key of item selected
|
public string Key { get; set; } // key of item selected
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public bool Required { get; set; } // optional - if the item is required
|
||||||
|
|
||||||
|
protected override void OnParametersSet()
|
||||||
|
{
|
||||||
|
if (Required)
|
||||||
|
{
|
||||||
|
if (!InputAttributes.ContainsKey(nameof(Required)))
|
||||||
|
{
|
||||||
|
InputAttributes.Add(nameof(Required), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (InputAttributes.ContainsKey(nameof(Required)))
|
||||||
|
{
|
||||||
|
InputAttributes.Remove(nameof(Required));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private async Task OnInput(ChangeEventArgs e)
|
private async Task OnInput(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
Value = e.Value?.ToString();
|
Value = e.Value?.ToString();
|
||||||
|
@ -40,10 +40,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FileId != -1 && _file != null && !UploadMultiple)
|
||||||
|
{
|
||||||
|
<input class="form-control" @bind="@_file.Name" disabled />
|
||||||
|
}
|
||||||
|
}
|
||||||
@if (ShowUpload && _haseditpermission)
|
@if (ShowUpload && _haseditpermission)
|
||||||
{
|
{
|
||||||
<div class="row">
|
<div class="row mt-2">
|
||||||
<div class="col mt-2">
|
<div class="col">
|
||||||
@if (UploadMultiple)
|
@if (UploadMultiple)
|
||||||
{
|
{
|
||||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple />
|
<input type="file" id="@_fileinputid" name="file" accept="@_filter" multiple />
|
||||||
@ -53,9 +60,9 @@
|
|||||||
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
|
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<div class="col mt-2 text-end">
|
<div class="col-auto">
|
||||||
<button type="button" class="btn btn-success" @onclick="UploadFiles">@SharedLocalizer["Upload"]</button>
|
<button type="button" class="btn btn-success" @onclick="UploadFiles">@SharedLocalizer["Upload"]</button>
|
||||||
@if (GetFileId() != -1)
|
@if (FileId != -1 && !UploadMultiple)
|
||||||
{
|
{
|
||||||
<button type="button" class="btn btn-danger mx-1" @onclick="DeleteFile">@SharedLocalizer["Delete"]</button>
|
<button type="button" class="btn btn-danger mx-1" @onclick="DeleteFile">@SharedLocalizer["Delete"]</button>
|
||||||
}
|
}
|
||||||
@ -157,6 +164,15 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public EventCallback<int> OnDelete { get; set; } // optional - executes a method in the calling component when a file is deleted
|
public EventCallback<int> OnDelete { get; set; } // optional - executes a method in the calling component when a file is deleted
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
// create unique id for component
|
||||||
|
_guid = Guid.NewGuid().ToString("N");
|
||||||
|
_fileinputid = "FileInput_" + _guid;
|
||||||
|
_progressinfoid = "ProgressInfo_" + _guid;
|
||||||
|
_progressbarid = "ProgressBar_" + _guid;
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
// packages folder is a framework folder for uploading installable nuget packages
|
// packages folder is a framework folder for uploading installable nuget packages
|
||||||
@ -168,8 +184,6 @@
|
|||||||
ShowSuccess = true;
|
ShowSuccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(Folder) && Folder != Constants.PackagesFolder)
|
if (!string.IsNullOrEmpty(Folder) && Folder != Constants.PackagesFolder)
|
||||||
{
|
{
|
||||||
Folder folder = await FolderService.GetFolderAsync(ModuleState.SiteId, Folder);
|
Folder folder = await FolderService.GetFolderAsync(ModuleState.SiteId, Folder);
|
||||||
@ -185,6 +199,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShowFolders)
|
||||||
|
{
|
||||||
|
_folders = await FolderService.GetFoldersAsync(ModuleState.SiteId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (FolderId != -1)
|
||||||
|
{
|
||||||
|
var folder = await FolderService.GetFolderAsync(FolderId);
|
||||||
|
if (folder != null)
|
||||||
|
{
|
||||||
|
_folders = new List<Folder> { folder };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FileId != -1)
|
if (FileId != -1)
|
||||||
{
|
{
|
||||||
File file = await FileService.GetFileAsync(FileId);
|
File file = await FileService.GetFileAsync(FileId);
|
||||||
@ -209,12 +239,6 @@
|
|||||||
|
|
||||||
await GetFiles();
|
await GetFiles();
|
||||||
|
|
||||||
// create unique id for component
|
|
||||||
_guid = Guid.NewGuid().ToString("N");
|
|
||||||
_fileinputid = "FileInput_" + _guid;
|
|
||||||
_progressinfoid = "ProgressInfo_" + _guid;
|
|
||||||
_progressbarid = "ProgressBar_" + _guid;
|
|
||||||
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +348,8 @@
|
|||||||
string restricted = "";
|
string restricted = "";
|
||||||
foreach (var upload in uploads)
|
foreach (var upload in uploads)
|
||||||
{
|
{
|
||||||
var extension = (upload.LastIndexOf(".") != -1) ? upload.Substring(upload.LastIndexOf(".") + 1) : "";
|
var filename = upload.Split(':')[0];
|
||||||
|
var extension = (filename.LastIndexOf(".") != -1) ? filename.Substring(filename.LastIndexOf(".") + 1) : "";
|
||||||
if (!Constants.UploadableFiles.Split(',').Contains(extension.ToLower()))
|
if (!Constants.UploadableFiles.Split(',').Contains(extension.ToLower()))
|
||||||
{
|
{
|
||||||
restricted += (restricted == "" ? "" : ",") + extension;
|
restricted += (restricted == "" ? "" : ",") + extension;
|
||||||
@ -351,19 +376,38 @@
|
|||||||
while (upload < uploads.Length && success)
|
while (upload < uploads.Length && success)
|
||||||
{
|
{
|
||||||
success = false;
|
success = false;
|
||||||
// note that progressive retry will only wait a maximum of 15 seconds which may not be long enough for very large file uploads
|
var filename = uploads[upload].Split(':')[0];
|
||||||
|
|
||||||
|
var size = Int64.Parse(uploads[upload].Split(':')[1]); // bytes
|
||||||
|
var megabits = (size / 1048576.0) * 8; // binary conversion
|
||||||
|
var uploadspeed = 2; // 2 Mbps (3G ranges from 300Kbps to 3Mbps)
|
||||||
|
var uploadtime = (megabits / uploadspeed); // seconds
|
||||||
|
var maxattempts = 5; // polling (minimum timeout duration will be 5 seconds)
|
||||||
|
var sleep = (int)Math.Ceiling(uploadtime / maxattempts) * 1000; // milliseconds
|
||||||
|
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (attempts < 5 && !success)
|
while (attempts < maxattempts && !success)
|
||||||
{
|
{
|
||||||
attempts += 1;
|
attempts += 1;
|
||||||
Thread.Sleep(1000 * attempts); // progressive retry
|
Thread.Sleep(sleep);
|
||||||
|
|
||||||
var file = await FileService.GetFileAsync(int.Parse(folder), uploads[upload]);
|
if (Folder == Constants.PackagesFolder)
|
||||||
|
{
|
||||||
|
var files = await FileService.GetFilesAsync(folder);
|
||||||
|
if (files != null && files.Any(item => item.Name == filename))
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var file = await FileService.GetFileAsync(int.Parse(folder), filename);
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
upload++;
|
upload++;
|
||||||
@ -373,8 +417,8 @@
|
|||||||
// reset progress indicators
|
// reset progress indicators
|
||||||
if (ShowProgress)
|
if (ShowProgress)
|
||||||
{
|
{
|
||||||
await interop.SetElementAttribute(_guid + "ProgressInfo", "style", "display: none;");
|
await interop.SetElementAttribute(_progressinfoid, "style", "display: none;");
|
||||||
await interop.SetElementAttribute(_guid + "ProgressBar", "style", "display: none;");
|
await interop.SetElementAttribute(_progressbarid, "style", "display: none;");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -405,11 +449,12 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// set FileId to first file in upload collection
|
// set FileId to first file in upload collection
|
||||||
var file = await FileService.GetFileAsync(int.Parse(folder), uploads[0]);
|
var file = await FileService.GetFileAsync(int.Parse(folder), uploads[0].Split(":")[0]);
|
||||||
if (file != null)
|
if (file != null)
|
||||||
{
|
{
|
||||||
FileId = file.FileId;
|
FileId = file.FileId;
|
||||||
await SetImage();
|
await SetImage();
|
||||||
|
await OnSelect.InvokeAsync(FileId);
|
||||||
await OnUpload.InvokeAsync(FileId);
|
await OnUpload.InvokeAsync(FileId);
|
||||||
}
|
}
|
||||||
await GetFiles();
|
await GetFiles();
|
||||||
@ -456,6 +501,7 @@
|
|||||||
await GetFiles();
|
await GetFiles();
|
||||||
FileId = -1;
|
FileId = -1;
|
||||||
await SetImage();
|
await SetImage();
|
||||||
|
await OnSelect.InvokeAsync(FileId);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
50
Oqtane.Client/Modules/Controls/InputList.razor
Normal file
50
Oqtane.Client/Modules/Controls/InputList.razor
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
@namespace Oqtane.Modules.Controls
|
||||||
|
@inherits LocalizableComponent
|
||||||
|
|
||||||
|
<input type="text" value="@Value" list="@_id" class="form-control" @onchange="(e => OnChange(e))" />
|
||||||
|
<datalist id="@_id" value="@Value">
|
||||||
|
@foreach(var kvp in DataList)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(kvp.Value))
|
||||||
|
{
|
||||||
|
<option value="@kvp.Key">@Localize(kvp.Value, kvp.Value)</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="@kvp.Key">@Localize(kvp.Key, kvp.Key)</option>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</datalist>
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private string _id;
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Value { get; set; }
|
||||||
|
|
||||||
|
[EditorRequired]
|
||||||
|
[Parameter]
|
||||||
|
public Dictionary<string, string> DataList { get; set; }
|
||||||
|
|
||||||
|
[EditorRequired]
|
||||||
|
[Parameter]
|
||||||
|
public EventCallback<string> ValueChanged { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
// create unique id for component
|
||||||
|
_id = "DataList_" + Guid.NewGuid().ToString("N");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OnChange(ChangeEventArgs e)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(e.Value.ToString()))
|
||||||
|
{
|
||||||
|
Value = e.Value.ToString();
|
||||||
|
if (ValueChanged.HasDelegate)
|
||||||
|
{
|
||||||
|
ValueChanged.InvokeAsync(Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,20 @@
|
|||||||
@namespace Oqtane.Modules.Controls
|
@namespace Oqtane.Modules.Controls
|
||||||
@inherits ModuleControlBase
|
@inherits ModuleControlBase
|
||||||
@inject IStringLocalizerFactory LocalizerFactory
|
@inject IStringLocalizerFactory LocalizerFactory
|
||||||
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
@typeparam TableItem
|
@typeparam TableItem
|
||||||
|
|
||||||
@if (ItemList != null)
|
@if (ItemList != null)
|
||||||
{
|
{
|
||||||
|
@if (!string.IsNullOrEmpty(SearchProperties))
|
||||||
|
{
|
||||||
|
<div class="input-group my-3">
|
||||||
|
<input id="search" class="form-control" placeholder=@string.Format(Localizer["SearchPlaceholder"], FormatSearchProperties()) @bind="@_search" />
|
||||||
|
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>
|
||||||
|
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
@if ((Toolbar == "Top" || Toolbar == "Both") && _pages > 0 && Items.Count() > _maxItems)
|
@if ((Toolbar == "Top" || Toolbar == "Both") && _pages > 0 && Items.Count() > _maxItems)
|
||||||
{
|
{
|
||||||
<ul class="pagination justify-content-center my-2">
|
<ul class="pagination justify-content-center my-2">
|
||||||
@ -175,6 +185,9 @@
|
|||||||
private int _startPage = 0;
|
private int _startPage = 0;
|
||||||
private int _endPage = 0;
|
private int _endPage = 0;
|
||||||
private int _columns = 0;
|
private int _columns = 0;
|
||||||
|
private string _search = "";
|
||||||
|
|
||||||
|
private IEnumerable<TableItem> AllItems;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Format { get; set; } // Table or Grid
|
public string Format { get; set; } // Table or Grid
|
||||||
@ -221,6 +234,9 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public Action<int> OnPageChange { get; set; } // a method to be executed in the calling component when the page changes
|
public Action<int> OnPageChange { get; set; } // a method to be executed in the calling component when the page changes
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string SearchProperties { get; set; } // comma delimited list of property names to include in search
|
||||||
|
|
||||||
private IEnumerable<TableItem> ItemList { get; set; }
|
private IEnumerable<TableItem> ItemList { get; set; }
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
@ -276,6 +292,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(SearchProperties))
|
||||||
|
{
|
||||||
|
AllItems = Items; // only used in search
|
||||||
|
if (!string.IsNullOrEmpty(_search))
|
||||||
|
{
|
||||||
|
Search();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(PageSize))
|
if (!string.IsNullOrEmpty(PageSize))
|
||||||
{
|
{
|
||||||
_maxItems = int.Parse(PageSize);
|
_maxItems = int.Parse(PageSize);
|
||||||
@ -369,4 +394,75 @@
|
|||||||
|
|
||||||
UpdateList(_page);
|
UpdateList(_page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Search()
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_search))
|
||||||
|
{
|
||||||
|
Items = AllItems.Where(item =>
|
||||||
|
{
|
||||||
|
var values = SearchProperties.Split(',')
|
||||||
|
.Select(itemType => GetPropertyValue(item, itemType))
|
||||||
|
.Where(value => value != null)
|
||||||
|
.Select(value => value.ToString().ToLower());
|
||||||
|
|
||||||
|
return values.Any(value => value.Contains(_search.ToLower()));
|
||||||
|
}).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Items = AllItems;
|
||||||
|
}
|
||||||
|
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
||||||
|
UpdateList(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private object GetPropertyValue(object obj, string propertyName)
|
||||||
|
{
|
||||||
|
var index = propertyName.IndexOf(".");
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
var propertyInfo = obj.GetType().GetProperty(propertyName.Substring(0, index));
|
||||||
|
if (propertyInfo != null)
|
||||||
|
{
|
||||||
|
return GetPropertyValue(propertyInfo.GetValue(obj), propertyName.Substring(index + 1));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var propertyInfo = obj.GetType().GetProperty(propertyName);
|
||||||
|
if (propertyInfo != null)
|
||||||
|
{
|
||||||
|
return propertyInfo.GetValue(obj);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
_search = "";
|
||||||
|
Items = AllItems;
|
||||||
|
_pages = (int)Math.Ceiling(Items.Count() / (decimal)_maxItems);
|
||||||
|
UpdateList(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string FormatSearchProperties()
|
||||||
|
{
|
||||||
|
var properties = new List<string>();
|
||||||
|
foreach (var property in SearchProperties.Split(',', StringSplitOptions.RemoveEmptyEntries))
|
||||||
|
{
|
||||||
|
var index = property.LastIndexOf(".");
|
||||||
|
if (index != -1)
|
||||||
|
{
|
||||||
|
properties.Add(property.Substring(index + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
properties.Add(property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string.Join(",", properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<div class="row" style="margin-bottom: 50px;">
|
<div class="row" style="margin-bottom: 50px;">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<TabStrip>
|
<TabStrip>
|
||||||
<TabPanel Name="Rich" Heading="Rich Text Editor">
|
<TabPanel Name="Rich" Heading="Rich Text Editor" ResourceKey="RichTextEditor">
|
||||||
@if (_richfilemanager)
|
@if (_richfilemanager)
|
||||||
{
|
{
|
||||||
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
<FileManager @ref="_fileManager" Filter="@Constants.ImageFiles" />
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
|
base.OnParametersSet(); // must be included to call method in LocalizableComponent
|
||||||
|
|
||||||
_heading = !string.IsNullOrEmpty(Heading) ? Localize(nameof(Heading), Heading) : Localize(nameof(Name), Name);
|
_heading = !string.IsNullOrEmpty(Heading) ? Localize(nameof(Heading), Heading) : Localize(nameof(Name), Name);
|
||||||
_expanded = (!string.IsNullOrEmpty(Expanded)) ? Expanded.ToLower() : "false";
|
_expanded = (!string.IsNullOrEmpty(Expanded)) ? Expanded.ToLower() : "false";
|
||||||
if (_expanded == "true") { _show = "show"; }
|
if (_expanded == "true") { _show = "show"; }
|
||||||
|
@ -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 System.Dynamic;
|
||||||
|
|
||||||
namespace Oqtane.Modules
|
namespace Oqtane.Modules
|
||||||
{
|
{
|
||||||
@ -280,13 +281,17 @@ namespace Oqtane.Modules
|
|||||||
|
|
||||||
public void SetModuleTitle(string title)
|
public void SetModuleTitle(string title)
|
||||||
{
|
{
|
||||||
var obj = new { PageModuleId = ModuleState.PageModuleId, Title = title };
|
dynamic obj = new ExpandoObject();
|
||||||
|
obj.PageModuleId = ModuleState.PageModuleId;
|
||||||
|
obj.Title = title;
|
||||||
SiteState.Properties.ModuleTitle = obj;
|
SiteState.Properties.ModuleTitle = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetModuleVisibility(bool visible)
|
public void SetModuleVisibility(bool visible)
|
||||||
{
|
{
|
||||||
var obj = new { PageModuleId = ModuleState.PageModuleId, Visible = visible };
|
dynamic obj = new ExpandoObject();
|
||||||
|
obj.PageModuleId = ModuleState.PageModuleId;
|
||||||
|
obj.Visible = visible;
|
||||||
SiteState.Properties.ModuleVisibility = obj;
|
SiteState.Properties.ModuleVisibility = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Version>4.0.1</Version>
|
<Version>5.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>
|
||||||
@ -12,7 +12,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/v4.0.1</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.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>
|
||||||
@ -21,12 +21,12 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.5" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
|
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
|
||||||
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
|
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
@ -1,19 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Loader;
|
using System.Runtime.Loader;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||||
using Microsoft.AspNetCore.Localization;
|
using Microsoft.AspNetCore.Localization;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
|
using Oqtane.Models;
|
||||||
using Oqtane.Modules;
|
using Oqtane.Modules;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
using Oqtane.UI;
|
using Oqtane.UI;
|
||||||
@ -65,6 +69,14 @@ namespace Oqtane.Client
|
|||||||
|
|
||||||
private static async Task LoadClientAssemblies(HttpClient http, IServiceProvider serviceProvider)
|
private static async Task LoadClientAssemblies(HttpClient http, IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
|
// get alias
|
||||||
|
var navigationManager = serviceProvider.GetRequiredService<NavigationManager>();
|
||||||
|
var urlpath = GetUrlPath(navigationManager.Uri);
|
||||||
|
var json = await http.GetStringAsync($"api/Installation/installed/?path={WebUtility.UrlEncode(urlpath)}");
|
||||||
|
var installation = JsonSerializer.Deserialize<Installation>(json, new JsonSerializerOptions(JsonSerializerDefaults.Web));
|
||||||
|
urlpath = installation.Alias.Path;
|
||||||
|
urlpath = (!string.IsNullOrEmpty(urlpath)) ? urlpath + "/" : urlpath;
|
||||||
|
|
||||||
var dlls = new Dictionary<string, byte[]>();
|
var dlls = new Dictionary<string, byte[]>();
|
||||||
var pdbs = new Dictionary<string, byte[]>();
|
var pdbs = new Dictionary<string, byte[]>();
|
||||||
var list = new List<string>();
|
var list = new List<string>();
|
||||||
@ -76,7 +88,7 @@ namespace Oqtane.Client
|
|||||||
if (files.Count() != 0)
|
if (files.Count() != 0)
|
||||||
{
|
{
|
||||||
// get list of assemblies from server
|
// get list of assemblies from server
|
||||||
var json = await http.GetStringAsync("/api/Installation/list");
|
json = await http.GetStringAsync($"{urlpath}api/Installation/list");
|
||||||
var assemblies = JsonSerializer.Deserialize<List<string>>(json);
|
var assemblies = JsonSerializer.Deserialize<List<string>>(json);
|
||||||
|
|
||||||
// determine which assemblies need to be downloaded
|
// determine which assemblies need to be downloaded
|
||||||
@ -138,7 +150,7 @@ namespace Oqtane.Client
|
|||||||
if (list.Count != 0)
|
if (list.Count != 0)
|
||||||
{
|
{
|
||||||
// get assemblies from server and load into client app domain
|
// get assemblies from server and load into client app domain
|
||||||
var zip = await http.GetByteArrayAsync($"/api/Installation/load?list=" + string.Join(",", list));
|
var zip = await http.GetByteArrayAsync($"{urlpath}api/Installation/load?list=" + string.Join(",", list));
|
||||||
|
|
||||||
// asemblies and debug symbols are packaged in a zip file
|
// asemblies and debug symbols are packaged in a zip file
|
||||||
using (ZipArchive archive = new ZipArchive(new MemoryStream(zip)))
|
using (ZipArchive archive = new ZipArchive(new MemoryStream(zip)))
|
||||||
@ -254,5 +266,10 @@ namespace Oqtane.Client
|
|||||||
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
|
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
|
||||||
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
|
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string GetUrlPath(string url)
|
||||||
|
{
|
||||||
|
return new Uri(url).AbsolutePath.Substring(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
789
Oqtane.Client/Resources/IconResources.resx
Normal file
789
Oqtane.Client/Resources/IconResources.resx
Normal file
@ -0,0 +1,789 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="Icon.AccountLogin" xml:space="preserve">
|
||||||
|
<value>Account Login</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.AccountLogout" xml:space="preserve">
|
||||||
|
<value>Account Logout</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ActionRedo" xml:space="preserve">
|
||||||
|
<value>Action Redo</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ActionUndo" xml:space="preserve">
|
||||||
|
<value>Action Undo</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.AlignCenter" xml:space="preserve">
|
||||||
|
<value>Align Center</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.AlignLeft" xml:space="preserve">
|
||||||
|
<value>Align Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.AlignRight" xml:space="preserve">
|
||||||
|
<value>Align Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Aperture" xml:space="preserve">
|
||||||
|
<value>Aperture</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowBottom" xml:space="preserve">
|
||||||
|
<value>Arrow Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowCircleBottom" xml:space="preserve">
|
||||||
|
<value>Arrow Circle Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowCircleLeft" xml:space="preserve">
|
||||||
|
<value>Arrow Circle Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowCircleRight" xml:space="preserve">
|
||||||
|
<value>Arrow Circle Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowCircleTop" xml:space="preserve">
|
||||||
|
<value>Arrow Circle Top</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowLeft" xml:space="preserve">
|
||||||
|
<value>Arrow Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowRight" xml:space="preserve">
|
||||||
|
<value>Arrow Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowThickBottom" xml:space="preserve">
|
||||||
|
<value>Arrow Thick Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowThickLeft" xml:space="preserve">
|
||||||
|
<value>Arrow Thick Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowThickRight" xml:space="preserve">
|
||||||
|
<value>Arrow Thick Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowThickTop" xml:space="preserve">
|
||||||
|
<value>Arrow Thick Top</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ArrowTop" xml:space="preserve">
|
||||||
|
<value>Arrow Top</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.AudioSpectrum" xml:space="preserve">
|
||||||
|
<value>Audio Spectrum</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Audio" xml:space="preserve">
|
||||||
|
<value>Audio</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Badge" xml:space="preserve">
|
||||||
|
<value>Badge</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Ban" xml:space="preserve">
|
||||||
|
<value>Ban</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.BarChart" xml:space="preserve">
|
||||||
|
<value>Bar Chart</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Basket" xml:space="preserve">
|
||||||
|
<value>Basket</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.BatteryEmpty" xml:space="preserve">
|
||||||
|
<value>Battery Empty</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.BatteryFull" xml:space="preserve">
|
||||||
|
<value>Battery Full</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Beaker" xml:space="preserve">
|
||||||
|
<value>Beaker</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bell" xml:space="preserve">
|
||||||
|
<value>Bell</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bluetooth" xml:space="preserve">
|
||||||
|
<value>Bluetooth</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bold" xml:space="preserve">
|
||||||
|
<value>Bold</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bolt" xml:space="preserve">
|
||||||
|
<value>Bolt</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Book" xml:space="preserve">
|
||||||
|
<value>Book</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bookmark" xml:space="preserve">
|
||||||
|
<value>Bookmark</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Box" xml:space="preserve">
|
||||||
|
<value>Box</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Briefcase" xml:space="preserve">
|
||||||
|
<value>Briefcase</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.BritishPound" xml:space="preserve">
|
||||||
|
<value>British Pound</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Browser" xml:space="preserve">
|
||||||
|
<value>Browser</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Brush" xml:space="preserve">
|
||||||
|
<value>Brush</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bug" xml:space="preserve">
|
||||||
|
<value>Bug</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Bullhorn" xml:space="preserve">
|
||||||
|
<value>Bullhorn</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Calculator" xml:space="preserve">
|
||||||
|
<value>Calculator</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Calendar" xml:space="preserve">
|
||||||
|
<value>Calendar</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CameraSlr" xml:space="preserve">
|
||||||
|
<value>Camera Slr</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CaretBottom" xml:space="preserve">
|
||||||
|
<value>Caret Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CaretLeft" xml:space="preserve">
|
||||||
|
<value>Caret Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CaretRight" xml:space="preserve">
|
||||||
|
<value>Caret Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CaretTop" xml:space="preserve">
|
||||||
|
<value>Caret Top</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Cart" xml:space="preserve">
|
||||||
|
<value>Cart</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Chat" xml:space="preserve">
|
||||||
|
<value>Chat</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Check" xml:space="preserve">
|
||||||
|
<value>Check</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ChevronBottom" xml:space="preserve">
|
||||||
|
<value>Chevron Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ChevronLeft" xml:space="preserve">
|
||||||
|
<value>Chevron Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ChevronRight" xml:space="preserve">
|
||||||
|
<value>Chevron Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ChevronTop" xml:space="preserve">
|
||||||
|
<value>Chevron Top</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CircleCheck" xml:space="preserve">
|
||||||
|
<value>Circle Check</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CircleX" xml:space="preserve">
|
||||||
|
<value>Circle X</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Clipboard" xml:space="preserve">
|
||||||
|
<value>Clipboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Clock" xml:space="preserve">
|
||||||
|
<value>Clock</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CloudDownload" xml:space="preserve">
|
||||||
|
<value>Cloud Download</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CloudUpload" xml:space="preserve">
|
||||||
|
<value>Cloud Upload</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Cloud" xml:space="preserve">
|
||||||
|
<value>Cloud</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Cloudy" xml:space="preserve">
|
||||||
|
<value>Cloudy</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Code" xml:space="preserve">
|
||||||
|
<value>Code</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Cog" xml:space="preserve">
|
||||||
|
<value>Cog</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CollapseDown" xml:space="preserve">
|
||||||
|
<value>Collapse Down</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CollapseLeft" xml:space="preserve">
|
||||||
|
<value>Collapse Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CollapseRight" xml:space="preserve">
|
||||||
|
<value>Collapse Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CollapseUp" xml:space="preserve">
|
||||||
|
<value>Collapse Up</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Command" xml:space="preserve">
|
||||||
|
<value>Command</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CommentSquare" xml:space="preserve">
|
||||||
|
<value>Comment Square</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Compass" xml:space="preserve">
|
||||||
|
<value>Compass</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Contrast" xml:space="preserve">
|
||||||
|
<value>Contrast</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Copywriting" xml:space="preserve">
|
||||||
|
<value>Copywriting</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.CreditCard" xml:space="preserve">
|
||||||
|
<value>Credit Card</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Crop" xml:space="preserve">
|
||||||
|
<value>Crop</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Dashboard" xml:space="preserve">
|
||||||
|
<value>Dashboard</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.DataTransferDownload" xml:space="preserve">
|
||||||
|
<value>Data Transfer Download</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.DataTransferUpload" xml:space="preserve">
|
||||||
|
<value>Data Transfer Upload</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Delete" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Dial" xml:space="preserve">
|
||||||
|
<value>Dial</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Document" xml:space="preserve">
|
||||||
|
<value>Document</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Dollar" xml:space="preserve">
|
||||||
|
<value>Dollar</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.DoubleQuoteSansLeft" xml:space="preserve">
|
||||||
|
<value>Double Quote Sans Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.DoubleQuoteSansRight" xml:space="preserve">
|
||||||
|
<value>Double Quote Sans Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.DoubleQuoteSerifLeft" xml:space="preserve">
|
||||||
|
<value>Double Quote Serif Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.DoubleQuoteSerifRight" xml:space="preserve">
|
||||||
|
<value>Double Quote Serif Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Droplet" xml:space="preserve">
|
||||||
|
<value>Droplet</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Eject" xml:space="preserve">
|
||||||
|
<value>Eject</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Elevator" xml:space="preserve">
|
||||||
|
<value>Elevator</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Ellipses" xml:space="preserve">
|
||||||
|
<value>Ellipses</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.EnvelopeClosed" xml:space="preserve">
|
||||||
|
<value>Envelope Closed</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.EnvelopeOpen" xml:space="preserve">
|
||||||
|
<value>Envelope Open</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Euro" xml:space="preserve">
|
||||||
|
<value>Euro</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Excerpt" xml:space="preserve">
|
||||||
|
<value>Excerpt</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ExpandDown" xml:space="preserve">
|
||||||
|
<value>Expand Down</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ExpandLeft" xml:space="preserve">
|
||||||
|
<value>Expand Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ExpandRight" xml:space="preserve">
|
||||||
|
<value>Expand Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ExpandUp" xml:space="preserve">
|
||||||
|
<value>Expand Up</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ExternalLink" xml:space="preserve">
|
||||||
|
<value>External Link</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Eye" xml:space="preserve">
|
||||||
|
<value>Eye</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Eyedropper" xml:space="preserve">
|
||||||
|
<value>Eyedropper</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.File" xml:space="preserve">
|
||||||
|
<value>File</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Fire" xml:space="preserve">
|
||||||
|
<value>Fire</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Flag" xml:space="preserve">
|
||||||
|
<value>Flag</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Flash" xml:space="preserve">
|
||||||
|
<value>Flash</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Folder" xml:space="preserve">
|
||||||
|
<value>Folder</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Fork" xml:space="preserve">
|
||||||
|
<value>Fork</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.FullscreenEnter" xml:space="preserve">
|
||||||
|
<value>Fullscreen Enter</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.FullscreenExit" xml:space="preserve">
|
||||||
|
<value>Fullscreen Exit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Globe" xml:space="preserve">
|
||||||
|
<value>Globe</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Graph" xml:space="preserve">
|
||||||
|
<value>Graph</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.GridFourUp" xml:space="preserve">
|
||||||
|
<value>Grid Four Up</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.GridThreeUp" xml:space="preserve">
|
||||||
|
<value>Grid Three Up</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.GridTwoUp" xml:space="preserve">
|
||||||
|
<value>Grid Two Up</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.HardDrive" xml:space="preserve">
|
||||||
|
<value>Hard Drive</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Header" xml:space="preserve">
|
||||||
|
<value>Header</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Headphones" xml:space="preserve">
|
||||||
|
<value>Headphones</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Heart" xml:space="preserve">
|
||||||
|
<value>Heart</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Home" xml:space="preserve">
|
||||||
|
<value>Home</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Image" xml:space="preserve">
|
||||||
|
<value>Image</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Inbox" xml:space="preserve">
|
||||||
|
<value>Inbox</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Infinity" xml:space="preserve">
|
||||||
|
<value>Infinity</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Info" xml:space="preserve">
|
||||||
|
<value>Info</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Italic" xml:space="preserve">
|
||||||
|
<value>Italic</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.JustifyCenter" xml:space="preserve">
|
||||||
|
<value>Justify Center</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.JustifyLeft" xml:space="preserve">
|
||||||
|
<value>Justify Left</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.JustifyRight" xml:space="preserve">
|
||||||
|
<value>Justify Right</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Key" xml:space="preserve">
|
||||||
|
<value>Key</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Laptop" xml:space="preserve">
|
||||||
|
<value>Laptop</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Layers" xml:space="preserve">
|
||||||
|
<value>Layers</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Lightbulb" xml:space="preserve">
|
||||||
|
<value>Lightbulb</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.LinkBroken" xml:space="preserve">
|
||||||
|
<value>Link Broken</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.LinkIntact" xml:space="preserve">
|
||||||
|
<value>Link Intact</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ListRich" xml:space="preserve">
|
||||||
|
<value>List Rich</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.List" xml:space="preserve">
|
||||||
|
<value>List</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Location" xml:space="preserve">
|
||||||
|
<value>Location</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.LockLocked" xml:space="preserve">
|
||||||
|
<value>Lock Locked</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.LockUnlocked" xml:space="preserve">
|
||||||
|
<value>Lock Unlocked</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.LoopCircular" xml:space="preserve">
|
||||||
|
<value>Loop Circular</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.LoopSquare" xml:space="preserve">
|
||||||
|
<value>Loop Square</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Loop" xml:space="preserve">
|
||||||
|
<value>Loop</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MagnifyingGlass" xml:space="preserve">
|
||||||
|
<value>Magnifying Glass</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MapMarker" xml:space="preserve">
|
||||||
|
<value>Map Marker</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Map" xml:space="preserve">
|
||||||
|
<value>Map</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaPause" xml:space="preserve">
|
||||||
|
<value>Media Pause</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaPlay" xml:space="preserve">
|
||||||
|
<value>Media Play</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaRecord" xml:space="preserve">
|
||||||
|
<value>Media Record</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaSkipBackward" xml:space="preserve">
|
||||||
|
<value>Media Skip Backward</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaSkipForward" xml:space="preserve">
|
||||||
|
<value>Media Skip Forward</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaStepBackward" xml:space="preserve">
|
||||||
|
<value>Media Step Backward</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaStepForward" xml:space="preserve">
|
||||||
|
<value>Media Step Forward</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MediaStop" xml:space="preserve">
|
||||||
|
<value>Media Stop</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MedicalCross" xml:space="preserve">
|
||||||
|
<value>Medical Cross</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Menu" xml:space="preserve">
|
||||||
|
<value>Menu</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Microphone" xml:space="preserve">
|
||||||
|
<value>Microphone</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Minus" xml:space="preserve">
|
||||||
|
<value>Minus</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Monitor" xml:space="preserve">
|
||||||
|
<value>Monitor</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Moon" xml:space="preserve">
|
||||||
|
<value>Moon</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Move" xml:space="preserve">
|
||||||
|
<value>Move</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.MusicalNote" xml:space="preserve">
|
||||||
|
<value>Musical Note</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Paperclip" xml:space="preserve">
|
||||||
|
<value>Paperclip</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Pencil" xml:space="preserve">
|
||||||
|
<value>Pencil</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.People" xml:space="preserve">
|
||||||
|
<value>People</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Person" xml:space="preserve">
|
||||||
|
<value>Person</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Phone" xml:space="preserve">
|
||||||
|
<value>Phone</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.PieChart" xml:space="preserve">
|
||||||
|
<value>Pie Chart</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Pin" xml:space="preserve">
|
||||||
|
<value>Pin</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.PlayCircle" xml:space="preserve">
|
||||||
|
<value>Play Circle</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Plus" xml:space="preserve">
|
||||||
|
<value>Plus</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.PowerStandby" xml:space="preserve">
|
||||||
|
<value>Power Standby</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Print" xml:space="preserve">
|
||||||
|
<value>Print</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Project" xml:space="preserve">
|
||||||
|
<value>Project</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Pulse" xml:space="preserve">
|
||||||
|
<value>Pulse</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.PuzzlePiece" xml:space="preserve">
|
||||||
|
<value>Puzzle Piece</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.QuestionMark" xml:space="preserve">
|
||||||
|
<value>Question Mark</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Rain" xml:space="preserve">
|
||||||
|
<value>Rain</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Random" xml:space="preserve">
|
||||||
|
<value>Random</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Reload" xml:space="preserve">
|
||||||
|
<value>Reload</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ResizeBoth" xml:space="preserve">
|
||||||
|
<value>Resize Both</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ResizeHeight" xml:space="preserve">
|
||||||
|
<value>Resize Height</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ResizeWidth" xml:space="preserve">
|
||||||
|
<value>Resize Width</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.RssAlt" xml:space="preserve">
|
||||||
|
<value>Rss Alt</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Rss" xml:space="preserve">
|
||||||
|
<value>Rss</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Script" xml:space="preserve">
|
||||||
|
<value>Script</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ShareBoxed" xml:space="preserve">
|
||||||
|
<value>Share Boxed</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Share" xml:space="preserve">
|
||||||
|
<value>Share</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Shield" xml:space="preserve">
|
||||||
|
<value>Shield</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Signal" xml:space="preserve">
|
||||||
|
<value>Signal</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Signpost" xml:space="preserve">
|
||||||
|
<value>Signpost</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.SortAscending" xml:space="preserve">
|
||||||
|
<value>Sort Ascending</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.SortDescending" xml:space="preserve">
|
||||||
|
<value>Sort Descending</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Spreadsheet" xml:space="preserve">
|
||||||
|
<value>Spreadsheet</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Star" xml:space="preserve">
|
||||||
|
<value>Star</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Sun" xml:space="preserve">
|
||||||
|
<value>Sun</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Tablet" xml:space="preserve">
|
||||||
|
<value>Tablet</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Tag" xml:space="preserve">
|
||||||
|
<value>Tag</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Tags" xml:space="preserve">
|
||||||
|
<value>Tags</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Target" xml:space="preserve">
|
||||||
|
<value>Target</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Task" xml:space="preserve">
|
||||||
|
<value>Task</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Terminal" xml:space="preserve">
|
||||||
|
<value>Terminal</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Text" xml:space="preserve">
|
||||||
|
<value>Text</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ThumbDown" xml:space="preserve">
|
||||||
|
<value>Thumb Down</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ThumbUp" xml:space="preserve">
|
||||||
|
<value>Thumb Up</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Timer" xml:space="preserve">
|
||||||
|
<value>Timer</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Transfer" xml:space="preserve">
|
||||||
|
<value>Transfer</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Trash" xml:space="preserve">
|
||||||
|
<value>Trash</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Underline" xml:space="preserve">
|
||||||
|
<value>Underline</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.VerticalAlignBottom" xml:space="preserve">
|
||||||
|
<value>Vertical Align Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.VerticalAlignCenter" xml:space="preserve">
|
||||||
|
<value>Vertical Align Center</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.VerticalAlignTop" xml:space="preserve">
|
||||||
|
<value>Vertical Align Top</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Video" xml:space="preserve">
|
||||||
|
<value>Video</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.VolumeHigh" xml:space="preserve">
|
||||||
|
<value>Volume High</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.VolumeLow" xml:space="preserve">
|
||||||
|
<value>Volume Low</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.VolumeOff" xml:space="preserve">
|
||||||
|
<value>Volume Off</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Warning" xml:space="preserve">
|
||||||
|
<value>Warning</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Wifi" xml:space="preserve">
|
||||||
|
<value>Wifi</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Wrench" xml:space="preserve">
|
||||||
|
<value>Wrench</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.X" xml:space="preserve">
|
||||||
|
<value>X</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.Yen" xml:space="preserve">
|
||||||
|
<value>Yen</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ZoomIn" xml:space="preserve">
|
||||||
|
<value>Zoom In</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon.ZoomOut" xml:space="preserve">
|
||||||
|
<value>Zoom Out</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
@ -162,4 +162,7 @@
|
|||||||
<data name="Name.Text" xml:space="preserve">
|
<data name="Name.Text" xml:space="preserve">
|
||||||
<value>Name:</value>
|
<value>Name:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DownloadFiles.Heading" xml:space="preserve">
|
||||||
|
<value>Download Files</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
|
||||||
@ -150,4 +150,7 @@
|
|||||||
<data name="Description.Text" xml:space="preserve">
|
<data name="Description.Text" xml:space="preserve">
|
||||||
<value>Description:</value>
|
<value>Description:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="File Management" xml:space="preserve">
|
||||||
|
<value>File Management</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
|
||||||
@ -178,9 +178,21 @@
|
|||||||
<value>Capacity:</value>
|
<value>Capacity:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ImageSizes.HelpText" xml:space="preserve">
|
<data name="ImageSizes.HelpText" xml:space="preserve">
|
||||||
<value>Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,x200,200x)</value>
|
<value>Enter a list of image sizes which can be generated dynamically from uploaded images (ie. 200x200,400x400). Use * to indicate the folder supports all image sizes.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ImageSizes.Text" xml:space="preserve">
|
<data name="ImageSizes.Text" xml:space="preserve">
|
||||||
<value>Image Sizes:</value>
|
<value>Image Sizes:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="FolderManagement.Title" xml:space="preserve">
|
||||||
|
<value>Folder Management!</value>
|
||||||
|
</data>
|
||||||
|
<data name="Private" xml:space="preserve">
|
||||||
|
<value>Private</value>
|
||||||
|
</data>
|
||||||
|
<data name="Public" xml:space="preserve">
|
||||||
|
<value>Public</value>
|
||||||
|
</data>
|
||||||
|
<data name="Folder Management" xml:space="preserve">
|
||||||
|
<value>Folder Management</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -195,4 +195,7 @@
|
|||||||
<data name="Message.NoJobs" xml:space="preserve">
|
<data name="Message.NoJobs" xml:space="preserve">
|
||||||
<value>Please Note That After An Initial Installation You Must <a href={0}>Restart</a> The Application In Order To Activate The Default Scheduled Jobs.</value>
|
<value>Please Note That After An Initial Installation You Must <a href={0}>Restart</a> The Application In Order To Activate The Default Scheduled Jobs.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Refresh.Text" xml:space="preserve">
|
||||||
|
<value>Refresh</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -124,7 +124,7 @@
|
|||||||
<value>Error Loading Packages</value>
|
<value>Error Loading Packages</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Module.Download" xml:space="preserve">
|
<data name="Success.Module.Download" xml:space="preserve">
|
||||||
<value>Module Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
<value>Module Package Downloaded 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>
|
||||||
@ -136,9 +136,12 @@
|
|||||||
<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>
|
||||||
</data>
|
</data>
|
||||||
<data name="Download.Heading" xml:space="preserve">
|
<data name="Download.Heading" xml:space="preserve">
|
||||||
<value>Download</value>
|
<value>Marketplace</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Upload.Heading" xml:space="preserve">
|
<data name="Upload.Heading" xml:space="preserve">
|
||||||
<value>Upload</value>
|
<value>Upload</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Product" xml:space="preserve">
|
||||||
|
<value>Product</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -132,6 +132,9 @@
|
|||||||
<data name="Message.Require.ValidName" xml:space="preserve">
|
<data name="Message.Require.ValidName" xml:space="preserve">
|
||||||
<value>You Must Provide A Valid Owner Name And Module Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template</value>
|
<value>You Must Provide A Valid Owner Name And Module Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.Require.ValidDescription" xml:space="preserve">
|
||||||
|
<value>You Must Provide A Valid Description (ie. No Punctuation)</value>
|
||||||
|
</data>
|
||||||
<data name="OwnerName.HelpText" xml:space="preserve">
|
<data name="OwnerName.HelpText" xml:space="preserve">
|
||||||
<value>Enter the name of the organization who is developing this module. It should not contain spaces or punctuation.</value>
|
<value>Enter the name of the organization who is developing this module. It should not contain spaces or punctuation.</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -196,7 +196,7 @@
|
|||||||
<value>Information</value>
|
<value>Information</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PackageName.HelpText" xml:space="preserve">
|
<data name="PackageName.HelpText" xml:space="preserve">
|
||||||
<value>The unique name of the package from which this module was installed</value>
|
<value>The unique name of the package from which this module was installed. This value must be specified within the module's IModule interface specification.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PackageName.Text" xml:space="preserve">
|
<data name="PackageName.Text" xml:space="preserve">
|
||||||
<value>Package Name:</value>
|
<value>Package Name:</value>
|
||||||
@ -225,4 +225,19 @@
|
|||||||
<data name="IsEnabled.Text" xml:space="preserve">
|
<data name="IsEnabled.Text" xml:space="preserve">
|
||||||
<value>Enabled?</value>
|
<value>Enabled?</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="View License" xml:space="preserve">
|
||||||
|
<value>View License</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.Validate" xml:space="preserve">
|
||||||
|
<value>Error Validating Package</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Download" xml:space="preserve">
|
||||||
|
<value>Package Version Has Been Verified. Please Select The Download Button To Obtain The Package.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Validate" xml:space="preserve">
|
||||||
|
<value>This Package Version Has Not Been Registered In The Oqtane Marketplace Or You Do Not Have The Right To Use It From This Installation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Validate" xml:space="preserve">
|
||||||
|
<value>Validate</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -144,6 +144,9 @@
|
|||||||
<data name="DeleteModule.Header" xml:space="preserve">
|
<data name="DeleteModule.Header" xml:space="preserve">
|
||||||
<value>Delete Module</value>
|
<value>Delete Module</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DeleteModule.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
<data name="InUse" xml:space="preserve">
|
<data name="InUse" xml:space="preserve">
|
||||||
<value>In Use?</value>
|
<value>In Use?</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -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
|
||||||
@ -132,4 +132,7 @@
|
|||||||
<data name="Success.Content.Export" xml:space="preserve">
|
<data name="Success.Content.Export" xml:space="preserve">
|
||||||
<value>Content Exported Successfully</value>
|
<value>Content Exported Successfully</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Export Content" xml:space="preserve">
|
||||||
|
<value>Export Content</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
|
||||||
@ -138,4 +138,7 @@
|
|||||||
<data name="Message.Required.ImportContent" xml:space="preserve">
|
<data name="Message.Required.ImportContent" xml:space="preserve">
|
||||||
<value>You Must Enter Some Content To Import</value>
|
<value>You Must Enter Some Content To Import</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Import Content" xml:space="preserve">
|
||||||
|
<value>Import Content</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
|
||||||
@ -156,4 +156,13 @@
|
|||||||
<data name="Module.Text" xml:space="preserve">
|
<data name="Module.Text" xml:space="preserve">
|
||||||
<value>Module:</value>
|
<value>Module:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Module Settings" xml:space="preserve">
|
||||||
|
<value>Module Settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="Pane.HelpText" xml:space="preserve">
|
||||||
|
<value>The pane where the module will be displayed</value>
|
||||||
|
</data>
|
||||||
|
<data name="Pane.Text" xml:space="preserve">
|
||||||
|
<value>Pane:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -249,4 +249,10 @@
|
|||||||
<data name="ThemeChanged.Message" xml:space="preserve">
|
<data name="ThemeChanged.Message" xml:space="preserve">
|
||||||
<value>Please Note That Overriding The Default Site Theme With An Unrelated Page Theme May Result In Compatibility Issues For Your Site</value>
|
<value>Please Note That Overriding The Default Site Theme With An Unrelated Page Theme May Result In Compatibility Issues For Your Site</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Permissions.Heading" xml:space="preserve">
|
||||||
|
<value>Permissions</value>
|
||||||
|
</data>
|
||||||
|
<data name="Theme.Heading" xml:space="preserve">
|
||||||
|
<value>Theme Settings</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -189,4 +189,10 @@
|
|||||||
<data name="Validation.Text" xml:space="preserve">
|
<data name="Validation.Text" xml:space="preserve">
|
||||||
<value>Validation: </value>
|
<value>Validation: </value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Rows.HelpText" xml:space="preserve">
|
||||||
|
<value>The number of rows for text entry (one is the default)</value>
|
||||||
|
</data>
|
||||||
|
<data name="Rows.Text" xml:space="preserve">
|
||||||
|
<value>Rows: </value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -138,4 +138,13 @@
|
|||||||
<data name="EditProfile.Text" xml:space="preserve">
|
<data name="EditProfile.Text" xml:space="preserve">
|
||||||
<value>Edit</value>
|
<value>Edit</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Category" xml:space="preserve">
|
||||||
|
<value>Category</value>
|
||||||
|
</data>
|
||||||
|
<data name="Order" xml:space="preserve">
|
||||||
|
<value>Order</value>
|
||||||
|
</data>
|
||||||
|
<data name="Title" xml:space="preserve">
|
||||||
|
<value>Title</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -120,9 +120,15 @@
|
|||||||
<data name="DeleteModule.Header" xml:space="preserve">
|
<data name="DeleteModule.Header" xml:space="preserve">
|
||||||
<value>Delete Module</value>
|
<value>Delete Module</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DeleteModule.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
<data name="DeletePage.Header" xml:space="preserve">
|
<data name="DeletePage.Header" xml:space="preserve">
|
||||||
<value>Delete Page</value>
|
<value>Delete Page</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DeletePage.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
<data name="NoPage.Deleted" xml:space="preserve">
|
<data name="NoPage.Deleted" xml:space="preserve">
|
||||||
<value>No Deleted Pages</value>
|
<value>No Deleted Pages</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -136,7 +136,7 @@
|
|||||||
<value>User Account Created. Please Check Your Email For Verification Instructions.</value>
|
<value>User Account Created. Please Check Your Email For Verification Instructions.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.User.AddInfo" xml:space="preserve">
|
<data name="Error.User.AddInfo" xml:space="preserve">
|
||||||
<value>Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.</value>
|
<value>Error Adding User. Please Ensure Password Meets Complexity Requirements And Username And Email Is Not Already In Use.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Password.NoMatch" xml:space="preserve">
|
<data name="Message.Password.NoMatch" xml:space="preserve">
|
||||||
<value>Passwords Entered Do Not Match</value>
|
<value>Passwords Entered Do Not Match</value>
|
||||||
@ -177,19 +177,4 @@
|
|||||||
<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>
|
@ -312,6 +312,9 @@
|
|||||||
<data name="Database.HelpText" xml:space="preserve">
|
<data name="Database.HelpText" xml:space="preserve">
|
||||||
<value>The type of database</value>
|
<value>The type of database</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DeleteSite.Header" xml:space="preserve">
|
||||||
|
<value>Delete Site</value>
|
||||||
|
</data>
|
||||||
<data name="DeleteSite.Text" xml:space="preserve">
|
<data name="DeleteSite.Text" xml:space="preserve">
|
||||||
<value>Delete Site</value>
|
<value>Delete Site</value>
|
||||||
</data>
|
</data>
|
||||||
@ -381,4 +384,22 @@
|
|||||||
<data name="Version.Text" xml:space="preserve">
|
<data name="Version.Text" xml:space="preserve">
|
||||||
<value>Version:</value>
|
<value>Version:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DeleteAlias.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
|
<data name="DeleteAlias.Header" xml:space="preserve">
|
||||||
|
<value>Delete Alias</value>
|
||||||
|
</data>
|
||||||
|
<data name="SiteGuid.HelpText" xml:space="preserve">
|
||||||
|
<value>The Unique Identifier For The Site</value>
|
||||||
|
</data>
|
||||||
|
<data name="SiteGuid.Text" xml:space="preserve">
|
||||||
|
<value>ID:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Retention.HelpText" xml:space="preserve">
|
||||||
|
<value>Number of days of notifications to retain</value>
|
||||||
|
</data>
|
||||||
|
<data name="Retention.Text" xml:space="preserve">
|
||||||
|
<value>Retention (Days):</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -132,9 +132,6 @@
|
|||||||
<data name="Theme.Select" xml:space="preserve">
|
<data name="Theme.Select" xml:space="preserve">
|
||||||
<value>Select Theme</value>
|
<value>Select Theme</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DefaultContainer.Admin" xml:space="preserve">
|
|
||||||
<value>Default Admin Container</value>
|
|
||||||
</data>
|
|
||||||
<data name="Aliases.HelpText" xml:space="preserve">
|
<data name="Aliases.HelpText" xml:space="preserve">
|
||||||
<value>The urls for the site (comman delimited). This can include domain names (ie. domain.com), subdomains (ie. sub.domain.com) or a virtual folder (ie. domain.com/folder).</value>
|
<value>The urls for the site (comman delimited). This can include domain names (ie. domain.com), subdomains (ie. sub.domain.com) or a virtual folder (ie. domain.com/folder).</value>
|
||||||
</data>
|
</data>
|
||||||
@ -183,9 +180,6 @@
|
|||||||
<data name="DefaultTheme.HelpText" xml:space="preserve">
|
<data name="DefaultTheme.HelpText" xml:space="preserve">
|
||||||
<value>Select the default theme for the site</value>
|
<value>Select the default theme for the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AdminContainer.HelpText" xml:space="preserve">
|
|
||||||
<value>Select the admin container for the site</value>
|
|
||||||
</data>
|
|
||||||
<data name="SiteTemplate.HelpText" xml:space="preserve">
|
<data name="SiteTemplate.HelpText" xml:space="preserve">
|
||||||
<value>Select the site template</value>
|
<value>Select the site template</value>
|
||||||
</data>
|
</data>
|
||||||
@ -207,9 +201,6 @@
|
|||||||
<data name="Name.Text" xml:space="preserve">
|
<data name="Name.Text" xml:space="preserve">
|
||||||
<value>Site Name: </value>
|
<value>Site Name: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="AdminContainer.Text" xml:space="preserve">
|
|
||||||
<value>Admin Container: </value>
|
|
||||||
</data>
|
|
||||||
<data name="SiteTemplate.Text" xml:space="preserve">
|
<data name="SiteTemplate.Text" xml:space="preserve">
|
||||||
<value>Site Template: </value>
|
<value>Site Template: </value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -219,11 +219,11 @@
|
|||||||
<data name="Success.Register" xml:space="preserve">
|
<data name="Success.Register" xml:space="preserve">
|
||||||
<value>You Have Been Successfully Registered For Updates</value>
|
<value>You Have Been Successfully Registered For Updates</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PackageService.HelpText" xml:space="preserve">
|
<data name="PackageManager.HelpText" xml:space="preserve">
|
||||||
<value>Specify If The Package Service Is Enabled For Installing Modules, Themes, And Translations</value>
|
<value>Specify The Package Manager Service For Installing Modules, Themes, And Translations. If This Field Is Blank It Means The Package Manager Service Is Disabled For This Installation.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PackageService.Text" xml:space="preserve">
|
<data name="PackageManager.Text" xml:space="preserve">
|
||||||
<value>Package Service Enabled?</value>
|
<value>Package Manager:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Swagger.HelpText" xml:space="preserve">
|
<data name="Swagger.HelpText" xml:space="preserve">
|
||||||
<value>Specify If Swagger Is Enabled For Your Server API</value>
|
<value>Specify If Swagger Is Enabled For Your Server API</value>
|
||||||
|
@ -124,7 +124,7 @@
|
|||||||
<value>Theme: </value>
|
<value>Theme: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Theme.Download" xml:space="preserve">
|
<data name="Success.Theme.Download" xml:space="preserve">
|
||||||
<value>Theme Package Saved Successfully. You Must <a href={0}>Restart</a> Your Application To Complete The Installation.</value>
|
<value>Theme Package Downloaded 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>
|
||||||
@ -135,4 +135,13 @@
|
|||||||
<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>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Download.Heading" xml:space="preserve">
|
||||||
|
<value>Marketplace</value>
|
||||||
|
</data>
|
||||||
|
<data name="Upload.Heading" xml:space="preserve">
|
||||||
|
<value>Upload</value>
|
||||||
|
</data>
|
||||||
|
<data name="Product" xml:space="preserve">
|
||||||
|
<value>Product</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
|
||||||
@ -163,7 +163,7 @@
|
|||||||
<value>The license of the theme</value>
|
<value>The license of the theme</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PackageName.HelpText" xml:space="preserve">
|
<data name="PackageName.HelpText" xml:space="preserve">
|
||||||
<value>The unique name of the package from which this module was installed</value>
|
<value>The unique name of the package from which this theme was installed. This value must be specified within the themee's ITheme interface specification.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="PackageName.Text" xml:space="preserve">
|
<data name="PackageName.Text" xml:space="preserve">
|
||||||
<value>Package Name:</value>
|
<value>Package Name:</value>
|
||||||
@ -177,4 +177,19 @@
|
|||||||
<data name="IsEnabled.Text" xml:space="preserve">
|
<data name="IsEnabled.Text" xml:space="preserve">
|
||||||
<value>Enabled?</value>
|
<value>Enabled?</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="View License" xml:space="preserve">
|
||||||
|
<value>View License</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.Validate" xml:space="preserve">
|
||||||
|
<value>Error Validating Package</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Download" xml:space="preserve">
|
||||||
|
<value>Package Version Has Been Verified. Please Select The Download Button To Obtain The Package.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Validate" xml:space="preserve">
|
||||||
|
<value>This Package Version Has Not Been Registered In The Oqtane Marketplace Or You Do Not Have The Right To Use It From This Installation</value>
|
||||||
|
</data>
|
||||||
|
<data name="Validate" xml:space="preserve">
|
||||||
|
<value>Validate</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -138,12 +138,21 @@
|
|||||||
<data name="DeleteTheme.Header" xml:space="preserve">
|
<data name="DeleteTheme.Header" xml:space="preserve">
|
||||||
<value>Delete Theme</value>
|
<value>Delete Theme</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DeleteTheme.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
<data name="CreateTheme.Text" xml:space="preserve">
|
<data name="CreateTheme.Text" xml:space="preserve">
|
||||||
<value>Create Theme</value>
|
<value>Create Theme</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="InstallTheme.Text" xml:space="preserve">
|
||||||
|
<value>Install Theme</value>
|
||||||
|
</data>
|
||||||
<data name="ViewTheme.Text" xml:space="preserve">
|
<data name="ViewTheme.Text" xml:space="preserve">
|
||||||
<value>View</value>
|
<value>View</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="EditTheme.Text" xml:space="preserve">
|
||||||
|
<value>Edit</value>
|
||||||
|
</data>
|
||||||
<data name="Enabled" xml:space="preserve">
|
<data name="Enabled" xml:space="preserve">
|
||||||
<value>Enabled?</value>
|
<value>Enabled?</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -141,4 +141,13 @@
|
|||||||
<data name="Upload.Heading" xml:space="preserve">
|
<data name="Upload.Heading" xml:space="preserve">
|
||||||
<value>Upload</value>
|
<value>Upload</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.Text" xml:space="preserve">
|
||||||
|
<value>Framework Is Already Up To Date</value>
|
||||||
|
</data>
|
||||||
|
<data name="MessageUpgrade.Text" xml:space="preserve">
|
||||||
|
<value>Upload A Framework Package (Oqtane.Framework.version.nupkg) And Then Select Upgrade</value>
|
||||||
|
</data>
|
||||||
|
<data name="Localhost.Text" xml:space="preserve">
|
||||||
|
<value>You Cannot Perform A System Update In A Development Environment</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
|
||||||
@ -121,7 +121,7 @@
|
|||||||
<value>Message: </value>
|
<value>Message: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.User.Invalid" xml:space="preserve">
|
<data name="Message.User.Invalid" xml:space="preserve">
|
||||||
<value>User Does Not Exist. Please Verify That The Username Provided Is Correct.</value>
|
<value>The User Specified Does Not Exist</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Notification.Add" xml:space="preserve">
|
<data name="Error.Notification.Add" xml:space="preserve">
|
||||||
<value>Error Adding Notification</value>
|
<value>Error Adding Notification</value>
|
||||||
@ -133,7 +133,7 @@
|
|||||||
<value>Enter the subject of the message</value>
|
<value>Enter the subject of the message</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.HelpText" xml:space="preserve">
|
<data name="Message.HelpText" xml:space="preserve">
|
||||||
<value>Enter the message</value>
|
<value>Enter the message content</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="To.Text" xml:space="preserve">
|
<data name="To.Text" xml:space="preserve">
|
||||||
<value>To: </value>
|
<value>To: </value>
|
||||||
@ -141,4 +141,13 @@
|
|||||||
<data name="Subject.Text" xml:space="preserve">
|
<data name="Subject.Text" xml:space="preserve">
|
||||||
<value>Subject: </value>
|
<value>Subject: </value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Send Notification" xml:space="preserve">
|
||||||
|
<value>Send Notification</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Required" xml:space="preserve">
|
||||||
|
<value>You Must Enter All Required Information</value>
|
||||||
|
</data>
|
||||||
|
<data name="Username.Enter" xml:space="preserve">
|
||||||
|
<value>Enter Username</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -228,4 +228,16 @@
|
|||||||
<data name="Profile.Heading" xml:space="preserve">
|
<data name="Profile.Heading" xml:space="preserve">
|
||||||
<value>Profile</value>
|
<value>Profile</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ViewNotification.Text" xml:space="preserve">
|
||||||
|
<value>View</value>
|
||||||
|
</data>
|
||||||
|
<data name="DeleteNotification.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
|
<data name="NoNotificationsReceived.Text" xml:space="preserve">
|
||||||
|
<value>No notifications have been received</value>
|
||||||
|
</data>
|
||||||
|
<data name="NoNotificationsSent.Text" xml:space="preserve">
|
||||||
|
<value>No notifications have been sent</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
|
||||||
@ -126,22 +126,43 @@
|
|||||||
<data name="Error.Notification.Add" xml:space="preserve">
|
<data name="Error.Notification.Add" xml:space="preserve">
|
||||||
<value>Error Adding Notification</value>
|
<value>Error Adding Notification</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Title" xml:space="preserve">
|
<data name="View Notification" xml:space="preserve">
|
||||||
<value>Title:</value>
|
<value>View Notification</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Subject" xml:space="preserve">
|
<data name="Date.HelpText" xml:space="preserve">
|
||||||
<value>Subject:</value>
|
<value>The date the message was sent</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Date" xml:space="preserve">
|
<data name="Date.Text" xml:space="preserve">
|
||||||
<value>Date:</value>
|
<value>Sent:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message" xml:space="preserve">
|
<data name="From.HelpText" xml:space="preserve">
|
||||||
|
<value>The user who sent the message</value>
|
||||||
|
</data>
|
||||||
|
<data name="From.Text" xml:space="preserve">
|
||||||
|
<value>From:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.HelpText" xml:space="preserve">
|
||||||
|
<value>The content of the message</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Text" xml:space="preserve">
|
||||||
<value>Message:</value>
|
<value>Message:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Reply" xml:space="preserve">
|
<data name="RE" xml:space="preserve">
|
||||||
<value>Reply</value>
|
<value>RE:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OriginalMessage" xml:space="preserve">
|
<data name="Subject.HelpText" xml:space="preserve">
|
||||||
<value>Original Message</value>
|
<value>The subject of the message</value>
|
||||||
|
</data>
|
||||||
|
<data name="Subject.Text" xml:space="preserve">
|
||||||
|
<value>Subject:</value>
|
||||||
|
</data>
|
||||||
|
<data name="System" xml:space="preserve">
|
||||||
|
<value>System</value>
|
||||||
|
</data>
|
||||||
|
<data name="To.HelpText" xml:space="preserve">
|
||||||
|
<value>The user who will be the recipient of the message</value>
|
||||||
|
</data>
|
||||||
|
<data name="To.Text" xml:space="preserve">
|
||||||
|
<value>To:</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
@ -118,7 +118,7 @@
|
|||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="Error.User.AddCheckPass" xml:space="preserve">
|
<data name="Error.User.AddCheckPass" xml:space="preserve">
|
||||||
<value>Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use.</value>
|
<value>Error Adding User. Please Ensure Password Meets Complexity Requirements And Username And Email Is Not Already In Use.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Password.NoMatch" xml:space="preserve">
|
<data name="Message.Password.NoMatch" xml:space="preserve">
|
||||||
<value>Passwords Entered Do Not Match</value>
|
<value>Passwords Entered Do Not Match</value>
|
||||||
@ -171,4 +171,10 @@
|
|||||||
<data name="Password.Placeholder" xml:space="preserve">
|
<data name="Password.Placeholder" xml:space="preserve">
|
||||||
<value>Password</value>
|
<value>Password</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Notify.HelpText" xml:space="preserve">
|
||||||
|
<value>Indicate if new users should receive an email notification</value>
|
||||||
|
</data>
|
||||||
|
<data name="Notify.Text" xml:space="preserve">
|
||||||
|
<value>Notify?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -168,12 +168,6 @@
|
|||||||
<data name="Password.Text" xml:space="preserve">
|
<data name="Password.Text" xml:space="preserve">
|
||||||
<value>Password:</value>
|
<value>Password:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Photo.HelpText" xml:space="preserve">
|
|
||||||
<value>A photo of the user</value>
|
|
||||||
</data>
|
|
||||||
<data name="Photo.Text" xml:space="preserve">
|
|
||||||
<value>Photo:</value>
|
|
||||||
</data>
|
|
||||||
<data name="Username.HelpText" xml:space="preserve">
|
<data name="Username.HelpText" xml:space="preserve">
|
||||||
<value>The unique username for a user. Note that this field can not be modified.</value>
|
<value>The unique username for a user. Note that this field can not be modified.</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -396,4 +396,61 @@
|
|||||||
<data name="ProfileClaimTypes.Text" xml:space="preserve">
|
<data name="ProfileClaimTypes.Text" xml:space="preserve">
|
||||||
<value>User Profile Claims:</value>
|
<value>User Profile Claims:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Username" xml:space="preserve">
|
||||||
|
<value>User Name</value>
|
||||||
|
</data>
|
||||||
|
<data name="Name" xml:space="preserve">
|
||||||
|
<value>Name</value>
|
||||||
|
</data>
|
||||||
|
<data name="Email" xml:space="preserve">
|
||||||
|
<value>Email</value>
|
||||||
|
</data>
|
||||||
|
<data name="ImportUsers.Text" xml:space="preserve">
|
||||||
|
<value>Import Users</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.Code" xml:space="preserve">
|
||||||
|
<value>code</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.CodeIdToken" xml:space="preserve">
|
||||||
|
<value>code id_token</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.CodeIdTokenToken" xml:space="preserve">
|
||||||
|
<value>code id_token token</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.CodeToken" xml:space="preserve">
|
||||||
|
<value>code token</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.IdToken" xml:space="preserve">
|
||||||
|
<value>id_token</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.IdTokenToken" xml:space="preserve">
|
||||||
|
<value>id_token token</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.None" xml:space="preserve">
|
||||||
|
<value>none</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthFlow.Token" xml:space="preserve">
|
||||||
|
<value>token</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthResponseType" xml:space="preserve">
|
||||||
|
<value>Authorization Response Type</value>
|
||||||
|
</data>
|
||||||
|
<data name="VerifyUsers.HelpText" xml:space="preserve">
|
||||||
|
<value>Do you want existing users to perform an additional email verification step to link their external login? If you disable this option, existing users will be linked automatically.</value>
|
||||||
|
</data>
|
||||||
|
<data name="VerifyUsers.Text" xml:space="preserve">
|
||||||
|
<value>Verify Existing Users?</value>
|
||||||
|
</data>
|
||||||
|
<data name="AlwaysRemember.HelpText" xml:space="preserve">
|
||||||
|
<value>Enabling this option will set a permanent cookie in conjunction with the Cookie Expiration Timespan, which will automatically sign in users the next time they visit the site. By default the site will use session cookies.</value>
|
||||||
|
</data>
|
||||||
|
<data name="AlwaysRemember.Text" xml:space="preserve">
|
||||||
|
<value>Always Remember User?</value>
|
||||||
|
</data>
|
||||||
|
<data name="CookieExpiration.HelpText" xml:space="preserve">
|
||||||
|
<value>You can choose to use a custom authentication cookie expiration timespan for each site (e.g. '08:00:00' for 8 hours). The default is 14 days if not specified.</value>
|
||||||
|
</data>
|
||||||
|
<data name="CookieExpiration.Text" xml:space="preserve">
|
||||||
|
<value>Cookie Expiration Timespan:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -117,61 +117,34 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="Template.Text" xml:space="preserve">
|
<data name="ImportFile.HelpText" xml:space="preserve">
|
||||||
<value>Template: </value>
|
<value>Upload or select a tab delimited text file containing user information. The file must be in the Template format specified (Roles can be specified as a comma delimited list).</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Template.Select" xml:space="preserve">
|
<data name="ImportFile.Text" xml:space="preserve">
|
||||||
<value>Select Template</value>
|
<value>Import File:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Module.Create" xml:space="preserve">
|
<data name="Error.Import" xml:space="preserve">
|
||||||
<value>Create Module</value>
|
<value>Error Importing Users</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Module.Activate" xml:space="preserve">
|
<data name="Import" xml:space="preserve">
|
||||||
<value>Activate Module</value>
|
<value>Import</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Info.Module.Creator" xml:space="preserve">
|
<data name="Message.Import.Failure" xml:space="preserve">
|
||||||
<value>Please Note That The Module Creator Is Only Intended To Be Used In A Development Environment</value>
|
<value>User Import Failed. Please Review Your Event Log For More Detailed Information.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Info.Module.Activate" xml:space="preserve">
|
<data name="Message.Import.Success" xml:space="preserve">
|
||||||
<value>Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below</value>
|
<value>User Import Successful. {0} Users Imported.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Module.Create" xml:space="preserve">
|
<data name="Message.Import.Validation" xml:space="preserve">
|
||||||
<value>The Source Code For Your Module Has Been Created At The Location Specified Below And Must Be Compiled In Order To Make It Functional. Once It Has Been Compiled You Must <a href={0}>Restart</a> Your Application To Apply These Changes.</value>
|
<value>You Must Specify A User File For Import</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Require.ValidName" xml:space="preserve">
|
<data name="Template" xml:space="preserve">
|
||||||
<value>You Must Provide A Valid Owner Name And Module Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template</value>
|
<value>Template</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="OwnerName.HelpText" xml:space="preserve">
|
<data name="Notify.HelpText" xml:space="preserve">
|
||||||
<value>Enter the name of the organization who is developing this module. It should not contain spaces or punctuation.</value>
|
<value>Indicate if new users should receive an email notification</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ModuleName.HelpText" xml:space="preserve">
|
<data name="Notify.Text" xml:space="preserve">
|
||||||
<value>Enter a name for this module. It should not contain spaces or punctuation.</value>
|
<value>Notify?</value>
|
||||||
</data>
|
|
||||||
<data name="Description.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter a short description for the module</value>
|
|
||||||
</data>
|
|
||||||
<data name="Template.HelpText" xml:space="preserve">
|
|
||||||
<value>Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server.</value>
|
|
||||||
</data>
|
|
||||||
<data name="FrameworkReference.HelpText" xml:space="preserve">
|
|
||||||
<value>Select a framework reference version</value>
|
|
||||||
</data>
|
|
||||||
<data name="Location.HelpText" xml:space="preserve">
|
|
||||||
<value>Location where the module will be created</value>
|
|
||||||
</data>
|
|
||||||
<data name="OwnerName.Text" xml:space="preserve">
|
|
||||||
<value>Owner Name: </value>
|
|
||||||
</data>
|
|
||||||
<data name="ModuleName.Text" xml:space="preserve">
|
|
||||||
<value>Module Name: </value>
|
|
||||||
</data>
|
|
||||||
<data name="Description.Text" xml:space="preserve">
|
|
||||||
<value>Description: </value>
|
|
||||||
</data>
|
|
||||||
<data name="FrameworkReference.Text" xml:space="preserve">
|
|
||||||
<value>Framework Reference: </value>
|
|
||||||
</data>
|
|
||||||
<data name="Location.Text" xml:space="preserve">
|
|
||||||
<value>Location: </value>
|
|
||||||
</data>
|
</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
|
||||||
@ -120,4 +120,7 @@
|
|||||||
<data name="PageOfPages" xml:space="preserve">
|
<data name="PageOfPages" xml:space="preserve">
|
||||||
<value>Page {0} of {1}</value>
|
<value>Page {0} of {1}</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SearchPlaceholder" xml:space="preserve">
|
||||||
|
<value>Search: {0}</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -129,4 +129,25 @@
|
|||||||
<data name="Message.Username.DontExist" xml:space="preserve">
|
<data name="Message.Username.DontExist" xml:space="preserve">
|
||||||
<value>User Does Not Exist With Name Specified</value>
|
<value>User Does Not Exist With Name Specified</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ModuleDefinition" xml:space="preserve">
|
||||||
|
<value>Module</value>
|
||||||
|
</data>
|
||||||
|
<data name="Page" xml:space="preserve">
|
||||||
|
<value>Page</value>
|
||||||
|
</data>
|
||||||
|
<data name="Folder" xml:space="preserve">
|
||||||
|
<value>Folder</value>
|
||||||
|
</data>
|
||||||
|
<data name="View" xml:space="preserve">
|
||||||
|
<value>View</value>
|
||||||
|
</data>
|
||||||
|
<data name="Edit" xml:space="preserve">
|
||||||
|
<value>Edit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Utilize" xml:space="preserve">
|
||||||
|
<value>Utilize</value>
|
||||||
|
</data>
|
||||||
|
<data name="Browse" xml:space="preserve">
|
||||||
|
<value>Browse</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
|
||||||
@ -156,6 +156,9 @@
|
|||||||
<data name="Message.Content.Restored" xml:space="preserve">
|
<data name="Message.Content.Restored" xml:space="preserve">
|
||||||
<value>Version Restored</value>
|
<value>Version Restored</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Edit Html/Text" xml:space="preserve">
|
||||||
|
<value>Edit Html/Text</value>
|
||||||
|
</data>
|
||||||
<data name="Restore.Header" xml:space="preserve">
|
<data name="Restore.Header" xml:space="preserve">
|
||||||
<value>Restore Version</value>
|
<value>Restore Version</value>
|
||||||
</data>
|
</data>
|
||||||
@ -165,4 +168,16 @@
|
|||||||
<data name="View.Text" xml:space="preserve">
|
<data name="View.Text" xml:space="preserve">
|
||||||
<value>View</value>
|
<value>View</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Edit.Heading" xml:space="preserve">
|
||||||
|
<value>Edit</value>
|
||||||
|
</data>
|
||||||
|
<data name="Versions.Heading" xml:space="preserve">
|
||||||
|
<value>Versions</value>
|
||||||
|
</data>
|
||||||
|
<data name="HtmlEditor.Heading" xml:space="preserve">
|
||||||
|
<value>Raw HTML Editor</value>
|
||||||
|
</data>
|
||||||
|
<data name="RichTextEditor.Heading" xml:space="preserve">
|
||||||
|
<value>Rich Text Editor</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
|
||||||
@ -120,6 +120,9 @@
|
|||||||
<data name="Edit.Action" xml:space="preserve">
|
<data name="Edit.Action" xml:space="preserve">
|
||||||
<value>Edit</value>
|
<value>Edit</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Edit.Text" xml:space="preserve">
|
||||||
|
<value>Edit</value>
|
||||||
|
</data>
|
||||||
<data name="Error.Content.Load" xml:space="preserve">
|
<data name="Error.Content.Load" xml:space="preserve">
|
||||||
<value>An Error Occurred Loading Content</value>
|
<value>An Error Occurred Loading Content</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -223,13 +223,13 @@
|
|||||||
<value>by</value>
|
<value>by</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Downloads" xml:space="preserve">
|
<data name="Search.Downloads" xml:space="preserve">
|
||||||
<value>downloads</value>
|
<value>Downloads</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Released" xml:space="preserve">
|
<data name="Search.Released" xml:space="preserve">
|
||||||
<value>released</value>
|
<value>Released</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Version" xml:space="preserve">
|
<data name="Search.Version" xml:space="preserve">
|
||||||
<value>version</value>
|
<value>Version</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Edit" xml:space="preserve">
|
<data name="Edit" xml:space="preserve">
|
||||||
<value>Edit</value>
|
<value>Edit</value>
|
||||||
@ -277,19 +277,19 @@
|
|||||||
<value>Installed Version</value>
|
<value>Installed Version</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Source" xml:space="preserve">
|
<data name="Search.Source" xml:space="preserve">
|
||||||
<value>source</value>
|
<value>Source</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.InfoRequired" xml:space="preserve">
|
<data name="Message.InfoRequired" xml:space="preserve">
|
||||||
<value>Please Provide All Required Information</value>
|
<value>Please Provide All Required Information</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Free" xml:space="preserve">
|
<data name="Free" xml:space="preserve">
|
||||||
<value>Free</value>
|
<value>Open Source</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Paid" xml:space="preserve">
|
<data name="Paid" xml:space="preserve">
|
||||||
<value>Paid</value>
|
<value>Commercial</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Search.Price" xml:space="preserve">
|
<data name="Search.Price" xml:space="preserve">
|
||||||
<value>price</value>
|
<value>Price</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Accept" xml:space="preserve">
|
<data name="Accept" xml:space="preserve">
|
||||||
<value>Accept</value>
|
<value>Accept</value>
|
||||||
@ -390,4 +390,46 @@
|
|||||||
<data name="Support" xml:space="preserve">
|
<data name="Support" xml:space="preserve">
|
||||||
<value>Support</value>
|
<value>Support</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Search.Alphabetical" xml:space="preserve">
|
||||||
|
<value>Alphabetical</value>
|
||||||
|
</data>
|
||||||
|
<data name="Buy" xml:space="preserve">
|
||||||
|
<value>Buy Now</value>
|
||||||
|
</data>
|
||||||
|
<data name="Search.Popularity" xml:space="preserve">
|
||||||
|
<value>Popularity</value>
|
||||||
|
</data>
|
||||||
|
<data name="Search.Results" xml:space="preserve">
|
||||||
|
<value>Results</value>
|
||||||
|
</data>
|
||||||
|
<data name="Search.RecentlyReleased" xml:space="preserve">
|
||||||
|
<value>Recently Released</value>
|
||||||
|
</data>
|
||||||
|
<data name="From" xml:space="preserve">
|
||||||
|
<value>From</value>
|
||||||
|
</data>
|
||||||
|
<data name="To" xml:space="preserve">
|
||||||
|
<value>To</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>
|
||||||
|
<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="ProfileInvalid" xml:space="preserve">
|
||||||
|
<value>{0} Is Not Valid</value>
|
||||||
|
</data>
|
||||||
|
<data name="ProfileRequired" xml:space="preserve">
|
||||||
|
<value>{0} Is Required</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
|
||||||
@ -186,4 +186,16 @@
|
|||||||
<data name="VisibilityView" xml:space="preserve">
|
<data name="VisibilityView" xml:space="preserve">
|
||||||
<value>Same As Page</value>
|
<value>Same As Page</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Confirm.Page.Delete" xml:space="preserve">
|
||||||
|
<value>Are You Sure You Want To Delete This Page?</value>
|
||||||
|
</data>
|
||||||
|
<data name="Location" xml:space="preserve">
|
||||||
|
<value>Location:</value>
|
||||||
|
</data>
|
||||||
|
<data name="LocationBottom" xml:space="preserve">
|
||||||
|
<value>Bottom</value>
|
||||||
|
</data>
|
||||||
|
<data name="LocationTop" xml:space="preserve">
|
||||||
|
<value>Top</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -22,7 +22,7 @@ namespace Oqtane.Services
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<List<Alias>> GetAliasesAsync()
|
public async Task<List<Alias>> GetAliasesAsync()
|
||||||
{
|
{
|
||||||
List<Alias> aliases = await GetJsonAsync<List<Alias>>(ApiUrl);
|
List<Alias> aliases = await GetJsonAsync<List<Alias>>(ApiUrl, Enumerable.Empty<Alias>().ToList());
|
||||||
return aliases.OrderBy(item => item.Name).ToList();
|
return aliases.OrderBy(item => item.Name).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ namespace Oqtane.Services
|
|||||||
public async Task<Folder> GetFolderAsync(int siteId, [NotNull] string folderPath)
|
public async Task<Folder> GetFolderAsync(int siteId, [NotNull] string folderPath)
|
||||||
{
|
{
|
||||||
var path = WebUtility.UrlEncode(folderPath);
|
var path = WebUtility.UrlEncode(folderPath);
|
||||||
return await GetJsonAsync<Folder>($"{ApiUrl}/{siteId}/{path}");
|
return await GetJsonAsync<Folder>($"{ApiUrl}/path/{siteId}/?path={path}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Folder> AddFolderAsync(Folder folder)
|
public async Task<Folder> AddFolderAsync(Folder folder)
|
||||||
|
@ -6,6 +6,7 @@ using Oqtane.Shared;
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
@ -14,11 +15,13 @@ namespace Oqtane.Services
|
|||||||
{
|
{
|
||||||
private readonly NavigationManager _navigationManager;
|
private readonly NavigationManager _navigationManager;
|
||||||
private readonly SiteState _siteState;
|
private readonly SiteState _siteState;
|
||||||
|
private readonly HttpClient _http;
|
||||||
|
|
||||||
public InstallationService(HttpClient http, SiteState siteState, NavigationManager navigationManager) : base(http, siteState)
|
public InstallationService(HttpClient http, SiteState siteState, NavigationManager navigationManager) : base(http, siteState)
|
||||||
{
|
{
|
||||||
_navigationManager = navigationManager;
|
_navigationManager = navigationManager;
|
||||||
_siteState = siteState;
|
_siteState = siteState;
|
||||||
|
_http = http;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ApiUrl => (_siteState.Alias == null)
|
private string ApiUrl => (_siteState.Alias == null)
|
||||||
@ -27,7 +30,15 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
public async Task<Installation> IsInstalled()
|
public async Task<Installation> IsInstalled()
|
||||||
{
|
{
|
||||||
var path = new Uri(_navigationManager.Uri).LocalPath.Substring(1);
|
var path = "";
|
||||||
|
if (_http.DefaultRequestHeaders.UserAgent.ToString().Contains(Constants.MauiUserAgent))
|
||||||
|
{
|
||||||
|
path = _http.DefaultRequestHeaders.GetValues(Constants.MauiAliasPath).First();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = new Uri(_navigationManager.Uri).LocalPath.Substring(1);
|
||||||
|
}
|
||||||
return await GetJsonAsync<Installation>($"{ApiUrl}/installed/?path={WebUtility.UrlEncode(path)}");
|
return await GetJsonAsync<Installation>($"{ApiUrl}/installed/?path={WebUtility.UrlEncode(path)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user