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 IInstallationService InstallationService
@inject IJSRuntime JSRuntime
@inject SiteState SiteState
@if (_initialized) @if (_initialized)
{ {
@ -26,15 +28,29 @@
} }
@code { @code {
private Installation _installation; private bool _initialized = false;
private bool _initialized; private Installation _installation = new Installation { Success = false, Message = "" };
private PageState PageState { get; set; } private PageState PageState { get; set; }
protected override async Task OnParametersSetAsync() protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
if (firstRender && !_initialized)
{
var interop = new Interop(JSRuntime);
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
_installation = await InstallationService.IsInstalled(); _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; _initialized = true;
StateHasChanged();
}
} }
private void ChangeState(PageState pageState) 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: 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 @namespace Oqtane.Installer.Controls
@implements Oqtane.Interfaces.IDatabaseConfigControl @implements Oqtane.Interfaces.IDatabaseConfigControl
@inject IStringLocalizer<Installer> Localizer @inject IStringLocalizer<Installer> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@{ @{
foreach (var field in _connectionStringFields) foreach (var field in _connectionStringFields)
@ -38,8 +39,8 @@
</td> </td>
<td> <td>
<select id="@fieldId" class="custom-select" @bind="@field.Value"> <select id="@fieldId" class="custom-select" @bind="@field.Value">
<option value="true" selected>@Localizer["True"]</option> <option value="true" selected>@SharedLocalizer["True"]</option>
<option value="false">@Localizer["False"]</option> <option value="false">@SharedLocalizer["False"]</option>
</select> </select>
</td> </td>
</tr> </tr>

View File

@ -1,6 +1,7 @@
@namespace Oqtane.Installer.Controls @namespace Oqtane.Installer.Controls
@implements Oqtane.Interfaces.IDatabaseConfigControl @implements Oqtane.Interfaces.IDatabaseConfigControl
@inject IStringLocalizer<Installer> Localizer @inject IStringLocalizer<Installer> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@{ @{
foreach (var field in _connectionStringFields) foreach (var field in _connectionStringFields)
@ -38,8 +39,8 @@
</td> </td>
<td> <td>
<select id="@fieldId" class="custom-select" @bind="@field.Value"> <select id="@fieldId" class="custom-select" @bind="@field.Value">
<option value="true" selected>@Localizer["True"]</option> <option value="true" selected>@SharedLocalizer["True"]</option>
<option value="false">@Localizer["False"]</option> <option value="false">@SharedLocalizer["False"]</option>
</select> </select>
</td> </td>
</tr> </tr>

View File

@ -7,18 +7,19 @@
@inject IDatabaseService DatabaseService @inject IDatabaseService DatabaseService
@inject IJSRuntime JSRuntime @inject IJSRuntime JSRuntime
@inject IStringLocalizer<Installer> Localizer @inject IStringLocalizer<Installer> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="mx-auto text-center"> <div class="mx-auto text-center">
<img src="oqtane-black.png" /> <img src="oqtane-black.png" />
<div style="font-weight: bold">@Localizer["Version:"] @Constants.Version</div> <div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version</div>
</div> </div>
</div> </div>
<hr class="app-rule" /> <hr class="app-rule" />
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="col text-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;"> <table class="form-group" cellpadding="4" cellspacing="4" style="margin: auto;">
<tbody> <tbody>
<tr> <tr>
@ -30,10 +31,17 @@
@if (_databases != null) @if (_databases != null)
{ {
foreach (var database in _databases) foreach (var database in _databases)
{
if (database.IsDefault)
{
<option value="@database.Name" selected>@Localizer[@database.Name]</option>
}
else
{ {
<option value="@database.Name">@Localizer[@database.Name]</option> <option value="@database.Name">@Localizer[@database.Name]</option>
} }
} }
}
</select> </select>
</td> </td>
</tr> </tr>
@ -47,7 +55,7 @@
</table> </table>
</div> </div>
<div class="col text-center"> <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;"> <table class="form-group" cellpadding="4" cellspacing="4" style="margin: auto;">
<tbody> <tbody>
<tr> <tr>
@ -94,6 +102,11 @@
</div> </div>
<div class="app-progress-indicator" style="@_loadingDisplay"></div> <div class="app-progress-indicator" style="@_loadingDisplay"></div>
</div> </div>
<div class="row">
<div class="mx-auto text-center">
<input type="checkbox" @bind="@_register" /> @Localizer["Register"]
</div>
</div>
</div> </div>
@code { @code {
@ -107,6 +120,7 @@
private string _hostPassword = string.Empty; private string _hostPassword = string.Empty;
private string _confirmPassword = string.Empty; private string _confirmPassword = string.Empty;
private string _hostEmail = string.Empty; private string _hostEmail = string.Empty;
private bool _register = true;
private string _message = string.Empty; private string _message = string.Empty;
private string _loadingDisplay = "display: none;"; private string _loadingDisplay = "display: none;";
@ -126,7 +140,7 @@
} }
catch catch
{ {
_message = Localizer["Error loading Database Configuration Control"]; _message = Localizer["Error.DbConfig.Load"];
} }
} }
@ -162,7 +176,7 @@
connectionString = databaseConfigControl.GetConnectionString(); connectionString = databaseConfigControl.GetConnectionString();
} }
if (connectionString != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "") if (connectionString != "" && _hostUsername != "" && _hostPassword.Length >= 6 && _hostPassword == _confirmPassword && _hostEmail != "" && _hostEmail.Contains("@"))
{ {
_loadingDisplay = ""; _loadingDisplay = "";
StateHasChanged(); StateHasChanged();
@ -181,7 +195,8 @@
HostName = UserNames.Host, HostName = UserNames.Host,
TenantName = TenantNames.Master, TenantName = TenantNames.Master,
IsNewTenant = true, IsNewTenant = true,
SiteName = Constants.DefaultSite SiteName = Constants.DefaultSite,
Register = _register
}; };
var installation = await InstallationService.Install(config); var installation = await InstallationService.Install(config);
@ -197,7 +212,7 @@
} }
else 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 @inherits ModuleBase
@inject IPageService PageService @inject IPageService PageService
@inject IUserService UserService @inject IUserService UserService
@inject IStringLocalizer<SharedResources> Localizer @inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="row"> <div class="row">
@foreach (var p in _pages) @foreach (var p in _pages)
@ -12,7 +12,7 @@
string url = NavigateUrl(p.Path); string url = NavigateUrl(p.Path);
<div class="col-md-2 mx-auto text-center"> <div class="col-md-2 mx-auto text-center">
<NavLink class="nav-link" href="@url" Match="NavLinkMatch.All"> <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> </NavLink>
</div> </div>
} }

View File

@ -11,7 +11,7 @@
Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId); Module module = await ModuleService.GetModuleAsync(ModuleState.ModuleId);
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) 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); AddModuleMessage(message, MessageType.Error);
} }

View File

@ -5,6 +5,7 @@
@inject IFileService FileService @inject IFileService FileService
@inject IFolderService FolderService @inject IFolderService FolderService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <TabStrip>
<TabPanel Name="Upload" Heading="Upload Files" ResourceKey="UploadFiles"> <TabPanel Name="Upload" Heading="Upload Files" ResourceKey="UploadFiles">
@ -18,7 +19,7 @@
</td> </td>
</tr> </tr>
</table> </table>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel> </TabPanel>
<TabPanel Name="Download" Heading="Download Files" ResourceKey="DownloadFiles"> <TabPanel Name="Download" Heading="Download Files" ResourceKey="DownloadFiles">
@if (_folders != null) @if (_folders != null)
@ -37,8 +38,8 @@
<Label For="folder" HelpText="Select the folder to save the file in" ResourceKey="Folder">Folder: </Label> <Label For="folder" HelpText="Select the folder to save the file in" ResourceKey="Folder">Folder: </Label>
</td> </td>
<td> <td>
<select id="folder" class="form-control" @bind="@_folderId"> <select id="folder" class="form-select" @bind="@_folderId">
<option value="-1">&lt;@Localizer["Select Folder"]&gt;</option> <option value="-1">&lt;@Localizer["Folder.Select"]&gt;</option>
@foreach (Folder folder in _folders) @foreach (Folder folder in _folders)
{ {
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option> <option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
@ -47,8 +48,8 @@
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="Download">@Localizer["Download"]</button> <button type="button" class="btn btn-success" @onclick="Download">@SharedLocalizer["Download"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
} }
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
@ -74,7 +75,7 @@
{ {
if (url == string.Empty || _folderId == -1) 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; return;
} }
@ -83,13 +84,13 @@
if (!Constants.UploadableFiles.Split(',') if (!Constants.UploadableFiles.Split(',')
.Contains(Path.GetExtension(filename).ToLower().Replace(".", ""))) .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; return;
} }
if (!filename.IsPathOrFileValid()) 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; return;
} }
@ -97,12 +98,12 @@
{ {
await FileService.UploadFileAsync(url, _folderId); await FileService.UploadFileAsync(url, _folderId);
await logger.LogInformation("File Downloaded Successfully From Url {Url}", url); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading File From Url {Url} {Error}", url, ex.Message); 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 IFolderService FolderService
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IStringLocalizer<Details> Localizer @inject IStringLocalizer<Details> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_folders != null) @if (_folders != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label for="name" HelpText="The name of the file" ResourceKey="Name">Name: </Label> <Label for="name" HelpText="The name of the file" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -21,7 +22,7 @@
<Label For="parent" HelpText="The folder where the file is located" ResourceKey="Folder">Folder: </Label> <Label For="parent" HelpText="The folder where the file is located" ResourceKey="Folder">Folder: </Label>
</td> </td>
<td> <td>
<select id="parent" class="form-control" @bind="@_folderId"> <select id="parent" class="form-select" @bind="@_folderId">
@foreach (Folder folder in _folders) @foreach (Folder folder in _folders)
{ {
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option> <option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
@ -38,8 +39,8 @@
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveFile">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveFile">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /> <br />
<br /> <br />
<AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo> <AuditInfo CreatedBy="@_createdBy" CreatedOn="@_createdOn" ModifiedBy="@_modifiedBy" ModifiedOn="@_modifiedOn"></AuditInfo>
@ -81,7 +82,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading File {FileId} {Error}", _fileId, ex.Message); 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 else
{ {
AddModuleMessage(Localizer["File Name Not Valid"], MessageType.Warning); AddModuleMessage(Localizer["Message.File.InvalidName"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving File {FileId} {Error}", _fileId, ex.Message); 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,16 +4,17 @@
@inject IFileService FileService @inject IFileService FileService
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_folders != null) @if (_folders != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="parent" HelpText="Select the parent folder" ResourceKey="Parent">Parent: </Label> <Label For="parent" HelpText="Select the parent folder" ResourceKey="Parent">Parent: </Label>
</td> </td>
<td> <td>
<select id="parent" class="form-control" @bind="@_parentId"> <select id="parent" class="form-select" @bind="@_parentId">
@if (PageState.QueryString.ContainsKey("id")) @if (PageState.QueryString.ContainsKey("id"))
{ {
<option value="-1">&lt;@Localizer["NoParent"]&gt;</option> <option value="-1">&lt;@Localizer["NoParent"]&gt;</option>
@ -44,7 +45,7 @@
} }
else 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.Private">@Localizer[FolderTypes.Private]</option>
<option value="@FolderTypes.Public">@Localizer[FolderTypes.Public]</option> <option value="@FolderTypes.Public">@Localizer[FolderTypes.Public]</option>
</select> </select>
@ -60,11 +61,13 @@
</table> </table>
@if (!_isSystem) @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")) @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" /> <ActionDialog Header="Delete Folder" Message="Are You Sure You Wish To Delete This Folder?" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteFolder())" ResourceKey="DeleteFolder" />
} }
<br /> <br />
@ -128,7 +131,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Folder {FolderId} {Error}", _folderId, ex.Message); 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) 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; return;
} }
if (!_name.IsPathOrFileValid()) if (!_name.IsPathOrFileValid())
{ {
AddModuleMessage(Localizer["Folder Name Not Valid."], MessageType.Warning); AddModuleMessage(Localizer["Message.Folder.InvalidName"], MessageType.Warning);
return; return;
} }
@ -191,13 +194,13 @@
} }
else else
{ {
AddModuleMessage(Localizer["An Error Was Encountered Saving The Folder"], MessageType.Error); AddModuleMessage(Localizer["Error.Folder.Save"], MessageType.Error);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving Folder {FolderId} {Error}", _folderId, ex.Message); 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 else
{ {
AddModuleMessage(Localizer["Folder Has Files And Cannot Be Deleted"], MessageType.Warning); AddModuleMessage(Localizer["Message.Folder.Files.InvalidDelete"], MessageType.Warning);
} }
} }
else else
{ {
AddModuleMessage(Localizer["Folder Has Subfolders And Cannot Be Deleted"], MessageType.Warning); AddModuleMessage(Localizer["Message.Folder.Subfolders.InvalidDelete"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Folder {Folder} {Error}", _folderId, ex.Message); 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 IFolderService FolderService
@inject IFileService FileService @inject IFileService FileService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_files != null) @if (_files != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Folder:"] </label> <label class="control-label">@Localizer["Folder"] </label>
</td> </td>
<td> <td>
<select class="form-control" @onchange="(e => FolderChanged(e))"> <select class="form-select" @onchange="(e => FolderChanged(e))">
@foreach (Folder folder in _folders) @foreach (Folder folder in _folders)
{ {
<option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option> <option value="@(folder.FolderId)">@(new string('-', folder.Level * 2))@(folder.Name)</option>
@ -31,23 +32,23 @@
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <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>
<th>@Localizer["Modified"]</th> <th>@Localizer["Modified"]</th>
<th>@Localizer["Type"]</th> <th>@Localizer["Type"]</th>
<th>@Localizer["Size"]</th> <th>@Localizer["Size"]</th>
</Header> </Header>
<Row> <Row>
<td><ActionLink Action="Details" Text="Edit" Parameters="@($"id=" + context.FileId.ToString())" ResourceKey="Details" /></td> <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><a href="@context.Url" target="_new">@context.Name</a></td>
<td>@context.ModifiedOn</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> <td>@string.Format("{0:0.00}", ((decimal)context.Size / 1000)) KB</td>
</Row> </Row>
</Pager> </Pager>
@if (_files.Count == 0) @if (_files.Count == 0)
{ {
<div class="text-center">@Localizer["No Files Exist In Selected Folder"]</div> <div class="text-center">@Localizer["NoFiles"]</div>
} }
} }
@ -73,7 +74,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Files {Error}", ex.Message); 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 FileService.DeleteFileAsync(file.FileId);
await logger.LogInformation("File Deleted {File}", file.Name); 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(); await GetFiles();
StateHasChanged(); StateHasChanged();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting File {File} {Error}", file.Name, ex.Message); 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 NavigationManager NavigationManager
@inject IJobService JobService @inject IJobService JobService
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="Enter the job name" ResourceKey="Name">Name: </Label> <Label For="name" HelpText="Enter the job name" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -26,9 +27,9 @@
<Label For="enabled" HelpText="Select whether you want the job enabled or not" ResourceKey="Enabled">Enabled? </Label> <Label For="enabled" HelpText="Select whether you want the job enabled or not" ResourceKey="Enabled">Enabled? </Label>
</td> </td>
<td> <td>
<select id="enabled" class="form-control" @bind="@_isEnabled"> <select id="enabled" class="form-select" @bind="@_isEnabled">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -38,7 +39,7 @@
</td> </td>
<td> <td>
<input id="runs-every" class="form-control" @bind="@_interval" /> <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="m">@Localizer["Minute(s)"]</option>
<option value="H">@Localizer["Hour(s)"]</option> <option value="H">@Localizer["Hour(s)"]</option>
<option value="d">@Localizer["Day(s)"]</option> <option value="d">@Localizer["Day(s)"]</option>
@ -79,8 +80,11 @@
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveJob">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveJob">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
@code { @code {
private int _jobId; private int _jobId;
@ -93,6 +97,10 @@
private string _endDate = string.Empty; private string _endDate = string.Empty;
private string _retentionHistory = string.Empty; private string _retentionHistory = string.Empty;
private string _nextExecution = 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; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -113,12 +121,16 @@
_endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty; _endDate = (job.EndDate != null) ? job.EndDate.ToString() : string.Empty;
_retentionHistory = job.RetentionHistory.ToString(); _retentionHistory = job.RetentionHistory.ToString();
_nextExecution = job.NextExecution.ToString(); _nextExecution = job.NextExecution.ToString();
createdby = job.CreatedBy;
createdon = job.CreatedOn;
modifiedby = job.ModifiedBy;
modifiedon = job.ModifiedOn;
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Job {JobId} {Error}", _jobId, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Udate Job {Job} {Error}", job, ex.Message); 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 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 @inherits ModuleBase
@inject IJobService JobService @inject IJobService JobService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_jobs == null) @if (_jobs == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
@ -19,8 +20,8 @@ else
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th> <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>
<th>@Localizer["Status"]</th> <th>@SharedLocalizer["Status"]</th>
<th>@Localizer["Frequency"]</th> <th>@Localizer["Frequency"]</th>
<th>@Localizer["NextExecution"]</th> <th>@Localizer["NextExecution"]</th>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
@ -118,7 +119,7 @@ else
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Job {Job} {Error}", job, ex.Message); 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,17 +2,18 @@
@inherits ModuleBase @inherits ModuleBase
@inject IJobLogService JobLogService @inject IJobLogService JobLogService
@inject IStringLocalizer<Log> Localizer @inject IStringLocalizer<Log> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_jobLogs == null) @if (_jobLogs == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<Pager Items="@_jobLogs"> <Pager Items="@_jobLogs">
<Header> <Header>
<th>@Localizer["Name"]</th> <th>@SharedLocalizer["Name"]</th>
<th>@Localizer["Status"]</th> <th>@SharedLocalizer["Status"]</th>
<th>@Localizer["Started"]</th> <th>@Localizer["Started"]</th>
<th>@Localizer["Finished"]</th> <th>@Localizer["Finished"]</th>
</Header> </Header>

View File

@ -7,10 +7,11 @@
@inject ILanguageService LanguageService @inject ILanguageService LanguageService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_supportedCultures == null) @if (_supportedCultures == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
@ -24,11 +25,11 @@ else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label> <Label For="name" HelpText="Name Of The Language" ResourceKey="Name">Name:</Label>
</td> </td>
<td> <td>
<select id="_code" class="form-control" @bind="@_code"> <select id="_code" class="form-select" @bind="@_code">
@foreach (var culture in _availableCultures) @foreach (var culture in _availableCultures)
{ {
<option value="@culture.Name">@culture.DisplayName</option> <option value="@culture.Name">@culture.DisplayName</option>
@ -41,56 +42,73 @@ else
<Label For="default" HelpText="Indicates Whether Or Not This Language Is The Default For The Site" ResourceKey="IsDefault">Default?</Label> <Label For="default" HelpText="Indicates Whether Or Not This Language Is The Default For The Site" ResourceKey="IsDefault">Default?</Label>
</td> </td>
<td> <td>
<select id="default" class="form-control" @bind="@_isDefault"> <select id="default" class="form-select" @bind="@_isDefault">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveLanguage">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveLanguage">@SharedLocalizer["Save"]</button>
} }
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel> </TabPanel>
<TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host"> <TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host">
@if (_packages != null && _packages.Count > 0) <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>
{
<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> <table class="table table-borderless" style=" margin: auto; width: 50% !important;">
<Pager Items="@_packages"> <tr>
<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> <td>
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadLanguage(context.PackageId, context.Version))>@Localizer["Download"]</button> <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)
{
@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> </td>
</Row> </Row>
</Pager> </Pager>
<button type="button" class="btn btn-success" @onclick="InstallLanguages">@Localizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
} }
else else
{ {
<ModuleMessage Type="MessageType.Info" Message="No Language Packages Are Available To Download"></ModuleMessage> <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>
<TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host"> <TabPanel Name="Upload" ResourceKey="Upload" Security="SecurityAccessLevel.Host">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <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>
<td> <td>
<FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="true" /> <FileManager Filter="nupkg" ShowFiles="false" Folder="Packages" UploadMultiple="true" />
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="InstallLanguages">@Localizer["Install"]</button> <button type="button" class="btn btn-success" @onclick="InstallLanguages">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
} }
@ -102,6 +120,7 @@ else
private IEnumerable<Culture> _supportedCultures; private IEnumerable<Culture> _supportedCultures;
private IEnumerable<Culture> _availableCultures; private IEnumerable<Culture> _availableCultures;
private List<Package> _packages; private List<Package> _packages;
private string _search = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -113,15 +132,45 @@ else
_supportedCultures = await LocalizationService.GetCulturesAsync(); _supportedCultures = await LocalizationService.GetCulturesAsync();
_availableCultures = _supportedCultures _availableCultures = _supportedCultures
.Where(c => !c.Name.Equals(Constants.DefaultCulture) && !languagesCodes.Contains(c.Name)); .Where(c => !c.Name.Equals(Constants.DefaultCulture) && !languagesCodes.Contains(c.Name));
_packages = await PackageService.GetPackagesAsync("language"); await LoadTranslations();
if (_supportedCultures.Count() == 1) if (_supportedCultures.Count() == 1)
{ {
_message = Localizer["The Only Installed Language Is English"]; _message = Localizer["OnlyEnglish"];
} }
else if (_availableCultures.Count() == 0) 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Adding Language {Language} {Error}", language, ex.Message); 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 try
{ {
await PackageService.InstallPackagesAsync(); 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) 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 PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Language Paclage {Name} {Version} Downloaded Successfully", packageid, version); 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(); StateHasChanged();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Language Package {Name} {Version}", packageid, version); await logger.LogError(ex, "Error Downloading Translation {Name} {Version}", packageid, version);
AddModuleMessage(Localizer["Error Downloading Language Package"], MessageType.Error); AddModuleMessage(Localizer["Error.Language.Download"], MessageType.Error);
} }
} }

