Compare commits

...

153 Commits

Author SHA1 Message Date
ddeb05dfe2 Merge pull request #1535 from sbwalker/dev
fix horizontal menu highlighting issue
2021-07-06 14:17:12 -04:00
792086140b fix horizontal menu highlighting issue 2021-07-06 14:21:54 -04:00
276431b62d update theme creator template to Bootstrap5 2021-07-06 11:00:45 -04:00
a89e7c06d4 Merge pull request #1534 from sbwalker/dev
update theme creator template to Bootstrap5
2021-07-06 10:56:02 -04:00
a79535d7d1 prepare for 2.2.0 release 2021-07-05 15:22:24 -04:00
649a134214 Merge pull request #1533 from sbwalker/dev
prepare for 2.2.0 release
2021-07-05 15:17:43 -04:00
910630cd26 Merge pull request #1531 from leigh-pointer/ModuleTemplates
Fix for #1530 Error in Module templates
2021-07-05 14:56:18 -04:00
a1baf70524 fix #1530 for Error in Module templates
The Get public Models.[Module] Get(int id) method in the [Module]Controller has an incorrect IF statement which in turn returns nothing and logs an error
2021-07-05 08:25:16 +02:00
7348540c4d Update README.md 2021-07-02 20:07:41 -04:00
534c6794f2 Merge pull request #1529 from sbwalker/dev
upgrade to Boostrap 5
2021-07-02 19:59:10 -04:00
cb7d9a0371 upgrade to Boostrap 5 2021-07-02 20:03:51 -04:00
525cbb87b0 allow disabling of swagger and package service 2021-07-01 09:11:29 -04:00
7f420e8a8f Merge pull request #1528 from sbwalker/dev
allow disabling of swagger and package service
2021-07-01 09:06:44 -04:00
eea417ff44 added logging for startup issues 2021-07-01 07:37:03 -04:00
070e00b735 Merge pull request #1527 from sbwalker/dev
added logging for startup issues
2021-07-01 07:32:34 -04:00
5268c326a1 suppress Internal EF Core API usage warning messages on build 2021-06-28 10:27:29 -04:00
49b2c323d0 Merge pull request #1523 from sbwalker/dev
suppress Internal EF Core API usage warning messages on build
2021-06-28 10:22:49 -04:00
bf6edceb36 Fix issue where module definition version was not being loaded correctly on startup. Also user customizable module definition properties were being overwritten on upgrade. 2021-06-28 10:21:48 -04:00
91eeeaf064 Merge pull request #1522 from sbwalker/dev
Fix issue where module definition version was not being loaded correctly on startup. Also user customizable module definition properties were being overwritten on upgrade.
2021-06-28 10:17:40 -04:00
17c0aec1fb show friendly message when no packages match criteria 2021-06-27 20:20:01 -04:00
e4c98ba24f Merge pull request #1519 from sbwalker/dev
show friendly message when no packages match criteria
2021-06-27 20:15:23 -04:00
8ef83b2de8 improve register for updates 2021-06-27 18:33:41 -04:00
376482e66e Merge pull request #1518 from sbwalker/dev
improve register for updates
2021-06-27 18:29:05 -04:00
2433958a0f fixed issue in SharedResource file 2021-06-27 08:59:04 -04:00
50bddd072b Merge pull request #1517 from sbwalker/dev
fixed issue in SharedResource file
2021-06-27 08:54:35 -04:00
b77d313715 Merge pull request #1515 from gjwalk/dev
Shared resources added
2021-06-27 08:50:46 -04:00
b59706ab8b Merge pull request #1516 from sbwalker/dev
add ability to register for updates
2021-06-27 08:47:25 -04:00
9e004f5b3c add ability to register for updates 2021-06-27 08:48:18 -04:00
f989f63546 Merge branch 'dev' into dev 2021-06-25 17:56:21 -04:00
ef6f5f2769 update resources 2021-06-25 17:03:29 -04:00
ba9ca22aaa update to resources 2021-06-25 16:34:30 -04:00
db1808d3e9 additional system info 2021-06-25 15:06:52 -04:00
8ad61a23c8 Merge pull request #1514 from sbwalker/dev
additional system info
2021-06-25 15:02:38 -04:00
e1e4d82684 resx file corrections 2021-06-25 08:22:36 -04:00
5d84eeea1d Merge pull request #1513 from sbwalker/dev
resx file corrections
2021-06-25 08:18:05 -04:00
509f054961 package UI updates 2021-06-25 08:10:15 -04:00
3a85eed397 Merge pull request #1512 from sbwalker/dev
package UI updates
2021-06-25 08:05:51 -04:00
52bcdb12c5 package management modifications 2021-06-24 18:02:01 -04:00
30a667debf Merge pull request #1511 from sbwalker/dev
package management modifications
2021-06-24 17:57:23 -04:00
161ab56701 improve handling of response status and logging in package controller 2021-06-24 10:42:43 -04:00
55bf2f1b6a Merge pull request #1510 from sbwalker/dev
improve handling of response status and logging in package controller
2021-06-24 10:38:31 -04:00
fb2a8e987e default resx fixes 2021-06-24 08:02:39 -04:00
0608287b5f Merge pull request #1509 from sbwalker/dev
default resx fixes
2021-06-24 07:58:08 -04:00
7fa30ff23c Merge pull request #1501 from Gotiap/dev
Allowed pages for external modules.
2021-06-24 07:37:49 -04:00
b0f76ff4e8 Merge pull request #1508 from sbwalker/dev
Page IsClickable column must be nullable in order to support upgrades, add more defensive logic
2021-06-24 07:37:27 -04:00
8e7b553ca8 Page IsClickable column must be nullable in order to support upgrades, add more defensive logic 2021-06-24 07:41:34 -04:00
89cc389918 Undo changes for login 2021-06-24 11:30:09 +05:30
bfafffd8cb add search to package manager components 2021-06-23 13:00:44 -04:00
4ea92652dd Merge pull request #1499 from ijaz-saeed/rich-text-editor
OnInitialized is not the right method to do this, Content is not set yet
2021-06-23 12:58:25 -04:00
6fbb325c42 Merge pull request #1506 from sbwalker/dev
add search to package manager components
2021-06-23 12:56:16 -04:00
c2f7546488 add database diagram 2021-06-22 14:30:20 -04:00
90778f5e1e Update README.md 2021-06-22 14:28:06 -04:00
c7d5f95949 Update README.md 2021-06-22 14:27:17 -04:00
67dff508ef Merge pull request #1504 from sbwalker/dev
add database diagram
2021-06-22 14:25:43 -04:00
c4e6a4af49 fix remaining default resx differences, enhance module message with ability to dismiss, fix issue in ConfigManager.RemoveSetting, introduce package registry service 2021-06-22 14:14:46 -04:00
c236e80e95 Merge pull request #1498 from ijaz-saeed/dev
adding SaveChangesAsync overloads to support Async save
2021-06-22 14:10:33 -04:00
1906a0ee8a Merge pull request #1502 from sbwalker/dev
fix remaining default resx differences, enhance module message with ability to dismiss, fix issue in ConfigManager.RemoveSetting, introduce package registry service
2021-06-22 14:10:23 -04:00
d348e9715f Allowed pages for external module.
Login internal module while edit, resolved error to be edit.
2021-06-22 10:51:05 +05:30
91a1bfcab2 adding SaveChangesAsync overloads to support Async save 2021-06-20 17:52:41 +05:00
73f2fc4f13 OnInitialized is not the right method to do this, Content is not available yet 2021-06-20 17:51:25 +05:00
247e00ecd4 implement shared resources 2021-06-18 16:56:54 -04:00
3274ab6258 Merge pull request #1497 from sbwalker/dev
implement shared resources
2021-06-18 16:52:27 -04:00
6bff09d0ca fix Localizer class specification 2021-06-18 16:46:15 -04:00
19f3095483 Merge pull request #1496 from sbwalker/dev
fix Localizer class specification
2021-06-18 16:41:47 -04:00
2e947625cd fix issue with HtmlText module rendering 2021-06-18 16:36:18 -04:00
8198f36530 Merge pull request #1495 from sbwalker/dev
fix issue with HtmlText module rendering
2021-06-18 16:32:09 -04:00
8bc0402801 fix syntax error 2021-06-18 16:30:49 -04:00
87aadcff5b Merge pull request #1494 from sbwalker/dev
fix syntax error
2021-06-18 16:27:00 -04:00
dc44fcd0d9 Merge pull request #1493 from gjwalk/dev
create default rex files with static keys
2021-06-18 16:21:37 -04:00
f7363504c2 Merge branch 'dev' into dev 2021-06-18 15:35:20 -04:00
ae0edcfd2d create default rex files with static keys 2021-06-18 14:45:38 -04:00
b180c260e5 Merge pull request #1492 from sbwalker/dev
improved error handling, improved consistency of console error messages, added ability to add a Decimal column in Migrations
2021-06-18 12:57:21 -04:00
3bc5744007 improved error handling, improved consistency of console error messages, added ability to add a Decimal column in Migrations 2021-06-18 13:01:42 -04:00
32c49f74d3 fix module template issues 2021-06-17 12:12:19 -04:00
8b70d1ccdc Merge pull request #1491 from sbwalker/dev
fix module template issues
2021-06-17 12:08:03 -04:00
f330c4fcb6 add extension method for Localization which allows specification of key and value 2021-06-16 22:16:48 -04:00
a953ca752e Merge pull request #1490 from sbwalker/dev
add extension method for Localization which allows specification of key and value
2021-06-16 22:12:48 -04:00
d32b622f7e allow order to be defined in page templates 2021-06-16 17:24:45 -04:00
8354d66c84 Merge pull request #1489 from sbwalker/dev
allow order to be defined in page templates
2021-06-16 17:20:53 -04:00
7ee9923b52 Merge pull request #1483 from leigh-pointer/SResControlPanel
Introduce SharedResource Localisation to ControlPanel
2021-06-16 16:27:52 -04:00
31c412a886 Merge pull request #1488 from sbwalker/dev
improvements to refresh logic, module template enhancements
2021-06-16 16:26:53 -04:00
72ff6fa0e7 improvements to refresh logic, module template enhancements 2021-06-16 16:31:02 -04:00
c6e12a614a Merge pull request #1485 from hishamco/database-projects
Add missing Oqtane.Server into Databases solution
2021-06-16 10:09:26 -04:00
cec24e7446 improve multi-tenancy navigation 2021-06-16 08:30:41 -04:00
05d7c7fc74 Merge pull request #1484 from hishamco/localization-cookie
Fix parsing localization cookie when the value is not present
2021-06-16 08:26:50 -04:00
0d10645d57 Merge pull request #1486 from sbwalker/dev
improve multi-tenancy navigation
2021-06-16 08:26:36 -04:00
1bfe4fbd4f Add missing Oqtane.Server to Databases solutions 2021-06-16 11:55:36 +03:00
c62a4ae8ae Fix parsing localization cookie when the value is not present 2021-06-16 11:02:12 +03:00
4fcfb2ab4e Introduce SharedResource Localisation
Updated the ControlPanel to use Shared resources for;
 Add, Edit, Delete, Cancel

Corrected the SharedResources.cs namespace.
2021-06-16 09:46:33 +02:00
0f208f3c30 Merge pull request #1 from oqtane/dev
merge
2021-06-16 09:19:09 +02:00
65a14da5a9 improve validation and exception handling in API Controllers 2021-06-15 19:11:00 -04:00
53f3245f1d Merge pull request #1482 from sbwalker/dev
improve validation and exception handling in API Controllers
2021-06-15 19:06:52 -04:00
ffbabcfb28 Update README.md 2021-06-15 09:18:17 -04:00
0a2293119e added back missing ITenantManager registration removed in #1245 2021-06-15 08:32:39 -04:00
abd9e2798d Merge pull request #1480 from sbwalker/dev
added back missing ITenantManager registration removed in #1245
2021-06-15 08:28:44 -04:00
f6cc11bd3b add logic removed in #1245 back to HttpClient creation 2021-06-15 08:23:26 -04:00
3e3bf937fd Merge pull request #1479 from sbwalker/dev
add logic removed in #1245 back to HttpClient creation
2021-06-15 08:19:20 -04:00
0fd16fbb59 added Oqtane.Client to _Imports so it can find the new SharedResources class 2021-06-15 07:59:05 -04:00
b2098bb2db Merge pull request #1478 from sbwalker/dev
added Oqtane.Client to _Imports so it can find the new SharedResources class
2021-06-15 07:54:54 -04:00
87c99e2ba7 Merge branch 'oqtane:dev' into dev 2021-06-15 07:46:51 -04:00
4a11524db3 Merge pull request #1245 from hishamco/clean-startup
Clean Startup Class
2021-06-15 07:45:12 -04:00
a9efc2792e Merge pull request #96 from oqtane/dev
sync
2021-06-15 07:42:22 -04:00
9558894a4f moved SharedResources class to proper location 2021-06-15 07:43:12 -04:00
abfb451290 Merge branch 'dev' into dev 2021-06-15 07:42:02 -04:00
e279bca8ad Merge pull request #1476 from leigh-pointer/SharedResource
SharedResources to reside at the project root.
2021-06-15 07:40:27 -04:00
f2b3d6bc5f SharedResources to reside at the project root.
Namespace was changed from Oqtane to Oqtane.Client
2021-06-15 07:09:22 +02:00
28694fc11f added defensive logic to app.razor, relocated shared resource definition in preparation for utilizing shared resources 2021-06-14 17:29:23 -04:00
e99d62d5c7 Merge pull request #1475 from sbwalker/dev
added defensive logic to app.razor, relocated shared resource definition in preparation for utilizing shared resources
2021-06-14 17:25:23 -04:00
216dd39474 Merge branch 'oqtane:dev' into dev 2021-06-13 15:24:05 -04:00
643895b62b add icon for reuse 2021-06-12 09:21:24 -04:00
bd0ee1370c Merge pull request #1471 from sbwalker/dev
add icon for reuse
2021-06-12 09:17:10 -04:00
7c181b65cd Fix merge conflict 2021-06-12 00:18:57 +03:00
bdf36fc49c bug fixes 2021-06-11 17:07:54 -04:00
965b935128 Merge pull request #1470 from sbwalker/dev
bug fixes
2021-06-11 17:03:57 -04:00
126024991c Merge remote-tracking branch 'upstream/dev' into clean-startup
# Conflicts:
#	Oqtane.Client/Program.cs
#	Oqtane.Server/Startup.cs
2021-06-11 23:54:38 +03:00
8f944e29ac set the DefaultDBType as the default database option in the Installer and Add Site UI 2021-06-11 08:43:46 -04:00
7b26ecfec8 Merge pull request #1467 from sbwalker/dev
set the DefaultDBType as the default database option in the Installer and Add Site UI
2021-06-11 08:40:17 -04:00
aa5aca3a8e back out auth policy header support as Blazor HttpClient is registered as Scoped and can not support variable headers 2021-06-11 07:54:02 -04:00
c46ef0fbc4 Merge pull request #1466 from sbwalker/dev
back out auth policy header support as Blazor HttpClient is registered as Scoped and can not support variable headers
2021-06-11 07:50:00 -04:00
d82fc8be90 added IsClickable Page property #1092, improve validation in Role Management, display database information in SQL Management, improve HttpClient header support 2021-06-10 20:10:46 -04:00
a51e7c2b44 Merge pull request #1465 from sbwalker/dev
added IsClickable Page property #1092, improve validation in Role Management, display database information in SQL Management, improve HttpClient header support
2021-06-10 20:06:41 -04:00
52d9c14d78 Update README.md 2021-06-10 13:06:05 -04:00
4bee097e66 fix Site Settings issue 2021-06-10 10:55:59 -04:00
6899a7cbb2 Merge pull request #1464 from sbwalker/dev
fix Site Settings issue
2021-06-10 10:51:49 -04:00
edc0e2a8fe Merge pull request #1462 from albahadly/dev
fix issue: WebAssembly with IDM app
2021-06-10 10:46:52 -04:00
f5f374d2ae #1460 fix issue: WebAssembly with IDM app 2021-06-11 01:06:20 +12:00
ece90c39cb Merge pull request #1461 from sbwalker/dev
refactoring, enhancements, and some fixes
2021-06-10 08:13:35 -04:00
bc720555c4 refactoring, enhancements, and some fixes 2021-06-10 08:16:02 -04:00
25dc6b9b08 when set Runtime as WebAssembly, IDM app recognize oqtane.zip and download this file and this make an issue and oqtane not work correctly and for this I set diffrent extention that IDM cant recognize it 2021-06-09 12:45:31 +12:00
36bd8e4b7f Update README.md 2021-06-07 15:58:04 -04:00
82c05a841f Improve validation and error handling in Controller methods 2021-06-07 15:29:08 -04:00
dd3385c447 Update README.md 2021-06-07 15:25:57 -04:00
93031c9aaa Merge pull request #1457 from sbwalker/dev
Improve validation and error handling in Controller methods
2021-06-07 15:25:04 -04:00
54cd360bb5 allow host to change runtime and rendermode settings in System Info 2021-06-06 11:04:37 -04:00
aa30caa1a7 Merge pull request #1451 from sbwalker/dev
allow host to change runtime and rendermode settings in System Info
2021-06-06 11:00:58 -04:00
900ea8cfbc allow host to view tenant information in Site Settings 2021-06-06 10:36:13 -04:00
cf99f04451 Merge pull request #1450 from sbwalker/dev
allow host to view tenant information in Site Settings
2021-06-06 10:32:21 -04:00
357ef09dd1 new controller auth parameter should take precedence over legacy 2021-06-06 10:03:54 -04:00
42d653969d Merge pull request #1449 from sbwalker/dev
new controller auth parameter should take precedence over legacy
2021-06-06 10:00:09 -04:00
a2b808fde2 use new service auth pattern in module template 2021-06-04 15:01:25 -04:00
33405b9457 Merge pull request #1448 from sbwalker/dev
use new service auth pattern in module template
2021-06-04 14:57:23 -04:00
ffb5ca44ec Merge pull request #1447 from oqtane/master
Merge pull request #1446 from oqtane/dev
2021-06-04 13:05:35 -04:00
3f8a0d4933 Merge pull request #1446 from oqtane/dev
2.1.0 release
2021-06-04 12:56:13 -04:00
97fb6ede7e Reuse AddOqtaneScopedServices() 2021-04-20 19:10:06 +03:00
f7d8888232 Refactor Program.cs 2021-04-20 19:01:56 +03:00
e7f5fe9827 Merge branch 'database' into clean-startup
# Conflicts:
#	Oqtane.Server/Startup.cs
2021-04-20 17:42:39 +03:00
8069d838d5 Merge pull request #4 from oqtane/master
sync
2021-04-20 08:50:44 -04:00
7417e8dd27 Merge branch 'dev' of https://github.com/oqtane/oqtane.framework into dev 2021-04-18 02:29:39 +03:00
a018e853a8 Register configuration in startup 2021-04-18 02:27:31 +03:00
73b13d7a54 Add Oqtane extension methods for clean startup 2021-04-18 02:25:40 +03:00
8da55e1926 Merge pull request #3 from oqtane/dev
sync
2021-04-01 19:31:21 -04:00
12b44f6fa5 Merge pull request #2 from oqtane/dev
sync
2021-02-23 18:50:55 -05:00
8cd355135b Merge pull request #1 from oqtane/dev
sync
2021-02-15 13:49:36 -05:00
336 changed files with 18073 additions and 14582 deletions

View File

@ -1,4 +1,6 @@
@inject IInstallationService InstallationService
@inject IJSRuntime JSRuntime
@inject SiteState SiteState
@if (_initialized)
{
@ -20,21 +22,35 @@
{
<div class="app-alert">
@_installation.Message
</div>
</div>
}
}
}
@code {
private Installation _installation;
private bool _initialized;
private bool _initialized = false;
private Installation _installation = new Installation { Success = false, Message = "" };
private PageState PageState { get; set; }
protected override async Task OnParametersSetAsync()
protected override async Task OnAfterRenderAsync(bool firstRender)
{
_installation = await InstallationService.IsInstalled();
_initialized = true;
if (firstRender && !_initialized)
{
var interop = new Interop(JSRuntime);
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
_installation = await InstallationService.IsInstalled();
if (_installation.Alias != null)
{
SiteState.Alias = _installation.Alias;
}
else
{
_installation.Message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
}
_initialized = true;
StateHasChanged();
}
}
private void ChangeState(PageState pageState)

View File

@ -1,3 +1,5 @@
using Microsoft.Extensions.Localization;
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Localization;
[assembly: RootNamespace("Oqtane")]
[assembly: InternalsVisibleTo("Oqtane.Server")]

View File

@ -0,0 +1,22 @@
namespace Microsoft.Extensions.Localization
{
public static class OqtaneLocalizationExtensions
{
/// <summary>
/// Gets the string resource for the specified key and returns the value if the resource does not exist
/// </summary>
/// <param name="localizer"></param>
/// <param name="key">the static key used to identify the string resource</param>
/// <param name="value">the default value if the resource for the static key does not exist</param>
/// <returns></returns>
public static string GetString(this IStringLocalizer localizer, string key, string value)
{
string localizedValue = localizer[key];
if (localizedValue == key && !string.IsNullOrEmpty(value)) // not localized
{
localizedValue = value;
}
return localizedValue;
}
}
}

View File

@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Components.Authorization;
using Oqtane.Providers;
using Oqtane.Services;
using Oqtane.Shared;
namespace Microsoft.Extensions.DependencyInjection
{
public static class OqtaneServiceCollectionExtensions
{
public static IServiceCollection AddOqtaneAuthorization(this IServiceCollection services)
{
services.AddAuthorizationCore();
services.AddScoped<IdentityAuthenticationStateProvider>();
services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<IdentityAuthenticationStateProvider>());
return services;
}
internal static IServiceCollection AddOqtaneScopedServices(this IServiceCollection services)
{
services.AddScoped<SiteState>();
services.AddScoped<IInstallationService, InstallationService>();
services.AddScoped<IModuleDefinitionService, ModuleDefinitionService>();
services.AddScoped<IThemeService, ThemeService>();
services.AddScoped<IAliasService, AliasService>();
services.AddScoped<ITenantService, TenantService>();
services.AddScoped<ISiteService, SiteService>();
services.AddScoped<IPageService, PageService>();
services.AddScoped<IModuleService, ModuleService>();
services.AddScoped<IPageModuleService, PageModuleService>();
services.AddScoped<IUserService, UserService>();
services.AddScoped<IProfileService, ProfileService>();
services.AddScoped<IRoleService, RoleService>();
services.AddScoped<IUserRoleService, UserRoleService>();
services.AddScoped<ISettingService, SettingService>();
services.AddScoped<IPackageService, PackageService>();
services.AddScoped<ILogService, LogService>();
services.AddScoped<IJobService, JobService>();
services.AddScoped<IJobLogService, JobLogService>();
services.AddScoped<INotificationService, NotificationService>();
services.AddScoped<IFolderService, FolderService>();
services.AddScoped<IFileService, FileService>();
services.AddScoped<ISiteTemplateService, SiteTemplateService>();
services.AddScoped<ISqlService, SqlService>();
services.AddScoped<ISystemService, SystemService>();
services.AddScoped<ILocalizationService, LocalizationService>();
services.AddScoped<ILanguageService, LanguageService>();
services.AddScoped<IDatabaseService, DatabaseService>();
services.AddScoped<ISyncService, SyncService>();
return services;
}
}
}

View File

@ -1,6 +1,7 @@
@namespace Oqtane.Installer.Controls
@implements Oqtane.Interfaces.IDatabaseConfigControl
@inject IStringLocalizer<Installer> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@{
foreach (var field in _connectionStringFields)
@ -10,7 +11,7 @@
{
var isVisible = "";
var fieldType = (field.Name == "Pwd") ? "password" : "text";
if ((field.Name == "Uid" || field.Name == "Pwd") )
if ((field.Name == "Uid" || field.Name == "Pwd"))
{
var intSecurityField = _connectionStringFields.Single(f => f.Name == "IntegratedSecurity");
if (intSecurityField != null)
@ -20,7 +21,7 @@
}
field.Value = field.Value.Replace("{{Date}}", DateTime.UtcNow.ToString("yyyyMMddHHmm"));
<tr style="@isVisible">
<td>
<Label For="@fieldId" HelpText="@field.HelpText" ResourceKey="@field.Name">@Localizer[$"{field.FriendlyName}:"]</Label>
@ -38,8 +39,8 @@
</td>
<td>
<select id="@fieldId" class="custom-select" @bind="@field.Value">
<option value="true" selected>@Localizer["True"]</option>
<option value="false">@Localizer["False"]</option>
<option value="true" selected>@SharedLocalizer["True"]</option>
<option value="false">@SharedLocalizer["False"]</option>
</select>
</td>
</tr>
@ -50,13 +51,13 @@
@code {
private readonly List<ConnectionStringField> _connectionStringFields = new()
{
new() {Name = "Server", FriendlyName = "Server", Value = "127.0.0.1", HelpText="Enter the database server"},
new() {Name = "Port", FriendlyName = "Port", Value = "5432", HelpText="Enter the port used to connect to the server"},
new() {Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}", HelpText="Enter the name of the database"},
new() {Name = "IntegratedSecurity", FriendlyName = "Integrated Security", Value = "true", HelpText="Select if you want integrated security or not"},
new() {Name = "Uid", FriendlyName = "User Id", Value = "", HelpText="Enter the username to use for the database"},
new() {Name = "Pwd", FriendlyName = "Password", Value = "", HelpText="Enter the password to use for the database"}
};
new() { Name = "Server", FriendlyName = "Server", Value = "127.0.0.1", HelpText = "Enter the database server" },
new() { Name = "Port", FriendlyName = "Port", Value = "5432", HelpText = "Enter the port used to connect to the server" },
new() { Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}", HelpText = "Enter the name of the database" },
new() { Name = "IntegratedSecurity", FriendlyName = "Integrated Security", Value = "true", HelpText = "Select if you want integrated security or not" },
new() { Name = "Uid", FriendlyName = "User Id", Value = "", HelpText = "Enter the username to use for the database" },
new() { Name = "Pwd", FriendlyName = "Password", Value = "", HelpText = "Enter the password to use for the database" }
};
public string GetConnectionString()
{
@ -69,7 +70,7 @@
var userId = _connectionStringFields[4].Value;
var password = _connectionStringFields[5].Value;
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database) && !String.IsNullOrEmpty(port))
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database) && !String.IsNullOrEmpty(port))
{
connectionString = $"Server={server};Port={port};Database={database};";
}

View File

