Merge pull request #5584 from sbwalker/dev
added a Setting Management UI
This commit is contained in:
226
Oqtane.Client/Modules/Admin/Settings/Add.razor
Normal file
226
Oqtane.Client/Modules/Admin/Settings/Add.razor
Normal file
@ -0,0 +1,226 @@
|
||||
@namespace Oqtane.Modules.Admin.Settings
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ISettingService SettingService
|
||||
@inject IStringLocalizer<Edit> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<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="entityName" HelpText="Entity Name" ResourceKey="EntityName">Entity:</Label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
@if (_entityNameElement == "input")
|
||||
{
|
||||
<input id="entityName" class="form-control" @bind="@_entityName" maxlength="256" required />
|
||||
}
|
||||
else
|
||||
{
|
||||
<select class="form-select custom-select" value="@_entityName" @onchange="(e => EntityNameChanged(e))">
|
||||
<option value="-"><@Localizer["Select Entity"]></option>
|
||||
@foreach (var entityName in _entityNames)
|
||||
{
|
||||
<option value="@entityName">@entityName</option>
|
||||
}
|
||||
</select>
|
||||
}
|
||||
<button type="button" class="btn btn-secondary" @onclick="@EntityNameClicked" tabindex="-1">@_entityNameTitle</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="entityId" HelpText="Entity Id" ResourceKey="EntityId">Id:</Label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
@if (_entityIdElement == "input")
|
||||
{
|
||||
<input id="entityId" class="form-control" @bind="@_entityId" maxlength="256" required />
|
||||
}
|
||||
else
|
||||
{
|
||||
<select class="form-select custom-select" @bind="@_entityId">
|
||||
<option value="-"><@Localizer["Select Id"]></option>
|
||||
@foreach (var entityId in _entityIds)
|
||||
{
|
||||
<option value="@entityId">@entityId</option>
|
||||
}
|
||||
</select>
|
||||
}
|
||||
<button type="button" class="btn btn-secondary" @onclick="@EntityIdClicked" tabindex="-1">@_entityIdTitle</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="settingName" HelpText="Setting Name" ResourceKey="SettingName">Name:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="settingName" class="form-control" @bind="@_settingName" maxlength="256" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="settingValue" HelpText="Setting Value" ResourceKey="SettingValue">Value:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="SettingValue" class="form-control" @bind="@_settingValue" maxlength="256" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="isPrivate" HelpText="Private" ResourceKey="IsPrivate">Private?</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="isPrivate" class="form-select" @bind="@_isPrivate">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
<option value="False">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<br /><br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSetting">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@code {
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
|
||||
private string _entityName = "-";
|
||||
private List<string> _entityNames = new List<string>();
|
||||
private string _entityNameElement = "select";
|
||||
private string _entityNameTitle = "";
|
||||
private string _entityId = "-";
|
||||
private List<int> _entityIds = new List<int>();
|
||||
private string _entityIdElement = "select";
|
||||
private string _entityIdTitle = "";
|
||||
private string _settingName = "";
|
||||
private string _settingValue = "";
|
||||
private string _isPrivate = "True";
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
_entityNameTitle = Localizer["Input"];
|
||||
_entityIdTitle = Localizer["Input"];
|
||||
|
||||
// default entity names
|
||||
_entityNames.Add(EntityNames.Host);
|
||||
_entityNames.Add(EntityNames.Job);
|
||||
_entityNames.Add(EntityNames.ModuleDefinition);
|
||||
_entityNames.Add(EntityNames.Theme);
|
||||
_entityNames.Add(EntityNames.Tenant);
|
||||
_entityNames.Add(EntityNames.Site);
|
||||
_entityNames.Add(EntityNames.Role);
|
||||
_entityNames.Add(EntityNames.Page);
|
||||
_entityNames.Add(EntityNames.Module);
|
||||
_entityNames.Add(EntityNames.Folder);
|
||||
_entityNames.Add(EntityNames.User);
|
||||
_entityNames.Add(EntityNames.Visitor);
|
||||
|
||||
// custom entity names
|
||||
var entityNames = await SettingService.GetEntityNamesAsync();
|
||||
foreach (var entityName in entityNames)
|
||||
{
|
||||
if (!_entityNames.Contains(entityName))
|
||||
{
|
||||
_entityNames.Add(entityName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Setting {Error}", ex.Message);
|
||||
AddModuleMessage(Localizer["Error.LoadSetting"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void EntityNameClicked()
|
||||
{
|
||||
if (_entityNameElement == "select")
|
||||
{
|
||||
_entityName = "";
|
||||
_entityNameElement = "input";
|
||||
_entityNameTitle = Localizer["Select"];
|
||||
_entityId = "";
|
||||
_entityIdElement = "input";
|
||||
_entityIdTitle = Localizer["Select"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_entityName = "-";
|
||||
_entityNameElement = "select";
|
||||
_entityNameTitle = Localizer["Input"];
|
||||
}
|
||||
}
|
||||
|
||||
private void EntityIdClicked()
|
||||
{
|
||||
if (_entityIdElement == "select")
|
||||
{
|
||||
_entityId = "";
|
||||
_entityIdElement = "input";
|
||||
_entityIdTitle = Localizer["Select"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_entityId = "-";
|
||||
_entityIdElement = "select";
|
||||
_entityIdTitle = Localizer["Input"];
|
||||
}
|
||||
}
|
||||
|
||||
private async void EntityNameChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_entityName = e.Value.ToString();
|
||||
_entityId = "-";
|
||||
_entityIdElement = "select";
|
||||
_entityIdTitle = Localizer["Input"];
|
||||
if (_entityName != "-")
|
||||
{
|
||||
_entityIds = await SettingService.GetEntityIdsAsync(_entityName);
|
||||
}
|
||||
else
|
||||
{
|
||||
_entityIds = new List<int>();
|
||||
}
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error On EntityNameChanged");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveSetting()
|
||||
{
|
||||
validated = true;
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
var setting = new Setting();
|
||||
setting.EntityName = _entityName;
|
||||
setting.EntityId = int.Parse(_entityId);
|
||||
setting.SettingName = _settingName;
|
||||
setting.SettingValue = _settingValue;
|
||||
setting.IsPrivate = (bool.Parse(_isPrivate));
|
||||
|
||||
try
|
||||
{
|
||||
setting = await SettingService.AddSettingAsync(setting);
|
||||
await logger.LogInformation("Setting Saved {Setting}", setting);
|
||||
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Setting {Setting} {Error}", setting, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.SaveSetting"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
122
Oqtane.Client/Modules/Admin/Settings/Edit.razor
Normal file
122
Oqtane.Client/Modules/Admin/Settings/Edit.razor
Normal file
@ -0,0 +1,122 @@
|
||||
@namespace Oqtane.Modules.Admin.Settings
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ISettingService SettingService
|
||||
@inject IStringLocalizer<Edit> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<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="entityName" HelpText="Entity Name" ResourceKey="EntityName">Entity:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="entityName" class="form-control" @bind="@_entityName" maxlength="256" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="entityId" HelpText="Entity Id" ResourceKey="EntityId">Id:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="entityId" class="form-control" @bind="@_entityId" maxlength="256" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="settingName" HelpText="Setting Name" ResourceKey="SettingName">Name:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="settingName" class="form-control" @bind="@_settingName" maxlength="256" disabled />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="settingValue" HelpText="Setting Value" ResourceKey="SettingValue">Value:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="SettingValue" class="form-control" @bind="@_settingValue" maxlength="256" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="isPrivate" HelpText="Private" ResourceKey="IsPrivate">Private?</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="isPrivate" class="form-select" @bind="@_isPrivate">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
<option value="False">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<br /><br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSetting">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
|
||||
<br /><br />
|
||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@code {
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
|
||||
private int _settingId;
|
||||
private string _entityName;
|
||||
private string _entityId;
|
||||
private string _settingName;
|
||||
private string _settingValue;
|
||||
private string _isPrivate;
|
||||
private string _createdby;
|
||||
private DateTime _createdon;
|
||||
private string _modifiedby;
|
||||
private DateTime _modifiedon;
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_settingId = int.Parse(PageState.QueryString["id"]);
|
||||
_entityName = PageState.QueryString["entity"];
|
||||
|
||||
try
|
||||
{
|
||||
var setting = await SettingService.GetSettingAsync(_entityName, _settingId);
|
||||
if (setting != null)
|
||||
{
|
||||
_entityId = setting.EntityId.ToString();
|
||||
_settingName = setting.SettingName;
|
||||
_settingValue = setting.SettingValue;
|
||||
_isPrivate = setting.IsPrivate.ToString();
|
||||
_createdby = setting.CreatedBy;
|
||||
_createdon = setting.CreatedOn;
|
||||
_modifiedby = setting.ModifiedBy;
|
||||
_modifiedon = setting.ModifiedOn;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Loading Setting {SettingId} {Error}", _settingId, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.LoadSetting"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveSetting()
|
||||
{
|
||||
validated = true;
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(form))
|
||||
{
|
||||
var setting = await SettingService.GetSettingAsync(_entityName, _settingId);
|
||||
setting.SettingValue = _settingValue;
|
||||
setting.IsPrivate = (_isPrivate != null && Boolean.Parse(_isPrivate));
|
||||
|
||||
try
|
||||
{
|
||||
setting = await SettingService.UpdateSettingAsync(setting);
|
||||
await logger.LogInformation("Setting Saved {Setting}", setting);
|
||||
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Saving Setting {Setting} {Error}", setting, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.SaveSetting"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
}
|
145
Oqtane.Client/Modules/Admin/Settings/Index.razor
Normal file
145
Oqtane.Client/Modules/Admin/Settings/Index.razor
Normal file
@ -0,0 +1,145 @@
|
||||
@namespace Oqtane.Modules.Admin.Settings
|
||||
@inherits ModuleBase
|
||||
@inject ISettingService SettingService
|
||||
@inject IStringLocalizer<Index> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<div class="col-sm-2">
|
||||
<ActionLink Action="Add" Text="Add Setting" Security="SecurityAccessLevel.Host" ResourceKey="AddSetting" ReturnUrl="@(NavigateUrl(PageState.Page.Path, AddUrlParameters(_entityName, _entityId)))" />
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<select class="form-select custom-select" value="@_entityName" @onchange="(e => EntityNameChanged(e))">
|
||||
<option value="-"><@Localizer["Select Entity"]></option>
|
||||
@foreach (var entityName in _entityNames)
|
||||
{
|
||||
<option value="@entityName">@entityName</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<select class="form-select custom-select" value="@_entityId" @onchange="(e => EntityIdChanged(e))">
|
||||
<option value="-"><@Localizer["Select Id"]></option>
|
||||
@foreach (var entityId in _entityIds)
|
||||
{
|
||||
<option value="@entityId">@entityId</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
||||
<Pager Items="@_settings" SearchProperties="SettingName,SettingValue">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>@Localizer["Name"]</th>
|
||||
<th>@Localizer["Value"]</th>
|
||||
</Header>
|
||||
<Row>
|
||||
<td><ActionLink Action="Edit" Text="Edit" Parameters="@($"entity={context.EntityName}&id={context.SettingId}")" Security="SecurityAccessLevel.Host" ResourceKey="EditSetting" ReturnUrl="@(NavigateUrl(PageState.Page.Path, AddUrlParameters(_entityName, _entityId)))" /></td>
|
||||
<td><ActionDialog Header="Delete Setting" Message="@string.Format(Localizer["Confirm.DeleteSetting"], context.SettingName)" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteSetting(context))" ResourceKey="DeleteSetting" /></td>
|
||||
<td>@context.SettingName</td>
|
||||
<td>@context.SettingValue</td>
|
||||
</Row>
|
||||
</Pager>
|
||||
|
||||
@code {
|
||||
private string _entityName = "-";
|
||||
private List<string> _entityNames = new List<string>();
|
||||
private string _entityId = "-";
|
||||
private List<int> _entityIds = new List<int>();
|
||||
private List<Setting> _settings = new List<Setting>();
|
||||
|
||||
public override string UrlParametersTemplate => "/{entityname}/{entityid}";
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
_entityNames = await SettingService.GetEntityNamesAsync();
|
||||
|
||||
if (UrlParameters.ContainsKey("entityname"))
|
||||
{
|
||||
_entityName = UrlParameters["entityname"];
|
||||
await GetEntityIds();
|
||||
}
|
||||
if (UrlParameters.ContainsKey("entityid"))
|
||||
{
|
||||
_entityId = UrlParameters["entityid"];
|
||||
await GetSettings();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GetEntityIds()
|
||||
{
|
||||
if (_entityName != "-")
|
||||
{
|
||||
_entityIds = await SettingService.GetEntityIdsAsync(_entityName);
|
||||
}
|
||||
else
|
||||
{
|
||||
_entityIds = new List<int>();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GetSettings()
|
||||
{
|
||||
if (_entityName != "-" && _entityId != "-")
|
||||
{
|
||||
_settings = await SettingService.GetSettingsAsync(_entityName, int.Parse(_entityId), "");
|
||||
_settings = _settings.OrderBy(item => item.SettingName).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
_settings = new List<Setting>();
|
||||
}
|
||||
}
|
||||
|
||||
private async void EntityNameChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_entityName = e.Value.ToString();
|
||||
_entityId = "-";
|
||||
await GetEntityIds();
|
||||
await GetSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error On EntityNameChanged");
|
||||
}
|
||||
}
|
||||
|
||||
private async void EntityIdChanged(ChangeEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
_entityId = e.Value.ToString();
|
||||
await GetSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error On EntityIdChanged");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteSetting(Setting setting)
|
||||
{
|
||||
try
|
||||
{
|
||||
await SettingService.DeleteSettingAsync(setting.EntityName, setting.EntityId, setting.SettingName);
|
||||
await logger.LogInformation("Setting Deleted {Setting}", setting);
|
||||
await GetSettings();
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Setting {Setting} {Error}", setting, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.DeleteSetting"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
156
Oqtane.Client/Resources/Modules/Admin/Settings/Add.resx
Normal file
156
Oqtane.Client/Resources/Modules/Admin/Settings/Add.resx
Normal file
@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="SettingName.Text" xml:space="preserve">
|
||||
<value>Name:</value>
|
||||
</data>
|
||||
<data name="SettingName.HelpText" xml:space="preserve">
|
||||
<value>Setting Name</value>
|
||||
</data>
|
||||
<data name="EntityId.HelpText" xml:space="preserve">
|
||||
<value>Select an existing Id or input a new Id. For Entities which are global such as master data, use the Id value '-1'.</value>
|
||||
</data>
|
||||
<data name="EntityName.HelpText" xml:space="preserve">
|
||||
<value>Select an existing Entity or input a custom Entity. Custom Entities with a prefix of 'Master:' will be stored in the master database.</value>
|
||||
</data>
|
||||
<data name="EntityId.Text" xml:space="preserve">
|
||||
<value>Id:</value>
|
||||
</data>
|
||||
<data name="EntityName.Text" xml:space="preserve">
|
||||
<value>Entity:</value>
|
||||
</data>
|
||||
<data name="Error.SaveSetting" xml:space="preserve">
|
||||
<value>Error Saving Setting</value>
|
||||
</data>
|
||||
<data name="Message.InfoRequired" xml:space="preserve">
|
||||
<value>Please Provide All Required Information</value>
|
||||
</data>
|
||||
<data name="SettingValue.Text" xml:space="preserve">
|
||||
<value>Value:</value>
|
||||
</data>
|
||||
<data name="SettingValue.HelpText" xml:space="preserve">
|
||||
<value>Setting Value</value>
|
||||
</data>
|
||||
<data name="IsPrivate.Text" xml:space="preserve">
|
||||
<value>Private?</value>
|
||||
</data>
|
||||
<data name="IsPrivate.HelpText" xml:space="preserve">
|
||||
<value>Indicates if this setting is private ie. if it should only be maintained on the server and not sent to the client</value>
|
||||
</data>
|
||||
</root>
|
159
Oqtane.Client/Resources/Modules/Admin/Settings/Edit.resx
Normal file
159
Oqtane.Client/Resources/Modules/Admin/Settings/Edit.resx
Normal file
@ -0,0 +1,159 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="SettingName.Text" xml:space="preserve">
|
||||
<value>Name:</value>
|
||||
</data>
|
||||
<data name="SettingName.HelpText" xml:space="preserve">
|
||||
<value>Setting Name</value>
|
||||
</data>
|
||||
<data name="EntityId.HelpText" xml:space="preserve">
|
||||
<value>Entity Id</value>
|
||||
</data>
|
||||
<data name="EntityName.HelpText" xml:space="preserve">
|
||||
<value>Entity Name</value>
|
||||
</data>
|
||||
<data name="EntityId.Text" xml:space="preserve">
|
||||
<value>Id:</value>
|
||||
</data>
|
||||
<data name="EntityName.Text" xml:space="preserve">
|
||||
<value>Entity:</value>
|
||||
</data>
|
||||
<data name="Error.LoadSetting" xml:space="preserve">
|
||||
<value>Error Loading Setting</value>
|
||||
</data>
|
||||
<data name="Error.SaveSetting" xml:space="preserve">
|
||||
<value>Error Saving Setting</value>
|
||||
</data>
|
||||
<data name="Message.InfoRequired" xml:space="preserve">
|
||||
<value>Please Provide All Required Information</value>
|
||||
</data>
|
||||
<data name="SettingValue.Text" xml:space="preserve">
|
||||
<value>Value:</value>
|
||||
</data>
|
||||
<data name="SettingValue.HelpText" xml:space="preserve">
|
||||
<value>Setting Value</value>
|
||||
</data>
|
||||
<data name="IsPrivate.Text" xml:space="preserve">
|
||||
<value>Private?</value>
|
||||
</data>
|
||||
<data name="IsPrivate.HelpText" xml:space="preserve">
|
||||
<value>Indicates if this setting is private ie. if it should only be maintained on the server and not sent to the client</value>
|
||||
</data>
|
||||
</root>
|
150
Oqtane.Client/Resources/Modules/Admin/Settings/Index.resx
Normal file
150
Oqtane.Client/Resources/Modules/Admin/Settings/Index.resx
Normal file
@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Confirm.DeleteSetting" xml:space="preserve">
|
||||
<value>Are You Sure You Wish To Delete The {0} Setting?</value>
|
||||
</data>
|
||||
<data name="Error.DeleteSetting" xml:space="preserve">
|
||||
<value>Error Deleting Setting</value>
|
||||
</data>
|
||||
<data name="AddSetting.Text" xml:space="preserve">
|
||||
<value>Add Setting</value>
|
||||
</data>
|
||||
<data name="DeleteSetting.Header" xml:space="preserve">
|
||||
<value>Delete Setting</value>
|
||||
</data>
|
||||
<data name="DeleteSetting.Text" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="EditSetting.Text" xml:space="preserve">
|
||||
<value>Edit</value>
|
||||
</data>
|
||||
<data name="Select Entity" xml:space="preserve">
|
||||
<value>Select Entity</value>
|
||||
</data>
|
||||
<data name="Select Id" xml:space="preserve">
|
||||
<value>Select Id</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="Value" xml:space="preserve">
|
||||
<value>Value</value>
|
||||
</data>
|
||||
</root>
|
@ -240,6 +240,19 @@ namespace Oqtane.Services
|
||||
/// <returns></returns>
|
||||
Task DeleteSettingAsync(string entityName, int settingId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets list of unique entity names
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<string>> GetEntityNamesAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of unique entity IDs for the given entity name
|
||||
/// </summary>
|
||||
/// <param name="entityName"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<int>> GetEntityIdsAsync(string entityName);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the given settingName (key) from the given key-value dictionary
|
||||
/// </summary>
|
||||
@ -494,6 +507,15 @@ namespace Oqtane.Services
|
||||
await DeleteAsync($"{Apiurl}/{settingId}/{entityName}");
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetEntityNamesAsync()
|
||||
{
|
||||
return await GetJsonAsync<List<string>>($"{Apiurl}/entitynames");
|
||||
}
|
||||
|
||||
public async Task<List<int>> GetEntityIdsAsync(string entityName)
|
||||
{
|
||||
return await GetJsonAsync<List<int>>($"{Apiurl}/entityids?entityname={entityName}");
|
||||
}
|
||||
|
||||
public string GetSetting(Dictionary<string, string> settings, string settingName, string defaultValue)
|
||||
{
|
||||
|
@ -248,6 +248,22 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
// GET: api/<controller>/entitynames
|
||||
[HttpGet("entitynames")]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<string> GetEntityNames()
|
||||
{
|
||||
return _settings.GetEntityNames();
|
||||
}
|
||||
|
||||
// GET: api/<controller>/entityids?entityname=x
|
||||
[HttpGet("entityids")]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<int> GetEntityIds(string entityName)
|
||||
{
|
||||
return _settings.GetEntityIds(entityName);
|
||||
}
|
||||
|
||||
// DELETE api/<controller>/clear
|
||||
[HttpDelete("clear")]
|
||||
[Authorize(Roles = RoleNames.Admin)]
|
||||
@ -297,6 +313,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
break;
|
||||
case EntityNames.Site:
|
||||
case EntityNames.Role:
|
||||
if (permissionName == PermissionNames.Edit)
|
||||
{
|
||||
authorized = User.IsInRole(RoleNames.Admin);
|
||||
@ -326,8 +343,14 @@ namespace Oqtane.Controllers
|
||||
authorized = true;
|
||||
if (permissionName == PermissionNames.Edit)
|
||||
{
|
||||
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, permissionName) ||
|
||||
_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, -1, PermissionNames.Write, RoleNames.Admin);
|
||||
if (entityId == -1)
|
||||
{
|
||||
authorized = User.IsInRole(entityName.ToLower().StartsWith("master:") ? RoleNames.Host : RoleNames.Admin);
|
||||
}
|
||||
else
|
||||
{
|
||||
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, permissionName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -347,6 +370,7 @@ namespace Oqtane.Controllers
|
||||
filter = !User.IsInRole(RoleNames.Host);
|
||||
break;
|
||||
case EntityNames.Site:
|
||||
case EntityNames.Role:
|
||||
filter = !User.IsInRole(RoleNames.Admin);
|
||||
break;
|
||||
case EntityNames.Page:
|
||||
@ -365,7 +389,7 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
break;
|
||||
default: // custom entity
|
||||
filter = !User.IsInRole(RoleNames.Admin) && !_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, PermissionNames.Edit);
|
||||
filter = !User.IsInRole(entityName.ToLower().StartsWith("master:") ? RoleNames.Host : RoleNames.Admin) && !_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, PermissionNames.Edit);
|
||||
break;
|
||||
}
|
||||
return filter;
|
||||
|
@ -19,6 +19,8 @@ namespace Oqtane.Repository
|
||||
Setting GetSetting(string entityName, int entityId, string settingName);
|
||||
void DeleteSetting(string entityName, int settingId);
|
||||
void DeleteSettings(string entityName, int entityId);
|
||||
IEnumerable<string> GetEntityNames();
|
||||
IEnumerable<int> GetEntityIds(string entityName);
|
||||
string GetSettingValue(IEnumerable<Setting> settings, string settingName, string defaultValue);
|
||||
string GetSettingValue(string entityName, int entityId, string settingName, string defaultValue);
|
||||
}
|
||||
@ -190,6 +192,18 @@ namespace Oqtane.Repository
|
||||
ManageCache(entityName);
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetEntityNames()
|
||||
{
|
||||
using var db = _tenantContextFactory.CreateDbContext();
|
||||
return db.Setting.Select(item => item.EntityName).Distinct().OrderBy(item => item).ToList();
|
||||
}
|
||||
public IEnumerable<int> GetEntityIds(string entityName)
|
||||
{
|
||||
using var db = _tenantContextFactory.CreateDbContext();
|
||||
return db.Setting.Where(item => item.EntityName == entityName)
|
||||
.Select(item => item.EntityId).Distinct().OrderBy(item => item).ToList();
|
||||
}
|
||||
|
||||
public string GetSettingValue(IEnumerable<Setting> settings, string settingName, string defaultValue)
|
||||
{
|
||||
var setting = settings.FirstOrDefault(item => item.SettingName == settingName);
|
||||
@ -218,7 +232,9 @@ namespace Oqtane.Repository
|
||||
|
||||
private bool IsMaster(string EntityName)
|
||||
{
|
||||
return (EntityName == EntityNames.ModuleDefinition || EntityName == EntityNames.Host);
|
||||
return EntityName == EntityNames.Host || EntityName == EntityNames.Job ||
|
||||
EntityName == EntityNames.ModuleDefinition || EntityName == EntityNames.Theme ||
|
||||
EntityName.ToLower().StartsWith("master:");
|
||||
}
|
||||
|
||||
private void ManageCache(string EntityName)
|
||||
|
Reference in New Issue
Block a user