View File

@ -4,10 +4,11 @@
@inject ILocalizationService LocalizationService @inject ILocalizationService LocalizationService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_languages == null) @if (_languages == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
@ -16,20 +17,20 @@ else
<Pager Items="@_languages"> <Pager Items="@_languages">
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th> <th>@SharedLocalizer["Name"]</th>
<th>@Localizer["Code"]</th> <th>@Localizer["Code"]</th>
<th>@Localizer["Default?"]</th> <th>@Localizer["Default"]</th>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
</Header> </Header>
<Row> <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.Name</td>
<td>@context.Code</td> <td>@context.Code</td>
<td><TriStateCheckBox Value="@(context.IsDefault)" Disabled="true"></TriStateCheckBox></td> <td><TriStateCheckBox Value="@(context.IsDefault)" Disabled="true"></TriStateCheckBox></td>
<td> <td>
@if (UpgradeAvailable(context.Code)) @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> </td>
</Row> </Row>
@ -54,7 +55,7 @@ else
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) 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); 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)) if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
await PackageService.DownloadPackageAsync(Constants.PackageId + ".Client." + code, Constants.Version, "Packages"); 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(); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Language Package {Code} {Version} {Error}", code, Constants.Version, ex.Message); await logger.LogError(ex, "Error Downloading Translation {Code} {Version} {Error}", code, Constants.Version, ex.Message);
AddModuleMessage(Localizer["Error Downloading Language Package"], MessageType.Error); AddModuleMessage(Localizer["Error.Language.Download"], MessageType.Error);
} }
} }
} }

View File

@ -3,7 +3,9 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IUserService UserService @inject IUserService UserService
@inject IServiceProvider ServiceProvider @inject IServiceProvider ServiceProvider
@inject SiteState SiteState
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_message != string.Empty) @if (_message != string.Empty)
{ {
@ -14,27 +16,27 @@
<text>...</text> <text>...</text>
</Authorizing> </Authorizing>
<Authorized> <Authorized>
<ModuleMessage Message="@Localizer["You Are Already Signed In"]" Type="MessageType.Info" /> <ModuleMessage Message="@Localizer["Info.SignedIn"]" Type="MessageType.Info" />
</Authorized> </Authorized>
<NotAuthorized> <NotAuthorized>
<form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate> <form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))"> <div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))">
<div class="form-group"> <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 /> <input type="text" @ref="username" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" required />
</div> </div>
<div class="form-group"> <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 /> <input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" required />
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="form-check form-check-inline"> <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" /> <input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
</div> </div>
</div> </div>
<button type="button" class="btn btn-primary" @onclick="Login">@Localizer["Login"]</button> <button type="button" class="btn btn-primary" @onclick="Login">@SharedLocalizer["Login"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
<br /><br /> <br /><br />
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button> <button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button>
</div> </div>
@ -82,11 +84,11 @@
if (user != null) 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 else
{ {
_message = Localizer["User Account Could Not Be Verified. Please Contact Your Administrator For Further Instructions."]; _message = Localizer["Message.Account.NotVerfied"];
_type = MessageType.Warning; _type = MessageType.Warning;
} }
} }
@ -108,7 +110,6 @@
{ {
if (PageState.Runtime == Oqtane.Shared.Runtime.Server) if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
{ {
// server-side Blazor
var user = new User(); var user = new User();
user.SiteId = PageState.Site.SiteId; user.SiteId = PageState.Site.SiteId;
user.Username = _username; user.Username = _username;
@ -118,16 +119,15 @@
if (user.IsAuthenticated) if (user.IsAuthenticated)
{ {
await logger.LogInformation("Login Successful For Username {Username}", _username); await logger.LogInformation("Login Successful For Username {Username}", _username);
// complete the login on the server so that the cookies are set correctly // server-side Blazor needs to post to the Login page so that the cookies are set correctly
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken"); var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/"); string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
await interop.SubmitForm(url, fields); await interop.SubmitForm(url, fields);
} }
else else
{ {
await logger.LogInformation("Login Failed For Username {Username}", _username); 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 else
@ -143,18 +143,18 @@
await logger.LogInformation("Login Successful For Username {Username}", _username); await logger.LogInformation("Login Successful For Username {Username}", _username);
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider)); var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged(); authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload")); NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
} }
else else
{ {
await logger.LogInformation("Login Failed For Username {Username}", _username); 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 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 IPageService PageService
@inject IPageModuleService PageModuleService @inject IPageModuleService PageModuleService
@inject IUserService UserService @inject IUserService UserService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Detail> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="dateTime" HelpText="The date and time of this log" ResourceKey="DateTime">Date/Time: </Label> <Label For="dateTime" HelpText="The date and time of this log" ResourceKey="DateTime">Date/Time: </Label>
</td> </td>
<td> <td>
@ -134,7 +135,7 @@
</td> </td>
</tr> </tr>
</table> </table>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code { @code {
private int _logId; private int _logId;
@ -207,7 +208,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Log {LogId} {Error}", _logId, ex.Message); 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

@ -2,10 +2,11 @@
@inherits ModuleBase @inherits ModuleBase
@inject ILogService LogService @inject ILogService LogService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_logs == null) @if (_logs == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
@ -13,7 +14,7 @@ else
<tr> <tr>
<td> <td>
<Label For="level" HelpText="Select the log level for event log items" ResourceKey="Level">Level: </Label><br /><br /> <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))"> <select id="level" class="form-select" @onchange="(e => LevelChanged(e))">
<option value="-">&lt;@Localizer["AllLevels"]&gt;</option> <option value="-">&lt;@Localizer["AllLevels"]&gt;</option>
<option value="Trace">@Localizer["Trace"]</option> <option value="Trace">@Localizer["Trace"]</option>
<option value="Debug">@Localizer["Debug"]</option> <option value="Debug">@Localizer["Debug"]</option>
@ -25,19 +26,19 @@ else
</td> </td>
<td> <td>
<Label For="function" HelpText="Select the function for event log items" ResourceKey="Function">Function: </Label><br /><br /> <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))"> <select id="function" class="form-select" @onchange="(e => FunctionChanged(e))">
<option value="-">&lt;@Localizer["AllFunctions"]&gt;</option> <option value="-">&lt;@Localizer["AllFunctions"]&gt;</option>
<option value="Create">@Localizer["Create"]</option> <option value="Create">@Localizer["Create"]</option>
<option value="Read">@Localizer["Read"]</option> <option value="Read">@Localizer["Read"]</option>
<option value="Update">@Localizer["Update"]</option> <option value="Update">@SharedLocalizer["Update"]</option>
<option value="Delete">@Localizer["Delete"]</option> <option value="Delete">@SharedLocalizer["Delete"]</option>
<option value="Security">@Localizer["Security"]</option> <option value="Security">@Localizer["Security"]</option>
<option value="Other">@Localizer["Other"]</option> <option value="Other">@Localizer["Other"]</option>
</select> </select>
</td> </td>
<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 /> <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="10">10</option>
<option value="50">50</option> <option value="50">50</option>
<option value="100">100</option> <option value="100">100</option>
@ -67,7 +68,7 @@ else
} }
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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Logs {Error}", ex.Message); 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 IModuleService ModuleService
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (string.IsNullOrEmpty(_moduledefinitionname) && _templates != null) @if (string.IsNullOrEmpty(_moduledefinitionname) && _templates != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <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>
<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> <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>
<td> <td>
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))"> <select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Select Template"]&gt;</option> <option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates) @foreach (Template template in _templates)
{ {
<option value="@template.Name">@template.Title</option> <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> <Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
</td> </td>
<td> <td>
<select id="reference" class="form-control" @bind="@_reference"> <select id="reference" class="form-select" @bind="@_reference">
@foreach (string version in _versions) @foreach (string version in _versions)
{ {
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0) if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -61,7 +62,7 @@
<option value="@(version)">@(version)</option> <option value="@(version)">@(version)</option>
} }
} }
<option value="local">@Localizer["Local Version"]</option> <option value="local">@SharedLocalizer["LocalVersion"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -77,11 +78,11 @@
</tr> </tr>
} }
</table> </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 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 { @code {
@ -108,11 +109,11 @@ else
if (string.IsNullOrEmpty(_moduledefinitionname)) 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 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) catch (Exception ex)
@ -136,11 +137,11 @@ else
GetLocation(); 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 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) catch (Exception ex)

View File

