Merge pull request #5765 from sbwalker/dev
remove MyModule and MyTheme from Application Template - solution can now be extended using Internal module/theme templates
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
using Microsoft.JSInterop;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Oqtane.Application
|
|
||||||
{
|
|
||||||
public class Interop
|
|
||||||
{
|
|
||||||
private readonly IJSRuntime _jsRuntime;
|
|
||||||
|
|
||||||
public Interop(IJSRuntime jsRuntime)
|
|
||||||
{
|
|
||||||
_jsRuntime = jsRuntime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
@using Oqtane.Modules.Controls
|
|
||||||
@using Oqtane.Application.Services
|
|
||||||
@using Oqtane.Application.Models
|
|
||||||
|
|
||||||
@namespace Oqtane.Application.MyModule
|
|
||||||
@inherits ModuleBase
|
|
||||||
@inject IMyModuleService MyModuleService
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
@inject IStringLocalizer<Edit> Localizer
|
|
||||||
|
|
||||||
<form @ref="form" class="@(validated ? " was-validated" : "needs-validation" )" novalidate>
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="name" HelpText="Enter a name" ResourceKey="Name">Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="name" class="form-control" @bind="@_name" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button type="button" class="btn btn-success" @onclick="Save">@Localizer["Save"]</button>
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@Localizer["Cancel"]</NavLink>
|
|
||||||
<br /><br />
|
|
||||||
@if (PageState.Action == "Edit")
|
|
||||||
{
|
|
||||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
|
||||||
}
|
|
||||||
</form>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
|
||||||
|
|
||||||
public override string Actions => "Add,Edit";
|
|
||||||
|
|
||||||
public override string Title => "Manage MyModule";
|
|
||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
|
||||||
{
|
|
||||||
new Stylesheet(ModulePath() + "Module.css")
|
|
||||||
};
|
|
||||||
|
|
||||||
private ElementReference form;
|
|
||||||
private bool validated = false;
|
|
||||||
|
|
||||||
private int _id;
|
|
||||||
private string _name;
|
|
||||||
private string _createdby;
|
|
||||||
private DateTime _createdon;
|
|
||||||
private string _modifiedby;
|
|
||||||
private DateTime _modifiedon;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (PageState.Action == "Edit")
|
|
||||||
{
|
|
||||||
_id = Int32.Parse(PageState.QueryString["id"]);
|
|
||||||
MyModule MyModule = await MyModuleService.GetMyModuleAsync(_id, ModuleState.ModuleId);
|
|
||||||
if (MyModule != null)
|
|
||||||
{
|
|
||||||
_name = MyModule.Name;
|
|
||||||
_createdby = MyModule.CreatedBy;
|
|
||||||
_createdon = MyModule.CreatedOn;
|
|
||||||
_modifiedby = MyModule.ModifiedBy;
|
|
||||||
_modifiedon = MyModule.ModifiedOn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading MyModule {MyModuleId} {Error}", _id, ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Message.LoadError"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Save()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
validated = true;
|
|
||||||
var interop = new Oqtane.UI.Interop(JSRuntime);
|
|
||||||
if (await interop.FormValid(form))
|
|
||||||
{
|
|
||||||
if (PageState.Action == "Add")
|
|
||||||
{
|
|
||||||
MyModule MyModule = new MyModule();
|
|
||||||
MyModule.ModuleId = ModuleState.ModuleId;
|
|
||||||
MyModule.Name = _name;
|
|
||||||
MyModule = await MyModuleService.AddMyModuleAsync(MyModule);
|
|
||||||
await logger.LogInformation("MyModule Added {MyModule}", MyModule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MyModule MyModule = await MyModuleService.GetMyModuleAsync(_id, ModuleState.ModuleId);
|
|
||||||
MyModule.Name = _name;
|
|
||||||
await MyModuleService.UpdateMyModuleAsync(MyModule);
|
|
||||||
await logger.LogInformation("MyModule Updated {MyModule}", MyModule);
|
|
||||||
}
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Message.SaveValidation"], MessageType.Warning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Saving MyModule {Error}", ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Message.SaveError"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
@using Oqtane.Application.Services
|
|
||||||
@using Oqtane.Application.Models
|
|
||||||
|
|
||||||
@namespace Oqtane.Application.MyModule
|
|
||||||
@inherits ModuleBase
|
|
||||||
@inject IMyModuleService MyModuleService
|
|
||||||
@inject NavigationManager NavigationManager
|
|
||||||
@inject IStringLocalizer<Index> Localizer
|
|
||||||
|
|
||||||
@if (_MyModules == null)
|
|
||||||
{
|
|
||||||
<p><em>Loading...</em></p>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<ActionLink Action="Add" Security="SecurityAccessLevel.Edit" Text="Add MyModule" ResourceKey="Add" />
|
|
||||||
<br />
|
|
||||||
<br />
|
|
||||||
@if (@_MyModules.Count != 0)
|
|
||||||
{
|
|
||||||
<Pager Items="@_MyModules">
|
|
||||||
<Header>
|
|
||||||
<th style="width: 1px;"> </th>
|
|
||||||
<th style="width: 1px;"> </th>
|
|
||||||
<th>@Localizer["Name"]</th>
|
|
||||||
</Header>
|
|
||||||
<Row>
|
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.MyModuleId.ToString())" ResourceKey="Edit" /></td>
|
|
||||||
<td><ActionDialog Header="Delete MyModule" Message="Are You Sure You Wish To Delete This MyModule?" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" ResourceKey="Delete" Id="@context.MyModuleId.ToString()" /></td>
|
|
||||||
<td>@context.Name</td>
|
|
||||||
</Row>
|
|
||||||
</Pager>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<p>@Localizer["Message.DisplayNone"]</p>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@code {
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
|
||||||
{
|
|
||||||
new Stylesheet(ModulePath() + "Module.css"),
|
|
||||||
new Script(ModulePath() + "Module.js")
|
|
||||||
};
|
|
||||||
|
|
||||||
List<Models.MyModule> _MyModules;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_MyModules = await MyModuleService.GetMyModulesAsync(ModuleState.ModuleId);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading MyModule {Error}", ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Message.LoadError"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task Delete(MyModule MyModule)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await MyModuleService.DeleteMyModuleAsync(MyModule.MyModuleId, ModuleState.ModuleId);
|
|
||||||
await logger.LogInformation("MyModule Deleted {MyModule}", MyModule);
|
|
||||||
_MyModules = await MyModuleService.GetMyModulesAsync(ModuleState.ModuleId);
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Deleting MyModule {MyModule} {Error}", MyModule, ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Message.DeleteError"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Oqtane.Models;
|
|
||||||
using Oqtane.Modules;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.MyModule
|
|
||||||
{
|
|
||||||
public class ModuleInfo : IModule
|
|
||||||
{
|
|
||||||
public ModuleDefinition ModuleDefinition => new ModuleDefinition
|
|
||||||
{
|
|
||||||
Name = "MyModule",
|
|
||||||
Description = "Example module",
|
|
||||||
Version = "1.0.0",
|
|
||||||
ServerManagerType = "Oqtane.Application.Manager.MyModuleManager, Oqtane.Application.Server.Oqtane",
|
|
||||||
ReleaseVersions = "1.0.0",
|
|
||||||
Dependencies = "Oqtane.Application.Shared.Oqtane",
|
|
||||||
PackageName = "Oqtane.Application"
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
@namespace Oqtane.Application.MyModule
|
|
||||||
@inherits ModuleBase
|
|
||||||
@inject ISettingService SettingService
|
|
||||||
@inject IStringLocalizer<Settings> Localizer
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="value" HelpText="Enter a value" ResourceKey="SettingName" ResourceType="@resourceType">Name: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input id="value" type="text" class="form-control" @bind="@_value" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private string resourceType = "Oqtane.Application.MyModule.Settings, Oqtane.Application.Client.Oqtane"; // for localization
|
|
||||||
public override string Title => "MyModdule Settings";
|
|
||||||
|
|
||||||
string _value;
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary<string, string> settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
|
||||||
_value = SettingService.GetSetting(settings, "SettingName", "");
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AddModuleMessage(ex.Message, MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateSettings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Dictionary<string, string> settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
|
||||||
SettingService.SetSetting(settings, "SettingName", _value);
|
|
||||||
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AddModuleMessage(ex.Message, MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,141 +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="Name.Text" xml:space="preserve">
|
|
||||||
<value>Name: </value>
|
|
||||||
</data>
|
|
||||||
<data name="Name.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter the name</value>
|
|
||||||
</data>
|
|
||||||
<data name="Save" xml:space="preserve">
|
|
||||||
<value>Save</value>
|
|
||||||
</data>
|
|
||||||
<data name="Cancel" xml:space="preserve">
|
|
||||||
<value>Cancel</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.SaveValidation" xml:space="preserve">
|
|
||||||
<value>Please Provide All Required Information</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.SaveError" xml:space="preserve">
|
|
||||||
<value>Error Saving MyModule</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.LoadError" xml:space="preserve">
|
|
||||||
<value>Error Loading MyModule</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,147 +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="Name" xml:space="preserve">
|
|
||||||
<value>Name</value>
|
|
||||||
</data>
|
|
||||||
<data name="Add.Text" xml:space="preserve">
|
|
||||||
<value>Add MyModule</value>
|
|
||||||
</data>
|
|
||||||
<data name="Edit.Text" xml:space="preserve">
|
|
||||||
<value>Edit</value>
|
|
||||||
</data>
|
|
||||||
<data name="Delete.Text" xml:space="preserve">
|
|
||||||
<value>Delete</value>
|
|
||||||
</data>
|
|
||||||
<data name="Delete.Header" xml:space="preserve">
|
|
||||||
<value>Delete MyModule</value>
|
|
||||||
</data>
|
|
||||||
<data name="Delete.Message" xml:space="preserve">
|
|
||||||
<value>Are You Sure You Wish To Delete This MyModule?</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.DisplayNone" xml:space="preserve">
|
|
||||||
<value>No MyModules To Display</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.LoadError" xml:space="preserve">
|
|
||||||
<value>Error Loading MyModule</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.DeleteError" xml:space="preserve">
|
|
||||||
<value>Error Deleting MyModule</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,126 +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 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="SettingName.Text" xml:space="preserve">
|
|
||||||
<value>Name: </value>
|
|
||||||
</data>
|
|
||||||
<data name="SettingName.HelpText" xml:space="preserve">
|
|
||||||
<value>Enter a value</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,126 +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="Title.HelpText" xml:space="preserve">
|
|
||||||
<value>Specify If The Module Title Should Be Displayed</value>
|
|
||||||
</data>
|
|
||||||
<data name="Title.Text" xml:space="preserve">
|
|
||||||
<value>Display Title</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,138 +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="Login.HelpText" xml:space="preserve">
|
|
||||||
<value>Specify if a Login option should be displayed. Note that this option does not prevent the login page from being accessible via a direct url.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Login.Text" xml:space="preserve">
|
|
||||||
<value>Show Login?</value>
|
|
||||||
</data>
|
|
||||||
<data name="Register.HelpText" xml:space="preserve">
|
|
||||||
<value>Specify if a Register option should be displayed. Note that this option is also dependent on the Allow Registration option in Site Settings.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Register.Text" xml:space="preserve">
|
|
||||||
<value>Show Register?</value>
|
|
||||||
</data>
|
|
||||||
<data name="Scope.HelpText" xml:space="preserve">
|
|
||||||
<value>Specify if the settings are applicable to this page or the entire site.</value>
|
|
||||||
</data>
|
|
||||||
<data name="Scope.Text" xml:space="preserve">
|
|
||||||
<value>Setting Scope:</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Oqtane.Services;
|
|
||||||
using Oqtane.Shared;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Services
|
|
||||||
{
|
|
||||||
public interface IMyModuleService
|
|
||||||
{
|
|
||||||
Task<List<Models.MyModule>> GetMyModulesAsync(int ModuleId);
|
|
||||||
|
|
||||||
Task<Models.MyModule> GetMyModuleAsync(int MyModuleId, int ModuleId);
|
|
||||||
|
|
||||||
Task<Models.MyModule> AddMyModuleAsync(Models.MyModule MyModule);
|
|
||||||
|
|
||||||
Task<Models.MyModule> UpdateMyModuleAsync(Models.MyModule MyModule);
|
|
||||||
|
|
||||||
Task DeleteMyModuleAsync(int MyModuleId, int ModuleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MyModuleService : ServiceBase, IMyModuleService
|
|
||||||
{
|
|
||||||
public MyModuleService(HttpClient http, SiteState siteState) : base(http, siteState) { }
|
|
||||||
|
|
||||||
private string Apiurl => CreateApiUrl("MyModule");
|
|
||||||
|
|
||||||
public async Task<List<Models.MyModule>> GetMyModulesAsync(int ModuleId)
|
|
||||||
{
|
|
||||||
List<Models.MyModule> Tasks = await GetJsonAsync<List<Models.MyModule>>(CreateAuthorizationPolicyUrl($"{Apiurl}?moduleid={ModuleId}", EntityNames.Module, ModuleId), Enumerable.Empty<Models.MyModule>().ToList());
|
|
||||||
return Tasks.OrderBy(item => item.Name).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Models.MyModule> GetMyModuleAsync(int MyModuleId, int ModuleId)
|
|
||||||
{
|
|
||||||
return await GetJsonAsync<Models.MyModule>(CreateAuthorizationPolicyUrl($"{Apiurl}/{MyModuleId}/{ModuleId}", EntityNames.Module, ModuleId));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Models.MyModule> AddMyModuleAsync(Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
return await PostJsonAsync<Models.MyModule>(CreateAuthorizationPolicyUrl($"{Apiurl}", EntityNames.Module, MyModule.ModuleId), MyModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Models.MyModule> UpdateMyModuleAsync(Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
return await PutJsonAsync<Models.MyModule>(CreateAuthorizationPolicyUrl($"{Apiurl}/{MyModule.MyModuleId}", EntityNames.Module, MyModule.ModuleId), MyModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteMyModuleAsync(int MyModuleId, int ModuleId)
|
|
||||||
{
|
|
||||||
await DeleteAsync(CreateAuthorizationPolicyUrl($"{Apiurl}/{MyModuleId}/{ModuleId}", EntityNames.Module, ModuleId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using System.Linq;
|
|
||||||
using Oqtane.Services;
|
|
||||||
using Oqtane.Application.Services;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Startup
|
|
||||||
{
|
|
||||||
public class ClientStartup : IClientStartup
|
|
||||||
{
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
if (!services.Any(s => s.ServiceType == typeof(IMyModuleService)))
|
|
||||||
{
|
|
||||||
services.AddScoped<IMyModuleService, MyModuleService>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
@namespace Oqtane.Application.MyTheme
|
|
||||||
@inherits ContainerBase
|
|
||||||
@inject ISettingService SettingService
|
|
||||||
|
|
||||||
<div class="@_classes">
|
|
||||||
@if (_title && ModuleState.Title != "-")
|
|
||||||
{
|
|
||||||
<div class="row px-4">
|
|
||||||
<div class="d-flex flex-nowrap">
|
|
||||||
<ModuleActions /><h2><ModuleTitle /></h2>
|
|
||||||
</div>
|
|
||||||
<hr class="app-rule" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<ModuleActions />
|
|
||||||
}
|
|
||||||
<div class="row px-4">
|
|
||||||
<div class="container-fluid">
|
|
||||||
<ModuleInstance />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
public override string Name => "Container";
|
|
||||||
|
|
||||||
private bool _title = true;
|
|
||||||
private string _classes = "container-fluid";
|
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
_title = bool.Parse(SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Title", "true"));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// error loading container settings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
@namespace Oqtane.Application.MyTheme
|
|
||||||
@inherits ModuleBase
|
|
||||||
@implements Oqtane.Interfaces.ISettingsControl
|
|
||||||
@inject ISettingService SettingService
|
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="title" ResourceKey="Title" ResourceType="@resourceType" HelpText="Specify If The Module Title Should Be Displayed">Display Title?</Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="title" class="form-select" @bind="@_title">
|
|
||||||
<option value="true">Yes</option>
|
|
||||||
<option value="false">No</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private string resourceType = "Oqtane.Application.MyTheme.ContainerSettings, Oqtane.Application.Client.Oqtane"; // for localization
|
|
||||||
private string _title = "true";
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
_title = SettingService.GetSetting(ModuleState.Settings, GetType().Namespace + ":Title", "true");
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AddModuleMessage(ex.Message, MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateSettings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Title", _title);
|
|
||||||
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
AddModuleMessage(ex.Message, MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Oqtane.Models;
|
|
||||||
using Oqtane.Themes;
|
|
||||||
using Oqtane.Shared;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.MyTheme
|
|
||||||
{
|
|
||||||
public class ThemeInfo : ITheme
|
|
||||||
{
|
|
||||||
public Oqtane.Models.Theme Theme => new Oqtane.Models.Theme
|
|
||||||
{
|
|
||||||
Name = "MyTheme",
|
|
||||||
Version = "1.0.0",
|
|
||||||
PackageName = "Oqtane.Application",
|
|
||||||
ThemeSettingsType = "Oqtane.Application.MyTheme.ThemeSettings, Oqtane.Application.Client.Oqtane",
|
|
||||||
ContainerSettingsType = "Oqtane.Application.MyTheme.ContainerSettings, Oqtane.Application.Client.Oqtane",
|
|
||||||
Resources = new List<Resource>()
|
|
||||||
{
|
|
||||||
new Stylesheet(Constants.BootstrapStylesheetUrl, Constants.BootstrapStylesheetIntegrity, "anonymous"),
|
|
||||||
new Stylesheet("~/Theme.css"),
|
|
||||||
new Script(Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
@namespace Oqtane.Application.MyTheme
|
|
||||||
@inherits ThemeBase
|
|
||||||
@inject ISettingService SettingService
|
|
||||||
|
|
||||||
<main role="main">
|
|
||||||
<nav class="navbar navbar-dark bg-primary fixed-top">
|
|
||||||
<Logo /><Menu Orientation="Horizontal" />
|
|
||||||
<div class="controls ms-auto">
|
|
||||||
<div class="controls-group"><UserProfile ShowRegister="@_register" /> <Login ShowLogin="@_login" /> <ControlPanel ButtonClass="btn-outline-light" /></div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div class="content">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<Pane Name="@PaneNames.Admin" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Pane Name="Top Full Width" />
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<Pane Name="Top 100%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<Pane Name="Left 50%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<Pane Name="Right 50%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<Pane Name="Left 33%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<Pane Name="Center 33%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<Pane Name="Right 33%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<Pane Name="Left Outer 25%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<Pane Name="Left Inner 25%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<Pane Name="Right Inner 25%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<Pane Name="Right Outer 25%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3">
|
|
||||||
<Pane Name="Left 25%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<Pane Name="Center 50%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<Pane Name="Right 25%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-8">
|
|
||||||
<Pane Name="Left Sidebar 66%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<Pane Name="Right Sidebar 33%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-4">
|
|
||||||
<Pane Name="Left Sidebar 33%" />
|
|
||||||
</div>
|
|
||||||
<div class="col-md-8">
|
|
||||||
<Pane Name="Right Sidebar 66%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-12">
|
|
||||||
<Pane Name="Bottom 100%" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Pane Name="Bottom Full Width" />
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
public override string Name => "MyTheme";
|
|
||||||
|
|
||||||
public override string Panes => PaneNames.Admin + ",Top Full Width,Top 100%,Left 50%,Right 50%,Left 33%,Center 33%,Right 33%,Left Outer 25%,Left Inner 25%,Right Inner 25%,Right Outer 25%,Left 25%,Center 50%,Right 25%,Left Sidebar 66%,Right Sidebar 33%,Left Sidebar 33%,Right Sidebar 66%,Bottom 100%,Bottom Full Width";
|
|
||||||
|
|
||||||
private bool _login = true;
|
|
||||||
private bool _register = true;
|
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var settings = SettingService.MergeSettings(PageState.Site.Settings, PageState.Page.Settings);
|
|
||||||
_login = bool.Parse(SettingService.GetSetting(settings, GetType().Namespace + ":Login", "true"));
|
|
||||||
_register = bool.Parse(SettingService.GetSetting(settings, GetType().Namespace + ":Register", "true"));
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// error loading theme settings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
@namespace Oqtane.Application.MyTheme
|
|
||||||
@inherits ModuleBase
|
|
||||||
@implements Oqtane.Interfaces.ISettingsControl
|
|
||||||
@inject ISettingService SettingService
|
|
||||||
@inject IStringLocalizer<ThemeSettings> Localizer
|
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
|
||||||
@attribute [OqtaneIgnore]
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="scope" ResourceKey="Scope" ResourceType="@resourceType" HelpText="Specify if the settings are applicable to this page or the entire site.">Setting Scope:</Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="scope" class="form-select" value="@_scope" @onchange="(e => ScopeChanged(e))">
|
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
|
||||||
{
|
|
||||||
<option value="site">@Localizer["Site"]</option>
|
|
||||||
}
|
|
||||||
<option value="page">@Localizer["Page"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="login" ResourceKey="Login" ResourceType="@resourceType" HelpText="Specify if a Login option should be displayed. Note that this option does not prevent the login page from being accessible via a direct url.">Show Login?</Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="login" class="form-select" @bind="@_login">
|
|
||||||
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
|
||||||
<option value="true">@SharedLocalizer["Yes"]</option>
|
|
||||||
<option value="false">@SharedLocalizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="register" ResourceKey="Register" ResourceType="@resourceType" HelpText="Specify if a Register option should be displayed. Note that this option is also dependent on the Allow Registration option in Site Settings.">Show Register?</Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="register" class="form-select" @bind="@_register">
|
|
||||||
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
|
||||||
<option value="true">@SharedLocalizer["Yes"]</option>
|
|
||||||
<option value="false">@SharedLocalizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private int pageId = -1;
|
|
||||||
private string resourceType = "Oqtane.Application.MyTheme.ThemeSettings, Oqtane.Application.Client.Oqtane"; // for localization
|
|
||||||
private string _scope = "page";
|
|
||||||
private string _login = "-";
|
|
||||||
private string _register = "-";
|
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
|
||||||
{
|
|
||||||
if (PageState.QueryString.ContainsKey("id"))
|
|
||||||
{
|
|
||||||
pageId = int.Parse(PageState.QueryString["id"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await LoadSettings();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading Settings {Error}", ex.Message);
|
|
||||||
AddModuleMessage("Error Loading Settings", MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task LoadSettings()
|
|
||||||
{
|
|
||||||
if (_scope == "site")
|
|
||||||
{
|
|
||||||
var settings = PageState.Site.Settings;
|
|
||||||
_login = SettingService.GetSetting(settings, GetType().Namespace + ":Login", "true");
|
|
||||||
_register = SettingService.GetSetting(settings, GetType().Namespace + ":Register", "true");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var settings = await SettingService.GetPageSettingsAsync(pageId);
|
|
||||||
settings = SettingService.MergeSettings(PageState.Site.Settings, settings);
|
|
||||||
_login = SettingService.GetSetting(settings, GetType().Namespace + ":Login", "-");
|
|
||||||
_register = SettingService.GetSetting(settings, GetType().Namespace + ":Register", "-");
|
|
||||||
}
|
|
||||||
await Task.Yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ScopeChanged(ChangeEventArgs eventArgs)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_scope = (string)eventArgs.Value;
|
|
||||||
await LoadSettings();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Loading Settings {Error}", ex.Message);
|
|
||||||
AddModuleMessage("Error Loading Settings", MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task UpdateSettings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_scope == "site")
|
|
||||||
{
|
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
|
||||||
if (_login != "-")
|
|
||||||
{
|
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_register != "-")
|
|
||||||
{
|
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Register", _register);
|
|
||||||
}
|
|
||||||
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var settings = await SettingService.GetPageSettingsAsync(pageId);
|
|
||||||
if (_login != "-")
|
|
||||||
{
|
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
|
|
||||||
}
|
|
||||||
if (_register != "-")
|
|
||||||
{
|
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Register", _register);
|
|
||||||
}
|
|
||||||
await SettingService.UpdatePageSettingsAsync(settings, pageId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Saving Settings {Error}", ex.Message);
|
|
||||||
AddModuleMessage("Error Saving Settings", MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.Enums;
|
|
||||||
using Oqtane.Infrastructure;
|
|
||||||
using Oqtane.Application.Services;
|
|
||||||
using Oqtane.Controllers;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Controllers
|
|
||||||
{
|
|
||||||
[Route(ControllerRoutes.ApiRoute)]
|
|
||||||
public class MyModuleController : ModuleControllerBase
|
|
||||||
{
|
|
||||||
private readonly IMyModuleService _MyModuleService;
|
|
||||||
|
|
||||||
public MyModuleController(IMyModuleService MyModuleService, ILogManager logger, IHttpContextAccessor accessor) : base(logger, accessor)
|
|
||||||
{
|
|
||||||
_MyModuleService = MyModuleService;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET: api/<controller>?moduleid=x
|
|
||||||
[HttpGet]
|
|
||||||
[Authorize(Policy = PolicyNames.ViewModule)]
|
|
||||||
public async Task<IEnumerable<Models.MyModule>> Get(string moduleid)
|
|
||||||
{
|
|
||||||
int ModuleId;
|
|
||||||
if (int.TryParse(moduleid, out ModuleId) && IsAuthorizedEntityId(EntityNames.Module, ModuleId))
|
|
||||||
{
|
|
||||||
return await _MyModuleService.GetMyModulesAsync(ModuleId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Get Attempt {ModuleId}", moduleid);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET api/<controller>/5
|
|
||||||
[HttpGet("{id}/{moduleid}")]
|
|
||||||
[Authorize(Policy = PolicyNames.ViewModule)]
|
|
||||||
public async Task<Models.MyModule> Get(int id, int moduleid)
|
|
||||||
{
|
|
||||||
Models.MyModule MyModule = await _MyModuleService.GetMyModuleAsync(id, moduleid);
|
|
||||||
if (MyModule != null && IsAuthorizedEntityId(EntityNames.Module, MyModule.ModuleId))
|
|
||||||
{
|
|
||||||
return MyModule;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Get Attempt {MyModuleId} {ModuleId}", id, moduleid);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// POST api/<controller>
|
|
||||||
[HttpPost]
|
|
||||||
[Authorize(Policy = PolicyNames.EditModule)]
|
|
||||||
public async Task<Models.MyModule> Post([FromBody] Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
if (ModelState.IsValid && IsAuthorizedEntityId(EntityNames.Module, MyModule.ModuleId))
|
|
||||||
{
|
|
||||||
MyModule = await _MyModuleService.AddMyModuleAsync(MyModule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Post Attempt {MyModule}", MyModule);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
MyModule = null;
|
|
||||||
}
|
|
||||||
return MyModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT api/<controller>/5
|
|
||||||
[HttpPut("{id}")]
|
|
||||||
[Authorize(Policy = PolicyNames.EditModule)]
|
|
||||||
public async Task<Models.MyModule> Put(int id, [FromBody] Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
if (ModelState.IsValid && MyModule.MyModuleId == id && IsAuthorizedEntityId(EntityNames.Module, MyModule.ModuleId))
|
|
||||||
{
|
|
||||||
MyModule = await _MyModuleService.UpdateMyModuleAsync(MyModule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Put Attempt {MyModule}", MyModule);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
MyModule = null;
|
|
||||||
}
|
|
||||||
return MyModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
// DELETE api/<controller>/5
|
|
||||||
[HttpDelete("{id}/{moduleid}")]
|
|
||||||
[Authorize(Policy = PolicyNames.EditModule)]
|
|
||||||
public async Task Delete(int id, int moduleid)
|
|
||||||
{
|
|
||||||
Models.MyModule MyModule = await _MyModuleService.GetMyModuleAsync(id, moduleid);
|
|
||||||
if (MyModule != null && IsAuthorizedEntityId(EntityNames.Module, MyModule.ModuleId))
|
|
||||||
{
|
|
||||||
await _MyModuleService.DeleteMyModuleAsync(id, MyModule.ModuleId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized v Delete Attempt {MyModuleId} {ModuleId}", id, moduleid);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text.Json;
|
|
||||||
using Oqtane.Modules;
|
|
||||||
using Oqtane.Models;
|
|
||||||
using Oqtane.Infrastructure;
|
|
||||||
using Oqtane.Interfaces;
|
|
||||||
using Oqtane.Enums;
|
|
||||||
using Oqtane.Repository;
|
|
||||||
using Oqtane.Application.Repository;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Manager
|
|
||||||
{
|
|
||||||
public class MyModuleManager : MigratableModuleBase, IInstallable, IPortable, ISearchable
|
|
||||||
{
|
|
||||||
private readonly IMyModuleRepository _MyModuleRepository;
|
|
||||||
private readonly IDBContextDependencies _DBContextDependencies;
|
|
||||||
|
|
||||||
public MyModuleManager(IMyModuleRepository MyModuleRepository, IDBContextDependencies DBContextDependencies)
|
|
||||||
{
|
|
||||||
_MyModuleRepository = MyModuleRepository;
|
|
||||||
_DBContextDependencies = DBContextDependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Install(Tenant tenant, string version)
|
|
||||||
{
|
|
||||||
return Migrate(new Context(_DBContextDependencies), tenant, MigrationType.Up);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Uninstall(Tenant tenant)
|
|
||||||
{
|
|
||||||
return Migrate(new Context(_DBContextDependencies), tenant, MigrationType.Down);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ExportModule(Module module)
|
|
||||||
{
|
|
||||||
string content = "";
|
|
||||||
List<Models.MyModule> MyModules = _MyModuleRepository.GetMyModules(module.ModuleId).ToList();
|
|
||||||
if (MyModules != null)
|
|
||||||
{
|
|
||||||
content = JsonSerializer.Serialize(MyModules);
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ImportModule(Module module, string content, string version)
|
|
||||||
{
|
|
||||||
List<Models.MyModule> MyModules = null;
|
|
||||||
if (!string.IsNullOrEmpty(content))
|
|
||||||
{
|
|
||||||
MyModules = JsonSerializer.Deserialize<List<Models.MyModule>>(content);
|
|
||||||
}
|
|
||||||
if (MyModules != null)
|
|
||||||
{
|
|
||||||
foreach(var Task in MyModules)
|
|
||||||
{
|
|
||||||
_MyModuleRepository.AddMyModule(new Models.MyModule { ModuleId = module.ModuleId, Name = Task.Name });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<SearchContent>> GetSearchContentsAsync(PageModule pageModule, DateTime lastIndexedOn)
|
|
||||||
{
|
|
||||||
var searchContentList = new List<SearchContent>();
|
|
||||||
|
|
||||||
foreach (var MyModule in _MyModuleRepository.GetMyModules(pageModule.ModuleId))
|
|
||||||
{
|
|
||||||
if (MyModule.ModifiedOn >= lastIndexedOn)
|
|
||||||
{
|
|
||||||
searchContentList.Add(new SearchContent
|
|
||||||
{
|
|
||||||
EntityName = "MyModule",
|
|
||||||
EntityId = MyModule.MyModuleId.ToString(),
|
|
||||||
Title = MyModule.Name,
|
|
||||||
Body = MyModule.Name,
|
|
||||||
ContentModifiedBy = MyModule.ModifiedBy,
|
|
||||||
ContentModifiedOn = MyModule.ModifiedOn
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.FromResult(searchContentList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Oqtane.Databases.Interfaces;
|
|
||||||
using Oqtane.Migrations;
|
|
||||||
using Oqtane.Application.Migrations.EntityBuilders;
|
|
||||||
using Oqtane.Application.Repository;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Migrations
|
|
||||||
{
|
|
||||||
[DbContext(typeof(Context))]
|
|
||||||
[Migration("Oqtane.Application.01.00.00.00")]
|
|
||||||
public class InitializeModule : MultiDatabaseMigration
|
|
||||||
{
|
|
||||||
public InitializeModule(IDatabase database) : base(database)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Up(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
var myModuleEntityBuilder = new MyModuleEntityBuilder(migrationBuilder, ActiveDatabase);
|
|
||||||
myModuleEntityBuilder.Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Down(MigrationBuilder migrationBuilder)
|
|
||||||
{
|
|
||||||
var myModuleEntityBuilder = new MyModuleEntityBuilder(migrationBuilder, ActiveDatabase);
|
|
||||||
myModuleEntityBuilder.Drop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Migrations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
|
||||||
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
|
||||||
using Oqtane.Databases.Interfaces;
|
|
||||||
using Oqtane.Migrations;
|
|
||||||
using Oqtane.Migrations.EntityBuilders;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Migrations.EntityBuilders
|
|
||||||
{
|
|
||||||
public class MyModuleEntityBuilder : AuditableBaseEntityBuilder<MyModuleEntityBuilder>
|
|
||||||
{
|
|
||||||
private const string _entityTableName = "MyModule";
|
|
||||||
private readonly PrimaryKey<MyModuleEntityBuilder> _primaryKey = new("PK_MyModule", x => x.MyModuleId);
|
|
||||||
private readonly ForeignKey<MyModuleEntityBuilder> _moduleForeignKey = new("FK_MyModule_Module", x => x.ModuleId, "Module", "ModuleId", ReferentialAction.Cascade);
|
|
||||||
|
|
||||||
public MyModuleEntityBuilder(MigrationBuilder migrationBuilder, IDatabase database) : base(migrationBuilder, database)
|
|
||||||
{
|
|
||||||
EntityTableName = _entityTableName;
|
|
||||||
PrimaryKey = _primaryKey;
|
|
||||||
ForeignKeys.Add(_moduleForeignKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override MyModuleEntityBuilder BuildTable(ColumnsBuilder table)
|
|
||||||
{
|
|
||||||
MyModuleId = AddAutoIncrementColumn(table, "MyModuleId");
|
|
||||||
ModuleId = AddIntegerColumn(table,"ModuleId");
|
|
||||||
Name = AddMaxStringColumn(table,"Name");
|
|
||||||
AddAuditableColumns(table);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> MyModuleId { get; set; }
|
|
||||||
public OperationBuilder<AddColumnOperation> ModuleId { get; set; }
|
|
||||||
public OperationBuilder<AddColumnOperation> Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Oqtane.Modules;
|
|
||||||
using Oqtane.Repository;
|
|
||||||
using Oqtane.Repository.Databases.Interfaces;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Repository
|
|
||||||
{
|
|
||||||
public class Context : DBContextBase, ITransientService, IMultiDatabase
|
|
||||||
{
|
|
||||||
public virtual DbSet<Models.MyModule> MyModule { get; set; }
|
|
||||||
|
|
||||||
public Context(IDBContextDependencies DBContextDependencies) : base(DBContextDependencies)
|
|
||||||
{
|
|
||||||
// ContextBase handles multi-tenant database connections
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder builder)
|
|
||||||
{
|
|
||||||
base.OnModelCreating(builder);
|
|
||||||
|
|
||||||
builder.Entity<Models.MyModule>().ToTable(ActiveDatabase.RewriteName("MyModule"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Oqtane.Modules;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Repository
|
|
||||||
{
|
|
||||||
public interface IMyModuleRepository
|
|
||||||
{
|
|
||||||
IEnumerable<Models.MyModule> GetMyModules(int ModuleId);
|
|
||||||
Models.MyModule GetMyModule(int MyModuleId);
|
|
||||||
Models.MyModule GetMyModule(int MyModuleId, bool tracking);
|
|
||||||
Models.MyModule AddMyModule(Models.MyModule MyModule);
|
|
||||||
Models.MyModule UpdateMyModule(Models.MyModule MyModule);
|
|
||||||
void DeleteMyModule(int MyModuleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MyModuleRepository : IMyModuleRepository, ITransientService
|
|
||||||
{
|
|
||||||
private readonly IDbContextFactory<Context> _factory;
|
|
||||||
|
|
||||||
public MyModuleRepository(IDbContextFactory<Context> factory)
|
|
||||||
{
|
|
||||||
_factory = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Models.MyModule> GetMyModules(int ModuleId)
|
|
||||||
{
|
|
||||||
using var db = _factory.CreateDbContext();
|
|
||||||
return db.MyModule.Where(item => item.ModuleId == ModuleId).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Models.MyModule GetMyModule(int MyModuleId)
|
|
||||||
{
|
|
||||||
return GetMyModule(MyModuleId, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Models.MyModule GetMyModule(int MyModuleId, bool tracking)
|
|
||||||
{
|
|
||||||
using var db = _factory.CreateDbContext();
|
|
||||||
if (tracking)
|
|
||||||
{
|
|
||||||
return db.MyModule.Find(MyModuleId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return db.MyModule.AsNoTracking().FirstOrDefault(item => item.MyModuleId == MyModuleId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Models.MyModule AddMyModule(Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
using var db = _factory.CreateDbContext();
|
|
||||||
db.MyModule.Add(MyModule);
|
|
||||||
db.SaveChanges();
|
|
||||||
return MyModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Models.MyModule UpdateMyModule(Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
using var db = _factory.CreateDbContext();
|
|
||||||
db.Entry(MyModule).State = EntityState.Modified;
|
|
||||||
db.SaveChanges();
|
|
||||||
return MyModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DeleteMyModule(int MyModuleId)
|
|
||||||
{
|
|
||||||
using var db = _factory.CreateDbContext();
|
|
||||||
Models.MyModule MyModule = db.MyModule.Find(MyModuleId);
|
|
||||||
db.MyModule.Remove(MyModule);
|
|
||||||
db.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Oqtane.Enums;
|
|
||||||
using Oqtane.Infrastructure;
|
|
||||||
using Oqtane.Models;
|
|
||||||
using Oqtane.Security;
|
|
||||||
using Oqtane.Shared;
|
|
||||||
using Oqtane.Application.Repository;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Services
|
|
||||||
{
|
|
||||||
public class ServerMyModuleService : IMyModuleService
|
|
||||||
{
|
|
||||||
private readonly IMyModuleRepository _MyModuleRepository;
|
|
||||||
private readonly IUserPermissions _userPermissions;
|
|
||||||
private readonly ILogManager _logger;
|
|
||||||
private readonly IHttpContextAccessor _accessor;
|
|
||||||
private readonly Alias _alias;
|
|
||||||
|
|
||||||
public ServerMyModuleService(IMyModuleRepository MyModuleRepository, IUserPermissions userPermissions, ITenantManager tenantManager, ILogManager logger, IHttpContextAccessor accessor)
|
|
||||||
{
|
|
||||||
_MyModuleRepository = MyModuleRepository;
|
|
||||||
_userPermissions = userPermissions;
|
|
||||||
_logger = logger;
|
|
||||||
_accessor = accessor;
|
|
||||||
_alias = tenantManager.GetAlias();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<Models.MyModule>> GetMyModulesAsync(int ModuleId)
|
|
||||||
{
|
|
||||||
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.View))
|
|
||||||
{
|
|
||||||
return Task.FromResult(_MyModuleRepository.GetMyModules(ModuleId).ToList());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Get Attempt {ModuleId}", ModuleId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Models.MyModule> GetMyModuleAsync(int MyModuleId, int ModuleId)
|
|
||||||
{
|
|
||||||
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.View))
|
|
||||||
{
|
|
||||||
return Task.FromResult(_MyModuleRepository.GetMyModule(MyModuleId));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Get Attempt {TaskId} {ModuleId}", MyModuleId, ModuleId);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Models.MyModule> AddMyModuleAsync(Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, MyModule.ModuleId, PermissionNames.Edit))
|
|
||||||
{
|
|
||||||
MyModule = _MyModuleRepository.AddMyModule(MyModule);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "MyModule Added {MyModule}", MyModule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Add Attempt {MyModule}", MyModule);
|
|
||||||
MyModule = null;
|
|
||||||
}
|
|
||||||
return Task.FromResult(MyModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Models.MyModule> UpdateMyModuleAsync(Models.MyModule MyModule)
|
|
||||||
{
|
|
||||||
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, MyModule.ModuleId, PermissionNames.Edit))
|
|
||||||
{
|
|
||||||
MyModule = _MyModuleRepository.UpdateMyModule(MyModule);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "MyModule Updated {MyModule}", MyModule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Update Attempt {MyModule}", MyModule);
|
|
||||||
MyModule = null;
|
|
||||||
}
|
|
||||||
return Task.FromResult(MyModule);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task DeleteMyModuleAsync(int MyModuleId, int ModuleId)
|
|
||||||
{
|
|
||||||
if (_userPermissions.IsAuthorized(_accessor.HttpContext.User, _alias.SiteId, EntityNames.Module, ModuleId, PermissionNames.Edit))
|
|
||||||
{
|
|
||||||
_MyModuleRepository.DeleteMyModule(MyModuleId);
|
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "MyModule Deleted {MyModuleId}", MyModuleId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized MyModule Delete Attempt {MyModuleId} {ModuleId}", MyModuleId, ModuleId);
|
|
||||||
}
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Oqtane.Infrastructure;
|
|
||||||
using Oqtane.Application.Repository;
|
|
||||||
using Oqtane.Application.Services;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Startup
|
|
||||||
{
|
|
||||||
public class ServerStartup : IServerStartup
|
|
||||||
{
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
|
||||||
{
|
|
||||||
// not implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConfigureMvc(IMvcBuilder mvcBuilder)
|
|
||||||
{
|
|
||||||
// not implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddTransient<IMyModuleService, ServerMyModuleService>();
|
|
||||||
services.AddDbContextFactory<Context>(opt => { }, ServiceLifetime.Transient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
/* Module Custom Styles */
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
/* Module Script */
|
|
||||||
var App = App || {};
|
|
||||||
|
|
||||||
App.MyModule = {
|
|
||||||
};
|
|
||||||
@@ -1,123 +0,0 @@
|
|||||||
/* Oqtane Styles */
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding-top: 7rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* App Logo */
|
|
||||||
.app-logo .img-fluid {
|
|
||||||
max-height: 90px;
|
|
||||||
padding: 0 5px 0 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table > :not(caption) > * > * {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table .form-control {
|
|
||||||
background-color: #ffffff !important;
|
|
||||||
border-width: 0.5px !important;
|
|
||||||
border-bottom-color: #ccc !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table .form-select {
|
|
||||||
background-color: #ffffff !important;
|
|
||||||
border-width: 0.5px !important;
|
|
||||||
border-bottom-color: #ccc !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table .btn-primary {
|
|
||||||
background-color: var(--bs-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.table .btn-secondary {
|
|
||||||
background-color: var(--bs-secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-dismissible .btn-close {
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls {
|
|
||||||
z-index: 2000;
|
|
||||||
padding-top: 15px;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-menu .nav-item {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
padding-bottom: 0.5rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-menu .nav-item a {
|
|
||||||
border-radius: 4px;
|
|
||||||
height: 3rem;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
line-height: 3rem;
|
|
||||||
padding-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-menu .nav-item a.active {
|
|
||||||
background-color: rgba(255,255,255,0.25);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-menu .nav-item a:hover {
|
|
||||||
background-color: rgba(255,255,255,0.1);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-menu .nav-link .oi {
|
|
||||||
width: 1.5rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
vertical-align: text-top;
|
|
||||||
top: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-toggler {
|
|
||||||
background-color: rgba(255, 255, 255, 0.1);
|
|
||||||
margin: .5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu {
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu span {
|
|
||||||
mix-blend-mode: difference;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 767.98px) {
|
|
||||||
|
|
||||||
.app-menu {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
position: fixed;
|
|
||||||
top: 60px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls {
|
|
||||||
height: 60px;
|
|
||||||
top: 15px;
|
|
||||||
position: fixed;
|
|
||||||
top: 0px;
|
|
||||||
width: 100%;
|
|
||||||
background-color: rgb(0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.controls-group {
|
|
||||||
float: right;
|
|
||||||
margin-right: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
position: relative;
|
|
||||||
top: 60px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using Oqtane.Models;
|
|
||||||
|
|
||||||
namespace Oqtane.Application.Models
|
|
||||||
{
|
|
||||||
public class MyModule : IAuditable
|
|
||||||
{
|
|
||||||
[Key]
|
|
||||||
public int MyModuleId { get; set; }
|
|
||||||
public int ModuleId { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public string CreatedBy { get; set; }
|
|
||||||
public DateTime CreatedOn { get; set; }
|
|
||||||
public string ModifiedBy { get; set; }
|
|
||||||
public DateTime ModifiedOn { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -146,12 +146,12 @@ else
|
|||||||
user = await UserService.AddLoginAsync(user, PageState.QueryString["token"], PageState.Site.Settings["ExternalLogin:ProviderType"], PageState.QueryString["key"], PageState.Site.Settings["ExternalLogin:ProviderName"]);
|
user = await UserService.AddLoginAsync(user, PageState.QueryString["token"], PageState.Site.Settings["ExternalLogin:ProviderType"], PageState.QueryString["key"], PageState.Site.Settings["ExternalLogin:ProviderName"]);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
await logger.LogInformation(LogFunction.Security, "User Login Linkage Successful For Username {Username}", _username);
|
await logger.LogInformation(LogFunction.Security, "External Login Linkage Successful For Username {Username}", _username);
|
||||||
AddModuleMessage(Localizer["Success.Account.Linked"], MessageType.Info);
|
AddModuleMessage(Localizer["Success.Account.Linked"], MessageType.Info);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await logger.LogError(LogFunction.Security, "User Login Linkage Failed For Username {Username}", _username);
|
await logger.LogError(LogFunction.Security, "External Login Linkage Failed For Username {Username}", _username);
|
||||||
AddModuleMessage(Localizer["Message.Account.NotLinked"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Account.NotLinked"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
_username = "";
|
_username = "";
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
<value>User Account Email Address Could Not Be Verified. Please Contact Your Administrator For Further Instructions.</value>
|
<value>User Account Email Address Could Not Be Verified. Please Contact Your Administrator For Further Instructions.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Success.Account.Linked" xml:space="preserve">
|
<data name="Success.Account.Linked" xml:space="preserve">
|
||||||
<value>User Account Linked Successfully. You Can Now Login With Your External Login Below.</value>
|
<value>External Login Linked Successfully. You Can Now Login.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Account.NotLinked" xml:space="preserve">
|
<data name="Message.Account.NotLinked" xml:space="preserve">
|
||||||
<value>External Login Could Not Be Linked. Please Contact Your Administrator For Further Instructions.</value>
|
<value>External Login Could Not Be Linked. Please Contact Your Administrator For Further Instructions.</value>
|
||||||
|
|||||||
@@ -259,7 +259,7 @@
|
|||||||
<value>Passkeys</value>
|
<value>Passkeys</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Logins.Heading" xml:space="preserve">
|
<data name="Logins.Heading" xml:space="preserve">
|
||||||
<value>Logins</value>
|
<value>External Logins</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Passkey" xml:space="preserve">
|
<data name="Passkey" xml:space="preserve">
|
||||||
<value>Passkey</value>
|
<value>Passkey</value>
|
||||||
|
|||||||
@@ -226,7 +226,7 @@
|
|||||||
<value>Passkeys</value>
|
<value>Passkeys</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Logins.Heading" xml:space="preserve">
|
<data name="Logins.Heading" xml:space="preserve">
|
||||||
<value>Logins</value>
|
<value>External Logins</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Passkey" xml:space="preserve">
|
<data name="Passkey" xml:space="preserve">
|
||||||
<value>Passkey</value>
|
<value>Passkey</value>
|
||||||
|
|||||||
@@ -521,7 +521,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized User Login Get Attempt {UserId} {SiteId}", id, _tenantManager.GetAlias().SiteId);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized External Login Get Attempt {UserId} {SiteId}", id, _tenantManager.GetAlias().SiteId);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -537,7 +537,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized User Login Post Attempt {Username} {Token}", user.Username, token);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized External Login Post Attempt {Username} {Token}", user.Username, token);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
user = null;
|
user = null;
|
||||||
}
|
}
|
||||||
@@ -555,7 +555,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized User Login Delete Attempt {UserId} {Provider} {Key}", id, provider, key);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized External Login Delete Attempt {UserId} {Provider} {Key}", id, provider, key);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -676,12 +676,12 @@ namespace Oqtane.Extensions
|
|||||||
var _syncManager = httpContext.RequestServices.GetRequiredService<ISyncManager>();
|
var _syncManager = httpContext.RequestServices.GetRequiredService<ISyncManager>();
|
||||||
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, "Login");
|
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, "Login");
|
||||||
|
|
||||||
_logger.Log(LogLevel.Information, "ExternalLogin", Enums.LogFunction.Security, "External User Login Successful For {Username} From IP Address {IPAddress} Using Provider {Provider}", user.Username, httpContext.Connection.RemoteIpAddress.ToString(), providerName);
|
_logger.Log(LogLevel.Information, "ExternalLogin", Enums.LogFunction.Security, "External Login Successful For {Username} From IP Address {IPAddress} Using Provider {Provider}", user.Username, httpContext.Connection.RemoteIpAddress.ToString(), providerName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
identity.Label = ExternalLoginStatus.AccessDenied;
|
identity.Label = ExternalLoginStatus.AccessDenied;
|
||||||
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, "External User Login Denied For {Username}. User Account Is Deleted Or Not An Active Member Of Site {SiteId}.", user.Username, user.SiteId);
|
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, "External Login Denied For {Username}. User Account Is Deleted Or Not An Active Member Of Site {SiteId}.", user.Username, user.SiteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user