@ -1,6 +1,7 @@
@namespace Oqtane.Installer.Controls
@implements Oqtane.Interfaces.IDatabaseConfigControl
@inject IStringLocalizer<Installer> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@{
foreach (var field in _connectionStringFields)
@ -10,7 +11,7 @@
{
var isVisible = "";
var fieldType = (field.Name == "Pwd") ? "password" : "text";
if ((field.Name == "Uid" || field.Name == "Pwd") )
if ((field.Name == "Uid" || field.Name == "Pwd"))
{
var intSecurityField = _connectionStringFields.Single(f => f.Name == "IntegratedSecurity");
if (intSecurityField != null)
@ -20,7 +21,7 @@
}
field.Value = field.Value.Replace("{{Date}}", DateTime.UtcNow.ToString("yyyyMMddHHmm"));
<tr style="@isVisible">
<td>
<Label For="@fieldId" HelpText="@field.HelpText" ResourceKey="@field.Name">@Localizer[$"{field.FriendlyName}:"]</Label>
@ -38,8 +39,8 @@
</td>
<td>
<select id="@fieldId" class="custom-select" @bind="@field.Value">
<option value="true" selected>@Localizer["True"]</option>
<option value="false">@Localizer["False"]</option>
<option value="true" selected>@SharedLocalizer["True"]</option>
<option value="false">@SharedLocalizer["False"]</option>
</select>
</td>
</tr>
@ -50,12 +51,12 @@
@code {
private readonly List<ConnectionStringField> _connectionStringFields = new()
{
new() {Name = "Server", FriendlyName = "Server", Value = ".", HelpText="Enter the database server"},
new() {Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}", HelpText="Enter the name of the database"},
new() {Name = "IntegratedSecurity", FriendlyName = "Integrated Security", Value = "true", HelpText="Select if you want integrated security or not"},
new() {Name = "Uid", FriendlyName = "User Id", Value = "", HelpText="Enter the username to use for the database"},
new() {Name = "Pwd", FriendlyName = "Password", Value = "", HelpText="Enter the password to use for the database"}
};
new() { Name = "Server", FriendlyName = "Server", Value = ".", HelpText = "Enter the database server" },
new() { Name = "Database", FriendlyName = "Database", Value = "Oqtane-{{Date}}", HelpText = "Enter the name of the database" },
new() { Name = "IntegratedSecurity", FriendlyName = "Integrated Security", Value = "true", HelpText = "Select if you want integrated security or not" },
new() { Name = "Uid", FriendlyName = "User Id", Value = "", HelpText = "Enter the username to use for the database" },
new() { Name = "Pwd", FriendlyName = "Password", Value = "", HelpText = "Enter the password to use for the database" }
};
public string GetConnectionString()
{
@ -67,7 +68,7 @@
var userId = _connectionStringFields[3].Value;
var password = _connectionStringFields[4].Value;
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database))
if (!String.IsNullOrEmpty(server) && !String.IsNullOrEmpty(database))
{
connectionString = $"Data Source={server};Initial Catalog={database};";
}

View File

@ -7,18 +7,19 @@
@inject IDatabaseService DatabaseService
@inject IJSRuntime JSRuntime
@inject IStringLocalizer<Installer> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="container">
<div class="row">
<div class="mx-auto text-center">
<img src="oqtane-black.png" />
<div style="font-weight: bold">@Localizer["Version:"] @Constants.Version</div>
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version</div>
</div>
</div>
<hr class="app-rule" />
<div class="row justify-content-center">
<div class="col text-center">
<h2>@Localizer["Database Configuration"]</h2><br />
<h2>@Localizer["DatabaseConfig"]</h2><br />
<table class="form-group" cellpadding="4" cellspacing="4" style="margin: auto;">
<tbody>
<tr>
@ -31,7 +32,14 @@
{
foreach (var database in _databases)
{
<option value="@database.Name">@Localizer[@database.Name]</option>
if (database.IsDefault)
{
<option value="@database.Name" selected>@Localizer[@database.Name]</option>
}
else
{
<option value="@database.Name">@Localizer[@database.Name]</option>
}
}
}
</select>
@ -47,7 +55,7 @@
</table>
</div>
<div class="col text-center">
<h2>@Localizer["Application Administrator"]</h2><br />
<h2>@Localizer["ApplicationAdmin"]</h2><br />
<table class="form-group" cellpadding="4" cellspacing="4" style="margin: auto;">
<tbody>
<tr>
@ -89,11 +97,16 @@
<hr class="app-rule" />
<div class="row">
<div class="mx-auto text-center">
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["Install Now"]</button><br /><br />
<button type="button" class="btn btn-success" @onclick="Install">@Localizer["InstallNow"]</button><br /><br />
<ModuleMessage Message="@_message" Type="MessageType.Error"></ModuleMessage>
</div>
<div class="app-progress-indicator" style="@_loadingDisplay"></div>
</div>
<div class="row">
<div class="mx-auto text-center">
<input type="checkbox" @bind="@_register" /> @Localizer["Register"]
</div>
</div>
</div>
@code {
@ -107,6 +120,7 @@
private string _hostPassword = string.Empty;
private string _confirmPassword = string.Empty;
private string _hostEmail = string.Empty;
private bool _register = true;
private string _message = string.Empty;
private string _loadingDisplay = "display: none;";
@ -126,7 +140,7 @@
}
catch
{
_message = Localizer["Error loading Database Configuration Control"];
_message = Localizer["Error.DbConfig.Load"];
}
}
@ -162,13 +176,13 @@
connectionString = databaseConfigControl.GetConnectionString();
}
if (connectionString != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "")
if (connectionString != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "" && _hostEmail.Contains("@"))
{
_loadingDisplay = "";
StateHasChanged();
Uri uri = new Uri(NavigationManager.Uri);
var database = _databases.SingleOrDefault(d => d.Name == _databaseName);
var config = new InstallConfig
@ -181,7 +195,8 @@
HostName = UserNames.Host,
TenantName = TenantNames.Master,
IsNewTenant = true,
SiteName = Constants.DefaultSite
SiteName = Constants.DefaultSite,
Register = _register
};
var installation = await InstallationService.Install(config);
@ -197,7 +212,7 @@
}
else
{
_message = Localizer["Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length"];
_message = Localizer["Message.Require.DbInfo"];
}
}

View File

@ -1,47 +0,0 @@
namespace Oqtane
{
public class SharedResources
{
public static readonly string UserLogin = "User Login";
public static readonly string UserRegistration = "User Registration";
public static readonly string PasswordReset = "Password Reset";
public static readonly string UserProfile = "User Profile";
public static readonly string AdminDashboard = "Admin Dashboard";
public static readonly string SiteSettings = "Site Settings";
public static readonly string PageManagement = "Page Management";
public static readonly string UserManagement = "User Management";
public static readonly string ProfileManagement = "Profile Management";
public static readonly string RoleManagement = "Role Management";
public static readonly string FileManagement = "File Management";
public static readonly string RecycleBin = "Recycle Bin";
public static readonly string EventLog = "Event Log";
public static readonly string SiteManagement = "Site Management";
public static readonly string ModuleManagement = "Module Management";
public static readonly string ThemeManagement = "Theme Management";
public static readonly string LanguageManagement = "Language Management";
public static readonly string ScheduledJobs = "Scheduled Jobs";
public static readonly string SqlManagement = "Sql Management";
public static readonly string SystemInfo = "System Info";
public static readonly string SystemUpdate = "System Update";
}
}

View File

@ -2,7 +2,7 @@
@inherits ModuleBase
@inject IPageService PageService
@inject IUserService UserService
@inject IStringLocalizer<SharedResources> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="row">
@foreach (var p in _pages)
@ -12,7 +12,7 @@
string url = NavigateUrl(p.Path);
<div class="col-md-2 mx-auto text-center">
<NavLink class="nav-link" href="@url" Match="NavLinkMatch.All">
<h2><span class="@p.Icon" aria-hidden="true"></span></h2>@Localizer[p.Name]
<h2><span class="@p.Icon" aria-hidden="true"></span></h2>@SharedLocalizer[p.Name]
</NavLink>
</div>
}

View File

@ -11,7 +11,7 @@
Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId);
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
string message = Localizer["A Problem Was Encountered Loading Module {0}", module.ModuleDefinitionName];
string message = string.Format(Localizer["Error.Module.Load"], module.ModuleDefinitionName);
AddModuleMessage(message, MessageType.Error);
}

View File

@ -5,6 +5,7 @@
@inject IFileService FileService
@inject IFolderService FolderService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Upload" Heading="Upload Files" ResourceKey="UploadFiles">
@ -18,7 +19,7 @@
</td>
</tr>
</table>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel>
<TabPanel Name="Download" Heading="Download Files" ResourceKey="DownloadFiles">
@if (_folders != null)
@ -37,8 +38,8 @@
<Label For="folder" HelpText="Select the folder to save the file in" ResourceKey="Folder">Folder: </Label>
</td>
<td>
<select id="folder" class="form-control" @bind="@_folderId">
<option value="-1">&lt;@Localizer["Select Folder"]&gt;</option>
<select id="folder" class="form-select" @bind="@_folderId">
<option value="-1">&lt;@Localizer["Folder.Select"]&gt;</option>
@foreach (Folder folder in _folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
@ -47,8 +48,8 @@
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="Download">@Localizer["Download"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="Download">@SharedLocalizer["Download"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
</TabPanel>
</TabStrip>
@ -74,7 +75,7 @@
{
if (url == string.Empty || _folderId == -1)
{
AddModuleMessage(Localizer["You Must Enter A Url And Select A Folder"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.UrlFolder"], MessageType.Warning);
return;
}
@ -83,13 +84,13 @@
if (!Constants.UploadableFiles.Split(',')
.Contains(Path.GetExtension(filename).ToLower().Replace(".", "")))
{
AddModuleMessage(Localizer["File Could Not Be Downloaded From Url Due To Its File Extension"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Download.InvalidExtension"], MessageType.Warning);
return;
}
if (!filename.IsPathOrFileValid())
{
AddModuleMessage(Localizer["You Must Enter A Url With A Valid File Name"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.UrlName"], MessageType.Warning);
return;
}
@ -97,12 +98,12 @@
{
await FileService.UploadFileAsync(url, _folderId);
await logger.LogInformation("File Downloaded Successfully From Url {Url}", url);
AddModuleMessage(Localizer["File Downloaded Successfully From Url"], MessageType.Success);
AddModuleMessage(Localizer["Success.Download.File"], MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading File From Url {Url} {Error}", url, ex.Message);
AddModuleMessage(Localizer["Error Downloading File From Url. Please Verify That The Url Is Valid."], MessageType.Error);
AddModuleMessage(Localizer["Error.Download.InvalidUrl"], MessageType.Error);
}
}
}

View File

@ -4,12 +4,13 @@
@inject IFolderService FolderService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Details> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_folders != null)
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label for="name" HelpText="The name of the file" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -21,7 +22,7 @@
<Label For="parent" HelpText="The folder where the file is located" ResourceKey="Folder">Folder: </Label>
</td>
<td>
<select id="parent" class="form-control" @bind="@_folderId">
<select id="parent" class="form-select" @bind="@_folderId">
@foreach (Folder folder in _folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
@ -38,8 +39,8 @@
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveFile">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveFile">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
@ -81,7 +82,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading File {FileId} {Error}", _fileId, ex.Message);
AddModuleMessage(Localizer["Error Loading File"], MessageType.Error);
AddModuleMessage(Localizer["Error.File.Load"], MessageType.Error);
}
}
@ -100,13 +101,13 @@
}
else
{
AddModuleMessage(Localizer["File Name Not Valid"], MessageType.Warning);
AddModuleMessage(Localizer["Message.File.InvalidName"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving File {FileId} {Error}", _fileId, ex.Message);
AddModuleMessage(Localizer["Error Saving File"], MessageType.Error);
AddModuleMessage(Localizer["Error.File.Save"], MessageType.Error);
}
}
}

View File

@ -4,19 +4,20 @@
@inject IFileService FileService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_folders != null)
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="parent" HelpText="Select the parent folder" ResourceKey="Parent">Parent: </Label>
</td>
<td>
<select id="parent" class="form-control" @bind="@_parentId">
<select id="parent" class="form-select" @bind="@_parentId">
@if (PageState.QueryString.ContainsKey("id"))
{
<option value="-1">&lt;@Localizer["No Parent"]&gt;</option>
<option value="-1">&lt;@Localizer["NoParent"]&gt;</option>
}
@foreach (Folder folder in _folders)
{
@ -44,7 +45,7 @@
}
else
{
<select id="type" class="form-control" @bind="@_type">
<select id="type" class="form-select" @bind="@_type">
<option value="@FolderTypes.Private">@Localizer[FolderTypes.Private]</option>
<option value="@FolderTypes.Public">@Localizer[FolderTypes.Public]</option>
</select>
@ -60,11 +61,13 @@
</table>
@if (!_isSystem)
{
<button type="button" class="btn btn-success" @onclick="SaveFolder">@Localizer["Save"]</button>
<button type="button" class="btn btn-success" @onclick="SaveFolder">@SharedLocalizer["Save"]</button>
@((MarkupString)"&nbsp;")
}
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@if (!_isSystem && PageState.QueryString.ContainsKey("id"))
{
@((MarkupString)"&nbsp;")
<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 />
@ -128,7 +131,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", _folderId, ex.Message);
AddModuleMessage(Localizer["Error Loading Folder"], MessageType.Error);
AddModuleMessage(Localizer["Error.Folder.Load"], MessageType.Error);
}
}
@ -136,13 +139,13 @@
{
if (_name == string.Empty || _parentId == -1)
{
AddModuleMessage(Localizer["Folders Must Have A Parent And A Name"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.FolderParent"], MessageType.Warning);
return;
}
if (!_name.IsPathOrFileValid())
{
AddModuleMessage(Localizer["Folder Name Not Valid."], MessageType.Warning);
AddModuleMessage(Localizer["Message.Folder.InvalidName"], MessageType.Warning);
return;
}
@ -191,13 +194,13 @@
}
else
{
AddModuleMessage(Localizer["An Error Was Encountered Saving The Folder"], MessageType.Error);
AddModuleMessage(Localizer["Error.Folder.Save"], MessageType.Error);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message);
AddModuleMessage(Localizer["Error Saving Folder"], MessageType.Error);
AddModuleMessage(Localizer["Error.Folder.Save"], MessageType.Error);
}
}
@ -225,18 +228,18 @@
}
else
{
AddModuleMessage(Localizer["Folder Has Files And Cannot Be Deleted"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Folder.Files.InvalidDelete"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["Folder Has Subfolders And Cannot Be Deleted"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Folder.Subfolders.InvalidDelete"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Folder {Folder} {Error}", _folderId, ex.Message);
AddModuleMessage(Localizer["Error Deleting Folder"], MessageType.Error);
AddModuleMessage(Localizer["Error.Folder.Delete"], MessageType.Error);
}
}
}

View File

@ -4,16 +4,17 @@
@inject IFolderService FolderService
@inject IFileService FileService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_files != null)
{
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">@Localizer["Folder:"] </label>
<label class="control-label">@Localizer["Folder"] </label>
</td>
<td>
<select class="form-control" @onchange="(e => FolderChanged(e))">
<select class="form-select" @onchange="(e => FolderChanged(e))">
@foreach (Folder folder in _folders)
{
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
@ -31,23 +32,23 @@
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@SharedLocalizer["Name"]</th>
<th>@Localizer["Modified"]</th>
<th>@Localizer["Type"]</th>
<th>@Localizer["Size"]</th>
</Header>
<Row>
<td><ActionLink Action="Details" Text="Edit" Parameters="@($"id=" + context.FileId.ToString())" ResourceKey="Details" /></td>
<td><ActionDialog Header="Delete File" Message="@Localizer["Are You Sure You Wish To Delete {0}?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" ResourceKey="DeleteFile" /></td>
<td><ActionDialog Header="Delete File" Message="@string.Format(Localizer["Confirm.File.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFile(context))" ResourceKey="DeleteFile" /></td>
<td><a href="@context.Url" target="_new">@context.Name</a></td>
<td>@context.ModifiedOn</td>
<td>@context.Extension.ToUpper() @Localizer["File"]</td>
<td>@context.Extension.ToUpper() @SharedLocalizer["File"]</td>
<td>@string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB</td>
</Row>
</Pager>
@if (_files.Count == 0)
{
<div class="text-center">@Localizer["No Files Exist In Selected Folder"]</div>
<div class="text-center">@Localizer["NoFiles"]</div>
}
}
@ -63,7 +64,7 @@
try
{
_folders = await FolderService.GetFoldersAsync(PageState.Site.SiteId);
if (_folderId == -1 && _folders.Count > 0)
{
_folderId = _folders[0].FolderId;
@ -73,7 +74,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Files"], MessageType.Error);
AddModuleMessage(Localizer["Error.File.Load"], MessageType.Error);
}
}
@ -93,7 +94,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Files"], MessageType.Error);
AddModuleMessage(Localizer["Error.File.Load"], MessageType.Error);
}
}
@ -103,14 +104,14 @@
{
await FileService.DeleteFileAsync(file.FileId);
await logger.LogInformation("File Deleted {File}", file.Name);
AddModuleMessage(Localizer["File {0} Deleted", file.Name], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.File.Delete"], file.Name), MessageType.Success);
await GetFiles();
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting File {File} {Error}", file.Name, ex.Message);
AddModuleMessage(Localizer["Error Deleting File {0}", file.Name], MessageType.Error);
AddModuleMessage(string.Format(Localizer["Error.File.Delete"], file.Name), MessageType.Error);
}
}
}

View File

@ -3,10 +3,11 @@
@inject NavigationManager NavigationManager
@inject IJobService JobService
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="name" HelpText="Enter the job name" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -26,9 +27,9 @@
<Label For="enabled" HelpText="Select whether you want the job enabled or not" ResourceKey="Enabled">Enabled? </Label>
</td>
<td>
<select id="enabled" class="form-control" @bind="@_isEnabled">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="enabled" class="form-select" @bind="@_isEnabled">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -38,7 +39,7 @@
</td>
<td>
<input id="runs-every" class="form-control" @bind="@_interval" />
<select id="runs-every" class="form-control" @bind="@_frequency">
<select id="runs-every" class="form-select" @bind="@_frequency">
<option value="m">@Localizer["Minute(s)"]</option>
<option value="H">@Localizer["Hour(s)"]</option>
<option value="d">@Localizer["Day(s)"]</option>
@ -79,8 +80,11 @@
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveJob">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveJob">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
@code {
private int _jobId;
@ -93,6 +97,10 @@
private string _endDate = string.Empty;
private string _retentionHistory = string.Empty;
private string _nextExecution = string.Empty;
private string createdby;
private DateTime createdon;
private string modifiedby;
private DateTime modifiedon;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -113,12 +121,16 @@
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
_retentionHistory = job.RetentionHistory.ToString();
_nextExecution = job.NextExecution.ToString();
createdby = job.CreatedBy;
createdon = job.CreatedOn;
modifiedby = job.ModifiedBy;
modifiedon = job.ModifiedOn;
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message);
AddModuleMessage(Localizer["Error Loading Job"], MessageType.Error);
AddModuleMessage(Localizer["Error.Job.Load"], MessageType.Error);
}
}
@ -171,12 +183,12 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Udate Job {Job} {Error}", job, ex.Message);
AddModuleMessage(Localizer["Error Updating Job"], MessageType.Error);
AddModuleMessage(Localizer["Error.Job.Update"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide The Job Name, Type, Frequency, and Retention"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.JobInfo"], MessageType.Warning);
}
}

View File

@ -2,10 +2,11 @@
@inherits ModuleBase
@inject IJobService JobService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_jobs == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
@ -19,10 +20,10 @@ else
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@Localizer["Status"]</th>
<th>@SharedLocalizer["Name"]</th>
<th>@SharedLocalizer["Status"]</th>
<th>@Localizer["Frequency"]</th>
<th>@Localizer["Next Execution"]</th>
<th>@Localizer["NextExecution"]</th>
<th style="width: 1px;">&nbsp;</th>
</Header>
<Row>
@ -118,7 +119,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Job {Job} {Error}", job, ex.Message);
AddModuleMessage(Localizer["Error Deleting Job"], MessageType.Error);
AddModuleMessage(Localizer["Error.Job.Delete"], MessageType.Error);
}
}

View File

@ -2,46 +2,47 @@
@inherits ModuleBase
@inject IJobLogService JobLogService
@inject IStringLocalizer<Log> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_jobLogs == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<Pager Items="@_jobLogs">
<Header>
<th>@Localizer["Name"]</th>
<th>@Localizer["Status"]</th>
<th>@Localizer["Started"]</th>
<th>@Localizer["Finished"]</th>
</Header>
<Row>
<td>@context.Job.Name</td>
<td>@DisplayStatus(context.Job.IsExecuting, context.Succeeded)</td>
<td>@context.StartDate</td>
<td>@context.FinishDate</td>
</Row>
<Detail>
<td colspan="4">@((MarkupString)context.Notes)</td>
</Detail>
</Pager>
<Pager Items="@_jobLogs">
<Header>
<th>@SharedLocalizer["Name"]</th>
<th>@SharedLocalizer["Status"]</th>
<th>@Localizer["Started"]</th>
<th>@Localizer["Finished"]</th>
</Header>
<Row>
<td>@context.Job.Name</td>
<td>@DisplayStatus(context.Job.IsExecuting, context.Succeeded)</td>
<td>@context.StartDate</td>
<td>@context.FinishDate</td>
</Row>
<Detail>
<td colspan="4">@((MarkupString)context.Notes)</td>
</Detail>
</Pager>
}
@code {
private List<JobLog> _jobLogs;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override async Task OnParametersSetAsync()
{
_jobLogs = await JobLogService.GetJobLogsAsync();
if (PageState.QueryString.ContainsKey("id"))
{
_jobLogs = _jobLogs.Where(item => item.JobId == Int32.Parse(PageState.QueryString["id"])).ToList();
}
_jobLogs = _jobLogs.OrderByDescending(item => item.JobLogId).ToList();
}
@ -63,7 +64,7 @@ else
status = Localizer["Failed"];
}
}
return status;
}
}

View File

@ -7,10 +7,11 @@
@inject ILanguageService LanguageService
@inject IPackageService PackageService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_supportedCultures == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
@ -22,75 +23,92 @@ else
}
else
{
<table class="table table-borderless">
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
</td>
<td>
<select id="_code" class="form-select" @bind="@_code">
@foreach (var culture in _availableCultures)
{
<option value="@culture.Name">@culture.DisplayName</option>
}
</select>
</td>
</tr>
<tr>
<td>
<Label For="default" HelpText="Indicates Whether Or Not This Language Is The Default For The Site" ResourceKey="IsDefault">Default?</Label>
</td>
<td>
<select id="default" class="form-select" @bind="@_isDefault">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveLanguage">@SharedLocalizer["Save"]</button>
}
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel>
<TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host">
<ModuleMessage Type="MessageType.Info" Message="Download one or more translations from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<table class="table table-borderless" style=" margin: auto; width: 50% !important;">
<tr>
<td>
<Label For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
</td>
<td>
<select id="_code" class="form-control" @bind="@_code">
@foreach (var culture in _availableCultures)
{
<option value="@culture.Name">@culture.DisplayName</option>
}
</select>
</td>
</tr>
<tr>
<td>
<Label For="default" HelpText="Indicates Whether Or Not This Language Is The Default For The Site" ResourceKey="IsDefault">Default?</Label>
</td>
<td>
<select id="default" class="form-control" @bind="@_isDefault">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
</select>
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>&nbsp;
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveLanguage">@Localizer["Save"]</button>
}
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
</TabPanel>
<TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host">
@if (_packages != null && _packages.Count > 0)
@if (_packages != null)
{
<ModuleMessage Type="MessageType.Info" Message="Download one or more language packages from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<Pager Items="@_packages">
<Header>
<th>@Localizer["Name"]</th>
<th>@Localizer["Version"]</th>
<th style="width: 1px"></th>
</Header>
<Row>
<td>@context.Name</td>
<td>@context.Version</td>
<td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadLanguage(context.PackageId, context.Version))>@Localizer["Download"]</button>
</td>
</Row>
</Pager>
<button type="button" class="btn btn-success" @onclick="InstallLanguages">@Localizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
}
else
{
<ModuleMessage Type="MessageType.Info" Message="No Language Packages Are Available To Download"></ModuleMessage>
@if (_packages.Count > 0)
{
<Pager Items="@_packages">
<Row>
<td>
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3>&nbsp;&nbsp;by:&nbsp;&nbsp;<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"]&nbsp;&nbsp;|&nbsp;&nbsp; @SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong>&nbsp;&nbsp;|&nbsp;&nbsp;@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>&nbsp;&nbsp;|&nbsp;&nbsp;@SharedLocalizer["Search.Source"]: <strong>@context.PackageUrl</strong>
</td>
<td style="vertical-align: middle;">
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadLanguage(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
</td>
</Row>
</Pager>
}
else
{
<br />
<div class="mx-auto text-center">
@Localizer["Search.NoResults"]
</div>
}
<button type="button" class="btn btn-success" @onclick="InstallLanguages">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload one or more language packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Language: </Label>
<Label HelpText="Upload one or more translations. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Language: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="true" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="InstallLanguages">@Localizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="InstallLanguages">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel>
</TabStrip>
}
@ -102,6 +120,7 @@ else
private IEnumerable<Culture> _supportedCultures;
private IEnumerable<Culture> _availableCultures;
private List<Package> _packages;
private string _search = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -113,15 +132,45 @@ else
_supportedCultures = await LocalizationService.GetCulturesAsync();
_availableCultures = _supportedCultures
.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !languagesCodes.Contains(c.Name));
_packages = await PackageService.GetPackagesAsync("language");
await LoadTranslations();
if (_supportedCultures.Count() == 1)
{
_message = Localizer["The Only Installed Language Is English"];
_message = Localizer["OnlyEnglish"];
}
else if (_availableCultures.Count() == 0)
{
_message = Localizer["All The Installed Languages Have Been Added."];
_message = Localizer["AllLanguages"];
}
}
private async Task LoadTranslations()
{
_packages = await PackageService.GetPackagesAsync("translation", _search);
}
private async Task Search()
{
try
{
await LoadTranslations();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Search");
}
}
private async Task Reset()
{
try
{
_search = "";
await LoadTranslations();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Reset");
}
}
@ -151,7 +200,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding Language {Language} {Error}", language, ex.Message);
AddModuleMessage(Localizer["Error Adding Language"], MessageType.Error);
AddModuleMessage(Localizer["Error.Language.Add"], MessageType.Error);
}
}
@ -160,11 +209,11 @@ else
try
{
await PackageService.InstallPackagesAsync();
AddModuleMessage(Localizer["Language Packages Installed Successfully. You Must <a href=\"{0}\">Restart</a> Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Language.Install"], NavigateUrl("admin/system")), MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Installing Language Package");
await logger.LogError(ex, "Error Installing Translations");
}
}
@ -174,13 +223,13 @@ else
{
await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Language Paclage {Name} {Version} Downloaded Successfully", packageid, version);
AddModuleMessage(Localizer["Language Package Downloaded Successfully. Click Install To Complete Installation."], MessageType.Success);
AddModuleMessage(Localizer["Success.Language.Download"], MessageType.Success);
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Language Package {Name} {Version}", packageid, version);
AddModuleMessage(Localizer["Error Downloading Language Package"], MessageType.Error);
await logger.LogError(ex, "Error Downloading Translation {Name} {Version}", packageid, version);
AddModuleMessage(Localizer["Error.Language.Download"], MessageType.Error);
}
}

View File

@ -4,10 +4,11 @@
@inject ILocalizationService LocalizationService
@inject IPackageService PackageService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_languages == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
@ -16,21 +17,21 @@ else
<Pager Items="@_languages">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@SharedLocalizer["Name"]</th>
<th>@Localizer["Code"]</th>
<th>@Localizer["Default?"]</th>
<th>@Localizer["Default"]</th>
<th style="width: 1px;">&nbsp;</th>
</Header>
<Row>
<td><ActionDialog Header="Delete Langauge" Message="@Localizer["Are You Sure You Wish To Delete The {0} Language From This Site?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteLanguage(context))" Disabled="@((context.IsDefault && _languages.Count > 2) || context.Code == Constants.DefaultCulture)" ResourceKey="DeleteLanguage" /></td>
<td><ActionDialog Header="Delete Language" Message="@string.Format(Localizer["Confirm.Language.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteLanguage(context))" Disabled="@((context.IsDefault && _languages.Count > 2) || context.Code == Constants.DefaultCulture)" ResourceKey="DeleteLanguage" /></td>
<td>@context.Name</td>
<td>@context.Code</td>
<td><TriStateCheckBox Value="@(context.IsDefault)" Disabled="true"></TriStateCheckBox></td>
<td>
@if (UpgradeAvailable(context.Code))
{
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadLanguage(context.Code))>@Localizer["Upgrade"]</button>
}
{
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadLanguage(context.Code))>@SharedLocalizer["Upgrade"]</button>
}
</td>
</Row>
</Pager>
@ -48,13 +49,13 @@ else
var cultures = await LocalizationService.GetCulturesAsync();
var culture = cultures.First(c => c.Name.Equals(Constants.DefaultCulture));
// Adds English as default language
_languages.Insert(0, new Language { Name = culture.DisplayName, Code = culture.Name, IsDefault = !_languages.Any(l => l.IsDefault) });
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
_packages = await PackageService.GetPackagesAsync("language");
_packages = await PackageService.GetPackagesAsync("translation");
}
}
@ -71,7 +72,7 @@ else
{
await logger.LogError(ex, "Error Deleting Language {Language} {Error}", language, ex.Message);
AddModuleMessage(Localizer["Error Deleting Language"], MessageType.Error);
AddModuleMessage(Localizer["Error.Language.Delete"], MessageType.Error);
}
}
@ -97,15 +98,15 @@ else
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
await PackageService.DownloadPackageAsync(Constants.PackageId + ".Client." + code, Constants.Version, "Packages");
await logger.LogInformation("Language Package Downloaded {Code} {Version}", code, Constants.Version);
await logger.LogInformation("Translation Downloaded {Code} {Version}", code, Constants.Version);
await PackageService.InstallPackagesAsync();
AddModuleMessage(Localizer["Language Package Installed Successfully. You Must <a href=\"{0}\">Restart</a> Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Language.Install"], NavigateUrl("admin/system")), MessageType.Success);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Language Package {Code} {Version} {Error}", code, Constants.Version, ex.Message);
AddModuleMessage(Localizer["Error Downloading Language Package"], MessageType.Error);
await logger.LogError(ex, "Error Downloading Translation {Code} {Version} {Error}", code, Constants.Version, ex.Message);
AddModuleMessage(Localizer["Error.Language.Download"], MessageType.Error);
}
}
}