@ -5,30 +5,50 @@
@inject IModuleDefinitionService ModuleDefinitionService @inject IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<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) @if (_packages != null)
{ {
<TabStrip> if (_packages.Count > 0)
@if (_packages.Count > 0)
{ {
<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>
<Pager Items="@_packages"> <Pager Items="@_packages">
<Header>
<th>@Localizer["Name"]</th>
<th>@Localizer["Version"]</th>
<th style="width: 1px"></th>
</Header>
<Row> <Row>
<td>@context.Name</td>
<td>@context.Version</td>
<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> </td>
</Row> </Row>
</Pager> </Pager>
</TabPanel>
} }
else
{
<br />
<div class="mx-auto text-center">
@Localizer["Search.NoResults"]
</div>
}
}
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload"> <TabPanel Name="Upload" ResourceKey="Upload">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
@ -43,12 +63,12 @@
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="InstallModules">@Localizer["Install"]</button> <button type="button" class="btn btn-success" @onclick="InstallModules">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code { @code {
private List<Package> _packages; private List<Package> _packages;
private string _search = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -56,9 +76,22 @@
{ {
try try
{ {
var moduledefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId); await LoadModuleDefinitions();
_packages = await PackageService.GetPackagesAsync("module"); }
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()) foreach (Package package in _packages.ToArray())
{ {
if (moduledefinitions.Exists(item => item.PackageName == package.PackageId)) if (moduledefinitions.Exists(item => item.PackageName == package.PackageId))
@ -67,10 +100,30 @@
} }
} }
} }
}
private async Task Search()
{
try
{
await LoadModuleDefinitions();
}
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message); await logger.LogError(ex, "Error On Search");
AddModuleMessage(Localizer["Error Loading Packages"], MessageType.Error); }
}
private async Task Reset()
{
try
{
_search = "";
await LoadModuleDefinitions();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Reset");
} }
} }
@ -79,7 +132,7 @@
try try
{ {
await ModuleDefinitionService.InstallModuleDefinitionsAsync(); 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) catch (Exception ex)
{ {
@ -93,13 +146,13 @@
{ {
await PackageService.DownloadPackageAsync(packageid, version, "Packages"); await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Module {ModuleDefinitionName} {Version} Downloaded Successfully", packageid, version); 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(); StateHasChanged();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version}", packageid, version); 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 IModuleDefinitionService ModuleDefinitionService
@inject IModuleService ModuleService @inject IModuleService ModuleService
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Create> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_templates != null) @if (_templates != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <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>
<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> <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>
<td> <td>
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))"> <select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Select Template"]&gt;</option> <option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates) @foreach (Template template in _templates)
{ {
<option value="@template.Name">@template.Title</option> <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> <Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
</td> </td>
<td> <td>
<select id="reference" class="form-control" @bind="@_reference"> <select id="reference" class="form-select" @bind="@_reference">
@foreach (string version in _versions) @foreach (string version in _versions)
{ {
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0) if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -61,7 +62,7 @@
<option value="@(version)">@(version)</option> <option value="@(version)">@(version)</option>
} }
} }
<option value="local">@Localizer["Local Version"]</option> <option value="local">@SharedLocalizer["LocalVersion"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -78,7 +79,7 @@
} }
</table> </table>
<button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button> <button type="button" class="btn btn-success" @onclick="CreateModule">@Localizer["CreateModule"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
} }
@code { @code {
@ -100,7 +101,7 @@
{ {
_templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync(); _templates = await ModuleDefinitionService.GetModuleDefinitionTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray(); _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) catch (Exception ex)
{ {
@ -117,11 +118,11 @@
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference }; var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition); moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
GetLocation(); 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 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) catch (Exception ex)

View File

@ -3,12 +3,13 @@
@inject IModuleDefinitionService ModuleDefinitionService @inject IModuleDefinitionService ModuleDefinitionService
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <TabStrip>
<TabPanel Name="Definition" ResourceKey="Definition"> <TabPanel Name="Definition" ResourceKey="Definition">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label> <Label For="name" HelpText="The name of the module" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -35,7 +36,7 @@
<Section Name="Information" ResourceKey="Information"> <Section Name="Information" ResourceKey="Information">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label> <Label For="moduledefinitionname" HelpText="The internal name of the module" ResourceKey="InternalName">Internal Name: </Label>
</td> </td>
<td> <td>
@ -103,8 +104,8 @@
</table> </table>
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveModuleDefinition">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /> <br />
<br /> <br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo> <AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
@ -161,7 +162,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving ModuleDefinition {ModuleDefinitionId} {Error}", _moduleDefinitionId, ex.Message); 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 IModuleDefinitionService ModuleDefinitionService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_moduleDefinitions == null) @if (_moduleDefinitions == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" /> <ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" />
@((MarkupString)"&nbsp;") @((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"> <Pager Items="@_moduleDefinitions">
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <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>
<th>@Localizer["Version"]</th> <th>@SharedLocalizer["Version"]</th>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
</Header> </Header>
<Row> <Row>
@ -28,7 +29,7 @@ else
<td> <td>
@if (context.AssemblyName != "Oqtane.Client") @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>
<td>@context.Name</td> <td>@context.Name</td>
@ -36,7 +37,7 @@ else
<td> <td>
@if (UpgradeAvailable(context.PackageName, context.Version)) @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> </td>
</Row> </Row>
@ -61,7 +62,7 @@ else
if (_moduleDefinitions == null) if (_moduleDefinitions == null)
{ {
await logger.LogError(ex, "Error Loading Modules {Error}", ex.Message); 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 PackageService.DownloadPackageAsync(packagename, version, "Packages");
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version); await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
await ModuleDefinitionService.InstallModuleDefinitionsAsync(); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version} {Error}", packagename, version, ex.Message); 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 try
{ {
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId); await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
AddModuleMessage(Localizer["Module Deleted Successfully"], MessageType.Success); AddModuleMessage(Localizer["Success.Module.Delete"], MessageType.Success);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload")); NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Module {ModuleDefinition} {Error}", moduleDefinition, ex.Message); 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 NavigationManager NavigationManager
@inject IModuleService ModuleService @inject IModuleService ModuleService
@inject IStringLocalizer<Export> Localizer @inject IStringLocalizer<Export> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tbody> <tbody>
<tr> <tr>
<td> <td width="30%">
<Label For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label> <Label For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
</td> </td>
<td> <td>
@ -17,7 +18,7 @@
</tbody> </tbody>
</table> </table>
<button type="button" class="btn btn-success" @onclick="ExportModule">@Localizer["Export"]</button> <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 { @code {

View File

@ -3,11 +3,12 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IModuleService ModuleService @inject IModuleService ModuleService
@inject IStringLocalizer<Import> Localizer @inject IStringLocalizer<Import> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tbody> <tbody>
<tr> <tr>
<td> <td width="30%">
<Label For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label> <Label For="content" HelpText="Enter the module content" ResourceKey="Content">Content: </Label>
</td> </td>
<td> <td>
@ -17,7 +18,7 @@
</tbody> </tbody>
</table> </table>
<button type="button" class="btn btn-success" @onclick="ImportModule">@Localizer["Import"]</button> <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 { @code {
@ -35,22 +36,22 @@
bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content); bool success = await ModuleService.ImportModuleAsync(ModuleState.ModuleId, _content);
if (success) if (success)
{ {
AddModuleMessage(Localizer["Content Imported Successfully"], MessageType.Success); AddModuleMessage(Localizer["Success.Content.Import"], MessageType.Success);
} }
else 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Importing Module {ModuleId} {Error}", ModuleState.ModuleId, ex.Message); 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 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 IModuleService ModuleService
@inject IPageModuleService PageModuleService @inject IPageModuleService PageModuleService
@inject IStringLocalizer<Settings> Localizer @inject IStringLocalizer<Settings> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <TabStrip>
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings"> <TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
@ -13,7 +14,7 @@
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label> <Label For="title" HelpText="Enter the title of the module" ResourceKey="Title">Title: </Label>
</td> </td>
<td> <td>
@ -25,7 +26,7 @@
<Label For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label> <Label For="container" HelpText="Select the module's container" ResourceKey="Container">Container: </Label>
</td> </td>
<td> <td>
<select id="container" class="form-control" @bind="@_containerType"> <select id="container" class="form-select" @bind="@_containerType">
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <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> <Label For="allpages" HelpText="Indicate if this module should be displayed on all pages" ResourceKey="DisplayOnAllPages">Display On All Pages? </Label>
</td> </td>
<td> <td>
<select id="allpages" class="form-control" @bind="@_allPages"> <select id="allpages" class="form-select" @bind="@_allPages">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -49,7 +50,7 @@
<Label For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label> <Label For="page" HelpText="The page that the module is located on" ResourceKey="Page">Page: </Label>
</td> </td>
<td> <td>
<select id="page" class="form-control" @bind="@_pageId"> <select id="page" class="form-select" @bind="@_pageId">
@foreach (Page p in PageState.Pages) @foreach (Page p in PageState.Pages)
{ {
if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions)) if (UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, p.Permissions))
@ -88,8 +89,11 @@
</TabPanel> </TabPanel>
} }
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveModule">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveModule">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon"></AuditInfo>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
@ -111,6 +115,10 @@
private Type _containerSettingsType; private Type _containerSettingsType;
private object _containerSettings; private object _containerSettings;
private RenderFragment ContainerSettingsComponent { get; set; } private RenderFragment ContainerSettingsComponent { get; set; }
private string createdby;
private DateTime createdon;
private string modifiedby;
private DateTime modifiedon;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@ -122,6 +130,10 @@
_permissions = ModuleState.Permissions; _permissions = ModuleState.Permissions;
_permissionNames = ModuleState.ModuleDefinition.PermissionNames; _permissionNames = ModuleState.ModuleDefinition.PermissionNames;
_pageId = ModuleState.PageId.ToString(); _pageId = ModuleState.PageId.ToString();
createdby = ModuleState.CreatedBy;
createdon = ModuleState.CreatedOn;
modifiedby = ModuleState.ModifiedBy;
modifiedon = ModuleState.ModifiedOn;
if (!string.IsNullOrEmpty(ModuleState.ModuleDefinition.SettingsType)) if (!string.IsNullOrEmpty(ModuleState.ModuleDefinition.SettingsType))
{ {
@ -212,7 +224,7 @@
} }
else 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 IPageService PageService
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip Refresh="@_refresh"> <TabStrip Refresh="@_refresh">
<TabPanel Name="Settings" ResourceKey="Settings"> <TabPanel Name="Settings" ResourceKey="Settings">
@ -11,7 +12,7 @@
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label> <Label For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -23,7 +24,7 @@
<Label For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label> <Label For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
</td> </td>
<td> <td>
<select id="Parent" class="form-control" @onchange="(e => ParentChanged(e))"> <select id="Parent" class="form-select" @onchange="(e => ParentChanged(e))">
<option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option> <option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option>
@foreach (Page page in _pageList) @foreach (Page page in _pageList)
{ {
@ -37,7 +38,7 @@
<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> <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>
<td> <td>
<select id="Insert" class="form-control" @bind="@_insert"> <select id="Insert" class="form-select" @bind="@_insert">
<option value="<<">@Localizer["AtBeginning"]</option> <option value="<<">@Localizer["AtBeginning"]</option>
@if (_children != null && _children.Count > 0) @if (_children != null && _children.Count > 0)
{ {
@ -48,8 +49,8 @@
</select> </select>
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
{ {
<select class="form-control" @bind="@_childid"> <select class="form-select" @bind="@_childid">
<option value="-1">&lt;@Localizer["Select Page"]&gt;</option> <option value="-1">&lt;@Localizer["Page.Select"]&gt;</option>
@foreach (Page page in _children) @foreach (Page page in _children)
{ {
<option value="@(page.PageId)">@(page.Name)</option> <option value="@(page.PageId)">@(page.Name)</option>
@ -60,12 +61,23 @@
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<select id="Navigation" class="form-control" @bind="@_isnavigation"> <select id="navigation" class="form-select" @bind="@_isnavigation">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</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> </select>
</td> </td>
</tr> </tr>
@ -89,7 +101,7 @@
<Section Name="Appearance" ResourceKey="Appearance"> <Section Name="Appearance" ResourceKey="Appearance">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <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>
<td> <td>
@ -101,7 +113,7 @@
<Label For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label> <Label For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
</td> </td>
<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) @foreach (var theme in _themes)
{ {
<option value="@theme.TypeName">@theme.Name</option> <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> <Label For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
</td> </td>
<td> <td>
<select id="defaultContainer" class="form-control" @bind="@_containertype"> <select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <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> <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>
<td> <td>
<select id="Personalizable" class="form-control" @bind="@_ispersonalizable"> <select id="Personalizable" class="form-select" @bind="@_ispersonalizable">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -162,8 +174,8 @@
</TabPanel> </TabPanel>
} }
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -180,6 +192,7 @@
private List<Page> _children; private List<Page> _children;
private int _childid = -1; private int _childid = -1;
private string _isnavigation = "True"; private string _isnavigation = "True";
private string _isclickable = "True";
private string _url; private string _url;
private string _ispersonalizable = "False"; private string _ispersonalizable = "False";
private string _themetype = string.Empty; private string _themetype = string.Empty;
@ -209,7 +222,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Initializing Page {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); 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)) 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; return;
} }
@ -351,6 +364,7 @@
} }
page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation)); page.IsNavigation = (_isnavigation == null ? true : Boolean.Parse(_isnavigation));
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
page.Url = _url; page.Url = _url;
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
@ -382,14 +396,14 @@
} }
else else
{ {
AddModuleMessage(Localizer["You Must Provide Page Name, Theme, and Container"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message); await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
AddModuleMessage(Localizer["Error Saving Page"], MessageType.Error); AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
} }
} }

View File

