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>
|
/// <returns></returns>
|
||||||
Task DeleteSettingAsync(string entityName, int settingId);
|
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>
|
/// <summary>
|
||||||
/// Gets the value of the given settingName (key) from the given key-value dictionary
|
/// Gets the value of the given settingName (key) from the given key-value dictionary
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -494,6 +507,15 @@ namespace Oqtane.Services
|
|||||||
await DeleteAsync($"{Apiurl}/{settingId}/{entityName}");
|
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)
|
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
|
// DELETE api/<controller>/clear
|
||||||
[HttpDelete("clear")]
|
[HttpDelete("clear")]
|
||||||
[Authorize(Roles = RoleNames.Admin)]
|
[Authorize(Roles = RoleNames.Admin)]
|
||||||
@ -297,6 +313,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EntityNames.Site:
|
case EntityNames.Site:
|
||||||
|
case EntityNames.Role:
|
||||||
if (permissionName == PermissionNames.Edit)
|
if (permissionName == PermissionNames.Edit)
|
||||||
{
|
{
|
||||||
authorized = User.IsInRole(RoleNames.Admin);
|
authorized = User.IsInRole(RoleNames.Admin);
|
||||||
@ -326,8 +343,14 @@ namespace Oqtane.Controllers
|
|||||||
authorized = true;
|
authorized = true;
|
||||||
if (permissionName == PermissionNames.Edit)
|
if (permissionName == PermissionNames.Edit)
|
||||||
{
|
{
|
||||||
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, permissionName) ||
|
if (entityId == -1)
|
||||||
_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, -1, PermissionNames.Write, RoleNames.Admin);
|
{
|
||||||
|
authorized = User.IsInRole(entityName.ToLower().StartsWith("master:") ? RoleNames.Host : RoleNames.Admin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, permissionName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -347,6 +370,7 @@ namespace Oqtane.Controllers
|
|||||||
filter = !User.IsInRole(RoleNames.Host);
|
filter = !User.IsInRole(RoleNames.Host);
|
||||||
break;
|
break;
|
||||||
case EntityNames.Site:
|
case EntityNames.Site:
|
||||||
|
case EntityNames.Role:
|
||||||
filter = !User.IsInRole(RoleNames.Admin);
|
filter = !User.IsInRole(RoleNames.Admin);
|
||||||
break;
|
break;
|
||||||
case EntityNames.Page:
|
case EntityNames.Page:
|
||||||
@ -365,7 +389,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // custom entity
|
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;
|
break;
|
||||||
}
|
}
|
||||||
return filter;
|
return filter;
|
||||||
|
@ -19,6 +19,8 @@ namespace Oqtane.Repository
|
|||||||
Setting GetSetting(string entityName, int entityId, string settingName);
|
Setting GetSetting(string entityName, int entityId, string settingName);
|
||||||
void DeleteSetting(string entityName, int settingId);
|
void DeleteSetting(string entityName, int settingId);
|
||||||
void DeleteSettings(string entityName, int entityId);
|
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(IEnumerable<Setting> settings, string settingName, string defaultValue);
|
||||||
string GetSettingValue(string entityName, int entityId, string settingName, string defaultValue);
|
string GetSettingValue(string entityName, int entityId, string settingName, string defaultValue);
|
||||||
}
|
}
|
||||||
@ -190,6 +192,18 @@ namespace Oqtane.Repository
|
|||||||
ManageCache(entityName);
|
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)
|
public string GetSettingValue(IEnumerable<Setting> settings, string settingName, string defaultValue)
|
||||||
{
|
{
|
||||||
var setting = settings.FirstOrDefault(item => item.SettingName == settingName);
|
var setting = settings.FirstOrDefault(item => item.SettingName == settingName);
|
||||||
@ -218,7 +232,9 @@ namespace Oqtane.Repository
|
|||||||
|
|
||||||
private bool IsMaster(string EntityName)
|
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)
|
private void ManageCache(string EntityName)
|
||||||
|
Reference in New Issue
Block a user