View File

@ -3,7 +3,9 @@
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject IServiceProvider ServiceProvider
@inject SiteState SiteState
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_message != string.Empty)
{
@ -14,29 +16,29 @@
<text>...</text>
</Authorizing>
<Authorized>
<ModuleMessage Message="@Localizer["You Are Already Signed In"]" Type="MessageType.Info" />
<ModuleMessage Message="@Localizer["Info.SignedIn"]" Type="MessageType.Info" />
</Authorized>
<NotAuthorized>
<form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))">
<div class="form-group">
<label for="Username" class="control-label">@Localizer["Username:"] </label>
<label for="Username" class="control-label">@SharedLocalizer["Username"] </label>
<input type="text" @ref="username" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" required />
</div>
<div class="form-group">
<label for="Password" class="control-label">@Localizer["Password:"] </label>
<label for="Password" class="control-label">@SharedLocalizer["Password"] </label>
<input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" required />
</div>
<div class="form-group">
<div class="form-check form-check-inline">
<label class="form-check-label" for="Remember">@Localizer["Remember Me?"]</label>&nbsp;
<label class="form-check-label" for="Remember">@Localizer["RememberMe"]</label>&nbsp;
<input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
</div>
</div>
<button type="button" class="btn btn-primary" @onclick="Login">@Localizer["Login"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</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>
<br /><br />
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["Forgot Password"]</button>
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button>
</div>
</form>
</NotAuthorized>
@ -57,7 +59,7 @@
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
public override List<Resource> Resources => new List<Resource>()
{
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};
@ -82,11 +84,11 @@
if (user != null)
{
_message = Localizer["User Account Verified Successfully. You Can Now Login With Your Username And Password Below."];
_message = Localizer["Success.Account.Verified"];
}
else
{
_message = Localizer["User Account Could Not Be Verified. Please Contact Your Administrator For Further Instructions."];
_message = Localizer["Message.Account.NotVerfied"];
_type = MessageType.Warning;
}
}
@ -108,7 +110,6 @@
{
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
{
// server-side Blazor
var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = _username;
@ -118,16 +119,15 @@
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
// complete the login on the server so that the cookies are set correctly
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
// server-side Blazor needs to post to the Login page so that the cookies are set correctly
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
await interop.SubmitForm(url, fields);
}
else
{
await logger.LogInformation("Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);
}
}
else
@ -143,18 +143,18 @@
await logger.LogInformation("Login Successful For Username {Username}", _username);
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
}
else
{
await logger.LogInformation("Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);
}
}
}
else
{
AddModuleMessage(Localizer["Please Provide Your Username And Password"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
}
}

View File

@ -6,11 +6,12 @@
@inject IPageService PageService
@inject IPageModuleService PageModuleService
@inject IUserService UserService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<Detail> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="dateTime" HelpText="The date and time of this log" ResourceKey="DateTime">Date/Time: </Label>
</td>
<td>
@ -134,7 +135,7 @@
</td>
</tr>
</table>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {
private int _logId;
@ -207,7 +208,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Log {LogId} {Error}", _logId, ex.Message);
AddModuleMessage(Localizer["Error Loading Log"], MessageType.Error);
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
}
}
}

View File

@ -1,11 +1,12 @@
@namespace Oqtane.Modules.Admin.Logs
@inherits ModuleBase
@inject ILogService LogService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_logs == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
@ -13,8 +14,8 @@ else
<tr>
<td>
<Label For="level" HelpText="Select the log level for event log items" ResourceKey="Level">Level: </Label><br /><br />
<select id="level" class="form-control" @onchange="(e => LevelChanged(e))">
<option value="-">&lt;@Localizer["All Levels"]&gt;</option>
<select id="level" class="form-select" @onchange="(e => LevelChanged(e))">
<option value="-">&lt;@Localizer["AllLevels"]&gt;</option>
<option value="Trace">@Localizer["Trace"]</option>
<option value="Debug">@Localizer["Debug"]</option>
<option value="Information">@Localizer["Information"]</option>
@ -25,19 +26,19 @@ else
</td>
<td>
<Label For="function" HelpText="Select the function for event log items" ResourceKey="Function">Function: </Label><br /><br />
<select id="function" class="form-control" @onchange="(e => FunctionChanged(e))">
<option value="-">&lt;@Localizer["All Functions"]&gt;</option>
<select id="function" class="form-select" @onchange="(e => FunctionChanged(e))">
<option value="-">&lt;@Localizer["AllFunctions"]&gt;</option>
<option value="Create">@Localizer["Create"]</option>
<option value="Read">@Localizer["Read"]</option>
<option value="Update">@Localizer["Update"]</option>
<option value="Delete">@Localizer["Delete"]</option>
<option value="Update">@SharedLocalizer["Update"]</option>
<option value="Delete">@SharedLocalizer["Delete"]</option>
<option value="Security">@Localizer["Security"]</option>
<option value="Other">@Localizer["Other"]</option>
</select>
</td>
<td>
<Label For="rows" HelpText="Select the maximum number of event log items to review. Please note that if you choose more than 10 items the information will be split into pages." ResourceKey="Rows">Maximum Items: </Label><br /><br />
<select id="rows" class="form-control" @onchange="(e => RowsChanged(e))">
<select id="rows" class="form-select" @onchange="(e => RowsChanged(e))">
<option value="10">10</option>
<option value="50">50</option>
<option value="100">100</option>
@ -67,7 +68,7 @@ else
}
else
{
<p><em>@Localizer["No Logs Match The Criteria Specified"]</em></p>
<p><em>@Localizer["NoLogs"]</em></p>
}
}
@ -88,7 +89,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Logs"], MessageType.Error);
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
}
}
@ -103,7 +104,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Logs"], MessageType.Error);
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
}
}
@ -118,7 +119,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Logs"], MessageType.Error);
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
}
}
@ -134,7 +135,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Logs"], MessageType.Error);
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
}
}

View File

@ -6,12 +6,13 @@
@inject IModuleService ModuleService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (string.IsNullOrEmpty(_moduledefinitionname) && _templates != null)
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label 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>
</td>
<td>
@ -39,8 +40,8 @@
<Label For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
</td>
<td>
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Select Template"]&gt;</option>
<select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates)
{
<option value="@template.Name">@template.Title</option>
@ -53,7 +54,7 @@
<Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
</td>
<td>
<select id="reference" class="form-control" @bind="@_reference">
<select id="reference" class="form-select" @bind="@_reference">
@foreach (string version in _versions)
{
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -61,7 +62,7 @@
<option value="@(version)">@(version)</option>
}
}
<option value="local">@Localizer["Local Version"]</option>
<option value="local">@SharedLocalizer["LocalVersion"]</option>
</select>
</td>
</tr>
@ -77,11 +78,11 @@
</tr>
}
</table>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["Create Module"]</button>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["Module.Create"]</button>
}
else
{
<button type="button" class="btn btn-success" @onclick="ActivateModule">@Localizer["Activate Module"]</button>
<button type="button" class="btn btn-success" @onclick="ActivateModule">@Localizer["Module.Activate"]</button>
}
@code {
@ -108,11 +109,11 @@ else
if (string.IsNullOrEmpty(_moduledefinitionname))
{
AddModuleMessage(Localizer["Please Note That The Module Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info);
AddModuleMessage(Localizer["Info.Module.Creator"], MessageType.Info);
}
else
{
AddModuleMessage(Localizer["Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below"], MessageType.Info);
AddModuleMessage(Localizer["Info.Module.Activate"], MessageType.Info);
}
}
catch (Exception ex)
@ -136,11 +137,11 @@ else
GetLocation();
AddModuleMessage(Localizer["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.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
}
else
{
AddModuleMessage(Localizer["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"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
}
}
catch (Exception ex)

View File

@ -5,50 +5,70 @@
@inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_packages != null)
{
<TabStrip>
@if (_packages.Count > 0)
<TabStrip>
<TabPanel Name="Download" ResourceKey="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<table class="table table-borderless" style="margin: auto; width: 50% !important;">
<tr>
<td>
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
</td>
<td>
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>&nbsp;
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
</td>
</tr>
</table>
@if (_packages != null)
{
<TabPanel Name="Download" ResourceKey="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more modules from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
if (_packages.Count > 0)
{
<Pager Items="@_packages">
<Header>
<th>@Localizer["Name"]</th>
<th>@Localizer["Version"]</th>
<th style="width: 1px"></th>
</Header>
<Row>
<td>@context.Name</td>
<td>@context.Version</td>
<td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>@Localizer["Download"]</button>
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3>&nbsp;&nbsp;by:&nbsp;&nbsp;<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"]&nbsp;&nbsp;|&nbsp;&nbsp; @SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong>&nbsp;&nbsp;|&nbsp;&nbsp;@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>&nbsp;&nbsp;|&nbsp;&nbsp;@SharedLocalizer["Search.Source"]: <strong>@context.PackageUrl</strong>
</td>
<td style="vertical-align: middle;">
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
</td>
</Row>
</Pager>
</TabPanel>
}
else
{
<br />
<div class="mx-auto text-center">
@Localizer["Search.NoResults"]
</div>
}
}
<TabPanel Name="Upload" ResourceKey="Upload">
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="true" />
</td>
</tr>
</table>
</TabPanel>
</TabStrip>
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload">
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload one or more module packages. Once they are uploaded click Install to complete the installation." ResourceKey="Module">Module: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="true" />
</td>
</tr>
</table>
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-success" @onclick="InstallModules">@Localizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
}
<button type="button" class="btn btn-success" @onclick="InstallModules">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {
private List<Package> _packages;
private string _search = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -56,9 +76,22 @@
{
try
{
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
_packages = await PackageService.GetPackagesAsync("module");
await LoadModuleDefinitions();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message);
AddModuleMessage(Localizer["Error.Package.Load"], MessageType.Error);
}
}
private async Task LoadModuleDefinitions()
{
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
_packages = await PackageService.GetPackagesAsync("module", _search);
if (_packages != null)
{
foreach (Package package in _packages.ToArray())
{
if (moduledefinitions.Exists(item => item.PackageName == package.PackageId))
@ -67,10 +100,30 @@
}
}
}
}
private async Task Search()
{
try
{
await LoadModuleDefinitions();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Packages"], MessageType.Error);
await logger.LogError(ex, "Error On Search");
}
}
private async Task Reset()
{
try
{
_search = "";
await LoadModuleDefinitions();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Reset");
}
}
@ -79,7 +132,7 @@
try
{
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
AddModuleMessage(Localizer["Module Installed Successfully. You Must <a href=\"{0}\">Restart</a> Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
}
catch (Exception ex)
{
@ -93,13 +146,13 @@
{
await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", packageid, version);
AddModuleMessage(Localizer["Modules Downloaded Successfully. Click Install To Complete Installation."], MessageType.Success);
AddModuleMessage(Localizer["Success.Module.Download"], MessageType.Success);
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version}", packageid, version);
AddModuleMessage(Localizer["Error Downloading Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Download"], MessageType.Error);
}
}
}

View File

@ -5,13 +5,14 @@
@inject IModuleDefinitionService ModuleDefinitionService
@inject IModuleService ModuleService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<Create> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_templates != null)
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label 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>
</td>
<td>
@ -39,8 +40,8 @@
<Label For="template" HelpText="Select a module template. Templates are located in the wwwroot/Modules/Templates folder on the server." ResourceKey="Template">Template: </Label>
</td>
<td>
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Select Template"]&gt;</option>
<select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates)
{
<option value="@template.Name">@template.Title</option>
@ -53,7 +54,7 @@
<Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
</td>
<td>
<select id="reference" class="form-control" @bind="@_reference">
<select id="reference" class="form-select" @bind="@_reference">
@foreach (string version in _versions)
{
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -61,7 +62,7 @@
<option value="@(version)">@(version)</option>
}
}
<option value="local">@Localizer["Local Version"]</option>
<option value="local">@SharedLocalizer["LocalVersion"]</option>
</select>
</td>
</tr>
@ -77,8 +78,8 @@
</tr>
}
</table>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["Create Module"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
@ -100,7 +101,7 @@
{
_templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
AddModuleMessage(Localizer["Please Note That The Module Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info);
AddModuleMessage(Localizer["Info.Module.Development"], MessageType.Info);
}
catch (Exception ex)
{
@ -117,11 +118,11 @@
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
GetLocation();
AddModuleMessage(Localizer["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 Activate The Module.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Module.Create"], NavigateUrl("admin/system")), MessageType.Success);
}
else
{
AddModuleMessage(Localizer["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"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Require.ValidName"], MessageType.Warning);
}
}
catch (Exception ex)

View File

@ -3,12 +3,13 @@
@inject IModuleDefinitionService ModuleDefinitionService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Definition" ResourceKey="Definition">
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -35,7 +36,7 @@
<Section Name="Information" ResourceKey="Information">
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
</td>
<td>
@ -103,8 +104,8 @@
</table>
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
@ -161,7 +162,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message);
AddModuleMessage(Localizer["Error Loading Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Load"], MessageType.Error);
}
}
@ -190,7 +191,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message);
AddModuleMessage(Localizer["Error Saving Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Save"], MessageType.Error);
}
}
}

View File

@ -4,23 +4,24 @@
@inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_moduleDefinitions == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" />
@((MarkupString)"&nbsp;")
<ActionLink Action="Create" Text="Create Module" ResourceKey="CreateModule" />
<ActionLink Action="Create" Text="Create Module" ResourceKey="CreateModule" Class="btn btn-secondary" />
<Pager Items="@_moduleDefinitions">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@Localizer["Version"]</th>
<th>@SharedLocalizer["Name"]</th>
<th>@SharedLocalizer["Version"]</th>
<th style="width: 1px;">&nbsp;</th>
</Header>
<Row>
@ -28,7 +29,7 @@ else
<td>
@if (context.AssemblyName != "Oqtane.Client")
{
<ActionDialog Header="Delete Module" Message="@Localizer["Are You Sure You Wish To Delete The {0} Module?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
<ActionDialog Header="Delete Module" Message="@string.Format(Localizer["Confirm.Module.Delete", context.Name])" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" />
}
</td>
<td>@context.Name</td>
@ -36,7 +37,7 @@ else
<td>
@if (UpgradeAvailable(context.PackageName, context.Version))
{
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.PackageName, context.Version))>@Localizer["Upgrade"]</button>
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.PackageName, context.Version))>@SharedLocalizer["Upgrade"]</button>
}
</td>
</Row>
@ -61,7 +62,7 @@ else
if (_moduleDefinitions == null)
{
await logger.LogError(ex, "Error Loading Modules {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Modules"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Load"], MessageType.Error);
}
}
}
@ -88,12 +89,12 @@ else
await PackageService.DownloadPackageAsync(packagename, version, "Packages");
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
await ModuleDefinitionService.InstallModuleDefinitionsAsync();
AddModuleMessage(Localizer["Module Installed Successfully. You Must <a href=\"{0}\">Restart</a> Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version} {Error}", packagename, version, ex.Message);
AddModuleMessage(Localizer["Error Downloading Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Download"], MessageType.Error);
}
}
@ -102,13 +103,13 @@ else
try
{
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
AddModuleMessage(Localizer["Module Deleted Successfully"], MessageType.Success);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload"));
AddModuleMessage(Localizer["Success.Module.Delete"], MessageType.Success);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Module {ModuleDefinition} {Error}", moduleDefinition, ex.Message);
AddModuleMessage(Localizer["Error Deleting Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
}
}
}

View File

@ -3,11 +3,12 @@
@inject NavigationManager NavigationManager
@inject IModuleService ModuleService
@inject IStringLocalizer<Export> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tbody>
<tr>
<td>
<td width="30%">
<Label For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
</td>
<td>
@ -17,7 +18,7 @@
</tbody>
</table>
<button type="button" class="btn btn-success" @onclick="ExportModule">@Localizer["Export"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {

View File

@ -3,11 +3,12 @@
@inject NavigationManager NavigationManager
@inject IModuleService ModuleService
@inject IStringLocalizer<Import> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tbody>
<tr>
<td>
<td width="30%">
<Label For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
</td>
<td>
@ -17,7 +18,7 @@
</tbody>
</table>
<button type="button" class="btn btn-success" @onclick="ImportModule">@Localizer["Import"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {
@ -35,22 +36,22 @@
bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
if (success)
{
AddModuleMessage(Localizer["Content Imported Successfully"], MessageType.Success);
AddModuleMessage(Localizer["Success.Content.Import"], MessageType.Success);
}
else
{
AddModuleMessage(Localizer["A Problem Was Encountered Importing Content. Please Ensure The Content Is Formatted Correctly For The Module."], MessageType.Warning);
AddModuleMessage(Localizer["Message.Content.ImportProblem"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Importing Module {ModuleId} {Error}", ModuleState.ModuleId, ex.Message);
AddModuleMessage(Localizer["Error Importing Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Import"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["You Must Enter Some Content To Import"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.ImportContent"], MessageType.Warning);
}
}
}

View File

@ -6,6 +6,7 @@
@inject IModuleService ModuleService
@inject IPageModuleService PageModuleService
@inject IStringLocalizer<Settings> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
@ -13,7 +14,7 @@
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label>
</td>
<td>
@ -25,7 +26,7 @@
<Label For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
</td>
<td>
<select id="container" class="form-control" @bind="@_containerType">
<select id="container" class="form-select" @bind="@_containerType">
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -38,9 +39,9 @@
<Label For="allpages" HelpText="Indicate if this module should be displayed on all pages" ResourceKey="DisplayOnAllPages">Display On All Pages? </Label>
</td>
<td>
<select id="allpages" class="form-control" @bind="@_allPages">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="allpages" class="form-select" @bind="@_allPages">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -49,7 +50,7 @@
<Label For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
</td>
<td>
<select id="page" class="form-control" @bind="@_pageId">
<select id="page" class="form-select" @bind="@_pageId">
@foreach (Page p in PageState.Pages)
{
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
@ -88,8 +89,11 @@
</TabPanel>
}
</TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveModule">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveModule">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
@ -111,6 +115,10 @@
private Type _containerSettingsType;
private object _containerSettings;
private RenderFragment ContainerSettingsComponent { get; set; }
private string createdby;
private DateTime createdon;
private string modifiedby;
private DateTime modifiedon;
protected override async Task OnInitializedAsync()
{
@ -122,6 +130,10 @@
_permissions = ModuleState.Permissions;
_permissionNames = ModuleState.ModuleDefinition.PermissionNames;
_pageId = ModuleState.PageId.ToString();
createdby = ModuleState.CreatedBy;
createdon = ModuleState.CreatedOn;
modifiedby = ModuleState.ModifiedBy;
modifiedon = ModuleState.ModifiedOn;
if (!string.IsNullOrEmpty(ModuleState.ModuleDefinition.SettingsType))
{
@ -212,7 +224,7 @@
}
else
{
AddModuleMessage(Localizer["You Must Provide A Title For The Module"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.Title"], MessageType.Warning);
}
}

View File

@ -4,6 +4,7 @@
@inject IPageService PageService
@inject IThemeService ThemeService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip Refresh="@_refresh">
<TabPanel Name="Settings" ResourceKey="Settings">
@ -11,7 +12,7 @@
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -23,8 +24,8 @@
<Label For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
</td>
<td>
<select id="Parent" class="form-control" @onchange="(e => ParentChanged(e))">
<option value="-1">&lt;@Localizer["Site Root"]&gt;</option>
<select id="Parent" class="form-select" @onchange="(e => ParentChanged(e))">
<option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option>
@foreach (Page page in _pageList)
{
<option value="@(page.PageId)">@(new string('-', page.Level * 2))@(page.Name)</option>
@ -37,19 +38,19 @@
<Label For="Insert" HelpText="Select the location where you would like the page to be inserted in relation to other pages" ResourceKey="Insert">Insert: </Label>
</td>
<td>
<select id="Insert" class="form-control" @bind="@_insert">
<option value="<<">@Localizer["At Beginning"]</option>
<select id="Insert" class="form-select" @bind="@_insert">
<option value="<<">@Localizer["AtBeginning"]</option>
@if (_children != null && _children.Count > 0)
{
<option value="<">@Localizer["Before"]</option>
<option value=">">@Localizer["After"]</option>
}
<option value=">>">@Localizer["At End"]</option>
<option value=">>">@Localizer["AtEnd"]</option>
</select>
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
{
<select class="form-control" @bind="@_childid">
<option value="-1">&lt;@Localizer["Select Page"]&gt;</option>
<select class="form-select" @bind="@_childid">
<option value="-1">&lt;@Localizer["Page.Select"]&gt;</option>
@foreach (Page page in _children)
{
<option value="@(page.PageId)">@(page.Name)</option>
@ -60,12 +61,23 @@
</tr>
<tr>
<td>
<Label For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
<Label For="navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
</td>
<td>
<select id="Navigation" class="form-control" @bind="@_isnavigation">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="navigation" class="form-select" @bind="@_isnavigation">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="clickable" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
</td>
<td>
<select id="clickable" class="form-select" @bind="@_isclickable">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -89,7 +101,7 @@
<Section Name="Appearance" ResourceKey="Appearance">
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label 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>
</td>
<td>
@ -101,7 +113,7 @@
<Label For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
</td>
<td>
<select id="Theme" class="form-control" value="@_themetype" @onchange="(e => ThemeChanged(e))">
<select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))">
@foreach (var theme in _themes)
{
<option value="@theme.TypeName">@theme.Name</option>
@ -114,8 +126,8 @@
<Label For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
</td>
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option>
<select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -136,9 +148,9 @@
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
</td>
<td>
<select id="Personalizable" class="form-control" @bind="@_ispersonalizable">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="Personalizable" class="form-select" @bind="@_ispersonalizable">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -162,8 +174,8 @@
</TabPanel>
}
</TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">@Localizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -180,6 +192,7 @@
private List<Page> _children;
private int _childid = -1;
private string _isnavigation = "True";
private string _isclickable = "True";
private string _url;
private string _ispersonalizable = "False";
private string _themetype = string.Empty;
@ -209,7 +222,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Initializing Page {Error}", ex.Message);
AddModuleMessage(Localizer["Error Initializing Page"], MessageType.Error);
AddModuleMessage(Localizer["Error.Page.Initialize"], MessageType.Error);
}
}
@ -244,7 +257,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
AddModuleMessage(Localizer["Error Loading Child Pages For Parent"], MessageType.Error);
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
}
}
@ -261,7 +274,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
AddModuleMessage(Localizer["Error Loading Pane Layouts For Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error);
}
}
@ -327,7 +340,7 @@
if (!PagePathIsUnique(page.Path, page.SiteId, _pageList))
{
AddModuleMessage(Localizer["A page with path {0} already exists for the selected parent page. The page path needs to be unique for the selected parent.", _path], MessageType.Warning);
AddModuleMessage(string.Format(Localizer["Message.Page.Exists"], _path), MessageType.Warning);
return;
}
@ -351,6 +364,7 @@
}
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
page.Url = _url;
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
@ -382,14 +396,14 @@
}
else
{
AddModuleMessage(Localizer["You Must Provide Page Name, Theme, and Container"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
AddModuleMessage(Localizer["Error Saving Page"], MessageType.Error);
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
}
}

View File

@ -5,6 +5,7 @@
@inject IPageService PageService
@inject IThemeService ThemeService
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip Refresh="@_refresh">
<TabPanel Name="Settings" ResourceKey="Settings">
@ -12,7 +13,7 @@
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -24,8 +25,8 @@
<Label For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
</td>
<td>
<select id="Parent" class="form-control" value="@_parentid" @onchange="(e => ParentChanged(e))">
<option value="-1">&lt;@Localizer["Site Root"]&gt;</option>
<select id="Parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))">
<option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option>
@foreach (Page page in _pageList)
{
if (page.PageId != _pageId)
@ -41,23 +42,23 @@
<Label For="Move" HelpText="Select the location where you would like the page to be moved in relation to other pages" ResourceKey="Move">Move: </Label>
</td>
<td>
<select id="Move" class="form-control" @bind="@_insert">
<select id="Move" class="form-select" @bind="@_insert">
@if (_parentid == _currentparentid)
{
<option value="=">&lt;@Localizer["Maintain Current Location"]&gt;</option>
<option value="=">&lt;@Localizer["ThisLocation.Keep"]&gt;</option>
}
<option value="<<">@Localizer["To Beginning"]</option>
<option value="<<">@Localizer["ToBeginning"]</option>
@if (_children != null && _children.Count > 0)
{
<option value="<">@Localizer["Before"]</option>
<option value=">">@Localizer["After"]</option>
}
<option value=">>">@Localizer["To End"]</option>
<option value=">>">@Localizer["ToEnd"]</option>
</select>
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
{
<select class="form-control" @bind="@_childid">
<option value="-1">&lt;@Localizer["Select Page"]&gt;</option>
<select class="form-select" @bind="@_childid">
<option value="-1">&lt;@Localizer["Page.Select"]&gt;</option>
@foreach (Page page in _children)
{
<option value="@(page.PageId)">@(page.Name)</option>
@ -71,9 +72,20 @@
<Label For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
</td>
<td>
<select id="Navigation" class="form-control" @bind="@_isnavigation">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="Navigation" class="form-select" @bind="@_isnavigation">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="Clickablen" HelpText="Select whether the link in the site navigation is enabled or disabled" ResourceKey="Clickable">Clickable? </Label>
</td>
<td>
<select id="Navigation" class="form-select" @bind="@_isclickable">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -97,7 +109,7 @@
<Section Name="Appearance" ResourceKey="Appearance">
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label 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>
</td>
<td>
@ -109,7 +121,7 @@
<Label For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
</td>
<td>
<select id="Theme" class="form-control" value="@_themetype" @onchange="(e => ThemeChanged(e))">
<select id="Theme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))">
@foreach (var theme in _themes)
{
<option value="@theme.TypeName">@theme.Name</option>
@ -122,8 +134,8 @@
<Label For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
</td>
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option>
<select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -144,9 +156,9 @@
<Label For="Personalizable" HelpText="Select whether you would like users to be able to personalize this page with their own content" ResourceKey="Personalizable">Personalizable? </Label>
</td>
<td>
<select id="Personalizable" class="form-control" @bind="@_ispersonalizable">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="Personalizable" class="form-select" @bind="@_ispersonalizable">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -175,8 +187,8 @@
</TabPanel>
}
</TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">@Localizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
<button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -195,6 +207,7 @@
private List<Page> _children;
private int _childid = -1;
private string _isnavigation;
private string _isclickable;
private string _url;
private string _ispersonalizable;
private string _themetype;
@ -247,6 +260,7 @@
_currentparentid = _parentid;
_isnavigation = page.IsNavigation.ToString();
_isclickable = page.IsClickable.ToString();
_url = page.Url;
_ispersonalizable = page.IsPersonalizable.ToString();
_themetype = page.ThemeType;
@ -275,7 +289,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message);
AddModuleMessage(Localizer["Error Loading Page"], MessageType.Error);
AddModuleMessage(Localizer["Error.Page.Load"], MessageType.Error);
}
}
@ -318,7 +332,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
AddModuleMessage(Localizer["Error Loading Child Pages For Parent"], MessageType.Error);
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
}
}
@ -335,7 +349,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
AddModuleMessage(Localizer["Error Loading Pane Layouts For Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Pane.Load"], MessageType.Error);
}
}
@ -401,7 +415,7 @@
if (!PagePathIsUnique(page.Path, page.SiteId, page.PageId, _pageList))
{
AddModuleMessage(Localizer["A page with path {0} already exists for the selected parent page. The page path needs to be unique for the selected parent.", _path], MessageType.Warning);
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
return;
}
@ -427,6 +441,7 @@
}
}
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
page.Url = _url;
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
@ -481,13 +496,13 @@
}
else
{
AddModuleMessage(Localizer["You Must Provide Page Name, Theme, and Container"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
AddModuleMessage(Localizer["Error Saving Page"], MessageType.Error);
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
}
}

View File

@ -2,7 +2,8 @@
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IPageService PageService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.Pages != null)
{
@ -12,11 +13,11 @@
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@SharedLocalizer["Name"]</th>
</Header>
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.PageId.ToString())" ResourceKey="EditPage" /></td>
<td><ActionDialog Header="Delete Page" Message="@Localizer["Are You Sure You Wish To Delete The {0} Page?", 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>@(new string('-', context.Level * 2))@(context.Name)</td>
</Row>
</Pager>
@ -30,7 +31,7 @@
try
{
page.IsDeleted = true;
await PageService.UpdatePageAsync(page);
await logger.LogInformation("Page Deleted {Page}", page);
NavigationManager.NavigateTo(NavigateUrl("admin/pages"));
@ -38,7 +39,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Page {Page} {Error}", page, ex.Message);
AddModuleMessage(Localizer["Error Deleting Page"], MessageType.Error);
AddModuleMessage(Localizer["Error.Page.Delete"], MessageType.Error);
}
}
}

