fix remaining default resx differences, enhance module message with ability to dismiss, fix issue in ConfigManager.RemoveSetting, introduce package registry service

This commit is contained in:
Shaun Walker 2021-06-22 14:14:46 -04:00
parent 247e00ecd4
commit c4e6a4af49
26 changed files with 643 additions and 420 deletions

View File

@ -55,17 +55,15 @@ else
<TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host"> <TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host">
@if (_packages != null && _packages.Count > 0) @if (_packages != null && _packages.Count > 0)
{ {
<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> <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>
<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>
<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 />
<strong>@context.Downloads.ToString("###,###,##0")</strong> downloads&nbsp;&nbsp;|&nbsp;&nbsp; released: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong>&nbsp;&nbsp;|&nbsp;&nbsp;version: <strong>@context.Version</strong><br />
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)
</td>
<td style="vertical-align: middle;">
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadLanguage(context.PackageId, context.Version))>@Localizer["Download"]</button> <button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadLanguage(context.PackageId, context.Version))>@Localizer["Download"]</button>
</td> </td>
</Row> </Row>
@ -75,14 +73,14 @@ else
} }
else else
{ {
<ModuleMessage Type="MessageType.Info" Message="No Language Packages Are Available To Download"></ModuleMessage> <ModuleMessage Type="MessageType.Info" Message="No Translations Are Available To Download"></ModuleMessage>
} }
</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" />
@ -113,7 +111,7 @@ 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"); _packages = await PackageService.GetPackagesAsync("translation");
if (_supportedCultures.Count() == 1) if (_supportedCultures.Count() == 1)
{ {
@ -164,7 +162,7 @@ else
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Installing Language Package"); await logger.LogError(ex, "Error Installing Translations");
} }
} }
@ -179,8 +177,8 @@ else
} }
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.Langauge.Download"], MessageType.Error); AddModuleMessage(Localizer["Error.Language.Download"], MessageType.Error);
} }
} }

View File

@ -22,7 +22,7 @@ else
<th style="width: 1px;">&nbsp;</th> <th style="width: 1px;">&nbsp;</th>
</Header> </Header>
<Row> <Row>
<td><ActionDialog Header="Delete Langauge" Message="@string.Format(Localizer["Confirm.Langauge.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><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>
@ -54,7 +54,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");
} }
} }
@ -97,15 +97,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(string.Format(Localizer["Success.Language.Install"], 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.Langauge.Download"], MessageType.Error); AddModuleMessage(Localizer["Error.Language.Download"], MessageType.Error);
} }
} }
} }

View File

@ -14,15 +14,13 @@
<TabPanel Name="Download" ResourceKey="Download"> <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> <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>
<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 />
<strong>@context.Downloads.ToString("###,###,##0")</strong> downloads&nbsp;&nbsp;|&nbsp;&nbsp; released: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong>&nbsp;&nbsp;|&nbsp;&nbsp;version: <strong>@context.Version</strong><br />
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)
</td>
<td style="vertical-align: middle;">
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>@Localizer["Download"]</button> <button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadModule(context.PackageId, context.Version))>@Localizer["Download"]</button>
</td> </td>
</Row> </Row>

View File

@ -14,15 +14,13 @@
<TabPanel Name="Download" ResourceKey="Download"> <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> <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>
<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 />
<strong>@context.Downloads.ToString("###,###,##0")</strong> downloads&nbsp;&nbsp;|&nbsp;&nbsp; released: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong>&nbsp;&nbsp;|&nbsp;&nbsp;version: <strong>@context.Version</strong><br />
@(context.Description.Length > 400 ? (context.Description.Substring(0, 400) + "...") : context.Description)
</td>
<td style="vertical-align: middle;">
<button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>@Localizer["Download"]</button> <button type="button" class="btn btn-primary" @onclick=@(async () => await DownloadTheme(context.PackageId, context.Version))>@Localizer["Download"]</button>
</td> </td>
</Row> </Row>

View File

@ -4,12 +4,15 @@
@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="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
<br /> <br />
} }