@ -5,6 +5,7 @@
@inject IPageService PageService @inject IPageService PageService
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip Refresh="@_refresh"> <TabStrip Refresh="@_refresh">
<TabPanel Name="Settings" ResourceKey="Settings"> <TabPanel Name="Settings" ResourceKey="Settings">
@ -12,7 +13,7 @@
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label> <Label For="Name" HelpText="Enter the page name" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -24,7 +25,7 @@
<Label For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label> <Label For="Parent" HelpText="Select the parent for the page in the site hierarchy" ResourceKey="Parent">Parent: </Label>
</td> </td>
<td> <td>
<select id="Parent" class="form-control" value="@_parentid" @onchange="(e => ParentChanged(e))"> <select id="Parent" class="form-select" value="@_parentid" @onchange="(e => ParentChanged(e))">
<option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option> <option value="-1">&lt;@Localizer["SiteRoot"]&gt;</option>
@foreach (Page page in _pageList) @foreach (Page page in _pageList)
{ {
@ -41,10 +42,10 @@
<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> <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>
<td> <td>
<select id="Move" class="form-control" @bind="@_insert"> <select id="Move" class="form-select" @bind="@_insert">
@if (_parentid == _currentparentid) @if (_parentid == _currentparentid)
{ {
<option value="=">&lt;@Localizer["Maintain Current Location"]&gt;</option> <option value="=">&lt;@Localizer["ThisLocation.Keep"]&gt;</option>
} }
<option value="<<">@Localizer["ToBeginning"]</option> <option value="<<">@Localizer["ToBeginning"]</option>
@if (_children != null && _children.Count > 0) @if (_children != null && _children.Count > 0)
@ -56,8 +57,8 @@
</select> </select>
@if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">")) @if (_children != null && _children.Count > 0 && (_insert == "<" || _insert == ">"))
{ {
<select class="form-control" @bind="@_childid"> <select class="form-select" @bind="@_childid">
<option value="-1">&lt;@Localizer["Select Page"]&gt;</option> <option value="-1">&lt;@Localizer["Page.Select"]&gt;</option>
@foreach (Page page in _children) @foreach (Page page in _children)
{ {
<option value="@(page.PageId)">@(page.Name)</option> <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> <Label For="Navigation" HelpText="Select whether the page is part of the site navigation or hidden" ResourceKey="Navigation">Navigation? </Label>
</td> </td>
<td> <td>
<select id="Navigation" class="form-control" @bind="@_isnavigation"> <select id="Navigation" class="form-select" @bind="@_isnavigation">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</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> </select>
</td> </td>
</tr> </tr>
@ -97,7 +109,7 @@
<Section Name="Appearance" ResourceKey="Appearance"> <Section Name="Appearance" ResourceKey="Appearance">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <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>
<td> <td>
@ -109,7 +121,7 @@
<Label For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label> <Label For="Theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
</td> </td>
<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) @foreach (var theme in _themes)
{ {
<option value="@theme.TypeName">@theme.Name</option> <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> <Label For="defaultContainer" HelpText="Select the default container for the page" ResourceKey="DefaultContainer">Default Container: </Label>
</td> </td>
<td> <td>
<select id="defaultContainer" class="form-control" @bind="@_containertype"> <select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <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> <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>
<td> <td>
<select id="Personalizable" class="form-control" @bind="@_ispersonalizable"> <select id="Personalizable" class="form-select" @bind="@_ispersonalizable">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -175,8 +187,8 @@
</TabPanel> </TabPanel>
} }
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="SavePage">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SavePage">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
@code { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -195,6 +207,7 @@
private List<Page> _children; private List<Page> _children;
private int _childid = -1; private int _childid = -1;
private string _isnavigation; private string _isnavigation;
private string _isclickable;
private string _url; private string _url;
private string _ispersonalizable; private string _ispersonalizable;
private string _themetype; private string _themetype;
@ -247,6 +260,7 @@
_currentparentid = _parentid; _currentparentid = _parentid;
_isnavigation = page.IsNavigation.ToString(); _isnavigation = page.IsNavigation.ToString();
_isclickable = page.IsClickable.ToString();
_url = page.Url; _url = page.Url;
_ispersonalizable = page.IsPersonalizable.ToString(); _ispersonalizable = page.IsPersonalizable.ToString();
_themetype = page.ThemeType; _themetype = page.ThemeType;
@ -275,7 +289,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Page {PageId} {Error}", _pageId, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); 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)) 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; return;
} }
@ -427,6 +441,7 @@
} }
} }
page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation)); page.IsNavigation = (_isnavigation == null || Boolean.Parse(_isnavigation));
page.IsClickable = (_isclickable == null ? true : Boolean.Parse(_isclickable));
page.Url = _url; page.Url = _url;
page.ThemeType = (_themetype != "-") ? _themetype : string.Empty; page.ThemeType = (_themetype != "-") ? _themetype : string.Empty;
if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType) if (!string.IsNullOrEmpty(page.ThemeType) && page.ThemeType == PageState.Site.DefaultThemeType)
@ -481,13 +496,13 @@
} }
else else
{ {
AddModuleMessage(Localizer["You Must Provide Page Name, Theme, and Container"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message); await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
AddModuleMessage(Localizer["Error Saving Page"], MessageType.Error); AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
} }
} }

View File