View File

@ -3,10 +3,11 @@
@inject NavigationManager NavigationManager
@inject IProfileService ProfileService
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -74,9 +75,9 @@
<Label For="required" HelpText="Should a user be required to provide a value for this profile item?" ResourceKey="Required">Required? </Label>
</td>
<td>
<select id="required" class="form-control" @bind="@_isrequired">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="required" class="form-select" @bind="@_isrequired">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -85,15 +86,21 @@
<Label For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
</td>
<td>
<select id="private" class="form-control" @bind="@_isprivate">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="private" class="form-select" @bind="@_isprivate">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveProfile">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@if (PageState.QueryString.ContainsKey("id"))
{
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
}
@code {
private int _profileid = -1;
@ -107,6 +114,10 @@
private string _options = string.Empty;
private string _isrequired = "False";
private string _isprivate = "False";
private string createdby;
private DateTime createdon;
private string modifiedby;
private DateTime modifiedon;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -132,13 +143,17 @@
_options = profile.Options;
_isrequired = profile.IsRequired.ToString();
_isprivate = profile.IsPrivate.ToString();
createdby = profile.CreatedBy;
createdon = profile.CreatedOn;
modifiedby = profile.ModifiedBy;
modifiedon = profile.ModifiedOn;
}
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Profile {ProfileId} {Error}", _profileid, ex.Message);
AddModuleMessage(Localizer["Error Loading Profile"], MessageType.Error);
AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error);
}
}
@ -182,7 +197,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Profile {ProfleId} {Error}", _profileid, ex.Message);
AddModuleMessage(Localizer["Error Saving Profile"], MessageType.Error);
AddModuleMessage(Localizer["Error.Profile.Save"], MessageType.Error);
}
}
}

View File

@ -2,10 +2,11 @@
@inherits ModuleBase
@inject IProfileService ProfileService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_profiles == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
@ -15,11 +16,11 @@ else
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@SharedLocalizer["Name"]</th>
</Header>
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ProfileId.ToString())" ResourceKey="EditProfile" /></td>
<td><ActionDialog Header="Delete Profile" Message="@Localizer["Are You Sure You Wish To Delete {0}?", context.Name]" Action="Delete" 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" Class="btn btn-danger" OnClick="@(async () => await DeleteProfile(context.ProfileId))" ResourceKey="DeleteProfile" /></td>
<td>@context.Name</td>
</Row>
</Pager>
@ -42,7 +43,7 @@ else
await ProfileService.DeleteProfileAsync(profileId);
await logger.LogInformation("Profile Deleted {ProfileId}", profileId);
AddModuleMessage(Localizer["Profile Deleted"], MessageType.Success);
AddModuleMessage(Localizer["Success.Profile.Delete"], MessageType.Success);
await GetProfilesAsync();
@ -51,7 +52,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Profile {ProfileId} {Error}", profileId, ex.Message);
AddModuleMessage(Localizer["Error Deleting Profile"], MessageType.Error);
AddModuleMessage(Localizer["Error.Profile.Delete"], MessageType.Error);
}
}

View File

@ -5,13 +5,14 @@
@inject IModuleService ModuleService
@inject IPageService PageService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Pages" ResourceKey="Pages">
@if (_pages == null)
{
<br />
<p>@Localizer["No Deleted Pages"]</p>
<p>@Localizer["NoPage.Deleted"]</p>
}
else
{
@ -19,13 +20,13 @@
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@Localizer["Deleted By"]</th>
<th>@Localizer["Deleted On"]</th>
<th>@SharedLocalizer["Name"]</th>
<th>@Localizer["DeletedBy"]</th>
<th>@Localizer["DeletedOn"]</th>
</Header>
<Row>
<td><button @onclick="@(() => RestorePage(context))" class="btn btn-info" title="Restore">Restore</button></td>
<td><ActionDialog Header="Delete Page" Message="@Localizer["Are You Sure You Wish To Permanently Delete The {0} Page?", 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.DeletedBy</td>
<td>@context.DeletedOn</td>
@ -43,7 +44,7 @@
@if (_modules == null)
{
<br />
<p>@Localizer["No Deleted Modules"]</p>
<p>@Localizer["NoModule.Deleted"]</p>
}
else
{
@ -53,12 +54,12 @@
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Page"]</th>
<th>@Localizer["Module"]</th>
<th>@Localizer["Deleted By"]</th>
<th>@Localizer["Deleted On"]</th>
<th>@Localizer["DeletedBy"]</th>
<th>@Localizer["DeletedOn"]</th>
</Header>
<Row>
<td><button @onclick="@(() => RestoreModule(context))" class="btn btn-info" title="Restore">@Localizer["Restore"]</button></td>
<td><ActionDialog Header="Delete Module" Message="@Localizer["Are You Sure You Wish To Permanently Delete The {0} Module?", context.Title]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
<td><ActionDialog Header="Delete Module" Message="@string.Format(Localizer["Confirm.Module.Delete"], context.Title)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
<td>@PageState.Pages.Find(item => item.PageId == context.PageId).Name</td>
<td>@context.Title</td>
<td>@context.DeletedBy</td>
@ -91,7 +92,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Deleted Pages Or Modules {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Deleted Pages Or Modules"], MessageType.Error);
AddModuleMessage(Localizer["Error.DeletedModulePage.Load"], MessageType.Error);
}
}
@ -118,7 +119,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Restoring Deleted Page {Page} {Error}", page, ex.Message);
AddModuleMessage(Localizer["Error Restoring Deleted Page"], MessageType.Error);
AddModuleMessage(Localizer["Error.Page.Restore"], MessageType.Error);
}
}
@ -175,7 +176,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Restoring Deleted Module {Module} {Error}", module, ex.Message);
AddModuleMessage(Localizer["Error Restoring Deleted Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Restore"], MessageType.Error);
}
}
@ -199,7 +200,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Permanently Deleting Module {Module} {Error}", module, ex.Message);
AddModuleMessage(Localizer["Error Permanently Deleting Module"], MessageType.Error);
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
}
}
@ -226,7 +227,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Permanently Deleting Modules {Error}", ex.Message);
AddModuleMessage(Localizer["Error Permanently Deleting Modules"], MessageType.Error);
AddModuleMessage(Localizer["Error.Modules.Delete"], MessageType.Error);
}
}
}

View File

@ -3,6 +3,7 @@
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.Site.AllowRegistration)
{
@ -11,41 +12,62 @@
<text>...</text>
</Authorizing>
<Authorized>
<ModuleMessage Message="@Localizer["You Are Already Registered"]" Type="MessageType.Info" />
<ModuleMessage Message="@Localizer["Info.Registration.Exists"]" Type="MessageType.Info" />
</Authorized>
<NotAuthorized>
<ModuleMessage Message="@Localizer["Please Note That Registration Requires A Valid Email Address In Order To Verify Your Identity"]" Type="MessageType.Info" />
<ModuleMessage Message="@Localizer["Info.Registration.InvalidEmail"]" Type="MessageType.Info" />
<div class="container">
<div class="form-group">
<label for="Username" class="control-label">@Localizer["Username:"] </label>
<input type="text" class="form-control" placeholder="Username" @bind="@_username" id="Username" />
</div>
<div class="form-group">
<label for="Password" class="control-label">@Localizer["Password:"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password" />
</div>
<div class="form-group">
<label for="Confirm" class="control-label">@Localizer["Confirm Password:"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm" />
</div>
<div class="form-group">
<label for="Email" class="control-label">@Localizer["Email:"] </label>
<input type="text" class="form-control" placeholder="Email" @bind="@_email" id="Email" />
</div>
<div class="form-group">
<label for="DisplayName" class="control-label">@Localizer["Full Name:"] </label>
<input type="text" class="form-control" placeholder="Full Name" @bind="@_displayName" id="DisplayName" />
</div>
<button type="button" class="btn btn-primary" @onclick="Register">@Localizer["Register"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
</div>
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="username" HelpText="Your username. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
</td>
<td>
<input id="username" class="form-control" @bind="@_username" readonly />
</td>
</tr>
<tr>
<td>
<Label For="password" HelpText="If you wish to change your password you can enter it here. Please choose a sufficiently secure password." ResourceKey="Password"></Label>
</td>
<td>
<input id="password" type="password" class="form-control" @bind="@_password" autocomplete="new-password" />
</td>
</tr>
<tr>
<td>
<Label For="confirm" HelpText="If you are changing your password you must enter it again to confirm it matches" ResourceKey="Confirm"></Label>
</td>
<td>
<input id="confirm" type="password" class="form-control" @bind="@_confirm" autocomplete="new-password" />
</td>
</tr>
<tr>
<td>
<Label For="email" HelpText="Your email address where you wish to receive notifications" ResourceKey="Email"></Label>
</td>
<td>
<input id="email" class="form-control" @bind="@_email" />
</td>
</tr>
<tr>
<td>
<Label For="displayname" HelpText="Your full name" ResourceKey="DisplayName"></Label>
</td>
<td>
<input id="displayname" class="form-control" @bind="@_displayname" />
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="Register">@Localizer["Register"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
</NotAuthorized>
</AuthorizeView>
}
else
{
<ModuleMessage Message="@Localizer["Registration is Disabled For This Site"]" Type="MessageType.Info" />
<ModuleMessage Message="@Localizer["Info.Registration.Disabled"]" Type="MessageType.Info" />
}
@code {
@ -53,7 +75,7 @@ else
private string _password = string.Empty;
private string _confirm = string.Empty;
private string _email = string.Empty;
private string _displayName = string.Empty;
private string _displayname = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
@ -71,7 +93,7 @@ else
{
SiteId = PageState.Site.SiteId,
Username = _username,
DisplayName = (_displayName == string.Empty ? _username : _displayName),
DisplayName = (_displayname == string.Empty ? _username : _displayname),
Email = _email,
Password = _password
};
@ -80,28 +102,28 @@ else
if (user != null)
{
await logger.LogInformation("User Created {Username} {Email}", _username, _email);
AddModuleMessage(Localizer["User Account Created. Please Check Your Email For Verification Instructions."], MessageType.Info);
AddModuleMessage(Localizer["Info.User.AccountCreate"], MessageType.Info);
}
else
{
await logger.LogError("Error Adding User {Username} {Email}", _username, _email);
AddModuleMessage(Localizer["Error Adding User. Please Ensure Password Meets Complexity Requirements And Username Is Not Already In Use."], MessageType.Error);
AddModuleMessage(Localizer["Error.User.AddInfo"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Username, Password, and Email Address"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", _username, _email, ex.Message);
AddModuleMessage(Localizer["Error Adding User"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
}
}

View File

@ -3,22 +3,23 @@
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="container">
<div class="form-group">
<label for="Username" class="control-label">@Localizer["Username:"] </label>
<input type="text" class="form-control" placeholder="Username" @bind="@_username" readonly id="Username"/>
<label for="Username" class="control-label">@SharedLocalizer["Username"] </label>
<input type="text" class="form-control" placeholder="Username" @bind="@_username" readonly id="Username" />
</div>
<div class="form-group">
<label for="Password" class="control-label">@Localizer["Password:"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password"/>
<label for="Password" class="control-label">@SharedLocalizer["Password"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password" />
</div>
<div class="form-group">
<label for="Confirm" class="control-label">@Localizer["Confirm Password:"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm"/>
<label for="Confirm" class="control-label">@Localizer["Password.Confirm"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm" />
</div>
<button type="button" class="btn btn-primary" @onclick="Reset">@Localizer["Reset Password"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
<button type="button" class="btn btn-primary" @onclick="Reset">@Localizer["Password.Reset"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
</div>
@code {
@ -35,7 +36,7 @@
_username = PageState.QueryString["name"];
}
else
{
{
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
}
}
@ -64,23 +65,23 @@
else
{
await logger.LogError("Error Resetting User Password {Username}", _username);
AddModuleMessage(Localizer["Error Resetting User Password. Please Ensure Password Meets Complexity Requirements."], MessageType.Error);
AddModuleMessage(Localizer["Error.Password.ResetInfo"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Username, Password, and Email Address"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Resetting User Password {Username} {Error}", _username, ex.Message);
AddModuleMessage(Localizer["Error Resetting User Password"], MessageType.Error);
AddModuleMessage(Localizer["Error.Password.Reset"], MessageType.Error);
}
}

View File

@ -3,40 +3,46 @@
@inject NavigationManager NavigationManager
@inject IRoleService RoleService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<Label For="name" HelpText="Name Of The Role" ResourceKey="Name">Name:</Label>
</td>
<td>
<input id="name" class="form-control" @bind="@_name" />
</td>
</tr>
<tr>
<td>
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose" ResourceKey="Description">Description:</Label>
</td>
<td>
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
</td>
</tr>
<tr>
<td>
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role" ResourceKey="AutoAssigned">Auto Assigned?</Label>
</td>
<td>
<select id="isautoassigned" class="form-control" @bind="@_isautoassigned">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveRole">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="name" HelpText="Name Of The Role" ResourceKey="Name">Name:</Label>
</td>
<td>
<input id="name" class="form-control" @bind="@_name" maxlength="256" required />
</td>
</tr>
<tr>
<td>
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose" ResourceKey="Description">Description:</Label>
</td>
<td>
<textarea id="description" class="form-control" @bind="@_description" rows="5" maxlength="256" required></textarea>
</td>
</tr>
<tr>
<td>
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role" ResourceKey="AutoAssigned">Auto Assigned?</Label>
</td>
<td>
<select id="isautoassigned" class="form-select" @bind="@_isautoassigned">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</form>
@code {
private ElementReference form;
private bool validated = false;
private string _name = string.Empty;
private string _description = string.Empty;
private string _isautoassigned = "False";
@ -45,24 +51,33 @@
private async Task SaveRole()
{
var role = new Role();
role.SiteId = PageState.Page.SiteId;
role.Name = _name;
role.Description = _description;
role.IsAutoAssigned = (_isautoassigned == null ? false : Boolean.Parse(_isautoassigned));
role.IsSystem = false;
try
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{
role = await RoleService.AddRoleAsync(role);
await logger.LogInformation("Role Added {Role}", role);
var role = new Role();
role.SiteId = PageState.Page.SiteId;
role.Name = _name;
role.Description = _description;
role.IsAutoAssigned = (_isautoassigned == null ? false : Boolean.Parse(_isautoassigned));
role.IsSystem = false;
NavigationManager.NavigateTo(NavigateUrl());
try
{
role = await RoleService.AddRoleAsync(role);
await logger.LogInformation("Role Added {Role}", role);
NavigationManager.NavigateTo(NavigateUrl());
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error.AddRole"], MessageType.Error);
}
}
catch (Exception ex)
else
{
await logger.LogError(ex, "Error Adding Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error Adding Role"], MessageType.Error);
AddModuleMessage(Localizer["Message.InfoRequired"], MessageType.Warning);
}
}

View File

@ -3,44 +3,56 @@
@inject NavigationManager NavigationManager
@inject IRoleService RoleService
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<Label For="name" HelpText="Name Of The Role" ResourceKey="Name">Name:</Label>
</td>
<td>
<input id="name" class="form-control" @bind="@_name" />
</td>
</tr>
<tr>
<td>
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose" ResourceKey="Description">Description:</Label>
</td>
<td>
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea>
</td>
</tr>
<tr>
<td>
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role" ResourceKey="AutoAssigned">Auto Assigned?</Label>
</td>
<td>
<select id="isautoassigned" class="form-control" @bind="@_isautoassigned">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveRole">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="name" HelpText="Name Of The Role" ResourceKey="Name">Name:</Label>
</td>
<td>
<input id="name" class="form-control" @bind="@_name" maxlength="256" required />
</td>
</tr>
<tr>
<td>
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose" ResourceKey="Description">Description:</Label>
</td>
<td>
<textarea id="description" class="form-control" @bind="@_description" rows="5" maxlength="256" required></textarea>
</td>
</tr>
<tr>
<td>
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role" ResourceKey="AutoAssigned">Auto Assigned?</Label>
</td>
<td>
<select id="isautoassigned" class="form-select" @bind="@_isautoassigned">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /><br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
</form>
@code {
private ElementReference form;
private bool validated = false;
private int _roleid;
private string _name = string.Empty;
private string _description = string.Empty;
private string _isautoassigned = "False";
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
private DateTime _modifiedon;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -55,33 +67,46 @@
_name = role.Name;
_description = role.Description;
_isautoassigned = role.IsAutoAssigned.ToString();
_createdby = role.CreatedBy;
_createdon = role.CreatedOn;
_modifiedby = role.ModifiedBy;
_modifiedon = role.ModifiedOn;
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Role {RoleId} {Error}", _roleid, ex.Message);
AddModuleMessage(Localizer["Error Loading Role"], MessageType.Error);
AddModuleMessage(Localizer["Error.LoadRole"], MessageType.Error);
}
}
private async Task SaveRole()
{
var role = await RoleService.GetRoleAsync(_roleid);
role.Name = _name;
role.Description = _description;
role.IsAutoAssigned = (_isautoassigned != null && Boolean.Parse(_isautoassigned));
role.IsSystem = false;
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{
var role = await RoleService.GetRoleAsync(_roleid);
role.Name = _name;
role.Description = _description;
role.IsAutoAssigned = (_isautoassigned != null && Boolean.Parse(_isautoassigned));
role.IsSystem = false;
try
{
role = await RoleService.UpdateRoleAsync(role);
await logger.LogInformation("Role Saved {Role}", role);
NavigationManager.NavigateTo(NavigateUrl());
try
{
role = await RoleService.UpdateRoleAsync(role);
await logger.LogInformation("Role Saved {Role}", role);
NavigationManager.NavigateTo(NavigateUrl());
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error.SaveRole"], MessageType.Error);
}
}
catch (Exception ex)
else
{
await logger.LogError(ex, "Error Saving Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error Saving Role"], MessageType.Error);
AddModuleMessage(Localizer["Message.InfoRequired"], MessageType.Warning);
}
}
}

View File

@ -2,10 +2,11 @@
@inherits ModuleBase
@inject IRoleService RoleService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_roles == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
@ -16,11 +17,11 @@ else
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@SharedLocalizer["Name"]</th>
</Header>
<Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.RoleId.ToString())" Disabled="@(context.IsSystem)" ResourceKey="Edit" /></td>
<td><ActionDialog Header="Delete Role" Message="@Localizer["Are You Sure You Wish To Delete The {0} Role?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteRole(context))" Disabled="@(context.IsSystem)" ResourceKey="DeleteRole" /></td>
<td><ActionDialog Header="Delete Role" Message="@string.Format(Localizer["Confirm.DeleteUser"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteRole(context))" Disabled="@(context.IsSystem)" ResourceKey="DeleteRole" /></td>
<td><ActionLink Action="Users" Parameters="@($"id=" + context.RoleId.ToString())" ResourceKey="Users" /></td>
<td>@context.Name</td>
</Row>
@ -33,6 +34,27 @@ else
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnParametersSetAsync()
{
await GetRoles();
}
private async Task DeleteRole(Role role)
{
try
{
await RoleService.DeleteRoleAsync(role.RoleId);
await logger.LogInformation("Role Deleted {Role}", role);
await GetRoles();
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error.DeleteRole"], MessageType.Error);
}
}
private async Task GetRoles()
{
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
@ -44,19 +66,4 @@ else
_roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
}
}
private async Task DeleteRole(Role role)
{
try
{
await RoleService.DeleteRoleAsync(role.RoleId);
await logger.LogInformation("Role Deleted {Role}", role);
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error Deleting Role"], MessageType.Error);
}
}
}

View File

@ -3,16 +3,17 @@
@inject IRoleService RoleService
@inject IUserRoleService UserRoleService
@inject IStringLocalizer<Users> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (userroles == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="role" HelpText="The role you are assigning users to" ResourceKey="Role">Role: </Label>
</td>
<td>
@ -24,8 +25,8 @@ else
<Label For="user" HelpText="Select a user" ResourceKey="User">User: </Label>
</td>
<td>
<select id="user" class="form-control" @bind="@userid">
<option value="-1">&lt;@Localizer["Select User"]&gt;</option>
<select id="user" class="form-select" @bind="@userid">
<option value="-1">&lt;@Localizer["User.Select"]&gt;</option>
@foreach (UserRole userrole in users)
{
<option value="@(userrole.UserId)">@userrole.User.DisplayName</option>
@ -50,8 +51,8 @@ else
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveUserRole">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveUserRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<hr class="app-rule" />
<p align="center">
@ -67,7 +68,7 @@ else
<td>@context.EffectiveDate</td>
<td>@context.ExpiryDate</td>
<td>
<ActionDialog Header="Remove User" Message="@Localizer["Are You Sure You Wish To Remove {0} From This Role?", context.User.DisplayName]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUserRole(context.UserRoleId))" Disabled="@(context.Role.IsAutoAssigned)" ResourceKey="DeleteUserRole" />
<ActionDialog Header="Remove User" Message="@string.Format(Localizer["Confirm.User.DeleteRole"], context.User.DisplayName)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUserRole(context.UserRoleId))" Disabled="@(context.Role.IsAutoAssigned || PageState.User.Username == UserNames.Host)" ResourceKey="DeleteUserRole" />
</td>
</Row>
</Pager>
@ -102,7 +103,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Users"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error);
}
}
@ -116,7 +117,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading User Roles {RoleId} {Error}", roleid, ex.Message);
AddModuleMessage(Localizer["Error Loading User Roles"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.LoadRole"], MessageType.Error);
}
}
@ -145,19 +146,19 @@ else
}
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success);
AddModuleMessage(Localizer["Success.User.AssignedRole"], MessageType.Success);
await GetUserRoles();
StateHasChanged();
}
else
{
AddModuleMessage(Localizer["You Must Select A User"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.UserSelect"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving User Roles {RoleId} {Error}", roleid, ex.Message);
AddModuleMessage(Localizer["Error Saving User Roles"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.SaveRole"], MessageType.Error);
}
}
@ -167,14 +168,14 @@ else
{
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success);
AddModuleMessage(Localizer["Confirm.User.RoleRemoved"], MessageType.Success);
await GetUserRoles();
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message);
AddModuleMessage(Localizer["Error Removing User From Role"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.RemoveRole"], MessageType.Error);
}
}
}

View File

@ -3,17 +3,19 @@
@inject NavigationManager NavigationManager
@inject ISiteService SiteService
@inject ITenantService TenantService
@inject IDatabaseService DatabaseService
@inject IAliasService AliasService
@inject IThemeService ThemeService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@inject INotificationService NotificationService
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_initialized)
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="name" HelpText="Enter the site name" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -22,28 +24,28 @@
</tr>
<tr>
<td>
<Label For="tenant" HelpText="Enter the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
<Label For="alias" HelpText="The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they should be separated by commas." ResourceKey="Aliases">Aliases: </Label>
</td>
<td>
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
</td>
</tr>
<tr>
<td>
<Label For="alias" HelpText="Enter the aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they can be separated by commas." ResourceKey="Aliases">Aliases: </Label>
</td>
<td>
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
}
else
{
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" readonly></textarea>
}
</td>
</tr>
<tr>
<td>
<Label For="allowRegister" HelpText="Do you want the users to be able to register for an account on the site" ResourceKey="AllowRegistration">Allow User Registration? </Label>
</td>
<td>
<select id="allowRegister" class="form-control" @bind="@_allowregistration">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="allowRegister" class="form-select" @bind="@_allowregistration">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -52,9 +54,9 @@
<Label For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label>
</td>
<td>
<select id="isDeleted" class="form-control" @bind="@_isdeleted">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="isDeleted" class="form-select" @bind="@_isdeleted">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -62,7 +64,7 @@
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
</td>
<td>
@ -82,8 +84,8 @@
<Label For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
</td>
<td>
<select id="defaultTheme" class="form-control" value="@_themetype" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;@Localizer["Select Theme"]&gt;</option>
<select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;@Localizer["Theme.Select"]&gt;</option>
@foreach (var theme in _themes)
{
<option value="@theme.TypeName">@theme.Name</option>
@ -96,8 +98,8 @@
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
</td>
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option>
<select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -110,9 +112,9 @@
<Label For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
</td>
<td>
<select id="defaultAdminContainer" class="form-control" @bind="@_admincontainertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option>
<option value="@Constants.DefaultAdminContainer">&lt;@Localizer["Default Admin Container"]&gt;</option>
<select id="defaultAdminContainer" class="form-select" @bind="@_admincontainertype">
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
<option value="@Constants.DefaultAdminContainer">&lt;@Localizer["DefaultAdminContainer"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -125,8 +127,9 @@
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
<table class="table table-borderless">
<tr>
<td colspan="2">
<strong>@Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In Scheduled Jobs"]</strong>
<td width="30%">&nbsp;</td>
<td>
<strong>@Localizer["Smtp.Required.EnableNotificationJob"]</strong><br />
</td>
</tr>
<tr>
@ -150,9 +153,9 @@
<Label For="enabledSSl" HelpText="Specify if SSL is required for your SMTP server" ResourceKey="UseSsl">SSL Enabled: </Label>
</td>
<td>
<select id="enabledSSl" class="form-control" @bind="@_smtpssl">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="enabledSSl" class="form-select" @bind="@_smtpssl">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -181,19 +184,19 @@
</td>
</tr>
</table>
<button type="button" class="btn btn-secondary" @onclick="SendEmail">@Localizer["Test SMTP Configuration"]</button>
<button type="button" class="btn btn-secondary" @onclick="SendEmail">@Localizer["Smtp.TestConfig"]</button>
<br /><br />
</Section>
<Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings">
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="isEnabled" HelpText="Select whether you would like this site to be available as a Progressive Web Application (PWA)" ResourceKey="EnablePWA">Is Enabled? </Label>
</td>
<td>
<select id="isEnabled" class="form-control" @bind="@_pwaisenabled">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="isEnabled" class="form-select" @bind="@_pwaisenabled">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -215,10 +218,40 @@
</tr>
</table>
</Section>
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
<Section Name="TenantInformation" Heading="Tenant Information" ResourceKey="TenantInformation">
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="tenant" HelpText="The tenant for the site" ResourceKey="Tenant">Tenant: </Label>
</td>
<td>
<input id="tenant" class="form-control" @bind="@_tenant" readonly />
</td>
</tr>
<tr>
<td>
<Label For="database" HelpText="The database for the tenant" ResourceKey="Database">Database: </Label>
</td>
<td>
<input id="database" class="form-control" @bind="@_database" readonly />
</td>
</tr>
<tr>
<td>
<Label For="connectionstring" HelpText="The connection information for the database" ResourceKey="ConnectionString">Connection: </Label>
</td>
<td>
<textarea id="connectionstring" class="form-control" @bind="@_connectionstring" rows="2" readonly></textarea>
</td>
</tr>
</table>
</Section>
}
<br />
<button type="button" class="btn btn-success" @onclick="SaveSite">@Localizer["Save"]</button>
<ActionDialog Header="Delete Site" Message="@Localizer["Are You Sure You Wish To Delete This Site?"]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteSite())" ResourceKey="DeleteSite" />
<button type="button" class="btn btn-success" @onclick="SaveSite">@SharedLocalizer["Save"]</button>
<ActionDialog Header="Delete Site" Message="@Localizer["Confirm.DeleteSite"]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteSite())" ResourceKey="DeleteSite" />
<br />
<br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
@ -230,8 +263,6 @@
private List<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>();
private string _name = string.Empty;
private List<Tenant> _tenantList;
private string _tenant = string.Empty;
private List<Alias> _aliasList;
private string _urls = string.Empty;
private int _logofileid = -1;
@ -253,6 +284,9 @@
private FileManager _pwaappiconfilemanager;
private int _pwasplashiconfileid = -1;
private FileManager _pwasplashiconfilemanager;
private string _tenant = string.Empty;
private string _database = string.Empty;
private string _connectionstring = string.Empty;
private string _createdby;
private DateTime _createdon;
private string _modifiedby;
@ -268,18 +302,24 @@
try
{
_themeList = await ThemeService.GetThemesAsync();
_aliasList = await AliasService.GetAliasesAsync();
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null)
{
_name = site.Name;
_tenantList = await TenantService.GetTenantsAsync();
_tenant = _tenantList.Find(item => item.TenantId == site.TenantId).Name;
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
_allowregistration = site.AllowRegistration.ToString();
_isdeleted = site.IsDeleted.ToString();
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
_urls += alias.Name + ",";
_aliasList = await AliasService.GetAliasesAsync();
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{
_urls += alias.Name + ",";
}
_urls = _urls.Substring(0, _urls.Length - 1);
}
_urls = _urls.Substring(0, _urls.Length - 1);
if (site.LogoFileId != null)
{
_logofileid = site.LogoFileId.Value;
@ -295,7 +335,6 @@
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
_allowregistration = site.AllowRegistration.ToString();
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
@ -327,13 +366,25 @@
_pwasplashiconfileid = site.PwaSplashIconFileId.Value;
}
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
var tenants = await TenantService.GetTenantsAsync();
var _databases = await DatabaseService.GetDatabasesAsync();
var tenant = tenants.Find(item => item.TenantId == site.TenantId);
if (tenant != null)
{
_tenant = tenant.Name;
_database = _databases.Find(item => item.DBType == tenant.DBType)?.Name;
_connectionstring = tenant.DBConnectionString;
}
}
_createdby = site.CreatedBy;
_createdon = site.CreatedOn;
_modifiedby = site.ModifiedBy;
_modifiedon = site.ModifiedOn;
_deletedby = site.DeletedBy;
_deletedon = site.DeletedOn;
_isdeleted = site.IsDeleted.ToString();
_initialized = true;
}
@ -365,7 +416,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message);
AddModuleMessage(Localizer["Error Loading Pane Layouts For Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.LoadPane"], MessageType.Error);
}
}
@ -376,11 +427,14 @@
if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-")
{
var unique = true;
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
unique = false;
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
{
unique = false;
}
}
}
@ -392,34 +446,30 @@
bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype);
site.Name = _name;
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
site.LogoFileId = null;
var logofileid = _logofilemanager.GetFileId();
if (logofileid != -1)
{
site.LogoFileId = logofileid;
}
var faviconFieldId = _faviconfilemanager.GetFileId();
if (faviconFieldId != -1)
{
site.FaviconFileId = faviconFieldId;
}
site.DefaultThemeType = _themetype;
site.DefaultContainerType = _containertype;
site.AdminContainerType = _admincontainertype;
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
site.PwaIsEnabled = (_pwaisenabled == null ? true : Boolean.Parse(_pwaisenabled));
var pwaappiconfileid = _pwaappiconfilemanager.GetFileId();
if (pwaappiconfileid != -1)
{
site.PwaAppIconFileId = pwaappiconfileid;
}
var pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId();
if (pwasplashiconfileid != -1)
{
@ -428,27 +478,6 @@
site = await SiteService.UpdateSiteAsync(site);
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{
if (!names.Contains(alias.Name))
{
await AliasService.DeleteAliasAsync(alias.AliasId);
}
}
foreach (string name in names)
{
if (!_aliasList.Exists(item => item.Name == name))
{
Alias alias = new Alias();
alias.Name = name;
alias.TenantId = site.TenantId;
alias.SiteId = site.SiteId;
await AliasService.AddAliasAsync(alias);
}
}
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
@ -458,31 +487,56 @@
SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{
if (!names.Contains(alias.Name))
{
await AliasService.DeleteAliasAsync(alias.AliasId);
}
}
foreach (string name in names)
{
if (!_aliasList.Exists(item => item.Name == name))
{
Alias alias = new Alias();
alias.Name = name;
alias.TenantId = site.TenantId;
alias.SiteId = site.SiteId;
await AliasService.AddAliasAsync(alias);
}
}
}
await logger.LogInformation("Site Settings Saved {Site}", site);
if (refresh)
{
NavigationManager.NavigateTo(NavigateUrl()); // refresh to show new theme or container
}
else
{
AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success);
AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
}
}
}
else
{
AddModuleMessage(Localizer["An Alias Specified Has Already Been Used For Another Site"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Site Name, Alias, And Default Theme/Container"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.SiteName"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message);
AddModuleMessage(Localizer["Error Saving Site"], MessageType.Error);
AddModuleMessage(Localizer["Error.SaveSite"], MessageType.Error);
}
}
@ -497,7 +551,7 @@
await logger.LogInformation("Site Deleted {SiteId}", PageState.Site.SiteId);
var aliases = await AliasService.GetAliasesAsync();
foreach (Alias a in aliases.Where(item => item.SiteId == PageState.Site.SiteId))
foreach (Alias a in aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId))
{
await AliasService.DeleteAliasAsync(a.AliasId);
}
@ -506,13 +560,13 @@
}
else
{
AddModuleMessage(Localizer["You Are Not Authorized To Delete The Site"], MessageType.Warning);
AddModuleMessage(Localizer["Message.FailAuth.DeleteSite"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message);
AddModuleMessage(Localizer["Error Deleting Site"], MessageType.Error);
AddModuleMessage(Localizer["Error.DeleteSite"], MessageType.Error);
}
}
@ -533,18 +587,17 @@
await logger.LogInformation("Site SMTP Settings Saved");
await NotificationService.AddNotificationAsync(new Notification(PageState.Site.SiteId, PageState.User.DisplayName, PageState.User.Email, PageState.User.DisplayName, PageState.User.Email, PageState.Site.Name + " SMTP Configuration Test", "SMTP Server Is Configured Correctly."));
AddModuleMessage(Localizer["SMTP Settings Saved And A Message Has Been Sent To The Email Address Associated To Your User Account... Please Wait A Few Minutes For Delivery. If You Do Not Receive The Email Please Review The Notification Job In Scheduled Jobs For Any Log Details."], MessageType.Info);
AddModuleMessage(Localizer["Info.Smtp.SaveSettings"], MessageType.Info);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Testing SMTP Configuration");
AddModuleMessage(Localizer["Error Testing SMTP Configuration"], MessageType.Error);
AddModuleMessage(Localizer["Error.Smtp.TestConfig"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["You Must Specify The SMTP Host, Port, And Sender"], MessageType.Warning);
AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning);
}
}
}