View File

@ -36,5 +36,6 @@
<ItemGroup> <ItemGroup>
<Folder Include="Resources\" /> <Folder Include="Resources\" />
<Folder Include="Resources\Themes\Controls\Theme\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -117,7 +117,16 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Register" xml:space="preserve"> <data name="Server.Text" xml:space="preserve">
<value>Register</value> <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>
</root> </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,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 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="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>
<data name="True" xml:space="preserve">
<value>Wahr</value>
</data>
<data name="False" xml:space="preserve">
<value>Falsch</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 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>
<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>
<data name="True" xml:space="preserve">
<value>Wahr</value>
</data>
<data name="False" xml:space="preserve">
<value>Falsch</value>
</data>
</root>

View File

@ -117,10 +117,10 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Login" xml:space="preserve"> <data name="Server.Text" xml:space="preserve">
<value>Login</value> <value>File Name:</value>
</data> </data>
<data name="Logout" xml:space="preserve"> <data name="Server.HelpText" xml:space="preserve">
<value>Logout</value> <value>Enter the file name to use for the database</value>
</data> </data>
</root> </root>

View File

@ -117,55 +117,37 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Version:" xml:space="preserve"> <data name="Version" xml:space="preserve">
<value>Version:</value> <value>Version:</value>
</data> </data>
<data name="Database Configuration" xml:space="preserve"> <data name="DatabaseConfig" xml:space="preserve">
<value>Database Configuration</value> <value>Database Configuration</value>
</data> </data>
<data name="Database Type:" xml:space="preserve"> <data name="DatabaseType" xml:space="preserve">
<value>Database Type:</value> <value>Database Type:</value>
</data> </data>
<data name="Local Database" xml:space="preserve"> <data name="ApplicationAdmin" xml:space="preserve">
<value>Local Database</value>
</data>
<data name="SQL Server" xml:space="preserve">
<value>SQL Server</value>
</data>
<data name="Server:" xml:space="preserve">
<value>Server:</value>
</data>
<data name="Database:" xml:space="preserve">
<value>Database:</value>
</data>
<data name="Integrated Security:" xml:space="preserve">
<value>Integrated Security:</value>
</data>
<data name="True" xml:space="preserve">
<value>True</value>
</data>
<data name="False" xml:space="preserve">
<value>False</value>
</data>
<data name="Username:" xml:space="preserve">
<value>Username:</value>
</data>
<data name="Password:" xml:space="preserve">
<value>Password:</value>
</data>
<data name="Application Administrator" xml:space="preserve">
<value>Application Administrator</value> <value>Application Administrator</value>
</data> </data>
<data name="Confirm:" xml:space="preserve"> <data name="Username" xml:space="preserve">
<value>Username:</value>
</data>
<data name="Password" xml:space="preserve">
<value>Password:</value>
</data>
<data name="Confirm" xml:space="preserve">
<value>Confirm:</value> <value>Confirm:</value>
</data> </data>
<data name="Email:" xml:space="preserve"> <data name="Email" xml:space="preserve">
<value>Email:</value> <value>Email:</value>
</data> </data>
<data name="InstallNow" xml:space="preserve"> <data name="InstallNow" xml:space="preserve">
<value>Install Now</value> <value>Install Now</value>
</data> </data>
<data name="Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length" xml:space="preserve"> <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 Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length</value> <value>Please Enter All Fields And Ensure Passwords Match And Are Greater Than 5 Characters In Length</value>
</data> </data>
</root> </root>

View File