@ -3,6 +3,7 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IPageService PageService @inject IPageService PageService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.Pages != null) @if (PageState.Pages != null)
{ {
@ -12,11 +13,11 @@
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <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> </Header>
<Row> <Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.PageId.ToString())" ResourceKey="EditPage" /></td> <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> <td>@(new string('-', context.Level * 2))@(context.Name)</td>
</Row> </Row>
</Pager> </Pager>
@ -38,7 +39,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Page {Page} {Error}", page, ex.Message); 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 NavigationManager NavigationManager
@inject IProfileService ProfileService @inject IProfileService ProfileService
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label> <Label For="name" HelpText="The name of this profile item" ResourceKey="Name">Name: </Label>
</td> </td>
<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> <Label For="required" HelpText="Should a user be required to provide a value for this profile item?" ResourceKey="Required">Required? </Label>
</td> </td>
<td> <td>
<select id="required" class="form-control" @bind="@_isrequired"> <select id="required" class="form-select" @bind="@_isrequired">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -85,15 +86,21 @@
<Label For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label> <Label For="private" HelpText="Should this profile item be visible to all users?" ResourceKey="Private">Private? </Label>
</td> </td>
<td> <td>
<select id="private" class="form-control" @bind="@_isprivate"> <select id="private" class="form-select" @bind="@_isprivate">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveProfile">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveProfile">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <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 { @code {
private int _profileid = -1; private int _profileid = -1;
@ -107,6 +114,10 @@
private string _options = string.Empty; private string _options = string.Empty;
private string _isrequired = "False"; private string _isrequired = "False";
private string _isprivate = "False"; private string _isprivate = "False";
private string createdby;
private DateTime createdon;
private string modifiedby;
private DateTime modifiedon;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
@ -132,13 +143,17 @@
_options = profile.Options; _options = profile.Options;
_isrequired = profile.IsRequired.ToString(); _isrequired = profile.IsRequired.ToString();
_isprivate = profile.IsPrivate.ToString(); _isprivate = profile.IsPrivate.ToString();
createdby = profile.CreatedBy;
createdon = profile.CreatedOn;
modifiedby = profile.ModifiedBy;
modifiedon = profile.ModifiedOn;
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Profile {ProfileId} {Error}", _profileid, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving Profile {ProfleId} {Error}", _profileid, ex.Message); 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 @inherits ModuleBase
@inject IProfileService ProfileService @inject IProfileService ProfileService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_profiles == null) @if (_profiles == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
@ -15,11 +16,11 @@ else
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <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> </Header>
<Row> <Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.ProfileId.ToString())" ResourceKey="EditProfile" /></td> <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> <td>@context.Name</td>
</Row> </Row>
</Pager> </Pager>
@ -42,7 +43,7 @@ else
await ProfileService.DeleteProfileAsync(profileId); await ProfileService.DeleteProfileAsync(profileId);
await logger.LogInformation("Profile Deleted {ProfileId}", profileId); await logger.LogInformation("Profile Deleted {ProfileId}", profileId);
AddModuleMessage(Localizer["Profile Deleted"], MessageType.Success); AddModuleMessage(Localizer["Success.Profile.Delete"], MessageType.Success);
await GetProfilesAsync(); await GetProfilesAsync();
@ -51,7 +52,7 @@ else
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Profile {ProfileId} {Error}", profileId, ex.Message); 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 IModuleService ModuleService
@inject IPageService PageService @inject IPageService PageService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <TabStrip>
<TabPanel Name="Pages" ResourceKey="Pages"> <TabPanel Name="Pages" ResourceKey="Pages">
@if (_pages == null) @if (_pages == null)
{ {
<br /> <br />
<p>@Localizer["No Deleted Pages"]</p> <p>@Localizer["NoPage.Deleted"]</p>
} }
else else
{ {
@ -19,13 +20,13 @@
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <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>
<th>@Localizer["DeletedBy"]</th> <th>@Localizer["DeletedBy"]</th>
<th>@Localizer["DeletedOn"]</th> <th>@Localizer["DeletedOn"]</th>
</Header> </Header>
<Row> <Row>
<td><button @onclick="@(() => RestorePage(context))" class="btn btn-info" title="Restore">Restore</button></td> <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.Name</td>
<td>@context.DeletedBy</td> <td>@context.DeletedBy</td>
<td>@context.DeletedOn</td> <td>@context.DeletedOn</td>
@ -43,7 +44,7 @@
@if (_modules == null) @if (_modules == null)
{ {
<br /> <br />
<p>@Localizer["No Deleted Modules"]</p> <p>@Localizer["NoModule.Deleted"]</p>
} }
else else
{ {
@ -58,7 +59,7 @@
</Header> </Header>
<Row> <Row>
<td><button @onclick="@(() => RestoreModule(context))" class="btn btn-info" title="Restore">@Localizer["Restore"]</button></td> <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>@PageState.Pages.Find(item => item.PageId == context.PageId).Name</td>
<td>@context.Title</td> <td>@context.Title</td>
<td>@context.DeletedBy</td> <td>@context.DeletedBy</td>
@ -91,7 +92,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Deleted Pages Or Modules {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Restoring Deleted Page {Page} {Error}", page, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Restoring Deleted Module {Module} {Error}", module, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Permanently Deleting Module {Module} {Error}", module, ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Permanently Deleting Modules {Error}", ex.Message); 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 NavigationManager NavigationManager
@inject IUserService UserService @inject IUserService UserService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.Site.AllowRegistration) @if (PageState.Site.AllowRegistration)
{ {
@ -11,41 +12,62 @@
<text>...</text> <text>...</text>
</Authorizing> </Authorizing>
<Authorized> <Authorized>
<ModuleMessage Message="@Localizer["You Are Already Registered"]" Type="MessageType.Info" /> <ModuleMessage Message="@Localizer["Info.Registration.Exists"]" Type="MessageType.Info" />
</Authorized> </Authorized>
<NotAuthorized> <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" />
<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>
<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-primary" @onclick="Register">@Localizer["Register"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
</div>
</NotAuthorized> </NotAuthorized>
</AuthorizeView> </AuthorizeView>
} }
else else
{ {
<ModuleMessage Message="@Localizer["Registration is Disabled For This Site"]" Type="MessageType.Info" /> <ModuleMessage Message="@Localizer["Info.Registration.Disabled"]" Type="MessageType.Info" />
} }
@code { @code {
@ -53,7 +75,7 @@ else
private string _password = string.Empty; private string _password = string.Empty;
private string _confirm = string.Empty; private string _confirm = string.Empty;
private string _email = string.Empty; private string _email = string.Empty;
private string _displayName = string.Empty; private string _displayname = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
@ -71,7 +93,7 @@ else
{ {
SiteId = PageState.Site.SiteId, SiteId = PageState.Site.SiteId,
Username = _username, Username = _username,
DisplayName = (_displayName == string.Empty ? _username : _displayName), DisplayName = (_displayname == string.Empty ? _username : _displayname),
Email = _email, Email = _email,
Password = _password Password = _password
}; };
@ -80,28 +102,28 @@ else
if (user != null) if (user != null)
{ {
await logger.LogInformation("User Created {Username} {Email}", _username, _email); 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 else
{ {
await logger.LogError("Error Adding User {Username} {Email}", _username, _email); 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 else
{ {
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
} }
} }
else else
{ {
AddModuleMessage(Localizer["You Must Provide A Username, Password, and Email Address"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", _username, _email, ex.Message); await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", _username, _email, ex.Message);
AddModuleMessage(Localizer["Error Adding User"], MessageType.Error); AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
} }
} }

View File

@ -3,22 +3,23 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IUserService UserService @inject IUserService UserService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<div class="container"> <div class="container">
<div class="form-group"> <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" class="form-control" placeholder="Username" @bind="@_username" readonly id="Username" /> <input type="text" class="form-control" placeholder="Username" @bind="@_username" readonly id="Username" />
</div> </div>
<div class="form-group"> <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" class="form-control" placeholder="Password" @bind="@_password" id="Password" /> <input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="Confirm" class="control-label">@Localizer["Confirm Password:"] </label> <label for="Confirm" class="control-label">@Localizer["Password.Confirm"] </label>
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm" /> <input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm" />
</div> </div>
<button type="button" class="btn btn-primary" @onclick="Reset">@Localizer["Reset Password"]</button> <button type="button" class="btn btn-primary" @onclick="Reset">@Localizer["Password.Reset"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
</div> </div>
@code { @code {
@ -64,23 +65,23 @@
else else
{ {
await logger.LogError("Error Resetting User Password {Username}", _username); 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 else
{ {
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
} }
} }
else else
{ {
AddModuleMessage(Localizer["You Must Provide A Username, Password, and Email Address"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Resetting User Password {Username} {Error}", _username, ex.Message); 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,14 +3,16 @@
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IRoleService RoleService @inject IRoleService RoleService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="Name Of The Role" ResourceKey="Name">Name:</Label> <Label For="name" HelpText="Name Of The Role" ResourceKey="Name">Name:</Label>
</td> </td>
<td> <td>
<input id="name" class="form-control" @bind="@_name" /> <input id="name" class="form-control" @bind="@_name" maxlength="256" required />
</td> </td>
</tr> </tr>
<tr> <tr>
@ -18,7 +20,7 @@
<Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose" ResourceKey="Description">Description:</Label> <Label For="description" HelpText="A Short Description Of The Role Which Describes Its Purpose" ResourceKey="Description">Description:</Label>
</td> </td>
<td> <td>
<textarea id="description" class="form-control" @bind="@_description" rows="5"></textarea> <textarea id="description" class="form-control" @bind="@_description" rows="5" maxlength="256" required></textarea>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -26,17 +28,21 @@
<Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role" ResourceKey="AutoAssigned">Auto Assigned?</Label> <Label For="isautoassigned" HelpText="Indicates Whether Or Not New Users Are Automatically Assigned To This Role" ResourceKey="AutoAssigned">Auto Assigned?</Label>
</td> </td>
<td> <td>
<select id="isautoassigned" class="form-control" @bind="@_isautoassigned"> <select id="isautoassigned" class="form-select" @bind="@_isautoassigned">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveRole">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</form>
@code { @code {
private ElementReference form;
private bool validated = false;
private string _name = string.Empty; private string _name = string.Empty;
private string _description = string.Empty; private string _description = string.Empty;
private string _isautoassigned = "False"; private string _isautoassigned = "False";
@ -44,6 +50,10 @@
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
private async Task SaveRole() private async Task SaveRole()
{
validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(form))
{ {
var role = new Role(); var role = new Role();
role.SiteId = PageState.Page.SiteId; role.SiteId = PageState.Page.SiteId;
@ -62,7 +72,12 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Adding Role {Role} {Error}", role, ex.Message); await logger.LogError(ex, "Error Adding Role {Role} {Error}", role, ex.Message);
AddModuleMessage(Localizer["Error Adding Role"], MessageType.Error); AddModuleMessage(Localizer["Error.AddRole"], MessageType.Error);
}
}
else
{
AddModuleMessage(Localizer["Message.InfoRequired"], MessageType.Warning);
} }
} }

View File

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

View File

@ -2,10 +2,11 @@
@inherits ModuleBase @inherits ModuleBase
@inject IRoleService RoleService @inject IRoleService RoleService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_roles == null) @if (_roles == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else 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 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> </Header>
<Row> <Row>
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.RoleId.ToString())" Disabled="@(context.IsSystem)" ResourceKey="Edit" /></td> <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><ActionLink Action="Users" Parameters="@($"id=" + context.RoleId.ToString())" ResourceKey="Users" /></td>
<td>@context.Name</td> <td>@context.Name</td>
</Row> </Row>
@ -33,6 +34,27 @@ else
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
protected override async Task OnParametersSetAsync() 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)) if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{ {
@ -44,19 +66,4 @@ else
_roles = await RoleService.GetRolesAsync(PageState.Site.SiteId); _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 IRoleService RoleService
@inject IUserRoleService UserRoleService @inject IUserRoleService UserRoleService
@inject IStringLocalizer<Users> Localizer @inject IStringLocalizer<Users> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (userroles == null) @if (userroles == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="role" HelpText="The role you are assigning users to" ResourceKey="Role">Role: </Label> <Label For="role" HelpText="The role you are assigning users to" ResourceKey="Role">Role: </Label>
</td> </td>
<td> <td>
@ -24,8 +25,8 @@ else
<Label For="user" HelpText="Select a user" ResourceKey="User">User: </Label> <Label For="user" HelpText="Select a user" ResourceKey="User">User: </Label>
</td> </td>
<td> <td>
<select id="user" class="form-control" @bind="@userid"> <select id="user" class="form-select" @bind="@userid">
<option value="-1">&lt;@Localizer["Select User"]&gt;</option> <option value="-1">&lt;@Localizer["User.Select"]&gt;</option>
@foreach (UserRole userrole in users) @foreach (UserRole userrole in users)
{ {
<option value="@(userrole.UserId)">@userrole.User.DisplayName</option> <option value="@(userrole.UserId)">@userrole.User.DisplayName</option>
@ -50,8 +51,8 @@ else
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveUserRole">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveUserRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<hr class="app-rule" /> <hr class="app-rule" />
<p align="center"> <p align="center">
@ -67,7 +68,7 @@ else
<td>@context.EffectiveDate</td> <td>@context.EffectiveDate</td>
<td>@context.ExpiryDate</td> <td>@context.ExpiryDate</td>
<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> </td>
</Row> </Row>
</Pager> </Pager>
@ -102,7 +103,7 @@ else
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading User Roles {RoleId} {Error}", roleid, ex.Message); 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); 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(); await GetUserRoles();
StateHasChanged(); StateHasChanged();
} }
else else
{ {
AddModuleMessage(Localizer["You Must Select A User"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.UserSelect"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving User Roles {RoleId} {Error}", roleid, ex.Message); 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 UserRoleService.DeleteUserRoleAsync(UserRoleId);
await logger.LogInformation("User Removed From Role {UserRoleId}", 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(); await GetUserRoles();
StateHasChanged(); StateHasChanged();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message); 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 NavigationManager NavigationManager
@inject ISiteService SiteService @inject ISiteService SiteService
@inject ITenantService TenantService @inject ITenantService TenantService
@inject IDatabaseService DatabaseService
@inject IAliasService AliasService @inject IAliasService AliasService
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject INotificationService NotificationService @inject INotificationService NotificationService
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_initialized) @if (_initialized)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="Enter the site name" ResourceKey="Name">Name: </Label> <Label For="name" HelpText="Enter the site name" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -22,28 +24,28 @@
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea> <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> </td>
</tr> </tr>
<tr> <tr>
<td> <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> <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>
<td> <td>
<select id="allowRegister" class="form-control" @bind="@_allowregistration"> <select id="allowRegister" class="form-select" @bind="@_allowregistration">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -52,9 +54,9 @@
<Label For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label> <Label For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label>
</td> </td>
<td> <td>
<select id="isDeleted" class="form-control" @bind="@_isdeleted"> <select id="isDeleted" class="form-select" @bind="@_isdeleted">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -62,7 +64,7 @@
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance"> <Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label> <Label For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
</td> </td>
<td> <td>
@ -82,8 +84,8 @@
<Label For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label> <Label For="defaultTheme" HelpText="Select the sites default theme" ResourceKey="DefaultTheme">Default Theme: </Label>
</td> </td>
<td> <td>
<select id="defaultTheme" class="form-control" value="@_themetype" @onchange="(e => ThemeChanged(e))"> <select id="defaultTheme" class="form-select" value="@_themetype" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;@Localizer["Select Theme"]&gt;</option> <option value="-">&lt;@Localizer["Theme.Select"]&gt;</option>
@foreach (var theme in _themes) @foreach (var theme in _themes)
{ {
<option value="@theme.TypeName">@theme.Name</option> <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> <Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
</td> </td>
<td> <td>
<select id="defaultContainer" class="form-control" @bind="@_containertype"> <select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <option value="@container.TypeName">@container.Name</option>
@ -110,8 +112,8 @@
<Label For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label> <Label For="defaultAdminContainer" HelpText="Select the default admin container for the site" ResourceKey="DefaultAdminContainer">Default Admin Container: </Label>
</td> </td>
<td> <td>
<select id="defaultAdminContainer" class="form-control" @bind="@_admincontainertype"> <select id="defaultAdminContainer" class="form-select" @bind="@_admincontainertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
<option value="@Constants.DefaultAdminContainer">&lt;@Localizer["DefaultAdminContainer"]&gt;</option> <option value="@Constants.DefaultAdminContainer">&lt;@Localizer["DefaultAdminContainer"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
@ -125,8 +127,9 @@
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings"> <Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td colspan="2"> <td width="30%">&nbsp;</td>
<strong>@Localizer["Please Note That SMTP Requires The Notification Job To Be Enabled In Scheduled Jobs"]</strong> <td>
<strong>@Localizer["Smtp.Required.EnableNotificationJob"]</strong><br />
</td> </td>
</tr> </tr>
<tr> <tr>
@ -150,9 +153,9 @@
<Label For="enabledSSl" HelpText="Specify if SSL is required for your SMTP server" ResourceKey="UseSsl">SSL Enabled: </Label> <Label For="enabledSSl" HelpText="Specify if SSL is required for your SMTP server" ResourceKey="UseSsl">SSL Enabled: </Label>
</td> </td>
<td> <td>
<select id="enabledSSl" class="form-control" @bind="@_smtpssl"> <select id="enabledSSl" class="form-select" @bind="@_smtpssl">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -181,19 +184,19 @@
</td> </td>
</tr> </tr>
</table> </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 /> <br /><br />
</Section> </Section>
<Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings"> <Section Name="PWA" Heading="Progressive Web Application Settings" ResourceKey="PWASettings">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <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>
<td> <td>
<select id="isEnabled" class="form-control" @bind="@_pwaisenabled"> <select id="isEnabled" class="form-select" @bind="@_pwaisenabled">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -215,10 +218,40 @@
</tr> </tr>
</table> </table>
</Section> </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 /> <br />
<button type="button" class="btn btn-success" @onclick="SaveSite">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveSite">@SharedLocalizer["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" /> <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 />
<br /> <br />
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo> <AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon" DeletedBy="@_deletedby" DeletedOn="@_deletedon"></AuditInfo>
@ -230,8 +263,6 @@
private List<ThemeControl> _themes = new List<ThemeControl>(); private List<ThemeControl> _themes = new List<ThemeControl>();
private List<ThemeControl> _containers = new List<ThemeControl>(); private List<ThemeControl> _containers = new List<ThemeControl>();
private string _name = string.Empty; private string _name = string.Empty;
private List<Tenant> _tenantList;
private string _tenant = string.Empty;
private List<Alias> _aliasList; private List<Alias> _aliasList;
private string _urls = string.Empty; private string _urls = string.Empty;
private int _logofileid = -1; private int _logofileid = -1;
@ -253,6 +284,9 @@
private FileManager _pwaappiconfilemanager; private FileManager _pwaappiconfilemanager;
private int _pwasplashiconfileid = -1; private int _pwasplashiconfileid = -1;
private FileManager _pwasplashiconfilemanager; private FileManager _pwasplashiconfilemanager;
private string _tenant = string.Empty;
private string _database = string.Empty;
private string _connectionstring = string.Empty;
private string _createdby; private string _createdby;
private DateTime _createdon; private DateTime _createdon;
private string _modifiedby; private string _modifiedby;
@ -268,18 +302,24 @@
try try
{ {
_themeList = await ThemeService.GetThemesAsync(); _themeList = await ThemeService.GetThemesAsync();
_aliasList = await AliasService.GetAliasesAsync();
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId); Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null) if (site != null)
{ {
_name = site.Name; _name = site.Name;
_tenantList = await TenantService.GetTenantsAsync(); _allowregistration = site.AllowRegistration.ToString();
_tenant = _tenantList.Find(item => item.TenantId == site.TenantId).Name; _isdeleted = site.IsDeleted.ToString();
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
_aliasList = await AliasService.GetAliasesAsync();
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{ {
_urls += alias.Name + ","; _urls += alias.Name + ",";
} }
_urls = _urls.Substring(0, _urls.Length - 1); _urls = _urls.Substring(0, _urls.Length - 1);
}
if (site.LogoFileId != null) if (site.LogoFileId != null)
{ {
_logofileid = site.LogoFileId.Value; _logofileid = site.LogoFileId.Value;
@ -295,7 +335,6 @@
_containers = ThemeService.GetContainerControls(_themeList, _themetype); _containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer; _containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer; _admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
_allowregistration = site.AllowRegistration.ToString();
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId); var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty); _smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
@ -327,13 +366,25 @@
_pwasplashiconfileid = site.PwaSplashIconFileId.Value; _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; _createdby = site.CreatedBy;
_createdon = site.CreatedOn; _createdon = site.CreatedOn;
_modifiedby = site.ModifiedBy; _modifiedby = site.ModifiedBy;
_modifiedon = site.ModifiedOn; _modifiedon = site.ModifiedOn;
_deletedby = site.DeletedBy; _deletedby = site.DeletedBy;
_deletedon = site.DeletedOn; _deletedon = site.DeletedOn;
_isdeleted = site.IsDeleted.ToString();
_initialized = true; _initialized = true;
} }
@ -365,7 +416,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Pane Layouts For Theme {ThemeType} {Error}", _themetype, ex.Message); 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,6 +427,8 @@
if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-") if (_name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-")
{ {
var unique = true; var unique = true;
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{ {
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId)) if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
@ -383,6 +436,7 @@
unique = false; unique = false;
} }
} }
}
if (unique) if (unique)
{ {
@ -392,34 +446,30 @@
bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype); bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype);
site.Name = _name; site.Name = _name;
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
site.LogoFileId = null; site.LogoFileId = null;
var logofileid = _logofilemanager.GetFileId(); var logofileid = _logofilemanager.GetFileId();
if (logofileid != -1) if (logofileid != -1)
{ {
site.LogoFileId = logofileid; site.LogoFileId = logofileid;
} }
var faviconFieldId = _faviconfilemanager.GetFileId(); var faviconFieldId = _faviconfilemanager.GetFileId();
if (faviconFieldId != -1) if (faviconFieldId != -1)
{ {
site.FaviconFileId = faviconFieldId; site.FaviconFileId = faviconFieldId;
} }
site.DefaultThemeType = _themetype; site.DefaultThemeType = _themetype;
site.DefaultContainerType = _containertype; site.DefaultContainerType = _containertype;
site.AdminContainerType = _admincontainertype; 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)); site.PwaIsEnabled = (_pwaisenabled == null ? true : Boolean.Parse(_pwaisenabled));
var pwaappiconfileid = _pwaappiconfilemanager.GetFileId(); var pwaappiconfileid = _pwaappiconfilemanager.GetFileId();
if (pwaappiconfileid != -1) if (pwaappiconfileid != -1)
{ {
site.PwaAppIconFileId = pwaappiconfileid; site.PwaAppIconFileId = pwaappiconfileid;
} }
var pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId(); var pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId();
if (pwasplashiconfileid != -1) if (pwasplashiconfileid != -1)
{ {
@ -428,6 +478,17 @@
site = await SiteService.UpdateSiteAsync(site); site = await SiteService.UpdateSiteAsync(site);
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
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); var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList()) foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{ {
@ -448,41 +509,34 @@
await AliasService.AddAliasAsync(alias); await AliasService.AddAliasAsync(alias);
} }
} }
}
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
await logger.LogInformation("Site Settings Saved {Site}", site); await logger.LogInformation("Site Settings Saved {Site}", site);
if (refresh) if (refresh)
{ {
NavigationManager.NavigateTo(NavigateUrl()); // refresh to show new theme or container NavigationManager.NavigateTo(NavigateUrl()); // refresh to show new theme or container
} }
else else
{ {
AddModuleMessage(Localizer["Site Settings Saved"], MessageType.Success); AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
} }
} }
} }
else else
{ {
AddModuleMessage(Localizer["An Alias Specified Has Already Been Used For Another Site"], MessageType.Warning); AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning);
} }
} }
else 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); 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); await logger.LogInformation("Site Deleted {SiteId}", PageState.Site.SiteId);
var aliases = await AliasService.GetAliasesAsync(); 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); await AliasService.DeleteAliasAsync(a.AliasId);
} }
@ -506,13 +560,13 @@
} }
else else
{ {
AddModuleMessage(Localizer["You Are Not Authorized To Delete The Site"], MessageType.Warning); AddModuleMessage(Localizer["Message.FailAuth.DeleteSite"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Site {SiteId} {Error}", PageState.Site.SiteId, ex.Message); 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 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.")); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Testing SMTP Configuration"); await logger.LogError(ex, "Error Testing SMTP Configuration");
AddModuleMessage(Localizer["Error Testing SMTP Configuration"], MessageType.Error); AddModuleMessage(Localizer["Error.Smtp.TestConfig"], MessageType.Error);
} }
} }
else 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 IInstallationService InstallationService
@inject IDatabaseService DatabaseService @inject IDatabaseService DatabaseService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_tenants == null) @if (_tenants == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="Enter the name of the site" ResourceKey="Name">Site Name: </Label> <Label For="name" HelpText="Enter the name of the site" ResourceKey="Name">Site Name: </Label>
</td> </td>
<td> <td>
@ -40,8 +41,8 @@ else
<Label For="defaultTheme" HelpText="Select the default theme for the website" ResourceKey="DefaultTheme">Default Theme: </Label> <Label For="defaultTheme" HelpText="Select the default theme for the website" ResourceKey="DefaultTheme">Default Theme: </Label>
</td> </td>
<td> <td>
<select id="defaultTheme" class="form-control" @onchange="(e => ThemeChanged(e))"> <select id="defaultTheme" class="form-select" @onchange="(e => ThemeChanged(e))">
<option value="-">&lt;@Localizer["Select Theme"]&gt;</option> <option value="-">&lt;@Localizer["Theme.Select"]&gt;</option>
@foreach (var theme in _themes) @foreach (var theme in _themes)
{ {
<option value="@theme.TypeName">@theme.Name</option> <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> <Label For="defaultContainer" HelpText="Select the default container for the site" ResourceKey="DefaultContainer">Default Container: </Label>
</td> </td>
<td> <td>
<select id="defaultContainer" class="form-control" @bind="@_containertype"> <select id="defaultContainer" class="form-select" @bind="@_containertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <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> <Label For="adminContainer" HelpText="Select the admin container for the site" ResourceKey="AdminContainer">Admin Container: </Label>
</td> </td>
<td> <td>
<select id="adminContainer" class="form-control" @bind="@_admincontainertype"> <select id="adminContainer" class="form-select" @bind="@_admincontainertype">
<option value="-">&lt;@Localizer["Select Container"]&gt;</option> <option value="-">&lt;@Localizer["Container.Select"]&gt;</option>
<option value="">&lt;@Localizer["Default Admin Container"]&gt;</option> <option value="">&lt;@Localizer["DefaultContainer.Admin"]&gt;</option>
@foreach (var container in _containers) @foreach (var container in _containers)
{ {
<option value="@container.TypeName">@container.Name</option> <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> <Label For="siteTemplate" HelpText="Select the site template" ResourceKey="SiteTemplate">Site Template: </Label>
</td> </td>
<td> <td>
<select id="siteTemplate" class="form-control" @bind="@_sitetemplatetype"> <select id="siteTemplate" class="form-select" @bind="@_sitetemplatetype">
<option value="-">&lt;@Localizer["Select Site Template"]&gt;</option> <option value="-">&lt;@Localizer["SiteTemplate.Select"]&gt;</option>
@foreach (SiteTemplate siteTemplate in _siteTemplates) @foreach (SiteTemplate siteTemplate in _siteTemplates)
{ {
<option value="@siteTemplate.TypeName">@siteTemplate.Name</option> <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> <Label For="tenant" HelpText="Select the tenant for the site" ResourceKey="Tenant">Tenant: </Label>
</td> </td>
<td> <td>
<select id="tenant" class="form-control" @onchange="(e => TenantChanged(e))"> <select id="tenant" class="form-select" @onchange="(e => TenantChanged(e))">
<option value="-">&lt;@Localizer["Select Tenant"]&gt;</option> <option value="-">&lt;@Localizer["Tenant.Select"]&gt;</option>
<option value="+">&lt;@Localizer["Create New Tenant"]&gt;</option> <option value="+">&lt;@Localizer["Tenant.Add"]&gt;</option>
@foreach (Tenant tenant in _tenants) @foreach (Tenant tenant in _tenants)
{ {
<option value="@tenant.TenantId">@tenant.Name</option> <option value="@tenant.TenantId">@tenant.Name</option>
@ -127,11 +128,18 @@ else
<Label For="databaseType" HelpText="Select the database type for the tenant" ResourceKey="DatabaseType">Database Type: </Label> <Label For="databaseType" HelpText="Select the database type for the tenant" ResourceKey="DatabaseType">Database Type: </Label>
</td> </td>
<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) @foreach (var database in _databases)
{
if (database.IsDefault)
{
<option value="@database.Name" selected>@Localizer[@database.Name]</option>
}
else
{ {
<option value="@database.Name">@Localizer[@database.Name]</option> <option value="@database.Name">@Localizer[@database.Name]</option>
} }
}
</select> </select>
</td> </td>
</tr> </tr>
@ -157,8 +165,8 @@ else
</tr> </tr>
} }
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveSite">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveSite">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
} }
@code { @code {
@ -211,7 +219,7 @@ else
} }
catch 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Containers For Theme {ThemeType} {Error}", _themetype, ex.Message); 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 else
{ {
AddModuleMessage(Localizer["You Must Specify A Server And Database"], MessageType.Error); AddModuleMessage(Localizer["Error.Required.ServerDatabase"], MessageType.Error);
} }
} }
else else
{ {
AddModuleMessage(Localizer["Invalid Host Password"], MessageType.Error); AddModuleMessage(Localizer["Error.InvalidPassword"], MessageType.Error);
} }
} }
else else
{ {
AddModuleMessage(Localizer["Tenant Name Is Missing Or Already Exists"], MessageType.Error); AddModuleMessage(Localizer["Error.TenantName.Exists"], MessageType.Error);
} }
} }
else else
@ -365,12 +373,12 @@ else
} }
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 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 IAliasService AliasService
@inject ISiteService SiteService @inject ISiteService SiteService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_sites == null) @if (_sites == null)
{ {
@ -16,11 +17,13 @@ else
<Pager Items="@_sites"> <Pager Items="@_sites">
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th> <th style="width: 1px;">&nbsp;</th>
<th>@SharedLocalizer["Name"]</th>
</Header> </Header>
<Row> <Row>
<td><NavLink class="btn btn-primary" href="@(_scheme + context.Name +"/admin/site")">@Localizer["Edit"]</NavLink></td> <td><button type="button" class="btn btn-primary" @onclick="@(async () => Edit(context.Name))">@SharedLocalizer["Edit"]</button></td>
<td><a href="@(_scheme + context.Name +"?reload")">@context.Name</a></td> <td><button type="button" class="btn btn-secondary" @onclick="@(async () => Browse(context.Name))">@Localizer["Browse"]</button></td>
<td>@context.Name</td>
</Row> </Row>
</Pager> </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 @inherits ModuleBase
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject ITenantService TenantService @inject ITenantService TenantService
@inject IDatabaseService DatabaseService
@inject ISqlService SqlService @inject ISqlService SqlService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_tenants == null) @if (_tenants == null)
{ {
<p><em>Loading...</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="tenant" HelpText="Select the tenant for the SQL server" ResourceKey="Tenant">Tenant: </Label> <Label For="tenant" HelpText="Select the tenant for the SQL server" ResourceKey="Tenant">Tenant: </Label>
</td> </td>
<td> <td>
<select id="teneant" class="form-control" @bind="_tenantid"> <select id="tenant" class="form-select" value="@_tenantid" @onchange="(e => TenantChanged(e))">
<option value="-1">&lt;@Localizer["Select Tenant"]&gt;</option> <option value="-1">&lt;@Localizer["Tenant.Select"]&gt;</option>
@foreach (Tenant tenant in _tenants) @foreach (Tenant tenant in _tenants)
{ {
<option value="@tenant.TenantId">@tenant.Name</option> <option value="@tenant.TenantId">@tenant.Name</option>
@ -26,6 +28,24 @@ else
</select> </select>
</td> </td>
</tr> </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> <tr>
<td> <td>
<Label For="sqlQeury" HelpText="Enter the query for the SQL server" ResourceKey="SqlQuery">SQL Query: </Label> <Label For="sqlQeury" HelpText="Enter the query for the SQL server" ResourceKey="SqlQuery">SQL Query: </Label>
@ -34,6 +54,7 @@ else
<textarea id="sqlQeury" class="form-control" @bind="@_sql" rows="5"></textarea> <textarea id="sqlQeury" class="form-control" @bind="@_sql" rows="5"></textarea>
</td> </td>
</tr> </tr>
}
</table> </table>
<button type="button" class="btn btn-success" @onclick="Execute">@Localizer["Execute"]</button> <button type="button" class="btn btn-success" @onclick="Execute">@Localizer["Execute"]</button>
<br /> <br />
@ -47,27 +68,68 @@ else
@code { @code {
private List<Tenant> _tenants; private List<Tenant> _tenants;
private string _tenantid = "-1"; private string _tenantid = "-1";
private string _database = string.Empty;
private string _connectionstring = string.Empty;
private string _sql = string.Empty; private string _sql = string.Empty;
private string _results = string.Empty; private string _results = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{
try
{ {
_tenants = await TenantService.GetTenantsAsync(); _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() private async Task Execute()
{
try
{ {
if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql)) if (_tenantid != "-1" && !string.IsNullOrEmpty(_sql))
{ {
var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql }; var sqlquery = new SqlQuery { TenantId = int.Parse(_tenantid), Query = _sql };
sqlquery = await SqlService.ExecuteQueryAsync(sqlquery); sqlquery = await SqlService.ExecuteQueryAsync(sqlquery);
_results = DisplayResults(sqlquery.Results); _results = DisplayResults(sqlquery.Results);
AddModuleMessage(Localizer["Success.QueryExecuted"], MessageType.Success);
} }
else else
{ {
AddModuleMessage(Localizer["You Must Select A Tenant And Provide A SQL Query"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.Tenant"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Executing SQL Query {SQL} {Error}", _sql, ex.Message);
AddModuleMessage(ex.Message, MessageType.Error);
} }
} }
@ -105,7 +167,7 @@ else
} }
else else
{ {
table = Localizer["No Results Returned"]; table = Localizer["Return.NoResult"];
} }
return table; return table;

View File

@ -3,10 +3,13 @@
@inject ISystemService SystemService @inject ISystemService SystemService
@inject IInstallationService InstallationService @inject IInstallationService InstallationService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Info" Heading="Info" ResourceKey="Info">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="version" HelpText="Framework Version" ResourceKey="FrameworkVersion">Framework Version: </Label> <Label For="version" HelpText="Framework Version" ResourceKey="FrameworkVersion">Framework Version: </Label>
</td> </td>
<td> <td>
@ -15,23 +18,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<Label For="runtime" HelpText="Blazor Runtime (Server or WebAssembly)" ResourceKey="BlazorRuntime">Blazor Runtime: </Label> <Label For="clrversion" HelpText="Common Language Runtime Version" ResourceKey="CLRVersion">CLR Version: </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>
<td> <td>
<input id="clrversion" class="form-control" @bind="@_clrversion" readonly /> <input id="clrversion" class="form-control" @bind="@_clrversion" readonly />
@ -39,7 +26,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<Label For="osversion" HelpText="Operating System Version" ResourceKey="OsVersion">OS Version: </Label> <Label For="osversion" HelpText="Operating System Version" ResourceKey="OSVersion">OS Version: </Label>
</td> </td>
<td> <td>
<input id="osversion" class="form-control" @bind="@_osversion" readonly /> <input id="osversion" class="form-control" @bind="@_osversion" readonly />
@ -61,34 +48,161 @@
<input id="servertime" class="form-control" @bind="@_servertime" readonly /> <input id="servertime" class="form-control" @bind="@_servertime" readonly />
</td> </td>
</tr> </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> </table>
<a class="btn btn-primary" href="swagger/index.html" target="_new">@Localizer["Access Framework API"]</a>&nbsp; <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" /> <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 { @code {
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
private string _version = string.Empty; private string _version = string.Empty;
private string _runtime = string.Empty;
private string _rendermode = string.Empty;
private string _clrversion = string.Empty; private string _clrversion = string.Empty;
private string _osversion = string.Empty; private string _osversion = string.Empty;
private string _serverpath = string.Empty; private string _serverpath = string.Empty;
private string _servertime = 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() protected override async Task OnInitializedAsync()
{ {
_version = Constants.Version; _version = Constants.Version;
_runtime = PageState.Runtime.ToString();
Dictionary<string, string> systeminfo = await SystemService.GetSystemInfoAsync(); Dictionary<string, string> systeminfo = await SystemService.GetSystemInfoAsync();
if (systeminfo != null) if (systeminfo != null)
{ {
_rendermode = systeminfo["rendermode"];
_clrversion = systeminfo["clrversion"]; _clrversion = systeminfo["clrversion"];
_osversion = systeminfo["osversion"]; _osversion = systeminfo["osversion"];
_serverpath = systeminfo["serverpath"]; _serverpath = systeminfo["serverpath"];
_servertime = systeminfo["servertime"]; _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(); ShowProgressIndicator();
var interop = new Interop(JSRuntime); var interop = new Interop(JSRuntime);
await interop.RedirectBrowser(NavigateUrl(""), 10); await interop.RedirectBrowser(NavigateUrl(""), 20);
await InstallationService.RestartAsync(); await InstallationService.RestartAsync();
} }
catch (Exception ex) catch (Exception ex)
@ -106,4 +220,20 @@
await logger.LogError(ex, "Error Restarting Application"); 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,30 +5,50 @@
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<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) @if (_packages != null)
{ {
<TabStrip> if (_packages.Count > 0)
@if (_packages.Count > 0)
{ {
<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>
<Pager Items="@_packages"> <Pager Items="@_packages">
<Header>
<th>@Localizer["Name"]</th>
<th>@Localizer["Version"]</th>
<th style="width: 1px;"></th>
</Header>
<Row> <Row>
<td>@context.Name</td>
<td>@context.Version</td>
<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> </td>
</Row> </Row>
</Pager> </Pager>
</TabPanel>
} }
else
{
<br />
<div class="mx-auto text-center">
@Localizer["Search.NoResults"]
</div>
}
}
</TabPanel>
<TabPanel Name="Upload" ResourceKey="Upload"> <TabPanel Name="Upload" ResourceKey="Upload">
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
@ -43,12 +63,12 @@
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-success" @onclick="InstallThemes">@Localizer["Install"]</button> <button type="button" class="btn btn-success" @onclick="InstallThemes">@SharedLocalizer["Install"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code { @code {
private List<Package> _packages; private List<Package> _packages;
private string _search = "";
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
@ -56,9 +76,22 @@
{ {
try try
{ {
var themes = await ThemeService.GetThemesAsync(); await LoadThemes();
_packages = await PackageService.GetPackagesAsync("theme"); }
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()) foreach (Package package in _packages.ToArray())
{ {
if (themes.Exists(item => item.PackageName == package.PackageId)) if (themes.Exists(item => item.PackageName == package.PackageId))
@ -67,10 +100,30 @@
} }
} }
} }
}
private async Task Search()
{
try
{
await LoadThemes();
}
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Packages {Error}", ex.Message); await logger.LogError(ex, "Error On Search");
AddModuleMessage(Localizer["Error Loading Packages"], MessageType.Error); }
}
private async Task Reset()
{
try
{
_search = "";
await LoadThemes();
}
catch (Exception ex)
{
await logger.LogError(ex, "Error On Reset");
} }
} }
@ -79,7 +132,7 @@
try try
{ {
await ThemeService.InstallThemesAsync(); 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) catch (Exception ex)
{ {
@ -93,13 +146,13 @@
{ {
await PackageService.DownloadPackageAsync(packageid, version, "Packages"); await PackageService.DownloadPackageAsync(packageid, version, "Packages");
await logger.LogInformation("Theme {ThemeName} {Version} Downloaded Successfully", packageid, version); 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(); StateHasChanged();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Module {ThemeName} {Version}", packageid, version); 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 IModuleService ModuleService
@inject IPageModuleService PageModuleService @inject IPageModuleService PageModuleService
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Create> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_templates != null) @if (_templates != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <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>
<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> <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>
<td> <td>
<select id="template" class="form-control" @onchange="(e => TemplateChanged(e))"> <select id="template" class="form-select" @onchange="(e => TemplateChanged(e))">
<option value="-">&lt;@Localizer["Select Template"]&gt;</option> <option value="-">&lt;@Localizer["Template.Select"]&gt;</option>
@foreach (Template template in _templates) @foreach (Template template in _templates)
{ {
<option value="@template.Name">@template.Title</option> <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> <Label For="reference" HelpText="Select a framework reference version" ResourceKey="FrameworkReference">Framework Reference: </Label>
</td> </td>
<td> <td>
<select id="reference" class="form-control" @bind="@_reference"> <select id="reference" class="form-select" @bind="@_reference">
@foreach (string version in _versions) @foreach (string version in _versions)
{ {
if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0) if (Version.Parse(version).CompareTo(Version.Parse(_minversion)) >= 0)
@ -54,7 +55,7 @@
<option value="@(version)">@(version)</option> <option value="@(version)">@(version)</option>
} }
} }
<option value="local">@Localizer["Local Version"]</option> <option value="local">@SharedLocalizer["LocalVersion"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -70,8 +71,8 @@
</tr> </tr>
} }
</table> </table>
<button type="button" class="btn btn-success" @onclick="CreateTheme">@Localizer["Create Theme"]</button> <button type="button" class="btn btn-success" @onclick="CreateTheme">@Localizer["Theme.Create"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
} }
@code { @code {
@ -92,7 +93,7 @@
{ {
_templates = await ThemeService.GetThemeTemplatesAsync(); _templates = await ThemeService.GetThemeTemplatesAsync();
_versions = Constants.ReleaseVersions.Split(',').Where(item => Version.Parse(item).CompareTo(Version.Parse("2.0.0")) >= 0).ToArray(); _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) catch (Exception ex)
{ {
@ -109,11 +110,11 @@
var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference }; var theme = new Theme { Owner = _owner, Name = _theme, Template = _template, Version = _reference };
theme = await ThemeService.CreateThemeAsync(theme); theme = await ThemeService.CreateThemeAsync(theme);
GetLocation(); 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 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) catch (Exception ex)

View File

@ -5,23 +5,24 @@
@inject IThemeService ThemeService @inject IThemeService ThemeService
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_themes == null) @if (_themes == null)
{ {
<p><em>Loading...</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<ActionLink Action="Add" Text="Install Theme" /> <ActionLink Action="Add" Text="Install Theme" />
@((MarkupString)"&nbsp;") @((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"> <Pager Items="@_themes">
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
<th scope="col">@Localizer["Name"]</th> <th scope="col">@SharedLocalizer["Name"]</th>
<th scope="col">@Localizer["Version"]</th> <th scope="col">@SharedLocalizer["Version"]</th>
<th>&nbsp;</th> <th>&nbsp;</th>
</Header> </Header>
<Row> <Row>
@ -29,7 +30,7 @@ else
<td> <td>
@if (context.AssemblyName != "Oqtane.Client") @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>
<td>@context.Name</td> <td>@context.Name</td>
@ -37,7 +38,7 @@ else
<td> <td>
@if (UpgradeAvailable(context.PackageName, context.Version)) @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></td> <td></td>
@ -63,7 +64,7 @@ else
if (_themes == null) if (_themes == null)
{ {
await logger.LogError(ex, "Error Loading Themes {Error}", ex.Message); 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 PackageService.DownloadPackageAsync(packagename, version, "Packages");
await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version); await logger.LogInformation("Theme Downloaded {ThemeName} {Version}", packagename, version);
await ThemeService.InstallThemesAsync(); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Theme {ThemeName} {Version} {Error}", packagename, version, ex.Message); 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 try
{ {
await ThemeService.DeleteThemeAsync(Theme.ThemeName); await ThemeService.DeleteThemeAsync(Theme.ThemeName);
AddModuleMessage(Localizer["Theme Deleted Successfully"], MessageType.Success); AddModuleMessage(Localizer["Success.Theme.Delete"], MessageType.Success);
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, "reload")); NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Deleting Theme {Theme} {Error}", Theme, ex.Message); 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 IThemeService ThemeService
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IStringLocalizer<View> Localizer @inject IStringLocalizer<View> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="name" HelpText="The name of the theme" ResourceKey="Name">Name: </Label> <Label For="name" HelpText="The name of the theme" ResourceKey="Name">Name: </Label>
</td> </td>
<td> <td>
@ -63,7 +64,7 @@
</td> </td>
</tr> </tr>
</table> </table>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code { @code {
private string _themeName = ""; private string _themeName = "";
@ -96,7 +97,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Theme {ThemeName} {Error}", _themeName, ex.Message); 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,16 +5,15 @@
@inject IPackageService PackageService @inject IPackageService PackageService
@inject IInstallationService InstallationService @inject IInstallationService InstallationService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_package != null)
{
<TabStrip> <TabStrip>
<TabPanel Name="Download" ResourceKey="Download"> <TabPanel Name="Download" ResourceKey="Download">
@if (_upgradeavailable) @if (_package != null && _upgradeavailable)
{ {
<ModuleMessage Type="MessageType.Info" Message="Select The Download Button To Download The Framework Upgrade Package And Then Select Upgrade"></ModuleMessage> <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-primary" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>@SharedLocalizer["Download"] @_package.Version</button>
<button type="button" class="btn btn-success" @onclick="Upgrade">@Localizer["Upgrade"]</button> <button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
} }
else else
{ {
@ -33,10 +32,9 @@
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="Upgrade">@Localizer["Upgrade"]</button> <button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
}
@code { @code {
private Package _package; private Package _package;
@ -72,16 +70,16 @@
{ {
try try
{ {
AddModuleMessage(Localizer["Please Be Patient While The Upgrade Is In Progress..."], MessageType.Info); AddModuleMessage(Localizer["Info.Upgrade.Wait"], MessageType.Info);
ShowProgressIndicator(); ShowProgressIndicator();
var interop = new Interop(JSRuntime); var interop = new Interop(JSRuntime);
await interop.RedirectBrowser(NavigateUrl(), 30); await interop.RedirectBrowser(NavigateUrl(), 20);
await InstallationService.Upgrade(); await InstallationService.Upgrade();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Executing Upgrade {Error}", ex.Message); 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(packageid, version, "Packages");
await PackageService.DownloadPackageAsync(Constants.UpdaterPackageId, 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Downloading Framework Package {Error}", ex.Message); 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

@ -4,12 +4,13 @@
@inject IUserService UserService @inject IUserService UserService
@inject INotificationService NotificationService @inject INotificationService NotificationService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null) @if (PageState.User != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label> <Label For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
</td> </td>
<td> <td>
@ -33,8 +34,8 @@
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-primary" @onclick="Send">@Localizer["Send"]</button> <button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
} }
@code { @code {
@ -60,13 +61,13 @@
} }
else else
{ {
AddModuleMessage(Localizer["User Does Not Exist. Please Verify That The Username Provided Is Correct."], MessageType.Warning); AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message); await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error); AddModuleMessage(Localizer["Error.Notification.Add"], MessageType.Error);
} }
} }

View File

@ -7,6 +7,7 @@
@inject INotificationService NotificationService @inject INotificationService NotificationService
@inject IFileService FileService @inject IFileService FileService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null && photo != null) @if (PageState.User != null && photo != null)
{ {
@ -22,56 +23,56 @@ else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<label for="Name" class="control-label">@Localizer["Username:"] </label> <Label For="username" HelpText="Your username. Note that this field can not be modified." ResourceKey="Username"></Label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@username" readonly /> <input id="username" class="form-control" @bind="@username" readonly />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<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> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<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> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input class="form-control" @bind="@email" /> <input id="email" class="form-control" @bind="@email" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label for="Name" class="control-label">@Localizer["Full Name:"] </label> <Label For="displayname" HelpText="Your full name" ResourceKey="DisplayName"></Label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@displayname" /> <input id="displayname" class="form-control" @bind="@displayname" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label for="Name" class="control-label">@Localizer["Photo:"] </label> <Label For="@photofileid.ToString()" HelpText="A photo of yourself" ResourceKey="Photo"></Label>
</td> </td>
<td> <td>
<FileManager FileId="@photofileid" @ref="filemanager" /> <FileManager FileId="@photofileid" @ref="filemanager" />
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-primary" @onclick="Save">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="Save">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
} }
</TabPanel> </TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile"> <TabPanel Name="Profile" ResourceKey="Profile">
@ -93,13 +94,13 @@ else
category = p.Category; category = p.Category;
} }
<tr> <tr>
<td> <td width="30%">
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label> <Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
</td> </td>
<td> <td>
@if (!string.IsNullOrEmpty(p.Options)) @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)) @foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{ {
@if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option)) @if (GetProfileValue(p.Name, "") == option || (GetProfileValue(p.Name, "") == "" && p.DefaultValue == option))
@ -129,8 +130,8 @@ else
} }
} }
</table> </table>
<button type="button" class="btn btn-primary" @onclick="Save">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="Save">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button> <button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
} }
</TabPanel> </TabPanel>
<TabPanel Name="Notifications" ResourceKey="Notifications"> <TabPanel Name="Notifications" ResourceKey="Notifications">
@ -205,9 +206,9 @@ else
</Pager> </Pager>
} }
<br /><hr /> <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="to">@Localizer["Inbox"]</option>
<option value="from">@Localizer["Sent Items"]</option> <option value="from">@Localizer["Items.Sent"]</option>
</select> </select>
} }
</TabPanel> </TabPanel>
@ -258,13 +259,13 @@ else
} }
else else
{ {
AddModuleMessage(Localizer["Current User Is Not Logged In"], MessageType.Warning); AddModuleMessage(Localizer["Message.User.NoLogIn"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); 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 else
{ {
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); AddModuleMessage(Localizer["Message.Password.Invalid"], MessageType.Warning);
} }
} }
else 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving User Profile {Error}", ex.Message); 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