View File

@ -11,16 +11,17 @@
@inject IInstallationService InstallationService
@inject IDatabaseService DatabaseService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_tenants == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="name" HelpText="Enter the name of the site" ResourceKey="Name">Site Name: </Label>
</td>
<td>
@ -40,8 +41,8 @@ else
<Label For="defaultTheme" HelpText="Select the default theme for the website" ResourceKey="DefaultTheme">Default Theme: </Label>
</td>
<td>
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;@Localizer["Select Theme"]&gt;</option>
<select id="defaultTheme" class="form-select" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;@Localizer["Theme.Select"]&gt;</option>
@foreach (var theme in _themes)
{
<option value="@theme.TypeName">@theme.Name</option>
@ -54,8 +55,8 @@ else
<Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
</td>
<td>
<select id="defaultContainer" class="form-control" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option>
<select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -68,9 +69,9 @@ else
<Label For="adminContainer" HelpText="Select the admin container for the site" ResourceKey="AdminContainer">Admin Container: </Label>
</td>
<td>
<select id="adminContainer" class="form-control" @bind="@_admincontainertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option>
<option value="">&lt;@Localizer["Default Admin Container"]&gt;</option>
<select id="adminContainer" class="form-select" @bind="@_admincontainertype">
<option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
<option value="">&lt;@Localizer["DefaultContainer.Admin"]&gt;</option>
@foreach (var container in _containers)
{
<option value="@container.TypeName">@container.Name</option>
@ -83,8 +84,8 @@ else
<Label For="siteTemplate" HelpText="Select the site template" ResourceKey="SiteTemplate">Site Template: </Label>
</td>
<td>
<select id="siteTemplate" class="form-control" @bind="@_sitetemplatetype">
<option value="-">&lt;@Localizer["Select Site Template"]&gt;</option>
<select id="siteTemplate" class="form-select" @bind="@_sitetemplatetype">
<option value="-">&lt;@Localizer["SiteTemplate.Select"]&gt;</option>
@foreach (SiteTemplate siteTemplate in _siteTemplates)
{
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option>
@ -97,9 +98,9 @@ else
<Label For="tenant" HelpText="Select the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
</td>
<td>
<select id="tenant" class="form-control" @onchange="(e => TenantChanged(e))">
<option value="-">&lt;@Localizer["Select Tenant"]&gt;</option>
<option value="+">&lt;@Localizer["Create New Tenant"]&gt;</option>
<select id="tenant" class="form-select" @onchange="(e => TenantChanged(e))">
<option value="-">&lt;@Localizer["Tenant.Select"]&gt;</option>
<option value="+">&lt;@Localizer["Tenant.Add"]&gt;</option>
@foreach (Tenant tenant in _tenants)
{
<option value="@tenant.TenantId">@tenant.Name</option>
@ -127,10 +128,17 @@ else
<Label For="databaseType" HelpText="Select the database type for the tenant" ResourceKey="DatabaseType">Database Type: </Label>
</td>
<td>
<select id="databaseType" class="custom-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))">
<select id="databaseType" class="form-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))">
@foreach (var database in _databases)
{
<option value="@database.Name">@Localizer[@database.Name]</option>
if (database.IsDefault)
{
<option value="@database.Name" selected>@Localizer[@database.Name]</option>
}
else
{
<option value="@database.Name">@Localizer[@database.Name]</option>
}
}
</select>
</td>
@ -157,8 +165,8 @@ else
</tr>
}
</table>
<button type="button" class="btn btn-success" @onclick="SaveSite">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveSite">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
@ -211,7 +219,7 @@ else
}
catch
{
AddModuleMessage(Localizer["Error loading Database Configuration Control"], MessageType.Error);
AddModuleMessage(Localizer["Error.Database.LoadConfig"], MessageType.Error);
}
}
@ -260,7 +268,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Containers For Theme {ThemeType} {Error}", _themetype, ex.Message);
AddModuleMessage(Localizer["Error Loading Containers For Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.LoadContainers"], MessageType.Error);
}
}
@ -313,17 +321,17 @@ else
}
else
{
AddModuleMessage(Localizer["You Must Specify A Server And Database"], MessageType.Error);
AddModuleMessage(Localizer["Error.Required.ServerDatabase"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["Invalid Host Password"], MessageType.Error);
AddModuleMessage(Localizer["Error.InvalidPassword"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["Tenant Name Is Missing Or Already Exists"], MessageType.Error);
AddModuleMessage(Localizer["Error.TenantName.Exists"], MessageType.Error);
}
}
else
@ -365,12 +373,12 @@ else
}
else
{
AddModuleMessage(Localizer["{0} Already Used For Another Site", string.Join(", ", duplicates.ToArray())], MessageType.Warning);
AddModuleMessage(string.Format(Localizer["Message.SiteName.InUse"], string.Join(", ", duplicates.ToArray())), MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Tenant, Site Name, Alias, Default Theme/Container, And Site Template"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.Tenant"], MessageType.Warning);
}
}
}

View File

@ -4,6 +4,7 @@
@inject IAliasService AliasService
@inject ISiteService SiteService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_sites == null)
{
@ -16,11 +17,13 @@ else
<Pager Items="@_sites">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th style="width: 1px;">&nbsp;</th>
<th>@SharedLocalizer["Name"]</th>
</Header>
<Row>
<td><NavLink class="btn btn-primary" href="@(_scheme + context.Name +"/admin/site")">@Localizer["Edit"]</NavLink></td>
<td><a href="@(_scheme + context.Name +"?reload")">@context.Name</a></td>
<td><button type="button" class="btn btn-primary" @onclick="@(async () => Edit(context.Name))">@SharedLocalizer["Edit"]</button></td>
<td><button type="button" class="btn btn-secondary" @onclick="@(async () => Browse(context.Name))">@Localizer["Browse"]</button></td>
<td>@context.Name</td>
</Row>
</Pager>
}
@ -46,4 +49,14 @@ else
}
}
}
private void Edit(string name)
{
NavigationManager.NavigateTo(_scheme + name + "/admin/site/?reload");
}
private void Browse(string name)
{
NavigationManager.NavigateTo(_scheme + name + "/?reload");
}
}

View File

@ -2,23 +2,25 @@
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject ITenantService TenantService
@inject IDatabaseService DatabaseService
@inject ISqlService SqlService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_tenants == null)
{
<p><em>Loading...</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="tenant" HelpText="Select the tenant for the SQL server" ResourceKey="Tenant">Tenant: </Label>
</td>
<td>
<select id="teneant" class="form-control" @bind="_tenantid">
<option value="-1">&lt;@Localizer["Select Tenant"]&gt;</option>
<select id="tenant" class="form-select" value="@_tenantid" @onchange="(e => TenantChanged(e))">
<option value="-1">&lt;@Localizer["Tenant.Select"]&gt;</option>
@foreach (Tenant tenant in _tenants)
{
<option value="@tenant.TenantId">@tenant.Name</option>
@ -26,14 +28,33 @@ else
</select>
</td>
</tr>
<tr>
<td>
<Label For="sqlQeury" HelpText="Enter the query for the SQL server" ResourceKey="SqlQuery">SQL Query: </Label>
</td>
<td>
<textarea id="sqlQeury" class="form-control" @bind="@_sql" rows="5"></textarea>
</td>
</tr>
@if (_tenantid != "-1")
{
<tr>
<td>
<Label For="database" HelpText="The database for the tenant" ResourceKey="Database">Database: </Label>
</td>
<td>
<input id="database" class="form-control" @bind="@_database" readonly />
</td>
</tr>
<tr>
<td>
<Label For="connectionstring" HelpText="The connection information for the database" ResourceKey="ConnectionString">Connection: </Label>
</td>
<td>
<textarea id="connectionstring" class="form-control" @bind="@_connectionstring" rows="2" readonly></textarea>
</td>
</tr>
<tr>
<td>
<Label For="sqlQeury" HelpText="Enter the query for the SQL server" ResourceKey="SqlQuery">SQL Query: </Label>
</td>
<td>
<textarea id="sqlQeury" class="form-control" @bind="@_sql" rows="5"></textarea>
</td>
</tr>
}
</table>
<button type="button" class="btn btn-success" @onclick="Execute">@Localizer["Execute"]</button>
<br />
@ -47,6 +68,8 @@ else
@code {
private List<Tenant> _tenants;
private string _tenantid = "-1";
private string _database = string.Empty;
private string _connectionstring = string.Empty;
private string _sql = string.Empty;
private string _results = string.Empty;
@ -54,20 +77,59 @@ else
protected override async Task OnInitializedAsync()
{
_tenants = await TenantService.GetTenantsAsync();
try
{
_tenants = await TenantService.GetTenantsAsync();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Tenants {Error}", ex.Message);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
private async void TenantChanged(ChangeEventArgs e)
{
try
{
_tenantid = (string)e.Value;
var tenants = await TenantService.GetTenantsAsync();
var _databases = await DatabaseService.GetDatabasesAsync();
var tenant = tenants.Find(item => item.TenantId == int.Parse(_tenantid));
if (tenant != null)
{
_database = _databases.Find(item => item.DBType == tenant.DBType)?.Name;
_connectionstring = tenant.DBConnectionString;
}
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Tenant {TenantId} {Error}", _tenantid, ex.Message);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
private async Task Execute()
{
if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql))
try
{
var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql };
sqlquery = await SqlService.ExecuteQueryAsync(sqlquery);
_results = DisplayResults(sqlquery.Results);
if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql))
{
var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql };
sqlquery = await SqlService.ExecuteQueryAsync(sqlquery);
_results = DisplayResults(sqlquery.Results);
AddModuleMessage(Localizer["Success.QueryExecuted"], MessageType.Success);
}
else
{
AddModuleMessage(Localizer["Message.Required.Tenant"], MessageType.Warning);
}
}
else
catch (Exception ex)
{
AddModuleMessage(Localizer["You Must Select A Tenant And Provide A SQL Query"], MessageType.Warning);
await logger.LogError(ex, "Error Executing SQL Query {SQL} {Error}", _sql, ex.Message);
AddModuleMessage(ex.Message, MessageType.Error);
}
}
@ -105,7 +167,7 @@ else
}
else
{
table = Localizer["No Results Returned"];
table = Localizer["Return.NoResult"];
}
return table;

View File

@ -3,92 +3,206 @@
@inject ISystemService SystemService
@inject IInstallationService InstallationService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<Label For="version" HelpText="Framework Version" ResourceKey="FrameworkVersion">Framework Version: </Label>
</td>
<td>
<input id="version" class="form-control" @bind="@_version" readonly />
</td>
</tr>
<tr>
<td>
<Label For="runtime" HelpText="Blazor Runtime (Server or WebAssembly)" ResourceKey="BlazorRuntime">Blazor Runtime: </Label>
</td>
<td>
<input id="runtime" class="form-control" @bind="@_runtime" readonly />
</td>
</tr>
<tr>
<td>
<Label For="rendermode" HelpText="Blazor Render Mode" ResourceKey="RenderMode">Render Mode: </Label>
</td>
<td>
<input id="rendermode" class="form-control" @bind="@_rendermode" readonly />
</td>
</tr>
<tr>
<td>
<Label For="clrversion" HelpText="Common Language Runtime Version" ResourceKey="ClrVerion">CLR Version: </Label>
</td>
<td>
<input id="clrversion" class="form-control" @bind="@_clrversion" readonly />
</td>
</tr>
<tr>
<td>
<Label For="osversion" HelpText="Operating System Version" ResourceKey="OsVersion">OS Version: </Label>
</td>
<td>
<input id="osversion" class="form-control" @bind="@_osversion" readonly />
</td>
</tr>
<tr>
<td>
<Label For="serverpath" HelpText="Server Path" ResourceKey="ServerPath">Server Path: </Label>
</td>
<td>
<input id="serverpath" class="form-control" @bind="@_serverpath" readonly />
</td>
</tr>
<tr>
<td>
<Label For="servertime" HelpText="Server Time" ResourceKey="ServerTime">Server Time: </Label>
</td>
<td>
<input id="servertime" class="form-control" @bind="@_servertime" readonly />
</td>
</tr>
</table>
<a class="btn btn-primary" href="swagger/index.html" target="_new">@Localizer["Access Framework API"]</a>&nbsp;
<ActionDialog Header="Restart Application" Message="Are You Sure You Wish To Restart The Application?" Action="Restart Application" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await RestartApplication())" ResourceKey="RestartApplication" />
<TabStrip>
<TabPanel Name="Info" Heading="Info" ResourceKey="Info">
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="version" HelpText="Framework Version" ResourceKey="FrameworkVersion">Framework Version: </Label>
</td>
<td>
<input id="version" class="form-control" @bind="@_version" readonly />
</td>
</tr>
<tr>
<td>
<Label For="clrversion" HelpText="Common Language Runtime Version" ResourceKey="CLRVersion">CLR Version: </Label>
</td>
<td>
<input id="clrversion" class="form-control" @bind="@_clrversion" readonly />
</td>
</tr>
<tr>
<td>
<Label For="osversion" HelpText="Operating System Version" ResourceKey="OSVersion">OS Version: </Label>
</td>
<td>
<input id="osversion" class="form-control" @bind="@_osversion" readonly />
</td>
</tr>
<tr>
<td>
<Label For="serverpath" HelpText="Server Path" ResourceKey="ServerPath">Server Path: </Label>
</td>
<td>
<input id="serverpath" class="form-control" @bind="@_serverpath" readonly />
</td>
</tr>
<tr>
<td>
<Label For="servertime" HelpText="Server Time" ResourceKey="ServerTime">Server Time: </Label>
</td>
<td>
<input id="servertime" class="form-control" @bind="@_servertime" readonly />
</td>
</tr>
<tr>
<td>
<Label For="installationid" HelpText="The Unique Identifier For Your Installation" ResourceKey="InstallationId">Installation ID: </Label>
</td>
<td>
<input id="installationid" class="form-control" @bind="@_installationid" readonly />
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<br /><input type="checkbox" @onchange="(e => RegisterChecked(e))" /> @Localizer["Register"]
</td>
</tr>
</table>
<br /><br />
<ActionDialog Header="Restart Application" Message="Are You Sure You Wish To Restart The Application?" Action="Restart Application" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await RestartApplication())" ResourceKey="RestartApplication" />
</TabPanel>
<TabPanel Name="Options" Heading="Options" ResourceKey="Options">
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="runtime" HelpText="Blazor Runtime (Server or WebAssembly)" ResourceKey="BlazorRuntime">Blazor Runtime: </Label>
</td>
<td>
<select id="runtime" class="form-select" @bind="@_runtime">
<option value="Server">@Localizer["Server"]</option>
<option value="WebAssembly">@Localizer["WebAssembly"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="rendermode" HelpText="Blazor Server Render Mode" ResourceKey="RenderMode">Render Mode: </Label>
</td>
<td>
<select id="rendermode" class="form-select" @bind="@_rendermode">
<option value="Server">@Localizer["Server"]</option>
<option value="ServerPrerendered">@Localizer["ServerPrerendered"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="detailederrors" HelpText="Specify If Detailed Errors Are Enabled For Blazor. This Option Should Not Not Be Enabled In Production." ResourceKey="DetailedErrors">Detailed Errors? </Label>
</td>
<td>
<select id="detailederrors" class="form-select" @bind="@_detailederrors">
<option value="true">@SharedLocalizer["True"]</option>
<option value="false">@SharedLocalizer["False"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="logginglevel" HelpText="The Minimum Logging Level For The Event Log. This Option Can Be Used To Control The Volume Of Items Stored In Your Event Log." ResourceKey="LoggingLevel">Logging Level: </Label>
</td>
<td>
<select id="logginglevel" class="form-select" @bind="@_logginglevel">
<option value="Trace">@Localizer["Trace"]</option>
<option value="Debug">@Localizer["Debug"]</option>
<option value="Information">@Localizer["Information"]</option>
<option value="Warning">@Localizer["Warning"]</option>
<option value="Error">@Localizer["Error"]</option>
<option value="Critical">@Localizer["Critical"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="swagger" HelpText="Specify If Swagger Is Enabled For Your Server API" ResourceKey="Swagger">Swagger Enabled? </Label>
</td>
<td>
<select id="swagger" class="form-select" @bind="@_swagger">
<option value="true">@SharedLocalizer["True"]</option>
<option value="false">@SharedLocalizer["False"]</option>
</select>
</td>
</tr>
<tr>
<td>
<Label For="packageservice" HelpText="Specify If The Package Service Is Enabled For Installing Modules, Themes, And Translations" ResourceKey="PackageService">Enable Package Service? </Label>
</td>
<td>
<select id="packageservice" class="form-select" @bind="@_packageservice">
<option value="true">@SharedLocalizer["True"]</option>
<option value="false">@SharedLocalizer["False"]</option>
</select>
</td>
</tr>
</table>
<br /><br />
<button type="button" class="btn btn-success" @onclick="SaveConfig">@SharedLocalizer["Save"]</button>&nbsp;
<a class="btn btn-primary" href="swagger/index.html" target="_new">@Localizer["Access.ApiFramework"]</a>&nbsp;
<ActionDialog Header="Restart Application" Message="Are You Sure You Wish To Restart The Application?" Action="Restart Application" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await RestartApplication())" ResourceKey="RestartApplication" />
</TabPanel>
</TabStrip>
@code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
private string _version = string.Empty;
private string _runtime = string.Empty;
private string _rendermode = string.Empty;
private string _clrversion = string.Empty;
private string _osversion = string.Empty;
private string _serverpath = string.Empty;
private string _servertime = string.Empty;
private string _installationid = string.Empty;
private string _runtime = string.Empty;
private string _rendermode = string.Empty;
private string _detailederrors = string.Empty;
private string _logginglevel = string.Empty;
private string _swagger = string.Empty;
private string _packageservice = string.Empty;
protected override async Task OnInitializedAsync()
{
_version = Constants.Version;
_runtime = PageState.Runtime.ToString();
Dictionary<string, string> systeminfo = await SystemService.GetSystemInfoAsync();
if (systeminfo != null)
{
_rendermode = systeminfo["rendermode"];
_clrversion = systeminfo["clrversion"];
_osversion = systeminfo["osversion"];
_serverpath = systeminfo["serverpath"];
_servertime = systeminfo["servertime"];
_installationid = systeminfo["installationid"];
_runtime = systeminfo["runtime"];
_rendermode = systeminfo["rendermode"];
_detailederrors = systeminfo["detailederrors"];
_logginglevel = systeminfo["logginglevel"];
_swagger = systeminfo["swagger"];
_packageservice = systeminfo["packageservice"];
}
}
private async Task SaveConfig()
{
try
{
var settings = new Dictionary<string, string>();
settings.Add("runtime", _runtime);
settings.Add("rendermode", _rendermode);
settings.Add("detailederrors", _detailederrors);
settings.Add("logginglevel", _logginglevel);
settings.Add("swagger", _swagger);
settings.Add("packageservice", _packageservice);
await SystemService.UpdateSystemInfoAsync(settings);
AddModuleMessage(Localizer["Success.UpdateConfig.Restart"], MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Configuration");
AddModuleMessage(Localizer["Error.UpdateConfig"], MessageType.Error);
}
}
@ -98,7 +212,7 @@
{
ShowProgressIndicator();
var interop = new Interop(JSRuntime);
await interop.RedirectBrowser(NavigateUrl(""), 10);
await interop.RedirectBrowser(NavigateUrl(""), 20);
await InstallationService.RestartAsync();
}
catch (Exception ex)
@ -106,4 +220,20 @@
await logger.LogError(ex, "Error Restarting Application");
}
}
private async Task RegisterChecked(ChangeEventArgs e)
{
try
{
if ((bool)e.Value)
{
await InstallationService.RegisterAsync(PageState.User.Email);
AddModuleMessage(Localizer["Success.Register"], MessageType.Success);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Register");
}
}
}

View File

@ -5,50 +5,70 @@
@inject IThemeService ThemeService
@inject IPackageService PackageService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_packages != null)
{
<TabStrip>
@if (_packages.Count > 0)
<TabStrip>
<TabPanel Name="Download" ResourceKey="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more themes from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
<table class="table table-borderless" style=" margin: auto; width: 50% !important;">
<tr>
<td>
<input id="search" class="form-control" placeholder="@SharedLocalizer["Search.Hint"]" @bind="@_search" />
</td>
<td>
<button type="button" class="btn btn-primary" @onclick="Search">@SharedLocalizer["Search"]</button>&nbsp;
<button type="button" class="btn btn-secondary" @onclick="Reset">@SharedLocalizer["Reset"]</button>
</td>
</tr>
</table>
@if (_packages != null)
{
<TabPanel Name="Download" ResourceKey="Download">
<ModuleMessage Type="MessageType.Info" Message="Download one or more themes from the list below. Once you are ready click Install to complete the installation."></ModuleMessage>
if (_packages.Count > 0)
{
<Pager Items="@_packages">
<Header>
<th>@Localizer["Name"]</th>
<th>@Localizer["Version"]</th>
<th style="width: 1px;"></th>
</Header>
<Row>
<td>@context.Name</td>
<td>@context.Version</td>
<td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>@Localizer["Download"]</button>
<h3 style="display: inline;"><a href="@context.ProductUrl" target="_new">@context.Name</a></h3>&nbsp;&nbsp;@SharedLocalizer["Search.By"]:&nbsp;&nbsp;<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"]&nbsp;&nbsp;|&nbsp;&nbsp; @SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong>&nbsp;&nbsp;|&nbsp;&nbsp;@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>&nbsp;&nbsp;|&nbsp;&nbsp;@SharedLocalizer["Search.Source"]: <strong>@context.PackageUrl</strong>
</td>
<td style="vertical-align: middle;">
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>@SharedLocalizer["Download"]</button>
</td>
</Row>
</Pager>
</TabPanel>
}
else
{
<br />
<div class="mx-auto text-center">
@Localizer["Search.NoResults"]
</div>
}
}
<TabPanel Name="Upload" ResourceKey="Upload">
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="@true" />
</td>
</tr>
</table>
</TabPanel>
</TabStrip>
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload">
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload one or more theme packages. Once they are uploaded click Install to complete the installation." ResourceKey="Theme">Theme: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="@true" />
</td>
</tr>
</table>
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-success" @onclick="InstallThemes">@Localizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
}
<button type="button" class="btn btn-success" @onclick="InstallThemes">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {
private List<Package> _packages;
private string _search = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -56,9 +76,22 @@
{
try
{
var themes = await ThemeService.GetThemesAsync();
_packages = await PackageService.GetPackagesAsync("theme");
await LoadThemes();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message);
AddModuleMessage(Localizer["Error.Package.Load"], MessageType.Error);
}
}
private async Task LoadThemes()
{
var themes = await ThemeService.GetThemesAsync();
_packages = await PackageService.GetPackagesAsync("theme", _search);
if (_packages != null)
{
foreach (Package package in _packages.ToArray())
{
if (themes.Exists(item => item.PackageName == package.PackageId))
@ -67,10 +100,30 @@
}
}
}
}
private async Task Search()
{
try
{
await LoadThemes();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Packages"], MessageType.Error);
await logger.LogError(ex, "Error On Search");
}
}
private async Task Reset()
{
try
{
_search = "";
await LoadThemes();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Reset");
}
}
@ -79,7 +132,7 @@
try
{
await ThemeService.InstallThemesAsync();
AddModuleMessage(Localizer["Theme Installed Successfully. You Must <a href=\"{0}\">Restart</a> Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
}
catch (Exception ex)
{
@ -93,13 +146,13 @@
{
await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Theme {ThemeName} {Version} Downloaded Successfully", packageid, version);
AddModuleMessage(Localizer["Themes Downloaded Successfully. Click Install To Complete Installation."], MessageType.Success);
AddModuleMessage(Localizer["Success.Theme.Download"], MessageType.Success);
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Module {ThemeName} {Version}", packageid, version);
AddModuleMessage(Localizer["Error Downloading Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.Download"], MessageType.Error);
}
}
}

View File

@ -6,13 +6,14 @@
@inject IModuleService ModuleService
@inject IPageModuleService PageModuleService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<Create> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_templates != null)
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="owner" HelpText="Enter the name of the organization who is developing this theme. It should not contain spaces or punctuation." ResourceKey="OwnerName">Owner Name: </Label>
</td>
<td>
@ -32,8 +33,8 @@
<Label For="template" HelpText="Select a theme template. Templates are located in the wwwroot/Themes/Templates folder on the server." ResourceKey="Template">Template: </Label>
</td>
<td>
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Select Template"]&gt;</option>
<select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates)
{
<option value="@template.Name">@template.Title</option>
@ -46,7 +47,7 @@
<Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
</td>
<td>
<select id="reference" class="form-control" @bind="@_reference">
<select id="reference" class="form-select" @bind="@_reference">
@foreach (string version in _versions)
{
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -54,7 +55,7 @@
<option value="@(version)">@(version)</option>
}
}
<option value="local">@Localizer["Local Version"]</option>
<option value="local">@SharedLocalizer["LocalVersion"]</option>
</select>
</td>
</tr>
@ -70,8 +71,8 @@
</tr>
}
</table>
<button type="button" class="btn btn-success" @onclick="CreateTheme">@Localizer["Create Theme"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="CreateTheme">@Localizer["Theme.Create"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
@ -92,7 +93,7 @@
{
_templates = await ThemeService.GetThemeTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray();
AddModuleMessage(Localizer["Please Note That The Theme Creator Is Only Intended To Be Used In A Development Environment"], MessageType.Info);
AddModuleMessage(Localizer["Info.Theme.CreatorIntent"], MessageType.Info);
}
catch (Exception ex)
{
@ -109,11 +110,11 @@
var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference };
theme = await ThemeService.CreateThemeAsync(theme);
GetLocation();
AddModuleMessage(Localizer["The Source Code For Your Theme 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 Activate The Module.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Theme.Create"], NavigateUrl("admin/system")), MessageType.Success);
}
else
{
AddModuleMessage(Localizer["You Must Provide A Valid Owner Name And Theme Name ( ie. No Punctuation Or Spaces And The Values Cannot Be The Same ) And Choose A Template"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.ValidName"], MessageType.Warning);
}
}
catch (Exception ex)

View File

@ -5,23 +5,24 @@
@inject IThemeService ThemeService
@inject IPackageService PackageService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_themes == null)
{
<p><em>Loading...</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<ActionLink Action="Add" Text="Install Theme" />
@((MarkupString)"&nbsp;")
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" />
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" Class="btn btn-secondary" />
<Pager Items="@_themes">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th scope="col">@Localizer["Name"]</th>
<th scope="col">@Localizer["Version"]</th>
<th scope="col">@SharedLocalizer["Name"]</th>
<th scope="col">@SharedLocalizer["Version"]</th>
<th>&nbsp;</th>
</Header>
<Row>
@ -29,7 +30,7 @@ else
<td>
@if (context.AssemblyName != "Oqtane.Client")
{
<ActionDialog Header="Delete Theme" Message="@Localizer["Are You Sure You Wish To Delete The {0} Theme?", context.Name]" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTheme(context))" ResourceKey="DeleteTheme" />
<ActionDialog Header="Delete Theme" Message="@string.Format(Localizer["Confirm.Theme.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteTheme(context))" ResourceKey="DeleteTheme" />
}
</td>
<td>@context.Name</td>
@ -37,7 +38,7 @@ else
<td>
@if (UpgradeAvailable(context.PackageName, context.Version))
{
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.PackageName, context.Version))>@Localizer["Upgrade"]</button>
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadTheme(context.PackageName, context.Version))>@SharedLocalizer["Upgrade"]</button>
}
</td>
<td></td>
@ -63,7 +64,7 @@ else
if (_themes == null)
{
await logger.LogError(ex, "Error Loading Themes {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Themes"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.Load"], MessageType.Error);
}
}
}
@ -89,12 +90,12 @@ else
await PackageService.DownloadPackageAsync(packagename, version, "Packages");
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
await ThemeService.InstallThemesAsync();
AddModuleMessage(Localizer["Theme Installed Successfully. You Must <a href=\"{0}\">Restart</a> Your Application To Apply These Changes.", NavigateUrl("admin/system")], MessageType.Success);
AddModuleMessage(string.Format(Localizer["Success.Theme.Install"], NavigateUrl("admin/system")), MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Theme {ThemeName} {Version} {Error}", packagename, version, ex.Message);
AddModuleMessage(Localizer["Error Downloading Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.Download"], MessageType.Error);
}
}
@ -103,13 +104,13 @@ else
try
{
await ThemeService.DeleteThemeAsync(Theme.ThemeName);
AddModuleMessage(Localizer["Theme Deleted Successfully"], MessageType.Success);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload"));
AddModuleMessage(Localizer["Success.Theme.Delete"], MessageType.Success);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Deleting Theme {Theme} {Error}", Theme, ex.Message);
AddModuleMessage(Localizer["Error Deleting Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.Delete"], MessageType.Error);
}
}
}