@ -117,73 +117,4 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Add" xml:space="preserve">
<value>Add</value>
</data>
<data name="AdminDash" xml:space="preserve">
<value>Admin Dashboard</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Container" xml:space="preserve">
<value>Container:</value>
</data>
<data name="ControlPanel" xml:space="preserve">
<value>Control Panel</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Delete</value>
</data>
<data name="Edit" xml:space="preserve">
<value>Edit</value>
</data>
<data name="Error.Authorize.No" xml:space="preserve">
<value>Not Authorized</value>
</data>
<data name="Message.Require.ModuleSelect" xml:space="preserve">
<value>You Must Select A Module</value>
</data>
<data name="Module.AddExisting" xml:space="preserve">
<value>Add Existing Module</value>
</data>
<data name="Module.AddNew" xml:space="preserve">
<value>Add New Module</value>
</data>
<data name="Module.Manage" xml:space="preserve">
<value>Module Management:</value>
</data>
<data name="Module.Select" xml:space="preserve">
<value>Select Module</value>
</data>
<data name="Modules" xml:space="preserve">
<value>Modules</value>
</data>
<data name="Page.Delete" xml:space="preserve">
<value>Delete Page</value>
</data>
<data name="Page.Manage" xml:space="preserve">
<value>Page Management:</value>
</data>
<data name="Page.Module.Add" xml:space="preserve">
<value>Add Module To Page</value>
</data>
<data name="Page.Publish" xml:space="preserve">
<value>Publish Page</value>
</data>
<data name="Page.Select" xml:space="preserve">
<value>Select Page</value>
</data>
<data name="Page.Unpublish" xml:space="preserve">
<value>Unpublish Page</value>
</data>
<data name="Pane" xml:space="preserve">
<value>Pane:</value>
</data>
<data name="Success.Page.ModuleAdd" xml:space="preserve">
<value>Module Added to Page</value>
</data>
<data name="Title" xml:space="preserve">
<value>Title:</value>
</data>
</root> </root>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -153,8 +153,8 @@
<data name="AllLanguages" xml:space="preserve"> <data name="AllLanguages" xml:space="preserve">
<value>All The Installed Languages Have Been Added.</value> <value>All The Installed Languages Have Been Added.</value>
</data> </data>
<data name="Error.Langauge.Download" xml:space="preserve"> <data name="Error.Language.Download" xml:space="preserve">
<value>Error Downloading Language Package</value> <value>Error Downloading Translation</value>
</data> </data>
<data name="Install" xml:space="preserve"> <data name="Install" xml:space="preserve">
<value>Install</value> <value>Install</value>
@ -163,12 +163,9 @@
<value>The Only Installed Language Is English</value> <value>The Only Installed Language Is English</value>
</data> </data>
<data name="Success.Language.Download" xml:space="preserve"> <data name="Success.Language.Download" xml:space="preserve">
<value>Language Package Downloaded Successfully. Click Install To Complete Installation.</value> <value>Translation Downloaded Successfully. Click Install To Complete Installation.</value>
</data> </data>
<data name="Success.Language.Install" xml:space="preserve"> <data name="Success.Language.Install" xml:space="preserve">
<value>Language Packages Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value> <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="Version" xml:space="preserve">
<value>Version</value>
</data> </data>
</root> </root>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -129,7 +129,7 @@
<data name="Code" xml:space="preserve"> <data name="Code" xml:space="preserve">
<value>Code</value> <value>Code</value>
</data> </data>
<data name="Confirm.Langauge.Delete" xml:space="preserve"> <data name="Confirm.Language.Delete" xml:space="preserve">
<value>Are You Sure You Wish To Delete The {0} Language?</value> <value>Are You Sure You Wish To Delete The {0} Language?</value>
</data> </data>
<data name="Error.Language.Delete" xml:space="preserve"> <data name="Error.Language.Delete" xml:space="preserve">
@ -139,13 +139,13 @@
<value>Add Language</value> <value>Add Language</value>
</data> </data>
<data name="DeleteLanguage.Header" xml:space="preserve"> <data name="DeleteLanguage.Header" xml:space="preserve">
<value>Delete Langauge</value> <value>Delete Language</value>
</data> </data>
<data name="Error.Langauge.Download" xml:space="preserve"> <data name="Error.Language.Download" xml:space="preserve">
<value>Error Downloading Language Package</value> <value>Error Downloading Translation</value>
</data> </data>
<data name="Success.Language.Install" xml:space="preserve"> <data name="Success.Language.Install" xml:space="preserve">
<value>Language Package Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value> <value>Translation Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data> </data>
<data name="Upgrade" xml:space="preserve"> <data name="Upgrade" xml:space="preserve">
<value>Upgrade</value> <value>Upgrade</value>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -123,15 +123,9 @@
<data name="Download" xml:space="preserve"> <data name="Download" xml:space="preserve">
<value>Download</value> <value>Download</value>
</data> </data>
<data name="Name" xml:space="preserve">
<value>Name</value>
</data>
<data name="Module.Text" xml:space="preserve"> <data name="Module.Text" xml:space="preserve">
<value>Module: </value> <value>Module: </value>
</data> </data>
<data name="Version" xml:space="preserve">
<value>Version</value>
</data>
<data name="Install" xml:space="preserve"> <data name="Install" xml:space="preserve">
<value>Install</value> <value>Install</value>
</data> </data>
@ -142,7 +136,7 @@
<value>Module Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value> <value>Module Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data> </data>
<data name="Success.Module.Download" xml:space="preserve"> <data name="Success.Module.Download" xml:space="preserve">
<value>Modules Downloaded Successfully. Click Install To Complete Installation.</value> <value>Module Downloaded Successfully. Click Install To Complete Installation.</value>
</data> </data>
<data name="Error.Module.Download" xml:space="preserve"> <data name="Error.Module.Download" xml:space="preserve">
<value>Error Downloading Module</value> <value>Error Downloading Module</value>