@ -4,13 +4,14 @@
@inject IUserService UserService @inject IUserService UserService
@inject INotificationService NotificationService @inject INotificationService NotificationService
@inject IStringLocalizer<View> Localizer @inject IStringLocalizer<View> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null) @if (PageState.User != null)
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<label class="control-label">@Localizer["Title:"] </label> <label class="control-label">@Localizer["Title"] </label>
</td> </td>
@if (title == "From") @if (title == "From")
{ {
@ -27,7 +28,7 @@
</tr> </tr>
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Subject:"] </label> <label class="control-label">@Localizer["Subject"] </label>
</td> </td>
@if (title == "From") @if (title == "From")
{ {
@ -46,7 +47,7 @@
{ {
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Date:"] </label> <label class="control-label">@Localizer["Date"] </label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@createdon" readonly /> <input class="form-control" @bind="@createdon" readonly />
@ -57,7 +58,7 @@
{ {
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Message:"] </label> <label class="control-label">@Localizer["Message"] </label>
</td> </td>
<td> <td>
<textarea class="form-control" @bind="@body" rows="5" readonly /> <textarea class="form-control" @bind="@body" rows="5" readonly />
@ -68,7 +69,7 @@
{ {
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Message:"] </label> <label class="control-label">@Localizer["Message"] </label>
</td> </td>
<td> <td>
<textarea class="form-control" @bind="@body" rows="5" /> <textarea class="form-control" @bind="@body" rows="5" />
@ -80,7 +81,7 @@
@if (reply != string.Empty) @if (reply != string.Empty)
{ {
<button type="button" class="btn btn-primary" @onclick="Send">@Localizer["Send"]</button> <button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
} }
else else
{ {
@ -89,7 +90,7 @@
<button type="button" class="btn btn-primary" @onclick="Reply">@Localizer["Reply"]</button> <button type="button" class="btn btn-primary" @onclick="Reply">@Localizer["Reply"]</button>
} }
} }
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /> <br />
<br /> <br />
@if (title == "To") @if (title == "To")
@ -158,7 +159,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Users {Error}", ex.Message); await logger.LogError(ex, "Error Loading Users {Error}", ex.Message);
AddModuleMessage(Localizer["Error Loading Users"], MessageType.Error); AddModuleMessage(Localizer["Error.User.Load"], MessageType.Error);
} }
} }
@ -188,13 +189,13 @@
} }
else else
{ {
AddModuleMessage(Localizer["User Does Not Exist. Please Verify That The Username Provided Is Correct."], MessageType.Warning); AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message); await logger.LogError(ex, "Error Adding Notification {Error}", ex.Message);
AddModuleMessage(Localizer["Error Adding Notification"], MessageType.Error); AddModuleMessage(Localizer["Error.Notification.Add"], MessageType.Error);
} }
} }
} }