View File

@ -4,10 +4,11 @@
@inject IThemeService ThemeService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<View> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="name" HelpText="The name of the theme" ResourceKey="Name">Name: </Label>
</td>
<td>
@ -63,7 +64,7 @@
</td>
</tr>
</table>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {
private string _themeName = "";
@ -96,7 +97,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message);
AddModuleMessage(Localizer["Error Loading Theme"], MessageType.Error);
AddModuleMessage(Localizer["Error.Theme.Loading"], MessageType.Error);
}
}
}

View File

@ -5,38 +5,36 @@
@inject IPackageService PackageService
@inject IInstallationService InstallationService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_package != null)
{
<TabStrip>
<TabPanel Name="Download" ResourceKey="Download">
@if (_upgradeavailable)
{
<ModuleMessage Type="MessageType.Info" Message="Select The Download Button To Download The Framework Upgrade Package And Then Select Upgrade"></ModuleMessage>
<button type="button" class="btn btn-primary" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>@Localizer["Download"] @_package.Version</button>
<button type="button" class="btn btn-success" @onclick="Upgrade">@Localizer["Upgrade"]</button>
}
else
{
<ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage>
}
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload">
<ModuleMessage Type="MessageType.Info" Message="Upload A Framework Package (Oqtane.Framework.version.nupkg) And Then Select Upgrade"></ModuleMessage>
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload A Framework Package And Then Select Upgrade" ResourceKey="Framework">Framework: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="Upgrade">@Localizer["Upgrade"]</button>
</TabPanel>
</TabStrip>
}
<TabStrip>
<TabPanel Name="Download" ResourceKey="Download">
@if (_package != null && _upgradeavailable)
{
<ModuleMessage Type="MessageType.Info" Message="Select The Download Button To Download The Framework Upgrade Package And Then Select Upgrade"></ModuleMessage>
<button type="button" class="btn btn-primary" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>@SharedLocalizer["Download"] @_package.Version</button>
<button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
}
else
{
<ModuleMessage Type="MessageType.Info" Message="Framework Is Already Up To Date"></ModuleMessage>
}
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload">
<ModuleMessage Type="MessageType.Info" Message="Upload A Framework Package (Oqtane.Framework.version.nupkg) And Then Select Upgrade"></ModuleMessage>
<table class="table table-borderless">
<tr>
<td>
<Label HelpText="Upload A Framework Package And Then Select Upgrade" ResourceKey="Framework">Framework: </Label>
</td>
<td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" />
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
</TabPanel>
</TabStrip>
@code {
private Package _package;
@ -72,16 +70,16 @@
{
try
{
AddModuleMessage(Localizer["Please Be Patient While The Upgrade Is In Progress..."], MessageType.Info);
AddModuleMessage(Localizer["Info.Upgrade.Wait"], MessageType.Info);
ShowProgressIndicator();
var interop = new Interop(JSRuntime);
await interop.RedirectBrowser(NavigateUrl(), 30);
await interop.RedirectBrowser(NavigateUrl(), 20);
await InstallationService.Upgrade();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Executing Upgrade {Error}", ex.Message);
AddModuleMessage(Localizer["Error Executing Upgrade"], MessageType.Error);
AddModuleMessage(Localizer["Error.Upgrade.Execute"], MessageType.Error);
}
}
@ -91,12 +89,12 @@
{
await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, version, "Packages");
AddModuleMessage(Localizer["Framework Downloaded Successfully... Please Select Upgrade To Complete the Process"], MessageType.Success);
AddModuleMessage(Localizer["Success.Framework.Download"], MessageType.Success);
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Downloading Framework Package {Error}", ex.Message);
AddModuleMessage(Localizer["Error Downloading Framework Package"], MessageType.Error);
AddModuleMessage(Localizer["Error.Framework.Download"], MessageType.Error);
}
}
}

View File

@ -1,73 +1,74 @@
@namespace Oqtane.Modules.Admin.UserProfile
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserService UserService
@namespace Oqtane.Modules.Admin.UserProfile
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject INotificationService NotificationService
@inject IStringLocalizer<Add> Localizer
@if (PageState.User != null)
{
<table class="table table-borderless">
<tr>
<td>
<Label For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
</td>
<td>
<input id="to" class="form-control" @bind="@username" />
</td>
</tr>
<tr>
<td>
<Label For="subject" HelpText="Enter the subject of the message" ResourceKey="Subject">Subject: </Label>
</td>
<td>
<input id="subject" class="form-control" @bind="@subject" />
</td>
</tr>
<tr>
<td>
<Label For="message" HelpText="Enter the message" ResourceKey="Message">Message: </Label>
</td>
<td>
<textarea id="message" class="form-control" @bind="@body" rows="5" />
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="Send">@Localizer["Send"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
}
@code {
private string username = "";
private string subject = "";
private string body = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
public override string Title => "Send Notification";
private async Task Send()
{
try
{
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null)
{
<table class="table table-borderless">
<tr>
<td width="30%">
<Label For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
</td>
<td>
<input id="to" class="form-control" @bind="@username" />
</td>
</tr>
<tr>
<td>
<Label For="subject" HelpText="Enter the subject of the message" ResourceKey="Subject">Subject: </Label>
</td>
<td>
<input id="subject" class="form-control" @bind="@subject" />
</td>
</tr>
<tr>
<td>
<Label For="message" HelpText="Enter the message" ResourceKey="Message">Message: </Label>
</td>
<td>
<textarea id="message" class="form-control" @bind="@body" rows="5" />
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
private string username = "";
private string subject = "";
private string body = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
public override string Title => "Send Notification";
private async Task Send()
{
try
{
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
{
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, null);
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage(Localizer["User Does Not Exist. Please Verify That The Username Provided Is Correct."], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error);
}
}
}
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
AddModuleMessage(Localizer["Error.Notification.Add"], MessageType.Error);
}
}
}

View File

@ -7,6 +7,7 @@
@inject INotificationService NotificationService
@inject IFileService FileService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null && photo != null)
{
@ -22,56 +23,56 @@ else
{
<table class="table table-borderless">
<tr>
<td>
<label for="Name" class="control-label">@Localizer["Username:"] </label>
<td width="30%">
<Label For="username" HelpText="Your username. Note that this field can not be modified." ResourceKey="Username"></Label>
</td>
<td>
<input class="form-control" @bind="@username" readonly />
<input id="username" class="form-control" @bind="@username" readonly />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">@Localizer["Password:"] </label>
<Label For="password" HelpText="If you wish to change your password you can enter it here. Please choose a sufficiently secure password." ResourceKey="Password"></Label>
</td>
<td>
<input type="password" class="form-control" @bind="@password" autocomplete="new-password" />
<input id ="password" type="password" class="form-control" @bind="@password" autocomplete="new-password" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">@Localizer["Confirm Password:"] </label>
<Label For="confirm" HelpText="If you are changing your password you must enter it again to confirm it matches" ResourceKey="Confirm"></Label>
</td>
<td>
<input type="password" class="form-control" @bind="@confirm" autocomplete="new-password" />
<input id="confirm" type="password" class="form-control" @bind="@confirm" autocomplete="new-password" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">@Localizer["Email:"] </label>
<Label For="email" HelpText="Your email address where you wish to receive notifications" ResourceKey="Email"></Label>
</td>
<td>
<input class="form-control" @bind="@email" />
<input id="email" class="form-control" @bind="@email" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">@Localizer["Full Name:"] </label>
<Label For="displayname" HelpText="Your full name" ResourceKey="DisplayName"></Label>
</td>
<td>
<input class="form-control" @bind="@displayname" />
<input id="displayname" class="form-control" @bind="@displayname" />
</td>
</tr>
<tr>
<td>
<label for="Name" class="control-label">@Localizer["Photo:"] </label>
<Label For="@photofileid.ToString()" HelpText="A photo of yourself" ResourceKey="Photo"></Label>
</td>
<td>
<FileManager FileId="@photofileid" @ref="filemanager" />
</td>
</tr>
</table>
<button type="button" class="btn btn-primary" @onclick="Save">@Localizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</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>
}
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
@ -93,13 +94,13 @@ else
category = p.Category;
}
<tr>
<td>
<td width="30%">
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
</td>
<td>
@if (!string.IsNullOrEmpty(p.Options))
{
<select id="@p.Name" class="form-control" @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))
@ -129,8 +130,8 @@ else
}
}
</table>
<button type="button" class="btn btn-primary" @onclick="Save">@Localizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</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>
}
</TabPanel>
<TabPanel Name="Notifications" ResourceKey="Notifications">
@ -205,9 +206,9 @@ else
</Pager>
}
<br /><hr />
<select class="form-control" @onchange="(e => FilterChanged(e))">
<select class="form-select" @onchange="(e => FilterChanged(e))">
<option value="to">@Localizer["Inbox"]</option>
<option value="from">@Localizer["Sent Items"]</option>
<option value="from">@Localizer["Items.Sent"]</option>
</select>
}
</TabPanel>
@ -258,13 +259,13 @@ else
}
else
{
AddModuleMessage(Localizer["Current User Is Not Logged In"], MessageType.Warning);
AddModuleMessage(Localizer["Message.User.NoLogIn"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading User Profile"], MessageType.Error);
AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error);
}
}
@ -304,18 +305,18 @@ else
}
else
{
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Username and Email Address As Well As All Required Profile Information"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving User Profile {Error}", ex.Message);
AddModuleMessage(Localizer["Error Saving User Profile"], MessageType.Error);
AddModuleMessage(Localizer["Error.Profile.Save"], MessageType.Error);
}
}

View File

@ -1,201 +1,202 @@
@namespace Oqtane.Modules.Admin.UserProfile
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserService UserService
@namespace Oqtane.Modules.Admin.UserProfile
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject INotificationService NotificationService
@inject IStringLocalizer<View> Localizer
@if (PageState.User != null)
{
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">@Localizer["Title:"] </label>
</td>
@if (title == "From")
{
<td>
<input class="form-control" @bind="@username" readonly />
</td>
}
@if (title == "To")
{
<td>
<input class="form-control" @bind="@username" />
</td>
}
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Subject:"] </label>
</td>
@if (title == "From")
{
<td>
<input class="form-control" @bind="@subject" readonly />
</td>
}
@if (title == "To")
{
<td>
<input class="form-control" @bind="@subject" />
</td>
}
</tr>
@if (title == "From")
{
<tr>
<td>
<label class="control-label">@Localizer["Date:"] </label>
</td>
<td>
<input class="form-control" @bind="@createdon" readonly />
</td>
</tr>
}
@if (title == "From")
{
<tr>
<td>
<label class="control-label">@Localizer["Message:"] </label>
</td>
<td>
<textarea class="form-control" @bind="@body" rows="5" readonly />
</td>
</tr>
}
@if (title == "To")
{
<tr>
<td>
<label class="control-label">@Localizer["Message:"] </label>
</td>
<td>
<textarea class="form-control" @bind="@body" rows="5" />
</td>
</tr>
}
</table>
@if (reply != string.Empty)
{
<button type="button" class="btn btn-primary" @onclick="Send">@Localizer["Send"]</button>
}
else
{
if (title == "From")
{
@inject IStringLocalizer<View> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null)
{
<table class="table table-borderless">
<tr>
<td width="30%">
<label class="control-label">@Localizer["Title"] </label>
</td>
@if (title == "From")
{
<td>
<input class="form-control" @bind="@username" readonly />
</td>
}
@if (title == "To")
{
<td>
<input class="form-control" @bind="@username" />
</td>
}
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Subject"] </label>
</td>
@if (title == "From")
{
<td>
<input class="form-control" @bind="@subject" readonly />
</td>
}
@if (title == "To")
{
<td>
<input class="form-control" @bind="@subject" />
</td>
}
</tr>
@if (title == "From")
{
<tr>
<td>
<label class="control-label">@Localizer["Date"] </label>
</td>
<td>
<input class="form-control" @bind="@createdon" readonly />
</td>
</tr>
}
@if (title == "From")
{
<tr>
<td>
<label class="control-label">@Localizer["Message"] </label>
</td>
<td>
<textarea class="form-control" @bind="@body" rows="5" readonly />
</td>
</tr>
}
@if (title == "To")
{
<tr>
<td>
<label class="control-label">@Localizer["Message"] </label>
</td>
<td>
<textarea class="form-control" @bind="@body" rows="5" />
</td>
</tr>
}
</table>
@if (reply != string.Empty)
{
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
}
else
{
if (title == "From")
{
<button type="button" class="btn btn-primary" @onclick="Reply">@Localizer["Reply"]</button>
}
}
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<br />
<br />
@if (title == "To")
{
<div class="control-group">
<label class="control-label">@Localizer["Original Message"] </label>
<textarea class="form-control" @bind="@reply" rows="5" readonly />
</div>
}
}
@code {
private int notificationid;
private string title = string.Empty;
private string username = "";
private string subject = string.Empty;
private string createdon = string.Empty;
private string body = string.Empty;
private string reply = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
public override string Title => "View Notification";
protected override async Task OnInitializedAsync()
{
try
{
notificationid = Int32.Parse(PageState.QueryString["id"]);
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
if (notification != null)
{
int userid = -1;
if (notification.ToUserId == PageState.User.UserId)
{
title = "From";
if (notification.FromUserId != null)
{
userid = notification.FromUserId.Value;
}
}
else
{
title = "To";
if (notification.ToUserId != null)
{
userid = notification.ToUserId.Value;
}
}
if (userid != -1)
{
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
if (user != null)
{
username = user.Username;
}
}
if (username == "")
{
username = "System";
}
subject = notification.Subject;
createdon = notification.CreatedOn.ToString();
body = notification.Body;
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Users"], MessageType.Error);
}
}
private void Reply()
{
title = "To";
if (!subject.Contains("RE:"))
{
subject = "RE: " + subject;
}
reply = body;
body = "\n\n____________________________________________\nSent: " + createdon + "\nSubject: " + subject + "\n\n" + body;
StateHasChanged();
}
private async Task Send()
{
try
{
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
}
}
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
@if (title == "To")
{
<div class="control-group">
<label class="control-label">@Localizer["OriginalMessage"] </label>
<textarea class="form-control" @bind="@reply" rows="5" readonly />
</div>
}
}
@code {
private int notificationid;
private string title = string.Empty;
private string username = "";
private string subject = string.Empty;
private string createdon = string.Empty;
private string body = string.Empty;
private string reply = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
public override string Title => "View Notification";
protected override async Task OnInitializedAsync()
{
try
{
notificationid = Int32.Parse(PageState.QueryString["id"]);
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
if (notification != null)
{
int userid = -1;
if (notification.ToUserId == PageState.User.UserId)
{
title = "From";
if (notification.FromUserId != null)
{
userid = notification.FromUserId.Value;
}
}
else
{
title = "To";
if (notification.ToUserId != null)
{
userid = notification.ToUserId.Value;
}
}
if (userid != -1)
{
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
if (user != null)
{
username = user.Username;
}
}
if (username == "")
{
username = "System";
}
subject = notification.Subject;
createdon = notification.CreatedOn.ToString();
body = notification.Body;
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message);
AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error);
}
}
private void Reply()
{
title = "To";
if (!subject.Contains("RE:"))
{
subject = "RE: " + subject;
}
reply = body;
body = "\n\n____________________________________________\nSent: " + createdon + "\nSubject: " + subject + "\n\n" + body;
StateHasChanged();
}
private async Task Send()
{
try
{
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
{
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage(Localizer["User Does Not Exist. Please Verify That The Username Provided Is Correct."], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error);
}
}
}
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
}
else
{
AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
AddModuleMessage(Localizer["Error.Notification.Add"], MessageType.Error);
}
}
}

View File