View File

@ -1,201 +0,0 @@
<?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="Save" xml:space="preserve">
<value>Save</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Yes" xml:space="preserve">
<value>Yes</value>
</data>
<data name="No" xml:space="preserve">
<value>No</value>
</data>
<data name="Name.Text" xml:space="preserve">
<value>Name: </value>
</data>
<data name="Container.Select" xml:space="preserve">
<value>Select Container</value>
</data>
<data name="Error.Theme.LoadPane" xml:space="preserve">
<value>Error Loading Pane Layouts For Theme</value>
</data>
<data name="DefaultContainer.Text" xml:space="preserve">
<value>Default Container: </value>
</data>
<data name="Theme.Select" xml:space="preserve">
<value>Select Theme</value>
</data>
<data name="Default Admin Container" xml:space="preserve">
<value>Default Admin Container</value>
</data>
<data name="Error.Aliases.InUse" xml:space="preserve">
<value>An Alias Specified Has Already Been Used For Another Site</value>
</data>
<data name="Message.required.SiteName" xml:space="preserve">
<value>You Must Provide A Site Name, Alias, And Default Theme/Container</value>
</data>
<data name="Error.SaveSite" xml:space="preserve">
<value>Error Saving Site</value>
</data>
<data name="Aliases.HelpText" xml:space="preserve">
<value>Enter the alias for the server</value>
</data>
<data name="DefaultContainer.HelpText" xml:space="preserve">
<value>Select the default container for the site</value>
</data>
<data name="DefaultAdminContainer.HelpText" xml:space="preserve">
<value>Select the default admin container for the site</value>
</data>
<data name="Tenant.Text" xml:space="preserve">
<value>Tenant: </value>
</data>
<data name="Aliases.Text" xml:space="preserve">
<value>Aliases: </value>
</data>
<data name="IsDeleted.Text" xml:space="preserve">
<value>Is Deleted? </value>
</data>
<data name="DefaultTheme.Text" xml:space="preserve">
<value>Default Theme: </value>
</data>
<data name="DefaultAdminContainer.Text" xml:space="preserve">
<value>Default Admin Container: </value>
</data>
<data name="Name.HelpText" xml:space="preserve">
<value>Enter the name of the site</value>
</data>
<data name="DefaultTheme.HelpText" xml:space="preserve">
<value>Select the default theme for the website</value>
</data>
<data name="IsDeleted.HelpText" xml:space="preserve">
<value>Has this site been deleted?</value>
</data>
<data name="Tenant.HelpText" xml:space="preserve">
<value>The tenant for the site</value>
</data>
<data name="ConnectionString.HelpText" xml:space="preserve">
<value>The database connection string</value>
</data>
<data name="ConnectionString.Text" xml:space="preserve">
<value>Connection String: </value>
</data>
</root>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
@ -123,12 +123,6 @@
<data name="Download" xml:space="preserve"> <data name="Download" xml:space="preserve">
<value>Download</value> <value>Download</value>
</data> </data>
<data name="Name" xml:space="preserve">
<value>Name</value>
</data>
<data name="Version" xml:space="preserve">
<value>Version</value>
</data>
<data name="Install" xml:space="preserve"> <data name="Install" xml:space="preserve">
<value>Install</value> <value>Install</value>
</data> </data>
@ -142,7 +136,7 @@
<value>Theme Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value> <value>Theme Installed Successfully. You Must &lt;a href=\"{0}\"&gt;Restart&lt;/a&gt; Your Application To Apply These Changes.</value>
</data> </data>
<data name="Success.Theme.Download" xml:space="preserve"> <data name="Success.Theme.Download" xml:space="preserve">
<value>Themes Downloaded Successfully. Click Install To Complete Installation.</value> <value>Theme Downloaded Successfully. Click Install To Complete Installation.</value>
</data> </data>
<data name="Error.Theme.Download" xml:space="preserve"> <data name="Error.Theme.Download" xml:space="preserve">
<value>Error Downloading Theme</value> <value>Error Downloading Theme</value>