View File

@ -5,6 +5,7 @@
@inject IProfileService ProfileService @inject IProfileService ProfileService
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IStringLocalizer<Add> Localizer @inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip> <TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity"> <TabPanel Name="Identity" ResourceKey="Identity">
@ -12,43 +13,43 @@
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<label class="control-label">@Localizer["Username:"] </label> <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>
<td> <td>
<input class="form-control" @bind="@username" /> <input id="username" class="form-control" @bind="@username" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input type="password" class="form-control" @bind="@password" /> <input id="password" type="password" class="form-control" @bind="@password" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input type="password" class="form-control" @bind="@confirm" /> <input id="confirm" type="password" class="form-control" @bind="@confirm" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input class="form-control" @bind="@email" /> <input id="email" class="form-control" @bind="@email" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Full Name:"] </label> <Label For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@displayname" /> <input id="displayname" class="form-control" @bind="@displayname" />
</td> </td>
</tr> </tr>
</table> </table>
@ -71,7 +72,7 @@
category = p.Category; category = p.Category;
} }
<tr> <tr>
<td> <td width="30%">
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label> <Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
</td> </td>
<td> <td>
@ -91,8 +92,8 @@
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-primary" @onclick="SaveUser">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@code { @code {
private string username = string.Empty; private string username = string.Empty;
@ -116,7 +117,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading User Profile {Error}", ex.Message); 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 else
{ {
await logger.LogError("Error Adding User {Username} {Email}", username, email); 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 else
{ {
AddModuleMessage(Localizer["Username Already Exists"], MessageType.Warning); AddModuleMessage(Localizer["Message.Username.Exists"], MessageType.Warning);
} }
} }
else else
{ {
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
} }
} }
else 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", username, email, ex.Message); await logger.LogError(ex, "Error Adding User {Username} {Email} {Error}", username, email, ex.Message);
AddModuleMessage(Localizer["Error Adding User"], MessageType.Error); AddModuleMessage(Localizer["Error.User.Add"], MessageType.Error);
} }
} }

View File