@ -5,6 +5,7 @@
@inject IProfileService ProfileService
@inject ISettingService SettingService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
@ -12,43 +13,43 @@
{
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">@Localizer["Username:"] </label>
<td width="30%">
<Label For="username" HelpText="A unique username for a user. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
</td>
<td>
<input class="form-control" @bind="@username" />
<input id="username" class="form-control" @bind="@username" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Password:"] </label>
<Label For="password" HelpText="The user's password. Please choose a password which is sufficiently secure." ResourceKey="Password"></Label>
</td>
<td>
<input type="password" class="form-control" @bind="@password" />
<input id="password" type="password" class="form-control" @bind="@password" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Confirm Password:"] </label>
<Label For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
</td>
<td>
<input type="password" class="form-control" @bind="@confirm" />
<input id="confirm" type="password" class="form-control" @bind="@confirm" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Email:"] </label>
<Label For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
</td>
<td>
<input class="form-control" @bind="@email" />
<input id="email" class="form-control" @bind="@email" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Full Name:"] </label>
<Label For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
</td>
<td>
<input class="form-control" @bind="@displayname" />
<input id="displayname" class="form-control" @bind="@displayname" />
</td>
</tr>
</table>
@ -71,7 +72,7 @@
category = p.Category;
}
<tr>
<td>
<td width="30%">
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
</td>
<td>
@ -91,8 +92,8 @@
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-primary" @onclick="SaveUser">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code {
private string username = string.Empty;
@ -116,7 +117,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading User Profile"], MessageType.Error);
AddModuleMessage(Localizer["Error.Profile.Load"], MessageType.Error);
}
}
@ -153,28 +154,28 @@
else
{
await logger.LogError("Error Adding User {Username} {Email}", username, email);
AddModuleMessage(Localizer["Error Adding User. Please Ensure Password Meets Complexity Requirements And Username And Email Are Not Already In Use."], MessageType.Error);
AddModuleMessage(Localizer["Error.User.AddCheckPass"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["Username Already Exists"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Username.Exists"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Username, Password, Email Address And All Required Profile Information"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", username, email, ex.Message);
AddModuleMessage(Localizer["Error Adding User"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
}
}

View File

@ -6,6 +6,7 @@
@inject ISettingService SettingService
@inject IFileService FileService
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null && photo != null)
{
@ -21,48 +22,48 @@ else
{
<table class="table table-borderless">
<tr>
<td>
<label class="control-label">@Localizer["Username:"] </label>
<td width="30%">
<Label For="username" HelpText="The unique username for a user. Note that this field can not be modified." ResourceKey="Username"></Label>
</td>
<td>
<input class="form-control" @bind="@username" readonly />
<input id="username" class="form-control" @bind="@username" readonly />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Password:"] </label>
<Label For="password" HelpText="The user's password. Please choose a password which is sufficiently secure." ResourceKey="Password"></Label>
</td>
<td>
<input type="password" class="form-control" @bind="@password" />
<input id="password" type="password" class="form-control" @bind="@password" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Confirm Password:"] </label>
<Label For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
</td>
<td>
<input type="password" class="form-control" @bind="@confirm" />
<input id="confirm" type="password" class="form-control" @bind="@confirm" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Email:"] </label>
<Label For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
</td>
<td>
<input class="form-control" @bind="@email" />
<input id="email" class="form-control" @bind="@email" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Full Name:"] </label>
<Label For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
</td>
<td>
<input class="form-control" @bind="@displayname" />
<input id="displayname" class="form-control" @bind="@displayname" />
</td>
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Photo:"] </label>
<Label For="@photofileid.ToString()" HelpText="A photo of the user" ResourceKey="Photo"></Label>
</td>
<td>
<FileManager FileId="@photofileid" @ref="filemanager" />
@ -70,12 +71,12 @@ else
</tr>
<tr>
<td>
<label class="control-label">@Localizer["Is Deleted?"] </label>
<Label For="isdeleted" HelpText="Indicate if the user is active" ResourceKey="IsDeleted"></Label>
</td>
<td>
<select class="form-control" @bind="@isdeleted">
<option value="True">@Localizer["Yes"]</option>
<option value="False">@Localizer["No"]</option>
<select id="isdeleted" class="form-select" @bind="@isdeleted">
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>
@ -99,7 +100,7 @@ else
category = p.Category;
}
<tr>
<td>
<td width="30%">
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
</td>
<td>
@ -119,8 +120,8 @@ else
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-primary" @onclick="SaveUser">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
@ -152,39 +153,42 @@ else
{
try
{
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
userid = Int32.Parse(PageState.QueryString["id"]);
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
if (user != null)
// OnParametersSetAsync is called when the edit modal is closed - in which case there is no id parameter
if (PageState.QueryString.ContainsKey("id"))
{
username = user.Username;
email = user.Email;
displayname = user.DisplayName;
if (user.PhotoFileId != null)
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
userid = Int32.Parse(PageState.QueryString["id"]);
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
if (user != null)
{
photofileid = user.PhotoFileId.Value;
photo = await FileService.GetFileAsync(photofileid);
username = user.Username;
email = user.Email;
displayname = user.DisplayName;
if (user.PhotoFileId != null)
{
photofileid = user.PhotoFileId.Value;
photo = await FileService.GetFileAsync(photofileid);
}
else
{
photofileid = -1;
photo = null;
}
settings = await SettingService.GetUserSettingsAsync(user.UserId);
createdby = user.CreatedBy;
createdon = user.CreatedOn;
modifiedby = user.ModifiedBy;
modifiedon = user.ModifiedOn;
deletedby = user.DeletedBy;
deletedon = user.DeletedOn;
isdeleted = user.IsDeleted.ToString();
}
else
{
photofileid = -1;
photo = null;
}
settings = await SettingService.GetUserSettingsAsync(user.UserId);
createdby = user.CreatedBy;
createdon = user.CreatedOn;
modifiedby = user.ModifiedBy;
modifiedon = user.ModifiedOn;
deletedby = user.DeletedBy;
deletedon = user.DeletedOn;
isdeleted = user.IsDeleted.ToString();
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading User {UserId} {Error}", userid, ex.Message);
AddModuleMessage(Localizer["Error Loading User"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error);
}
}
@ -222,18 +226,18 @@ else
}
else
{
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["You Must Provide A Username, Password, Email Address, And All Required Profile Information"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.ProfileInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving User {Username} {Email} {Error}", username, email, ex.Message);
AddModuleMessage(Localizer["Error Saving User"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.Save"], MessageType.Error);
}
}

View File

@ -4,39 +4,43 @@
@inject IUserService UserService
@inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (userroles == null)
{
<p>
<em>@Localizer["Loading..."]</em>
<em>@SharedLocalizer["Loading"]</em>
</p>
}
else
{
<div class="form-row">
<div class="col">
<ActionLink Action="Add" Text="Add User" ResourceKey="AddUser" />
</div>
<div class="col">
<div class="input-group flex-nowrap">
<input class="form-control" @bind="@_search" />&nbsp;<button class="btn btn-secondary" @onclick="OnSearch">@Localizer["Search"]</button>
</div>
</div>
</div>
<table class="table table-borderless">
<tr>
<td>
<div><ActionLink Action="Add" Text="Add User" ResourceKey="AddUser" /></div>
</td>
<td>
<input class="form-control" @bind="@_search" />
</td>
<td>
<button class="btn btn-secondary" @onclick="OnSearch">@SharedLocalizer["Search"]</button>
</td>
</tr>
</table>
<Pager Items="@userroles">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
<th>@SharedLocalizer["Name"]</th>
</Header>
<Row>
<td>
<ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="EditUser" />
</td>
<td>
<ActionDialog Header="Delete User" Message="@Localizer["Are You Sure You Wish To Delete {0}?", context.User.DisplayName]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUser(context))" Disabled="@(context.Role.Name == RoleNames.Host)" ResourceKey="DeleteUser" />
<ActionDialog Header="Delete User" Message="@string.Format(Localizer["Confirm.User.Delete"], context.User.DisplayName)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUser(context))" Disabled="@(context.Role.Name == RoleNames.Host)" ResourceKey="DeleteUser" />
</td>
<td>
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" />
@ -66,7 +70,7 @@ else
if (string.IsNullOrEmpty(_search))
{
results = results.Where(item =>
results = results.Where(item =>
(
item.User.Username.Contains(search, StringComparison.OrdinalIgnoreCase) ||
item.User.Email.Contains(search, StringComparison.OrdinalIgnoreCase) ||

View File

@ -4,16 +4,17 @@
@inject IUserService UserService
@inject IUserRoleService UserRoleService
@inject IStringLocalizer<Roles> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (userroles == null)
{
<p><em>@Localizer["Loading..."]</em></p>
<p><em>@SharedLocalizer["Loading"]</em></p>
}
else
{
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="user" HelpText="The user you are assigning roles to" ResourceKey="User">User: </Label>
</td>
<td>
@ -25,8 +26,8 @@ else
<Label For="role" HelpText="Select a role" ResourceKey="Role">Role: </Label>
</td>
<td>
<select id="role" class="form-control" @bind="@roleid">
<option value="-1">&lt;@Localizer["Select Role"]&gt;</option>
<select id="role" class="form-select" @bind="@roleid">
<option value="-1">&lt;@Localizer["Role.Select"]&gt;</option>
@foreach (Role role in roles)
{
<option value="@(role.RoleId)">@role.Name</option>
@ -51,8 +52,8 @@ else
</td>
</tr>
</table>
<button type="button" class="btn btn-success" @onclick="SaveUserRole">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveUserRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<hr class="app-rule" />
<p align="center">
@ -68,7 +69,7 @@ else
<td>@context.EffectiveDate</td>
<td>@context.ExpiryDate</td>
<td>
<ActionDialog Header="Remove Role" Message="@Localizer["Are You Sure You Wish To Remove This User From The {0} Role?", context.Role.Name]" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUserRole(context.UserRoleId))" Disabled="@(context.Role.IsAutoAssigned || (context.Role.Name == RoleNames.Host && userid == PageState.User.UserId))" ResourceKey="DeleteUserRole" />
<ActionDialog Header="Remove Role" Message="@string.Format(Localizer["Confirm.User.RemoveRole"], context.Role.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUserRole(context.UserRoleId))" Disabled="@(context.Role.IsAutoAssigned || (context.Role.Name == RoleNames.Host && userid == PageState.User.UserId))" ResourceKey="DeleteUserRole" />
</td>
</Row>
</Pager>
@ -107,7 +108,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading Roles {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Roles"], MessageType.Error);
AddModuleMessage(Localizer["Error.LoadRole"], MessageType.Error);
}
}
@ -121,7 +122,7 @@ else
catch (Exception ex)
{
await logger.LogError(ex, "Error Loading User Roles {UserId} {Error}", userid, ex.Message);
AddModuleMessage(Localizer["Error Loading User Roles"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.LoadRole"], MessageType.Error);
}
}
@ -181,19 +182,19 @@ else
}
await logger.LogInformation("User Assigned To Role {UserRole}", userrole);
AddModuleMessage(Localizer["User Assigned To Role"], MessageType.Success);
AddModuleMessage(Localizer["Success.User.AssignRole"], MessageType.Success);
await GetUserRoles();
StateHasChanged();
}
else
{
AddModuleMessage(Localizer["You Must Select A Role"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required.Role"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving User Roles {UserId} {Error}", userid, ex.Message);
AddModuleMessage(Localizer["Error Saving User Roles"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.SaveRole"], MessageType.Error);
}
}
@ -203,14 +204,14 @@ else
{
await UserRoleService.DeleteUserRoleAsync(UserRoleId);
await logger.LogInformation("User Removed From Role {UserRoleId}", UserRoleId);
AddModuleMessage(Localizer["User Removed From Role"], MessageType.Success);
AddModuleMessage(Localizer["Success.User.Remove"], MessageType.Success);
await GetUserRoles();
StateHasChanged();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message);
AddModuleMessage(Localizer["Error Removing User From Role"], MessageType.Error);
AddModuleMessage(Localizer["Error.User.RemoveRole"], MessageType.Error);
}
}
}

View File

@ -9,7 +9,7 @@
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">@Header</h5>
<button type="button" class="close" @onclick="DisplayModal" aria-label="Close">&times;</button>
<button type="button" class="btn-close" aria-label="Close" @onclick="DisplayModal"></button>
</div>
<div class="modal-body">
<p>@Message</p>

View File

@ -44,12 +44,12 @@
if (!String.IsNullOrEmpty(CreatedBy))
{
_text += $" {Localizer["by"]} <b>{CreatedBy}</b>";
_text += $" {Localizer["By"]} <b>{CreatedBy}</b>";
}
if (CreatedOn != null)
{
_text += $" {Localizer["on"]} <b>{CreatedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
_text += $" {Localizer["On"]} <b>{CreatedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
}
_text += "</p>";
@ -57,7 +57,7 @@
if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn.HasValue)
{
_text += $"<p style=\"{Style}\">{Localizer["Last modified"]} ";
_text += $"<p style=\"{Style}\">{Localizer["LastModified"]} ";
if (!String.IsNullOrEmpty(ModifiedBy))
{
@ -78,12 +78,12 @@
if (!String.IsNullOrEmpty(DeletedBy))
{
_text += $" {Localizer["by"]} <b>{DeletedBy}</b>";
_text += $" {Localizer["By"]} <b>{DeletedBy}</b>";
}
if (DeletedOn != null)
{
_text += $" {Localizer["on"]} <b>{DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
_text += $" {Localizer["On"]} <b>{DeletedOn.Value.ToString("MMM dd yyyy HH:mm:ss")}</b>";
}
_text += "</p>";

View File

@ -3,6 +3,7 @@
@inject IFolderService FolderService
@inject IFileService FileService
@inject IStringLocalizer<FileManager> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_folders != null)
{
@ -12,10 +13,10 @@
@if (ShowFolders || FolderId <= 0)
{
<div>
<select class="form-control" value="@FolderId" @onchange="(e => FolderChanged(e))">
<select class="form-select" value="@FolderId" @onchange="(e => FolderChanged(e))">
@if (string.IsNullOrEmpty(Folder))
{
<option value="-1">&lt;@Localizer["Select Folder"]&gt;</option>
<option value="-1">&lt;@Localizer["Folder.Select"]&gt;</option>
}
@foreach (Folder folder in _folders)
{
@ -27,8 +28,8 @@
@if (ShowFiles)
{
<div>
<select class="form-control" value="@FileId" @onchange="(e => FileChanged(e))">
<option value="-1">&lt;@Localizer["Select File"]&gt;</option>
<select class="form-select" value="@FileId" @onchange="(e => FileChanged(e))">
<option value="-1">&lt;@Localizer["File.Select"]&gt;</option>
@foreach (File file in _files)
{
<option value="@(file.FileId)">@(file.Name)</option>
@ -48,11 +49,11 @@
<input type="file" id="@_fileinputid" name="file" accept="@_filter" />
}
<span id="@_progressinfoid"></span><progress id="@_progressbarid" style="width: 150px; visibility: hidden;"></progress>
<span class="float-right">
<button type="button" class="btn btn-success" @onclick="UploadFile">@Localizer["Upload"]</button>
<span class="float-end">
<button type="button" class="btn btn-success" @onclick="UploadFile">@SharedLocalizer["Upload"]</button>
@if (ShowFiles && GetFileId() != -1)
{
<button type="button" class="btn btn-danger" @onclick="DeleteFile">@Localizer["Delete"]</button>
<button type="button" class="btn btn-danger" @onclick="DeleteFile">@SharedLocalizer["Delete"]</button>
}
</span>
</div>
@ -208,7 +209,7 @@
{
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message);
_message = Localizer["Error Loading Files"];
_message = Localizer["Error.File.Load"];
_messagetype = MessageType.Error;
}
}
@ -268,7 +269,7 @@
{
await logger.LogInformation("File Upload Succeeded {Files}", upload);
_message = Localizer["File Upload Succeeded"];
_message = Localizer["Success.File.Upload"];
_messagetype = MessageType.Success;
await GetFiles();
@ -288,7 +289,7 @@
{
await logger.LogError("File Upload Failed For {Files}", result.Replace(",", ", "));
_message = Localizer["File Upload Failed"];
_message = Localizer["Error.File.Upload"];
_messagetype = MessageType.Error;
}
}
@ -296,13 +297,13 @@
{
await logger.LogError(ex, "File Upload Failed {Error}", ex.Message);
_message = Localizer["File Upload Failed"];
_message = Localizer["Error.File.Upload"];
_messagetype = MessageType.Error;
}
}
else
{
_message = Localizer["You Have Not Selected A File To Upload"];
_message = Localizer["Message.File.NotSelected"];
_messagetype = MessageType.Warning;
}
}
@ -315,7 +316,7 @@
await FileService.DeleteFileAsync(FileId);
await logger.LogInformation("File Deleted {File}", FileId);
_message = Localizer["File Deleted"];
_message = Localizer["Success.File.Delete"];
_messagetype = MessageType.Success;
await GetFiles();
@ -327,7 +328,7 @@
{
await logger.LogError(ex, "Error Deleting File {File} {Error}", FileId, ex.Message);
_message = Localizer["Error Deleting File"];
_message = Localizer["Error.File.Delete"];
_messagetype = MessageType.Error;
}
}

View File

@ -30,6 +30,11 @@ else
{
base.OnParametersSet();
if (string.IsNullOrEmpty(Class))
{
Class = "form-label";
}
_openLabel = "<label";
if (!string.IsNullOrEmpty(For))
{

View File

@ -4,12 +4,13 @@
@if (!string.IsNullOrEmpty(_message))
{
<div class="@_classname" role="alert">
<div class="@_classname alert-dismissible fade show" role="alert">
@((MarkupString)_message)
@if (Type == MessageType.Error && PageState != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
@((MarkupString)"&nbsp;&nbsp;")<NavLink href="@NavigateUrl("admin/log")">View Details</NavLink>
}
<button type="button" class="btn-close" aria-label="Close" @onclick="DismissModal"></button>
</div>
<br />
}
@ -54,4 +55,10 @@
return classname;
}
private void DismissModal()
{
_message = "";
StateHasChanged();
}
}

View File

@ -8,15 +8,15 @@
<div class="mx-auto text-center">
@if (_endPage > 1)
{
<button class="btn btn-secondary mr-1" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></button>
<button class="btn btn-secondary m-1" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="first" aria-hidden="true"></span></button>
}
@if (_page > _maxPages)
{
<button class="btn btn-secondary mr-1" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></button>
<button class="btn btn-secondary m-1" @onclick=@(async () => SetPagerSize("back"))><span class="oi oi-media-skip-backward" title="back" aria-hidden="true"></span></button>
}
@if (_endPage > 1)
{
<button class="btn btn-secondary mr-1" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
<button class="btn btn-secondary m-1" @onclick=@(async () => NavigateToPage("previous"))><span class="oi oi-chevron-left" title="previous" aria-hidden="true"></span></button>
@for (int i = _startPage; i <= _endPage; i++)
{
var pager = i;
@ -24,15 +24,15 @@
@pager
</button>
}
<button class="btn btn-secondary mr-1" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></button>
<button class="btn btn-secondary m-1" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></button>
}
@if (_endPage < _pages)
{
<button class="btn btn-secondary mr-1" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></button>
<button class="btn btn-secondary m-1" @onclick=@(async () => SetPagerSize("forward"))><span class="oi oi-media-skip-forward" title="forward" aria-hidden="true"></span></button>
}
@if (_endPage > 1)
{
<button class="btn btn-secondary mr-1" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></button>
<button class="btn btn-secondary m-1" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="last" aria-hidden="true"></span></button>
}
@if (_endPage > 1)
{

View File

@ -2,12 +2,13 @@
@inherits ModuleControlBase
@inject IRoleService RoleService
@inject IUserService UserService
@inject IStringLocalizer<PermissionGrid> Localizer
@inject IStringLocalizer<PermissionGrid> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_permissions != null)
{
<br />
<table class="table" style="width: 50%; min-width: 250px;">
<table class="table table-borderless" style="width: 50%; min-width: 250px;">
<tbody>
<tr>
<th scope="col">@Localizer["Role"]</th>
@ -33,7 +34,7 @@
</table>
@if (_users.Count != 0)
{
<table class="table" style="width: 50%; min-width: 250px;">
<table class="table table-borderless" style="width: 50%; min-width: 250px;">
<thead>
<tr>
<th scope="col">@Localizer["User"]</th>
@ -61,12 +62,12 @@
</tbody>
</table>
}
<table class="table" style="width: 50%; min-width: 250px;">
<table class="table table-borderless" style="width: 50%; min-width: 250px;">
<tbody>
<tr>
<td class="input-group">
<input type="text" name="Username" class="form-control" placeholder="@Localizer["Enter Username"]" @bind="@_username" />
<button type="button" class="btn btn-primary" @onclick="AddUser">@Localizer["Add"]</button>
<input type="text" name="Username" class="form-control" placeholder="@Localizer["Username.Enter"]" @bind="@_username" />
<button type="button" class="btn btn-primary" @onclick="AddUser">@SharedLocalizer["Add"]</button>
</td>
</tr>
</tbody>
@ -180,7 +181,7 @@
}
catch
{
_message = Localizer["Username Does Not Exist"];
_message = Localizer["Message.Username.DontExist"];
}
}

View File

@ -14,9 +14,9 @@
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
<br />
}
<div class="row justify-content-center" style="margin-bottom: 20px;">
<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">@Localizer["Synchronize Content"]</button>&nbsp;&nbsp;
<button type="button" class="btn btn-primary" @onclick="InsertImage">@Localizer["Insert Image"]</button>
<div class="d-flex justify-content-center mb-2">
<button type="button" class="btn btn-secondary" @onclick="RefreshRichText">@Localizer["SynchronizeContent"]</button>&nbsp;&nbsp;
<button type="button" class="btn btn-primary" @onclick="InsertImage">@Localizer["InsertImage"]</button>
@if (_filemanagervisible)
{
@((MarkupString)"&nbsp;&nbsp;")
@ -66,8 +66,8 @@
</div>
</TabPanel>
<TabPanel Name="Raw" Heading="Raw HTML Editor" ResourceKey="HtmlEditor">
<div class="row justify-content-center" style="margin-bottom: 20px;">
<button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">@Localizer["Synchronize Content"]</button>
<div class="d-flex justify-content-center mb-2">
<button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">@Localizer["SynchronizeContent"]</button>
</div>
@if (ReadOnly)
{
@ -143,6 +143,8 @@
await interop.LoadEditorContent(_editorElement, Content);
_content = Content; // raw HTML
// preserve a copy of the rich text content ( Quill sanitizes content so we need to retrieve it from the editor )
_original = await interop.GetHtml(_editorElement);
}
@ -200,7 +202,7 @@
}
else
{
_message = Localizer["You Must Select An Image To Insert"];
_message = Localizer["Message.Require.Image"];
}
}
else

View File

@ -1,14 +1,14 @@
@namespace Oqtane.Modules.Controls
@inherits LocalizableComponent
<div class="d-flex">
<div class="d-flex mt-2">
<div>
<a data-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
<a data-bs-toggle="collapse" class="app-link-unstyled" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
<h5>@_heading</h5>
</a>
</div>
<div class="ml-auto">
<a data-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
<div class="ms-auto">
<a data-bs-toggle="collapse" class="app-link-unstyled float-right" href="#@Name" aria-expanded="@_expanded" aria-controls="@Name" @onclick:preventDefault="true">
<i class="oi oi-chevron-bottom"></i>&nbsp;
</a>
</div>

View File

@ -10,13 +10,13 @@
<li class="nav-item" @key="tabPanel.Name">
@if (tabPanel.Name == ActiveTab)
{
<a class="nav-link active" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
<a class="nav-link active" data-bs-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
@tabPanel.DisplayHeading()
</a>
}
else
{
<a class="nav-link" data-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
<a class="nav-link" data-bs-toggle="tab" href="#@tabPanel.Name" role="tab" @onclick:preventDefault="true">
@tabPanel.DisplayHeading()
</a>
}

View File

@ -52,11 +52,11 @@
{
case true:
_src = "images/checked.png";
_title = Localizer["Permission Granted"];
_title = Localizer["PermissionGranted"];
break;
case false:
_src = "images/unchecked.png";
_title = Localizer["Permission Denied"];
_title = Localizer["PermissionDenied"];
break;
case null:
_src = "images/null.png";

View File

@ -7,12 +7,13 @@
@inject ISettingService SettingService
@inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_content != null)
{
<RichTextEditor Content="@_content" AllowFileManagement="@_allowfilemanagement" @ref="@RichTextEditorHtml"></RichTextEditor>
<button type="button" class="btn btn-success" @onclick="SaveContent">@Localizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
<button type="button" class="btn btn-success" @onclick="SaveContent">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@if (!string.IsNullOrEmpty(_content))
{
<br />
@ -96,7 +97,7 @@
catch (Exception ex)
{
await logger.LogError(ex, "Error Saving Content {Error}", ex.Message);
AddModuleMessage(Localizer["Error Saving Content"], MessageType.Error);
AddModuleMessage(Localizer["Error.Content.Save"], MessageType.Error);
}
}
}

View File

@ -2,17 +2,21 @@
@namespace Oqtane.Modules.HtmlText
@inherits ModuleBase
@inject IHtmlTextService HtmlTextService
@inject IStringLocalizer<Edit> Localizer
@((MarkupString)content)
@if (PageState.EditMode)
{
<br /><ActionLink Action="Edit" EditMode="true" ResourceKey="Edit" /><br /><br />
<br />
<ActionLink Action="Edit" EditMode="true" ResourceKey="Edit" />
<br />
<br />
}
@code {
public override List<Resource> Resources => new List<Resource>()
{
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};

View File

@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Oqtane.Services;
@ -9,34 +7,28 @@ namespace Oqtane.Modules.HtmlText.Services
{
public class HtmlTextService : ServiceBase, IHtmlTextService, IService
{
private readonly SiteState _siteState;
public HtmlTextService(HttpClient http, SiteState siteState) : base(http, siteState) {}
public HtmlTextService(HttpClient http, SiteState siteState) : base(http)
{
_siteState = siteState;
}
private string ApiUrl => CreateApiUrl("HtmlText", _siteState.Alias);
private string ApiUrl => CreateApiUrl("HtmlText");
public async Task<Models.HtmlText> GetHtmlTextAsync(int moduleId)
{
var htmltext = await GetJsonAsync<List<Models.HtmlText>>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", new Dictionary<string, int>() { { EntityNames.Module, moduleId } }));
return htmltext.FirstOrDefault();
return await GetJsonAsync<Models.HtmlText>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", EntityNames.Module, moduleId));
}
public async Task AddHtmlTextAsync(Models.HtmlText htmlText)
{
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", new Dictionary<string, int>() { { EntityNames.Module, htmlText.ModuleId } }), htmlText);
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", EntityNames.Module, htmlText.ModuleId), htmlText);
}
public async Task UpdateHtmlTextAsync(Models.HtmlText htmlText)
{
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", new Dictionary<string, int>() { { EntityNames.Module, htmlText.ModuleId } }), htmlText);
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", EntityNames.Module, htmlText.ModuleId), htmlText);
}
public async Task DeleteHtmlTextAsync(int moduleId)
{
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", new Dictionary<string, int>() { { EntityNames.Module, moduleId } }));
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", EntityNames.Module, moduleId));
}
}
}

View File

@ -3,16 +3,17 @@
@inject ISettingService SettingService
@implements Oqtane.Interfaces.ISettingsControl
@inject IStringLocalizer<Settings> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless">
<tr>
<td>
<td width="30%">
<Label For="files" ResourceKey="Allow File Management" HelpText="Specify If Editors Can Upload and Select Files">Allow File Management: </Label>
</td>
<td>
<select id="files" class="form-control" @bind="@_allowfilemanagement">
<option value="true">@Localizer["Yes"]</option>
<option value="false">@Localizer["No"]</option>
<select id="files" class="form-select" @bind="@_allowfilemanagement">
<option value="true">@SharedLocalizer["Yes"]</option>
<option value="false">@SharedLocalizer["No"]</option>
</select>
</td>
</tr>

View File

@ -84,11 +84,21 @@ namespace Oqtane.Modules
return NavigateUrl(path, "");
}
public string NavigateUrl(bool refresh)
{
return NavigateUrl(PageState.Page.Path, refresh);
}
public string NavigateUrl(string path, string parameters)
{
return Utilities.NavigateUrl(PageState.Alias.Path, path, parameters);
}
public string NavigateUrl(string path, bool refresh)
{
return Utilities.NavigateUrl(PageState.Alias.Path, path, refresh ? "refresh" : "");
}
public string EditUrl(string action)
{
return EditUrl(ModuleState.ModuleId, action);

View File

@ -5,7 +5,7 @@
<OutputType>Exe</OutputType>
<RazorLangVersion>3.0</RazorLangVersion>
<Configurations>Debug;Release</Configurations>
<Version>2.1.0</Version>
<Version>2.2.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -13,7 +13,7 @@
<Copyright>.NET Foundation</Copyright>
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.1.0</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v2.2.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
@ -33,4 +33,9 @@
<ItemGroup>
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
<Folder Include="Resources\Themes\Controls\Theme\" />
</ItemGroup>
</Project>

View File

@ -8,14 +8,11 @@ using System.Net.Http;
using System.Reflection;
using System.Runtime.Loader;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop;
using Oqtane.Interfaces;
using Oqtane.Modules;
using Oqtane.Providers;
using Oqtane.Services;
using Oqtane.Shared;
using Oqtane.UI;
@ -28,7 +25,8 @@ namespace Oqtane.Client
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
HttpClient httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)};
var httpClient = new HttpClient {BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)};
builder.Services.AddSingleton(httpClient);
builder.Services.AddOptions();
@ -37,38 +35,10 @@ namespace Oqtane.Client
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
// register auth services
builder.Services.AddAuthorizationCore();
builder.Services.AddScoped<IdentityAuthenticationStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<IdentityAuthenticationStateProvider>());
builder.Services.AddOqtaneAuthorization();
// register scoped core services
builder.Services.AddScoped<SiteState>();
builder.Services.AddScoped<IInstallationService, InstallationService>();
builder.Services.AddScoped<IModuleDefinitionService, ModuleDefinitionService>();
builder.Services.AddScoped<IThemeService, ThemeService>();
builder.Services.AddScoped<IAliasService, AliasService>();
builder.Services.AddScoped<ITenantService, TenantService>();
builder.Services.AddScoped<ISiteService, SiteService>();
builder.Services.AddScoped<IPageService, PageService>();
builder.Services.AddScoped<IModuleService, ModuleService>();
builder.Services.AddScoped<IPageModuleService, PageModuleService>();
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IProfileService, ProfileService>();
builder.Services.AddScoped<IRoleService, RoleService>();
builder.Services.AddScoped<IUserRoleService, UserRoleService>();
builder.Services.AddScoped<ISettingService, SettingService>();
builder.Services.AddScoped<IPackageService, PackageService>();
builder.Services.AddScoped<ILogService, LogService>();
builder.Services.AddScoped<IJobService, JobService>();
builder.Services.AddScoped<IJobLogService, JobLogService>();
builder.Services.AddScoped<INotificationService, NotificationService>();
builder.Services.AddScoped<IFolderService, FolderService>();
builder.Services.AddScoped<IFileService, FileService>();
builder.Services.AddScoped<ISiteTemplateService, SiteTemplateService>();
builder.Services.AddScoped<ISqlService, SqlService>();
builder.Services.AddScoped<ISystemService, SystemService>();
builder.Services.AddScoped<ILocalizationService, LocalizationService>();
builder.Services.AddScoped<ILanguageService, LanguageService>();
builder.Services.AddOqtaneScopedServices();
await LoadClientAssemblies(httpClient);
@ -76,38 +46,15 @@ namespace Oqtane.Client
foreach (var assembly in assemblies)
{
// dynamically register module services
var implementationTypes = assembly.GetInterfaces<IService>();
foreach (var implementationType in implementationTypes)
{
if (implementationType.AssemblyQualifiedName != null)
{
var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}"));
builder.Services.AddScoped(serviceType ?? implementationType, implementationType);
}
}
RegisterModuleServices(assembly, builder.Services);
// register client startup services
var startUps = assembly.GetInstances<IClientStartup>();
foreach (var startup in startUps)
{
startup.ConfigureServices(builder.Services);
}
RegisterClientStartups(assembly, builder.Services);
}
var host = builder.Build();
var jsRuntime = host.Services.GetRequiredService<IJSRuntime>();
var interop = new Interop(jsRuntime);
var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName);
var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie).UICultures[0].Value;
var localizationService = host.Services.GetRequiredService<ILocalizationService>();
var cultures = await localizationService.GetCulturesAsync();
if (culture == null || !cultures.Any(c => c.Name.Equals(culture, StringComparison.OrdinalIgnoreCase)))
{
culture = cultures.Single(c => c.IsDefault).Name;
}
SetCulture(culture);
await SetCultureFromLocalizationCookie(host.Services);
ServiceActivator.Configure(host.Services);
@ -163,6 +110,45 @@ namespace Oqtane.Client
}
}
private static void RegisterModuleServices(Assembly assembly, IServiceCollection services)
{
var implementationTypes = assembly.GetInterfaces<IService>();
foreach (var implementationType in implementationTypes)
{
if (implementationType.AssemblyQualifiedName != null)
{
var serviceType = Type.GetType(implementationType.AssemblyQualifiedName.Replace(implementationType.Name, $"I{implementationType.Name}"));
services.AddScoped(serviceType ?? implementationType, implementationType);
}
}
}
private static void RegisterClientStartups(Assembly assembly, IServiceCollection services)
{
var startUps = assembly.GetInstances<IClientStartup>();
foreach (var startup in startUps)
{
startup.ConfigureServices(services);
}
}
private static async Task SetCultureFromLocalizationCookie(IServiceProvider serviceProvider)
{
var jsRuntime = serviceProvider.GetRequiredService<IJSRuntime>();
var interop = new Interop(jsRuntime);
var localizationCookie = await interop.GetCookie(CookieRequestCultureProvider.DefaultCookieName);
var culture = CookieRequestCultureProvider.ParseCookieValue(localizationCookie)?.UICultures?[0].Value;
var localizationService = serviceProvider.GetRequiredService<ILocalizationService>();
var cultures = await localizationService.GetCulturesAsync();
if (culture == null || !cultures.Any(c => c.Name.Equals(culture, StringComparison.OrdinalIgnoreCase)))
{
culture = cultures.Single(c => c.IsDefault).Name;
}
SetCulture(culture);
}
private static void SetCulture(string culture)
{
var cultureInfo = CultureInfo.GetCultureInfo(culture);

View File

@ -30,14 +30,11 @@ namespace Oqtane.Providers
// get HttpClient lazily from IServiceProvider as you cannot use standard dependency injection due to the AuthenticationStateProvider being initialized prior to NavigationManager(https://github.com/aspnet/AspNetCore/issues/11867 )
var http = _serviceProvider.GetRequiredService<HttpClient>();
// get alias as SiteState has not been initialized ( cannot use AliasService as it is not yet registered )
var path = new Uri(_navigationManager.Uri).LocalPath.Substring(1);
var alias = await http.GetFromJsonAsync<Alias>($"/api/Alias/name/?path={WebUtility.UrlEncode(path)}&sync={DateTime.UtcNow.ToString("yyyyMMddHHmmssfff")}");
// get user
User user = await http.GetFromJsonAsync<User>(Utilities.TenantUrl(alias, "/api/User/authenticate"));
var siteState = _serviceProvider.GetRequiredService<SiteState>();
User user = await http.GetFromJsonAsync<User>(Utilities.TenantUrl(siteState.Alias, "/api/User/authenticate"));
if (user.IsAuthenticated)
{
identity = UserSecurity.CreateClaimsIdentity(alias, user);
identity = UserSecurity.CreateClaimsIdentity(siteState.Alias, user);
}
return new AuthenticationState(new ClaimsPrincipal(identity));

View File

@ -0,0 +1,132 @@
<?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 xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<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="Server.Text" xml:space="preserve">
<value>Server:</value>
</data>
<data name="Server.HelpText" xml:space="preserve">
<value>Enter the database server</value>
</data>
<data name="Database.Text" xml:space="preserve">
<value>Database:</value>
</data>
<data name="Database.HelpText" xml:space="preserve">
<value>Enter the name of the database</value>
</data>
</root>

View File

@ -0,0 +1,150 @@
<?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 xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<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="Server.Text" xml:space="preserve">
<value>Server:</value>
</data>
<data name="Server.HelpText" xml:space="preserve">
<value>Enter the database server</value>
</data>
<data name="Port.Text" xml:space="preserve">
<value>Port:</value>
</data>
<data name="Port.HelpText" xml:space="preserve">
<value>Enter the port used to connect to the server</value>
</data>
<data name="Database.Text" xml:space="preserve">
<value>Database:</value>
</data>
<data name="Database.HelpText" xml:space="preserve">
<value>Enter the name of the database</value>
</data>
<data name="Uid.Text" xml:space="preserve">
<value>User Id:</value>
</data>
<data name="Uid.HelpText" xml:space="preserve">
<value>Enter the username to use for the database</value>
</data>
<data name="Pwd.Text" xml:space="preserve">
<value>Password:</value>
</data>
<data name="Pwd.HelpText" xml:space="preserve">
<value>Enter the password to use for the database</value>
</data>
</root>

View File

@ -0,0 +1,156 @@
<?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="Server.Text" xml:space="preserve">
<value>Server:</value>
</data>
<data name="Server.HelpText" xml:space="preserve">
<value>Enter the database server</value>
</data>
<data name="Port.Text" xml:space="preserve">
<value>Port:</value>
</data>
<data name="Port.HelpText" xml:space="preserve">
<value>Enter the port used to connect to the server</value>
</data>
<data name="Database.Text" xml:space="preserve">
<value>Database:</value>
</data>
<data name="Database.HelpText" xml:space="preserve">
<value>Enter the name of the database</value>
</data>
<data name="IntegratedSecurity.Text" xml:space="preserve">
<value>Integrated Security:</value>
</data>
<data name="IntegratedSecurity.HelpText" xml:space="preserve">
<value>Select if you want integrated security or not</value>
</data>
<data name="Uid.Text" xml:space="preserve">
<value>User Id:</value>
</data>
<data name="Uid.HelpText" xml:space="preserve">
<value>Enter the username to use for the database</value>
</data>
<data name="Pwd.Text" xml:space="preserve">
<value>Password:</value>
</data>
<data name="Pwd.HelpText" xml:space="preserve">
<value>Enter the password to use for the database</value>
</data>
</root>

View File

@ -0,0 +1,150 @@
<?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="Server.Text" xml:space="preserve">
<value>Server:</value>
</data>
<data name="Server.HelpText" xml:space="preserve">
<value>Enter the database server</value>
</data>
<data name="Database.Text" xml:space="preserve">
<value>Database:</value>
</data>
<data name="Database.HelpText" xml:space="preserve">
<value>Enter the name of the database</value>
</data>
<data name="IntegratedSecurity.Text" xml:space="preserve">
<value>Integrated Security:</value>
</data>
<data name="IntegratedSecurity.HelpText" xml:space="preserve">
<value>Select if you want integrated security or not</value>
</data>
<data name="Uid.Text" xml:space="preserve">
<value>User Id:</value>
</data>
<data name="Uid.HelpText" xml:space="preserve">
<value>Enter the username to use for the database</value>
</data>
<data name="Pwd.Text" xml:space="preserve">
<value>Password:</value>
</data>
<data name="Pwd.HelpText" xml:space="preserve">
<value>Enter the password to use for the database</value>
</data>
</root>

View File

@ -0,0 +1,126 @@
<?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 xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
<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="Server.Text" xml:space="preserve">
<value>File Name:</value>
</data>
<data name="Server.HelpText" xml:space="preserve">
<value>Enter the file name to use for the database</value>
</data>
</root>

View File

@ -0,0 +1,141 @@
<?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="DatabaseConfig" xml:space="preserve">
<value>Database Configuration</value>
</data>
<data name="DatabaseType" xml:space="preserve">
<value>Database Type:</value>
</data>
<data name="ApplicationAdmin" xml:space="preserve">
<value>Application Administrator</value>
</data>
<data name="InstallNow" xml:space="preserve">
<value>Install Now</value>
</data>
<data name="Error.DbConfig.Load" xml:space="preserve">
<value>Error loading Database Configuration Control</value>
</data>
<data name="Message.Require.DbInfo" xml:space="preserve">
<value>Please Enter All Required Fields. Ensure Passwords Match And Are Greater Than 5 Characters In Length. Ensure Email Address Provided Is Valid.</value>
</data>
<data name="Register" xml:space="preserve">
<value>Please Register Me For Major Product Updates And Security Bulletins</value>
</data>
</root>

View File

@ -0,0 +1,120 @@
<?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>
</root>

View File

@ -0,0 +1,123 @@
<?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="Error.Module.Load" xml:space="preserve">
<value>A Problem Was Encountered Loading Module {0}</value>
</data>
</root>

View File

@ -0,0 +1,159 @@
<?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="Folder.Select" xml:space="preserve">
<value>Select Folder</value>
</data>
<data name="Message.Required.UrlFolder" xml:space="preserve">
<value>You Must Enter A Url And Select A Folder</value>
</data>
<data name="Message.Download.InvalidExtension" xml:space="preserve">
<value>File Could Not Be Downloaded From Url Due To Its File Extension</value>
</data>
<data name="Message.Required.UrlName" xml:space="preserve">
<value>You Must Enter A Url With A Valid File Name</value>
</data>
<data name="Success.Download.File" xml:space="preserve">
<value>File Downloaded Successfully From Url</value>
</data>
<data name="Error.Download.InvalidUrl" xml:space="preserve">
<value>Error Downloading File From Url. Please Verify That The Url Is Valid.</value>
</data>
<data name="Upload.HelpText" xml:space="preserve">
<value>Upload the file you want</value>
</data>
<data name="Url.HelpText" xml:space="preserve">
<value>Enter the url of the file you wish to download</value>
</data>
<data name="Folder.HelpText" xml:space="preserve">
<value>Select the folder to save the file in</value>
</data>
<data name="Upload.Text" xml:space="preserve">
<value>Upload: </value>
</data>
<data name="Url.Text" xml:space="preserve">
<value>Url: </value>
</data>
<data name="Folder.Text" xml:space="preserve">
<value>Folder: </value>
</data>
<data name="UploadFiles.Heading" xml:space="preserve">
<value>Upload Files</value>
</data>
</root>

View File

@ -0,0 +1,147 @@
<?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="Folder.Text" xml:space="preserve">
<value>Folder: </value>
</data>
<data name="Error.File.Load" xml:space="preserve">
<value>Error Loading File</value>
</data>
<data name="Message.File.InvalidName" xml:space="preserve">
<value>File Name Not Valid</value>
</data>
<data name="Error.File.Save" xml:space="preserve">
<value>Error Saving File</value>
</data>
<data name="Name.HelpText" xml:space="preserve">
<value>The name of the file</value>
</data>
<data name="Folder.HelpText" xml:space="preserve">
<value>The folder where the file is located</value>
</data>
<data name="Size.HelpText" xml:space="preserve">
<value>The size of the file (in bytes)</value>
</data>
<data name="Name.Text" xml:space="preserve">
<value>Name: </value>
</data>
<data name="Size.Text" xml:space="preserve">
<value>Size: </value>
</data>
</root>

View File

@ -0,0 +1,168 @@
<?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="Name.Text" xml:space="preserve">
<value>Name: </value>
</data>
<data name="NoParent" xml:space="preserve">
<value>No Parent</value>
</data>
<data name="Error.Folder.Load" xml:space="preserve">
<value>Error Loading Folder</value>
</data>
<data name="Message.Required.FolderParent" xml:space="preserve">
<value>Folders Must Have A Parent And A Name</value>
</data>
<data name="Message.Folder.InvalidName" xml:space="preserve">
<value>Folder Name Not Valid.</value>
</data>
<data name="Error.Folder.Save" xml:space="preserve">
<value>Error Saving Folder</value>
</data>
<data name="Message.Folder.Files.InvalidDelete" xml:space="preserve">
<value>Folder Has Files And Cannot Be Deleted</value>
</data>
<data name="Message.Folder.Subfolders.InvalidDelete" xml:space="preserve">
<value>Folder Has Subfolders And Cannot Be Deleted</value>
</data>
<data name="Error.Folder.Delete" xml:space="preserve">
<value>Error Deleting Folder</value>
</data>
<data name="Parent.HelpText" xml:space="preserve">
<value>Select the parent folder</value>
</data>
<data name="Name.HelpText" xml:space="preserve">
<value>Enter the folder name</value>
</data>
<data name="Permissions.HelpText" xml:space="preserve">
<value>Select the permissions you want for the folder</value>
</data>
<data name="Parent.Text" xml:space="preserve">
<value>Parent: </value>
</data>
<data name="Permissions.Text" xml:space="preserve">
<value>Permissions: </value>
</data>
<data name="DeleteFolder.Header" xml:space="preserve">
<value>Delete Folder</value>
</data>
<data name="DeleteFolder.Message" xml:space="preserve">
<value>Are You Sure You Wish To Delete This Folder?</value>
</data>
</root>

View File

@ -0,0 +1,162 @@
<?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="Error.File.Load" xml:space="preserve">
<value>Error Loading Files</value>
</data>
<data name="UploadFiles.Heading" xml:space="preserve">
<value>Upload Files</value>
</data>
<data name="Confirm.File.Delete" xml:space="preserve">
<value>Are You Sure You Wish To Delete {0}?</value>
</data>
<data name="NoFiles" xml:space="preserve">
<value>No Files Exist In Selected Folder</value>
</data>
<data name="Success.File.Delete" xml:space="preserve">
<value>File {0} Deleted</value>
</data>
<data name="Error.File.Delete" xml:space="preserve">
<value>Error Deleting File {0}</value>
</data>
<data name="EditFolder.Text" xml:space="preserve">
<value>Edit Folder</value>
</data>
<data name="AddFolder.Text" xml:space="preserve">
<value>Add Folder</value>
</data>
<data name="Details.Text" xml:space="preserve">
<value>Edit</value>
</data>
<data name="DeleteFile.Header" xml:space="preserve">
<value>Delete File</value>
</data>
<data name="Folder" xml:space="preserve">
<value>Folder</value>
</data>
<data name="Modified" xml:space="preserve">
<value>Modified</value>
</data>
<data name="Size" xml:space="preserve">
<value>Size</value>
</data>
<data name="Type" xml:space="preserve">
<value>Type</value>
</data>
</root>

View File

@ -0,0 +1,189 @@
<?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="Name.Text" xml:space="preserve">
<value>Name: </value>
</data>
<data name="Minute(s)" xml:space="preserve">
<value>Minute(s)</value>
</data>
<data name="Hour(s)" xml:space="preserve">
<value>Hour(s)</value>
</data>
<data name="Day(s)" xml:space="preserve">
<value>Day(s)</value>
</data>
<data name="Month(s)" xml:space="preserve">
<value>Month(s)</value>
</data>
<data name="Error.Job.Load" xml:space="preserve">
<value>Error Loading Job</value>
</data>
<data name="Error.Job.Update" xml:space="preserve">
<value>Error Updating Job</value>
</data>
<data name="Message.Required.JobInfo" xml:space="preserve">
<value>You Must Provide The Job Name, Type, Frequency, and Retention</value>
</data>
<data name="Name.HelpText" xml:space="preserve">
<value>Enter the job name</value>
</data>
<data name="Type.HelpText" xml:space="preserve">
<value>The fully qualified job type name</value>
</data>
<data name="Enabled.HelpText" xml:space="preserve">
<value>Select whether you want the job enabled or not</value>
</data>
<data name="RunsEvery.HelpText" xml:space="preserve">
<value>Select how often you want the job to run</value>
</data>
<data name="Starting.HelpText" xml:space="preserve">
<value>What time do you want the job to start</value>
</data>
<data name="Ending.HelpText" xml:space="preserve">
<value>When do you want the job to end</value>
</data>
<data name="RetentionLog.HelpText" xml:space="preserve">
<value>Number of log entries to retain for this job</value>
</data>
<data name="NextExecution.HelpText" xml:space="preserve">
<value>Next execution for this job.</value>
</data>
<data name="Type.Text" xml:space="preserve">
<value>Type: </value>
</data>
<data name="Enabled.Text" xml:space="preserve">
<value>Enabled? </value>
</data>
<data name="RunsEvery.Text" xml:space="preserve">
<value>Runs Every: </value>
</data>
<data name="Starting.Text" xml:space="preserve">
<value>Starting: </value>
</data>
<data name="Ending.Text" xml:space="preserve">
<value>Ending: </value>
</data>
<data name="RetentionLog.Text" xml:space="preserve">
<value>Retention Log (Items): </value>
</data>
<data name="NextExecution.Text" xml:space="preserve">
<value>Next Execution: </value>
</data>
</root>

View File

@ -0,0 +1,171 @@
<?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="NextExecution" xml:space="preserve">
<value>Next Execution</value>
</data>
<data name="Disabled" xml:space="preserve">
<value>Disabled</value>
</data>
<data name="Executing" xml:space="preserve">
<value>Executing</value>
</data>
<data name="Idle" xml:space="preserve">
<value>Idle</value>
</data>
<data name="Every" xml:space="preserve">
<value>Every</value>
</data>
<data name="Minute" xml:space="preserve">
<value>Minute</value>
</data>
<data name="Hour" xml:space="preserve">
<value>Hour</value>
</data>
<data name="Day" xml:space="preserve">
<value>Day</value>
</data>
<data name="Month" xml:space="preserve">
<value>Month</value>
</data>
<data name="s" xml:space="preserve">
<value>s</value>
</data>
<data name="Error.Job.Delete" xml:space="preserve">
<value>Error Deleting Job</value>
</data>
<data name="ViewJobs.Text" xml:space="preserve">
<value>View Logs</value>
</data>
<data name="DeleteJob.Header" xml:space="preserve">
<value>Delete Job</value>
</data>
<data name="DeleteJob.Message" xml:space="preserve">
<value>Are You Sure You Wish To Delete This Job?</value>
</data>
<data name="Frequency" xml:space="preserve">
<value>Frequency</value>
</data>
<data name="Start" xml:space="preserve">
<value>Start</value>
</data>
<data name="Stop" xml:space="preserve">
<value>Stop</value>
</data>
</root>

View File

@ -0,0 +1,135 @@
<?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="Executing" xml:space="preserve">
<value>Executing</value>
</data>
<data name="Started" xml:space="preserve">
<value>Started</value>
</data>
<data name="Finished" xml:space="preserve">
<value>Finished</value>
</data>
<data name="Succeeded" xml:space="preserve">
<value>Succeeded</value>
</data>
<data name="Failed" xml:space="preserve">
<value>Failed</value>
</data>
</root>

View File

@ -0,0 +1,156 @@
<?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="The Only Supported Culture That Has Been Defined Is English" xml:space="preserve">
<value>The Only Supported Culture That Has Been Defined Is English</value>
</data>
<data name="Error.Language.Add" xml:space="preserve">
<value>Error Adding Language</value>
</data>
<data name="Name.HelpText" xml:space="preserve">
<value>Name Of The Langauage</value>
</data>
<data name="IsDefault.HelpText" xml:space="preserve">
<value>Indicates Whether Or Not This Language Is The Default For The Site</value>
</data>
<data name="Name.Text" xml:space="preserve">
<value>Name:</value>
</data>
<data name="IsDefault.Text" xml:space="preserve">
<value>Default?</value>
</data>
<data name="AllLanguages" xml:space="preserve">
<value>All The Installed Languages Have Been Added.</value>
</data>
<data name="Error.Language.Download" xml:space="preserve">
<value>Error Downloading Translation</value>
</data>
<data name="OnlyEnglish" xml:space="preserve">
<value>The Only Installed Language Is English</value>
</data>
<data name="Success.Language.Download" xml:space="preserve">
<value>Translation Downloaded Successfully. Click Install To Complete Installation.</value>
</data>
<data name="Success.Language.Install" xml:space="preserve">
<value>Translations Installed Successfully. You Must &lt;a href={0}&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data>
<data name="Search.NoResults" xml:space="preserve">
<value>No Translations Match The Criteria Provided Or Package Service Is Disabled</value>
</data>
</root>

View File

@ -0,0 +1,144 @@
<?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="Code" xml:space="preserve">
<value>Code</value>
</data>
<data name="Confirm.Language.Delete" xml:space="preserve">
<value>Are You Sure You Wish To Delete The {0} Language?</value>
</data>
<data name="Error.Language.Delete" xml:space="preserve">
<value>Error Deleting Language</value>
</data>
<data name="AddLanguage.Text" xml:space="preserve">
<value>Add Language</value>
</data>
<data name="DeleteLanguage.Header" xml:space="preserve">
<value>Delete Language</value>
</data>
<data name="Error.Language.Download" xml:space="preserve">
<value>Error Downloading Translation</value>
</data>
<data name="Success.Language.Install" xml:space="preserve">
<value>Translation Installed Successfully. You Must &lt;a href={0}&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data>
<data name="Default" xml:space="preserve">
<value>Default</value>
</data>
</root>

View File

@ -0,0 +1,141 @@
<?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="RememberMe" xml:space="preserve">
<value>Remember Me?</value>
</data>
<data name="ForgotPassword" xml:space="preserve">
<value>Forgot Password</value>
</data>
<data name="Success.Account.Verified" xml:space="preserve">
<value>User Account Verified Successfully. You Can Now Login With Your Username And Password Below.</value>
</data>
<data name="Message.Account.NotVerfied" xml:space="preserve">
<value>User Account Could Not Be Verified. Please Contact Your Administrator For Further Instructions.</value>
</data>
<data name="Error.Login.Fail" xml:space="preserve">
<value>Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email.</value>
</data>
<data name="Message.Required.UserInfo" xml:space="preserve">
<value>Please Provide Your Username And Password</value>
</data>
<data name="Info.SignedIn" xml:space="preserve">
<value>You Are Already Signed In</value>
</data>
</root>

View File

@ -0,0 +1,210 @@
<?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="Url.Text" xml:space="preserve">
<value>Url: </value>
</data>
<data name="Error Loading Log" xml:space="preserve">
<value>Error Loading Log</value>
</data>
<data name="DateTime.HelpText" xml:space="preserve">
<value>The date and time of this log</value>
</data>
<data name="Level.HelpText" xml:space="preserve">
<value>The level of this log</value>
</data>
<data name="Feature.HelpText" xml:space="preserve">
<value>The feature that was affected</value>
</data>
<data name="Function.HelpText" xml:space="preserve">
<value>The function that was performed</value>
</data>
<data name="Category.HelpText" xml:space="preserve">
<value>The categories that were affected</value>
</data>
<data name="Page.HelpText" xml:space="preserve">
<value>The page that was affected</value>
</data>
<data name="Module.HelpText" xml:space="preserve">
<value>The module that was affected</value>
</data>
<data name="User.HelpText" xml:space="preserve">
<value>The user that caused this log</value>
</data>
<data name="Url.HelpText" xml:space="preserve">
<value>The url the log comes from</value>
</data>
<data name="Template.HelpText" xml:space="preserve">
<value>What the log is about</value>
</data>
<data name="Message.HelpText" xml:space="preserve">
<value>The message that the system generated</value>
</data>
<data name="Exception.HelpText" xml:space="preserve">
<value>The exceptions generated by the system</value>
</data>
<data name="Properties.HelpText" xml:space="preserve">
<value>The properties that were affected</value>
</data>
<data name="Server.HelpText" xml:space="preserve">
<value>The server that was affected</value>
</data>
<data name="DateTime.Text" xml:space="preserve">
<value>Date/Time: </value>
</data>
<data name="Level.Text" xml:space="preserve">
<value>Level: </value>
</data>
<data name="Feature.Text" xml:space="preserve">
<value>Feature: </value>
</data>
<data name="Function.Text" xml:space="preserve">
<value>Function: </value>
</data>
<data name="Category.Text" xml:space="preserve">
<value>Category: </value>
</data>
<data name="Page.Text" xml:space="preserve">
<value>Page: </value>
</data>
<data name="Module.Text" xml:space="preserve">
<value>Module: </value>
</data>
<data name="User.Text" xml:space="preserve">
<value>User: </value>
</data>
<data name="Template.Text" xml:space="preserve">
<value>Template: </value>
</data>
<data name="Message.Text" xml:space="preserve">
<value>Message: </value>
</data>
<data name="Exception.Text" xml:space="preserve">
<value>Exception: </value>
</data>
<data name="Properties.Text" xml:space="preserve">
<value>Properties: </value>
</data>
<data name="Server.Text" xml:space="preserve">
<value>Server: </value>
</data>
<data name="Error.Log.Load" xml:space="preserve">
<value>Error Loading Log</value>
</data>
</root>

View File

@ -0,0 +1,192 @@
<?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="Level.Text" xml:space="preserve">
<value>Level: </value>
</data>
<data name="Function.Text" xml:space="preserve">
<value>Function: </value>
</data>
<data name="AllLevels" xml:space="preserve">
<value>All Levels</value>
</data>
<data name="Trace" xml:space="preserve">
<value>Trace</value>
</data>
<data name="Debug" xml:space="preserve">
<value>Debug</value>
</data>
<data name="Information" xml:space="preserve">
<value>Information</value>
</data>
<data name="Warning" xml:space="preserve">
<value>Warning</value>
</data>
<data name="Error" xml:space="preserve">
<value>Error</value>
</data>
<data name="Critical" xml:space="preserve">
<value>Critical</value>
</data>
<data name="AllFunctions" xml:space="preserve">
<value>All Functions</value>
</data>
<data name="Read" xml:space="preserve">
<value>Read</value>
</data>
<data name="Security" xml:space="preserve">
<value>Security</value>
</data>
<data name="Other" xml:space="preserve">
<value>Other</value>
</data>
<data name="Date" xml:space="preserve">
<value>Date</value>
</data>
<data name="Level" xml:space="preserve">
<value>Level</value>
</data>
<data name="Feature" xml:space="preserve">
<value>Feature</value>
</data>
<data name="Function" xml:space="preserve">
<value>Function</value>
</data>
<data name="NoLogs" xml:space="preserve">
<value>No Logs Match The Criteria Specified</value>
</data>
<data name="Error.Log.Load" xml:space="preserve">
<value>Error Loading Logs</value>
</data>
<data name="Level.HelpText" xml:space="preserve">
<value>Select the log level for event log items</value>
</data>
<data name="Function.HelpText" xml:space="preserve">
<value>Select the function for event log items</value>
</data>
<data name="Rows.HelpText" xml:space="preserve">
<value>Select the maximum number of event log items to review. Please note that if you choose more than 10 items the information will be split into pages.</value>
</data>
<data name="Rows.Text" xml:space="preserve">
<value>Maximum Items: </value>
</data>
<data name="Create" xml:space="preserve">
<value>Create</value>
</data>
</root>

View File

@ -0,0 +1,177 @@
<?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="Template.Text" xml:space="preserve">
<value>Template: </value>
</data>
<data name="Template.Select" xml:space="preserve">
<value>Select Template</value>
</data>
<data name="Module.Create" xml:space="preserve">
<value>Create Module</value>
</data>
<data name="Module.Activate" xml:space="preserve">
<value>Activate Module</value>
</data>
<data name="Info.Module.Creator" xml:space="preserve">
<value>Please Note That The Module Creator Is Only Intended To Be Used In A Development Environment</value>
</data>
<data name="Info.Module.Activate" xml:space="preserve">
<value>Once You Have Compiled The Module And Restarted The Application You Can Activate The Module Below</value>
</data>
<data name="Success.Module.Create" 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 &lt;a href={0}&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data>
<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>
</data>
<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>
</data>
<data name="ModuleName.HelpText" xml:space="preserve">
<value>Enter a name for this module. It should not contain spaces or punctuation.</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>
</root>

Some files were not shown because too many files have changed in this diff Show More