View File

@ -186,4 +186,7 @@
<data name="Title" xml:space="preserve"> <data name="Title" xml:space="preserve">
<value>Title:</value> <value>Title:</value>
</data> </data>
<data name="System.Update" xml:space="preserve">
<value>Check For System Updates</value>
</data>
</root> </root>

View File

@ -6,7 +6,8 @@ namespace Oqtane.Services
{ {
public interface IPackageService public interface IPackageService
{ {
Task<List<Package>> GetPackagesAsync(string tag); Task<List<Package>> GetPackagesAsync(string type);
Task<List<Package>> GetPackagesAsync(string type, string search);
Task DownloadPackageAsync(string packageId, string version, string folder); Task DownloadPackageAsync(string packageId, string version, string folder);
Task InstallPackagesAsync(); Task InstallPackagesAsync();
} }

View File

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using System.Linq; using System.Linq;
using Oqtane.Documentation; using Oqtane.Documentation;
using Oqtane.Shared; using Oqtane.Shared;
using System.Net;
namespace Oqtane.Services namespace Oqtane.Services
{ {
@ -19,10 +20,15 @@ namespace Oqtane.Services
} }
private string Apiurl => CreateApiUrl("Package", _siteState.Alias); private string Apiurl => CreateApiUrl("Package", _siteState.Alias);
public async Task<List<Package>> GetPackagesAsync(string tag) public async Task<List<Package>> GetPackagesAsync(string type)
{ {
List<Package> packages = await GetJsonAsync<List<Package>>($"{Apiurl}?tag={tag}"); return await GetPackagesAsync(type, "");
return packages.OrderByDescending(item => item.Downloads).ToList(); }
public async Task<List<Package>> GetPackagesAsync(string type, string search)
{
List<Package> packages = await GetJsonAsync<List<Package>>($"{Apiurl}?type={type}&search={WebUtility.UrlEncode(search)}");
return packages.OrderByDescending(item => item.Downloads).ToList(); // order by popularity
} }
public async Task DownloadPackageAsync(string packageId, string version, string folder) public async Task DownloadPackageAsync(string packageId, string version, string folder)

View File

@ -15,7 +15,6 @@
@if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions)) @if (_moduleDefinitions != null && UserSecurity.IsAuthorized(PageState.User, PermissionNames.Edit, PageState.Page.Permissions))
{ {
<div class="app-controlpanel" style="@_display"> <div class="app-controlpanel" style="@_display">
<div class="@CardClass"> <div class="@CardClass">
<div class="@HeaderClass"> <div class="@HeaderClass">
<span class="font-weight-bold">@Localizer["ControlPanel"]</span> <span class="font-weight-bold">@Localizer["ControlPanel"]</span>
@ -91,7 +90,6 @@
</div> </div>
} }
<hr class="app-rule" /> <hr class="app-rule" />
<div class="row"> <div class="row">
<div class="col text-center"> <div class="col text-center">
<label for="Module" class="control-label">@Localizer["Module.Manage"] </label> <label for="Module" class="control-label">@Localizer["Module.Manage"] </label>
@ -189,11 +187,14 @@
</select> </select>
</div> </div>
</div> </div>
<br /> <br />
<button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">@Localizer["Page.Module.Add"]</button> <button type="button" class="btn btn-primary btn-block mx-auto" @onclick="@AddModule">@Localizer["Page.Module.Add"]</button>
@((MarkupString) Message) @((MarkupString) Message)
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
<hr class="app-rule" />
<NavLink class="btn btn-info btn-block mx-auto" href="@NavigateUrl("admin/update")">@Localizer["System.Update"]</NavLink>
}
</div> </div>
</div> </div>
</div> </div>