@ -6,6 +6,7 @@
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IFileService FileService @inject IFileService FileService
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null && photo != null) @if (PageState.User != null && photo != null)
{ {
@ -21,48 +22,48 @@ else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<label class="control-label">@Localizer["Username:"] </label> <Label For="username" HelpText="The unique username for a user. Note that this field can not be modified." ResourceKey="Username"></Label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@username" readonly /> <input id="username" class="form-control" @bind="@username" readonly />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input type="password" class="form-control" @bind="@password" /> <input id="password" type="password" class="form-control" @bind="@password" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input type="password" class="form-control" @bind="@confirm" /> <input id="confirm" type="password" class="form-control" @bind="@confirm" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <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>
<td> <td>
<input class="form-control" @bind="@email" /> <input id="email" class="form-control" @bind="@email" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Full Name:"] </label> <Label For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
</td> </td>
<td> <td>
<input class="form-control" @bind="@displayname" /> <input id="displayname" class="form-control" @bind="@displayname" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Photo:"] </label> <Label For="@photofileid.ToString()" HelpText="A photo of the user" ResourceKey="Photo"></Label>
</td> </td>
<td> <td>
<FileManager FileId="@photofileid" @ref="filemanager" /> <FileManager FileId="@photofileid" @ref="filemanager" />
@ -70,12 +71,12 @@ else
</tr> </tr>
<tr> <tr>
<td> <td>
<label class="control-label">@Localizer["Is Deleted?"] </label> <Label For="isdeleted" HelpText="Indicate if the user is active" ResourceKey="IsDeleted"></Label>
</td> </td>
<td> <td>
<select class="form-control" @bind="@isdeleted"> <select id="isdeleted" class="form-select" @bind="@isdeleted">
<option value="True">@Localizer["Yes"]</option> <option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@Localizer["No"]</option> <option value="False">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>
@ -99,7 +100,7 @@ else
category = p.Category; category = p.Category;
} }
<tr> <tr>
<td> <td width="30%">
<Label For="@p.Name" HelpText="@p.Description">@p.Title</Label> <Label For="@p.Name" HelpText="@p.Description">@p.Title</Label>
</td> </td>
<td> <td>
@ -119,8 +120,8 @@ else
</TabPanel> </TabPanel>
</TabStrip> </TabStrip>
<button type="button" class="btn btn-primary" @onclick="SaveUser">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br /> <br />
<br /> <br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo> <AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
@ -151,9 +152,11 @@ else
protected override async Task OnParametersSetAsync() protected override async Task OnParametersSetAsync()
{ {
try try
{
// OnParametersSetAsync is called when the edit modal is closed - in which case there is no id parameter
if (PageState.QueryString.ContainsKey("id"))
{ {
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId); profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
userid = Int32.Parse(PageState.QueryString["id"]); userid = Int32.Parse(PageState.QueryString["id"]);
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId); var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
if (user != null) if (user != null)
@ -181,10 +184,11 @@ else
isdeleted = user.IsDeleted.ToString(); isdeleted = user.IsDeleted.ToString();
} }
} }
}
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading User {UserId} {Error}", userid, ex.Message); 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 else
{ {
AddModuleMessage(Localizer["Passwords Entered Do Not Match"], MessageType.Warning); AddModuleMessage(Localizer["Message.Password.NoMatch"], MessageType.Warning);
} }
} }
else 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving User {Username} {Email} {Error}", username, email, ex.Message); 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 IUserService UserService
@inject ISettingService SettingService @inject ISettingService SettingService
@inject IStringLocalizer<Index> Localizer @inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (userroles == null) @if (userroles == null)
{ {
<p> <p>
<em>@Localizer["Loading..."]</em> <em>@SharedLocalizer["Loading"]</em>
</p> </p>
} }
else else
{ {
<div class="form-row"> <table class="table table-borderless">
<div class="col"> <tr>
<ActionLink Action="Add" Text="Add User" ResourceKey="AddUser" /> <td>
</div> <div><ActionLink Action="Add" Text="Add User" ResourceKey="AddUser" /></div>
<div class="col"> </td>
<div class="input-group flex-nowrap"> <td>
<input class="form-control" @bind="@_search" />&nbsp;<button class="btn btn-secondary" @onclick="OnSearch">@Localizer["Search"]</button> <input class="form-control" @bind="@_search" />
</div> </td>
</div> <td>
</div> <button class="btn btn-secondary" @onclick="OnSearch">@SharedLocalizer["Search"]</button>
</td>
</tr>
</table>
<Pager Items="@userroles"> <Pager Items="@userroles">
<Header> <Header>
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th> <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> </Header>
<Row> <Row>
<td> <td>
<ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="EditUser" /> <ActionLink Action="Edit" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="EditUser" />
</td> </td>
<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>
<td> <td>
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" /> <ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" />

View File

@ -4,16 +4,17 @@
@inject IUserService UserService @inject IUserService UserService
@inject IUserRoleService UserRoleService @inject IUserRoleService UserRoleService
@inject IStringLocalizer<Roles> Localizer @inject IStringLocalizer<Roles> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (userroles == null) @if (userroles == null)
{ {
<p><em>@Localizer["Loading..."]</em></p> <p><em>@SharedLocalizer["Loading"]</em></p>
} }
else else
{ {
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td> <td width="30%">
<Label For="user" HelpText="The user you are assigning roles to" ResourceKey="User">User: </Label> <Label For="user" HelpText="The user you are assigning roles to" ResourceKey="User">User: </Label>
</td> </td>
<td> <td>
@ -25,8 +26,8 @@ else
<Label For="role" HelpText="Select a role" ResourceKey="Role">Role: </Label> <Label For="role" HelpText="Select a role" ResourceKey="Role">Role: </Label>
</td> </td>
<td> <td>
<select id="role" class="form-control" @bind="@roleid"> <select id="role" class="form-select" @bind="@roleid">
<option value="-1">&lt;@Localizer["Select Role"]&gt;</option> <option value="-1">&lt;@Localizer["Role.Select"]&gt;</option>
@foreach (Role role in roles) @foreach (Role role in roles)
{ {
<option value="@(role.RoleId)">@role.Name</option> <option value="@(role.RoleId)">@role.Name</option>
@ -51,8 +52,8 @@ else
</td> </td>
</tr> </tr>
</table> </table>
<button type="button" class="btn btn-success" @onclick="SaveUserRole">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveUserRole">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<hr class="app-rule" /> <hr class="app-rule" />
<p align="center"> <p align="center">
@ -68,7 +69,7 @@ else
<td>@context.EffectiveDate</td> <td>@context.EffectiveDate</td>
<td>@context.ExpiryDate</td> <td>@context.ExpiryDate</td>
<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> </td>
</Row> </Row>
</Pager> </Pager>
@ -107,7 +108,7 @@ else
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Roles {Error}", ex.Message); 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) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading User Roles {UserId} {Error}", userid, ex.Message); 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); 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(); await GetUserRoles();
StateHasChanged(); StateHasChanged();
} }
else else
{ {
AddModuleMessage(Localizer["You Must Select A Role"], MessageType.Warning); AddModuleMessage(Localizer["Message.Required.Role"], MessageType.Warning);
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving User Roles {UserId} {Error}", userid, ex.Message); 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 UserRoleService.DeleteUserRoleAsync(UserRoleId);
await logger.LogInformation("User Removed From Role {UserRoleId}", 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(); await GetUserRoles();
StateHasChanged(); StateHasChanged();
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Removing User From Role {UserRoleId} {Error}", UserRoleId, ex.Message); 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-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title">@Header</h5> <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>
<div class="modal-body"> <div class="modal-body">
<p>@Message</p> <p>@Message</p>

View File

@ -44,12 +44,12 @@
if (!String.IsNullOrEmpty(CreatedBy)) if (!String.IsNullOrEmpty(CreatedBy))
{ {
_text += $" {Localizer["by"]} <b>{CreatedBy}</b>"; _text += $" {Localizer["By"]} <b>{CreatedBy}</b>";
} }
if (CreatedOn != null) 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>"; _text += "</p>";
@ -57,7 +57,7 @@
if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn.HasValue) if (!String.IsNullOrEmpty(ModifiedBy) || ModifiedOn.HasValue)
{ {
_text += $"<p style=\"{Style}\">{Localizer["Last modified"]} "; _text += $"<p style=\"{Style}\">{Localizer["LastModified"]} ";
if (!String.IsNullOrEmpty(ModifiedBy)) if (!String.IsNullOrEmpty(ModifiedBy))
{ {
@ -78,12 +78,12 @@
if (!String.IsNullOrEmpty(DeletedBy)) if (!String.IsNullOrEmpty(DeletedBy))
{ {
_text += $" {Localizer["by"]} <b>{DeletedBy}</b>"; _text += $" {Localizer["By"]} <b>{DeletedBy}</b>";
} }
if (DeletedOn != null) 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>"; _text += "</p>";

View File

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

View File

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

View File

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

View File

@ -8,15 +8,15 @@
<div class="mx-auto text-center"> <div class="mx-auto text-center">
@if (_endPage > 1) @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) @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) @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++) @for (int i = _startPage; i <= _endPage; i++)
{ {
var pager = i; var pager = i;
@ -24,15 +24,15 @@
@pager @pager
</button> </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) @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) @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) @if (_endPage > 1)
{ {

View File

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

View File

@ -14,7 +14,7 @@
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage> <ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
<br /> <br />
} }
<div class="row justify-content-center" style="margin-bottom: 20px;"> <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-secondary" @onclick="RefreshRichText">@Localizer["SynchronizeContent"]</button>&nbsp;&nbsp;
<button type="button" class="btn btn-primary" @onclick="InsertImage">@Localizer["InsertImage"]</button> <button type="button" class="btn btn-primary" @onclick="InsertImage">@Localizer["InsertImage"]</button>
@if (_filemanagervisible) @if (_filemanagervisible)
@ -66,7 +66,7 @@
</div> </div>
</TabPanel> </TabPanel>
<TabPanel Name="Raw" Heading="Raw HTML Editor" ResourceKey="HtmlEditor"> <TabPanel Name="Raw" Heading="Raw HTML Editor" ResourceKey="HtmlEditor">
<div class="row justify-content-center" style="margin-bottom: 20px;"> <div class="d-flex justify-content-center mb-2">
<button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">@Localizer["SynchronizeContent"]</button> <button type="button" class="btn btn-secondary" @onclick="RefreshRawHtml">@Localizer["SynchronizeContent"]</button>
</div> </div>
@if (ReadOnly) @if (ReadOnly)
@ -143,6 +143,8 @@
await interop.LoadEditorContent(_editorElement, Content); 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 ) // 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); _original = await interop.GetHtml(_editorElement);
} }
@ -200,7 +202,7 @@
} }
else else
{ {
_message = Localizer["You Must Select An Image To Insert"]; _message = Localizer["Message.Require.Image"];
} }
} }
else else

View File

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

View File

@ -10,13 +10,13 @@
<li class="nav-item" @key="tabPanel.Name"> <li class="nav-item" @key="tabPanel.Name">
@if (tabPanel.Name == ActiveTab) @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() @tabPanel.DisplayHeading()
</a> </a>
} }
else 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() @tabPanel.DisplayHeading()
</a> </a>
} }

View File

@ -7,12 +7,13 @@
@inject ISettingService SettingService @inject ISettingService SettingService
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject IStringLocalizer<Edit> Localizer @inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (_content != null) @if (_content != null)
{ {
<RichTextEditor Content="@_content" AllowFileManagement="@_allowfilemanagement" @ref="@RichTextEditorHtml"></RichTextEditor> <RichTextEditor Content="@_content" AllowFileManagement="@_allowfilemanagement" @ref="@RichTextEditorHtml"></RichTextEditor>
<button type="button" class="btn btn-success" @onclick="SaveContent">@Localizer["Save"]</button> <button type="button" class="btn btn-success" @onclick="SaveContent">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink> <NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
@if (!string.IsNullOrEmpty(_content)) @if (!string.IsNullOrEmpty(_content))
{ {
<br /> <br />
@ -96,7 +97,7 @@
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Saving Content {Error}", ex.Message); 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,12 +2,16 @@
@namespace Oqtane.Modules.HtmlText @namespace Oqtane.Modules.HtmlText
@inherits ModuleBase @inherits ModuleBase
@inject IHtmlTextService HtmlTextService @inject IHtmlTextService HtmlTextService
@inject IStringLocalizer<Edit> Localizer
@((MarkupString)content) @((MarkupString)content)
@if (PageState.EditMode) @if (PageState.EditMode)
{ {
<br /><ActionLink Action="Edit" EditMode="true" ResourceKey="Edit" /><br /><br /> <br />
<ActionLink Action="Edit" EditMode="true" ResourceKey="Edit" />
<br />
<br />
} }
@code { @code {

View File

@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Oqtane.Services; using Oqtane.Services;
@ -9,34 +7,28 @@ namespace Oqtane.Modules.HtmlText.Services
{ {
public class HtmlTextService : ServiceBase, IHtmlTextService, IService 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) private string ApiUrl => CreateApiUrl("HtmlText");
{
_siteState = siteState;
}
private string ApiUrl => CreateApiUrl("HtmlText", _siteState.Alias);
public async Task<Models.HtmlText> GetHtmlTextAsync(int moduleId) 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 await GetJsonAsync<Models.HtmlText>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", EntityNames.Module, moduleId));
return htmltext.FirstOrDefault();
} }
public async Task AddHtmlTextAsync(Models.HtmlText htmlText) 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) 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) 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 @inject ISettingService SettingService
@implements Oqtane.Interfaces.ISettingsControl @implements Oqtane.Interfaces.ISettingsControl
@inject IStringLocalizer<Settings> Localizer @inject IStringLocalizer<Settings> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <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> <Label For="files" ResourceKey="Allow File Management" HelpText="Specify If Editors Can Upload and Select Files">Allow File Management: </Label>
</td> </td>
<td> <td>
<select id="files" class="form-control" @bind="@_allowfilemanagement"> <select id="files" class="form-select" @bind="@_allowfilemanagement">
<option value="true">@Localizer["Yes"]</option> <option value="true">@SharedLocalizer["Yes"]</option>
<option value="false">@Localizer["No"]</option> <option value="false">@SharedLocalizer["No"]</option>
</select> </select>
</td> </td>
</tr> </tr>

View File

@ -84,11 +84,21 @@ namespace Oqtane.Modules
return NavigateUrl(path, ""); return NavigateUrl(path, "");
} }
public string NavigateUrl(bool refresh)
{
return NavigateUrl(PageState.Page.Path, refresh);
}
public string NavigateUrl(string path, string parameters) public string NavigateUrl(string path, string parameters)
{ {
return Utilities.NavigateUrl(PageState.Alias.Path, path, 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) public string EditUrl(string action)
{ {
return EditUrl(ModuleState.ModuleId, action); return EditUrl(ModuleState.ModuleId, action);

View File

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

View File

@ -8,14 +8,11 @@ using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Runtime.Loader; using System.Runtime.Loader;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop; using Microsoft.JSInterop;
using Oqtane.Interfaces;
using Oqtane.Modules; using Oqtane.Modules;
using Oqtane.Providers;
using Oqtane.Services; using Oqtane.Services;
using Oqtane.Shared; using Oqtane.Shared;
using Oqtane.UI; using Oqtane.UI;
@ -28,7 +25,8 @@ namespace Oqtane.Client
{ {
var builder = WebAssemblyHostBuilder.CreateDefault(args); var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app"); 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.AddSingleton(httpClient);
builder.Services.AddOptions(); builder.Services.AddOptions();
@ -37,38 +35,10 @@ namespace Oqtane.Client
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
// register auth services // register auth services
builder.Services.AddAuthorizationCore(); builder.Services.AddOqtaneAuthorization();
builder.Services.AddScoped<IdentityAuthenticationStateProvider>();
builder.Services.AddScoped<AuthenticationStateProvider>(s => s.GetRequiredService<IdentityAuthenticationStateProvider>());
// register scoped core services // register scoped core services
builder.Services.AddScoped<SiteState>(); builder.Services.AddOqtaneScopedServices();
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>();
await LoadClientAssemblies(httpClient); await LoadClientAssemblies(httpClient);
@ -76,38 +46,15 @@ namespace Oqtane.Client
foreach (var assembly in assemblies) foreach (var assembly in assemblies)
{ {
// dynamically register module services // dynamically register module services
var implementationTypes = assembly.GetInterfaces<IService>(); RegisterModuleServices(assembly, builder.Services);
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);
}
}
// register client startup services // register client startup services
var startUps = assembly.GetInstances<IClientStartup>(); RegisterClientStartups(assembly, builder.Services);
foreach (var startup in startUps)
{
startup.ConfigureServices(builder.Services);
}
} }
var host = builder.Build(); 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))) await SetCultureFromLocalizationCookie(host.Services);
{
culture = cultures.Single(c => c.IsDefault).Name;
}
SetCulture(culture);
ServiceActivator.Configure(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) private static void SetCulture(string culture)
{ {
var cultureInfo = CultureInfo.GetCultureInfo(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 ) // 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>(); var http = _serviceProvider.GetRequiredService<HttpClient>();
// get alias as SiteState has not been initialized ( cannot use AliasService as it is not yet registered ) var siteState = _serviceProvider.GetRequiredService<SiteState>();
var path = new Uri(_navigationManager.Uri).LocalPath.Substring(1); User user = await http.GetFromJsonAsync<User>(Utilities.TenantUrl(siteState.Alias, "/api/User/authenticate"));
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"));
if (user.IsAuthenticated) if (user.IsAuthenticated)
{ {
identity = UserSecurity.CreateClaimsIdentity(alias, user); identity = UserSecurity.CreateClaimsIdentity(siteState.Alias, user);
} }
return new AuthenticationState(new ClaimsPrincipal(identity)); 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>

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="Module.Text" xml:space="preserve">
<value>Module: </value>
</data>
<data name="Error.Package.Load" xml:space="preserve">
<value>Error Loading Packages</value>
</data>
<data name="Success.Module.Install" xml:space="preserve">
<value>Module Installed Successfully. You Must &lt;a href={0}&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data>
<data name="Success.Module.Download" xml:space="preserve">
<value>Module Downloaded Successfully. Click Install To Complete Installation.</value>
</data>
<data name="Error.Module.Download" xml:space="preserve">
<value>Error Downloading Module</value>
</data>
<data name="Module.HelpText" xml:space="preserve">
<value>Upload one or more module packages. Once they are uploaded click Install to complete the installation.</value>
</data>
<data name="Search.NoResults" xml:space="preserve">
<value>No Modules Match The Criteria Provided Or Package Service Is Disabled</value>
</data>
</root>

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