View File

@ -21,52 +21,50 @@ namespace Oqtane.Controllers
{ {
private readonly IInstallationManager _installationManager; private readonly IInstallationManager _installationManager;
private readonly IWebHostEnvironment _environment; private readonly IWebHostEnvironment _environment;
private readonly IConfigManager _configManager;
private readonly ILogManager _logger; private readonly ILogManager _logger;
public PackageController(IInstallationManager installationManager, IWebHostEnvironment environment, ILogManager logger) public PackageController(IInstallationManager installationManager, IWebHostEnvironment environment, IConfigManager configManager, ILogManager logger)
{ {
_installationManager = installationManager; _installationManager = installationManager;
_environment = environment; _environment = environment;
_configManager = configManager;
_logger = logger; _logger = logger;
} }
// GET: api/<controller>?tag=x // GET: api/<controller>?type=x&search=y
[HttpGet] [HttpGet]
[Authorize(Roles = RoleNames.Host)] [Authorize(Roles = RoleNames.Host)]
public async Task<IEnumerable<Package>> Get(string tag) public async Task<IEnumerable<Package>> Get(string type, string search)
{ {
List<Package> packages = new List<Package>(); // get packages
List<Package> packages;
using (var httpClient = new HttpClient()) using (var client = new HttpClient())
{ {
var searchResult = await GetJson<SearchResult>(httpClient, "https://azuresearch-usnc.nuget.org/query?q=tags:oqtane"); client.DefaultRequestHeaders.Add("Referer", HttpContext.Request.Host.Value);
foreach(Data data in searchResult.Data) packages = await GetJson<List<Package>>(client, Constants.PackageRegistryUrl + $"/api/registry/packages/?installationid={GetInstallationId()}&type={type.ToLower()}&version={Constants.Version}&search={search}");
{
if (data.Tags.Contains(tag))
{
Package package = new Package();
package.PackageId = data.Id;
package.Name = data.Title;
package.Description = data.Description;
package.Owner = data.Authors[0];
package.Version = data.Version;
package.Downloads = data.TotalDownloads;
packages.Add(package);
} }
}
}
return packages; return packages;
} }
[HttpPost] [HttpPost]
[Authorize(Roles = RoleNames.Host)] [Authorize(Roles = RoleNames.Host)]
public async Task Post(string packageid, string version, string folder) public async Task Post(string packageid, string version, string folder)
{
// get package info
Package package = null;
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Referer", HttpContext.Request.Host.Value);
package = await GetJson<Package>(client, Constants.PackageRegistryUrl + $"/api/registry/package/?installationid={GetInstallationId()}&packageid={packageid}&version={version}");
}
if (package != null)
{ {
using (var httpClient = new HttpClient()) using (var httpClient = new HttpClient())
{ {
folder = Path.Combine(_environment.ContentRootPath, folder); folder = Path.Combine(_environment.ContentRootPath, folder);
var response = await httpClient.GetAsync("https://www.nuget.org/api/v2/package/" + packageid.ToLower() + "/" + version).ConfigureAwait(false); var response = await httpClient.GetAsync(package.PackageUrl).ConfigureAwait(false);
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
string filename = packageid + "." + version + ".nupkg"; string filename = packageid + "." + version + ".nupkg";
using (var fileStream = new FileStream(Path.Combine(folder, filename), FileMode.Create, FileAccess.Write, FileShare.None)) using (var fileStream = new FileStream(Path.Combine(folder, filename), FileMode.Create, FileAccess.Write, FileShare.None))
@ -75,6 +73,18 @@ namespace Oqtane.Controllers
} }
} }
} }
}
private string GetInstallationId()
{
var installationid = _configManager.GetSetting("InstallationId", "");
if (installationid == "")
{
installationid = Guid.NewGuid().ToString();
_configManager.AddOrUpdateSetting("InstallationId", installationid, true);
}
return installationid;
}
private async Task<T> GetJson<T>(HttpClient httpClient, string url) private async Task<T> GetJson<T>(HttpClient httpClient, string url)
{ {

View File

@ -102,7 +102,10 @@ namespace Oqtane.Infrastructure
jsonObj[currentSection] = value; jsonObj[currentSection] = value;
break; break;
case "remove": case "remove":
if (jsonObj.Property(currentSection) != null)
{
jsonObj.Property(currentSection).Remove(); jsonObj.Property(currentSection).Remove();
}
break; break;
} }
} }

View File

@ -1,8 +1,9 @@
using System;
namespace Oqtane.Models namespace Oqtane.Models
{ {
/// <summary> /// <summary>
/// A software Package which is like an Oqtane Plugin / Extension. /// A software Package for installation.
/// This is used for creating lists from NuGet to offer for installation.
/// </summary> /// </summary>
public class Package public class Package
{ {
@ -12,19 +13,29 @@ namespace Oqtane.Models
public string PackageId { get; set; } public string PackageId { get; set; }
/// <summary> /// <summary>
/// Name of the package - may contains part or the entire Namespace. /// Owner of the package
/// </summary>
public string Owner { get; set; }
/// <summary>
/// Url for the owner of the package
/// </summary>
public string OwnerUrl { get; set; }
/// <summary>
/// Friendly name of the package
/// </summary> /// </summary>
public string Name { get; set; } public string Name { get; set; }
/// <summary> /// <summary>
/// Nice description of the Package. /// Description of the Package.
/// </summary> /// </summary>
public string Description { get; set; } public string Description { get; set; }
/// <summary> /// <summary>
/// Owner / Creator of the package - usually retrieved from NuGet. /// Friendly name of the package
/// </summary> /// </summary>
public string Owner { get; set; } public string ProductUrl { get; set; }
/// <summary> /// <summary>
/// Version as defined in the NuGet package. /// Version as defined in the NuGet package.
@ -32,8 +43,23 @@ namespace Oqtane.Models
public string Version { get; set; } public string Version { get; set; }
/// <summary> /// <summary>
/// Download count on NuGet to show how popular the package is. /// Download count to show how popular the package is.
/// </summary> /// </summary>
public long Downloads { get; set; } public long Downloads { get; set; }
/// <summary>
/// date the package was released
/// </summary>
public DateTime ReleaseDate { get; set; }
/// <summary>
/// The direct Url for downloading the package
/// </summary>
public string PackageUrl { get; set; }
/// <summary>
/// Indicates if any known security vulnerabilities exist ( only applicable to framework packages )
/// </summary>
public int Vulnerability { get; set; }
} }
} }

View File

@ -7,6 +7,7 @@ namespace Oqtane.Shared {
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0"; public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0";
public const string PackageId = "Oqtane.Framework"; public const string PackageId = "Oqtane.Framework";
public const string UpdaterPackageId = "Oqtane.Updater"; public const string UpdaterPackageId = "Oqtane.Updater";
public const string PackageRegistryUrl = "https://www.oqtane.net";
public const string DefaultDBType = "Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer"; public const string DefaultDBType = "Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer";