add raw file editing to configuration page in webfront

This commit is contained in:
RaidMax
2021-09-16 16:27:40 -05:00
parent 68c1151191
commit 33c63f01db
8 changed files with 307 additions and 81 deletions

View File

@ -0,0 +1,58 @@
@model IEnumerable<WebfrontCore.ViewModels.ConfigurationFileInfo>
@{
ViewData["Title"] = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CONFIGURATION_TITLE"];
var noticeText = Utilities.CurrentLocalization.LocalizationIndex["WEBFRONT_CONFIGURATION_SAVING_CHANGES"];
static string FormatHtmlId(string value) => value?.Replace(".", "").Replace(" ", "_");
}
@section styles
{
<link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/styles/atom-one-dark.min.css">
}
<div class="row">
<div class="col-12 text-white-50 ">
<h3 class="text-white">@ViewData["Title"]</h3>
<h5 class="mb-4">@noticeText</h5>
<ul class="nav nav-tabs border-bottom-dark">
<li class="nav-item">
<a class="nav-link" asp-action="Edit">@ViewBag.Localization["WEBFRONT_CONFIGURATION_GUI"]</a>
</li>
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#files">@ViewBag.Localization["WEBFRONT_CONFIGURATION_FILES"]</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane" id="editor">
</div>
<div class="tab-pane active" id="files">
@foreach (var file in Model)
{
<div class="bg-primary mb-0 pl-3 pr-3 p-2 text-white d-flex border-bottom-dark">
<span class="oi oi-expand-down align-self-center mr-2 expand-file-icon" data-editor-id="#edit_file_@FormatHtmlId(file.FileName)" title="Toggle Expand"></span>
<span>@file.FileName</span>
</div>
<div class="edit-file bg-dark d-none" id="edit_file_@FormatHtmlId(file.FileName)" data-file-name="@file.FileName">
<pre class="mb-0 mr-auto" spellcheck="false"><code class="language-json bg-dark editable" contenteditable="true" id="edit_file_code_@FormatHtmlId(file.FileName)">@file.FileContent</code></pre>
<button type="button" class="btn btn-primary align-self-end m-3 file-save-button" data-file-name="@file.FileName">Save</button>
</div>
}
</div>
</div>
</div>
@section scripts
{
<!-- I don't want to include the entire highlight js into the bundle for this 1 page -->
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.2.0/highlight.min.js"></script>
<environment include="Development">
<script type="text/javascript" src="~/js/configuration.js"></script>
</environment>
}
</div>

View File

@ -16,19 +16,19 @@
string[] getLinkedPropertyName(System.Reflection.PropertyInfo info)
{
var test = (info.GetCustomAttributes(false)
.Where(_attr => _attr.GetType() == typeof(ConfigurationLinked))
.FirstOrDefault() as ConfigurationLinked);
.Where(_attr => _attr.GetType() == typeof(ConfigurationLinked))
.FirstOrDefault() as ConfigurationLinked);
return test?.LinkedPropertyNames ?? new string[0];
}
bool shouldIgnore(System.Reflection.PropertyInfo info) => (info.GetCustomAttributes(false)
.Where(_attr => _attr.GetType() == typeof(ConfigurationIgnore))
.FirstOrDefault() as ConfigurationIgnore) != null;
.Where(_attr => _attr.GetType() == typeof(ConfigurationIgnore))
.FirstOrDefault() as ConfigurationIgnore) != null;
bool isOptional(System.Reflection.PropertyInfo info) => (info.GetCustomAttributes(false)
.Where(_attr => _attr.GetType() == typeof(ConfigurationOptional))
.FirstOrDefault() as ConfigurationOptional) != null;
.Where(_attr => _attr.GetType() == typeof(ConfigurationOptional))
.FirstOrDefault() as ConfigurationOptional) != null;
bool hasLinkedParent(System.Reflection.PropertyInfo info)
{
@ -40,88 +40,104 @@
<div class="col-12 text-white-50 ">
<h3 class="text-white">@ViewData["Title"]</h3>
<h5 class="mb-4">@noticeText</h5>
<form id="configurationForm" asp-controller="Configuration" asp-action="Save" method="post">
@foreach (var property in properties)
{
if (shouldIgnore(property))
{
continue;
}
string[] linkedPropertyNames = getLinkedPropertyName(property);
<ul class="nav nav-tabs border-bottom-dark">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#editor">GUI Editor</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-action="Files">Files</a>
</li>
</ul>
// bool type
if (property.PropertyType == typeof(bool))
{
<div class="form-group form-check bg-primary mb-0 pl-3 pr-3 p-2">
@Html.Editor(property.Name, linkedPropertyNames.Length > 0 ? new { htmlAttributes = new { @class = "has-related-content mb-0", data_related_content = string.Join(',', linkedPropertyNames.Select(_id => $"#{_id}_content")) } } : null)
@Html.Label(property.Name, null, new { @class = "form-check-label ml-1" })
</div>
}
// array type
else if (property.PropertyType.IsArray)
{
// special type for server config, I don't like this but for now it's ok
@if (property.PropertyType.GetElementType() == typeof(ServerConfiguration))
<div class="tab-content">
<div class="tab-pane active" id="editor">
<form id="configurationForm" asp-controller="Configuration" asp-action="Save" method="post">
@foreach (var property in properties)
{
<div id="@($"{property.Name}_content")" class="pl-3 pr-3 pt-2 pb-3 bg-dark">
@for (int i = 0; i < Model.Servers.Length; i++)
if (shouldIgnore(property))
{
continue;
}
string[] linkedPropertyNames = getLinkedPropertyName(property);
// bool type
if (property.PropertyType == typeof(bool))
{
<div class="form-group form-check bg-primary mb-0 pl-3 pr-3 p-2">
@Html.Editor(property.Name, linkedPropertyNames.Length > 0 ? new {htmlAttributes = new {@class = "has-related-content mb-0", data_related_content = string.Join(',', linkedPropertyNames.Select(_id => $"#{_id}_content"))}} : null)
@Html.Label(property.Name, null, new {@class = "form-check-label ml-1"})
</div>
}
// array type
else if (property.PropertyType.IsArray)
{
// special type for server config, I don't like this but for now it's ok
@if (property.PropertyType.GetElementType() == typeof(ServerConfiguration))
{
@Html.EditorFor(model => model.Servers[i]);
<div id="@($"{property.Name}_content")" class="pl-3 pr-3 pt-2 pb-3 bg-dark">
@for (int i = 0; i < Model.Servers.Length; i++)
{
@Html.EditorFor(model => model.Servers[i])
;
}
<a asp-controller="Configuration" asp-action="GetNewListItem" asp-route-propertyName="@property.Name" class="btn btn-primary configuration-server-add-new">@addServerText</a>
</div>
}
<a asp-controller="Configuration" asp-action="GetNewListItem" asp-route-propertyName="@property.Name" class="btn btn-primary configuration-server-add-new">@addServerText</a>
</div>
}
else if (hasLinkedParent(property))
{
<div id="@($"{property.Name}_content")" class="@(linkedPropertyNames.Length == 0 ? "hide" : "hide") bg-dark pl-3 pr-3 pb-2">
@if (linkedPropertyNames.Length == 0)
else if (hasLinkedParent(property))
{
@Html.Label(property.Name, null, new { @class = "mt-2 d-block" })
<div id="@($"{property.Name}_content")" class="@(linkedPropertyNames.Length == 0 ? "hide" : "hide") bg-dark pl-3 pr-3 pb-2">
@if (linkedPropertyNames.Length == 0)
{
@Html.Label(property.Name, null, new {@class = "mt-2 d-block"})
}
@Html.Editor(property.Name, new {htmlAttributes = new {@class = $"form-group form-control bg-dark text-white-50 {(linkedPropertyNames.Length == 0 ? "mb-3" : "mb-0")}"}})
<a asp-controller="Configuration" asp-action="GetNewListItem" asp-route-propertyName="@property.Name" class="btn btn-primary configuration-add-new">@addText</a>
</div>
}
@Html.Editor(property.Name, new { htmlAttributes = new { @class = $"form-group form-control bg-dark text-white-50 {(linkedPropertyNames.Length == 0 ? "mb-3" : "mb-0")}" } })
<a asp-controller="Configuration" asp-action="GetNewListItem" asp-route-propertyName="@property.Name" class="btn btn-primary configuration-add-new">@addText</a>
</div>
}
else
{
@Html.Label(property.Name, null, new { @class = "bg-primary pl-3 pr-3 p-2 mb-0 w-100" })
<div id="@($"{property.Name}_content")" class="pl-3 pr-3 pt-2 pb-3 bg-dark">
@Html.Editor(property.Name, new { htmlAttributes = new { @class = "form-control bg-dark text-white-50 mt-3 mb-3", placeholder = isOptional(property) ? optionalText : "" } })
<a asp-controller="Configuration" asp-action="GetNewListItem" asp-route-propertyName="@property.Name" class="btn btn-primary configuration-add-new">@addText</a>
</div>
}
}
else
{
@Html.Label(property.Name, null, new {@class = "bg-primary pl-3 pr-3 p-2 mb-0 w-100"})
<div id="@($"{property.Name}_content")" class="pl-3 pr-3 pt-2 pb-3 bg-dark">
@Html.Editor(property.Name, new {htmlAttributes = new {@class = "form-control bg-dark text-white-50 mt-3 mb-3", placeholder = isOptional(property) ? optionalText : ""}})
<a asp-controller="Configuration" asp-action="GetNewListItem" asp-route-propertyName="@property.Name" class="btn btn-primary configuration-add-new">@addText</a>
</div>
}
}
else
{
if (hasLinkedParent(property))
{
<div id="@($"{property.Name}_content")" class="@(hasLinkedParent(property) ? "hide" : "") bg-dark pl-3 pr-3 pt-2 pb-3">
@Html.Label(property.Name, null, new { @class = "mt-1" })
@Html.Editor(property.Name, new { htmlAttributes = new { @class = "form-group form-control bg-dark text-white-50 mb-0", placeholder = isOptional(property) ? optionalText : "" } })
</div>
}
else
{
if (hasLinkedParent(property))
{
<div id="@($"{property.Name}_content")" class="@(hasLinkedParent(property) ? "hide" : "") bg-dark pl-3 pr-3 pt-2 pb-3">
@Html.Label(property.Name, null, new {@class = "mt-1"})
@Html.Editor(property.Name, new {htmlAttributes = new {@class = "form-group form-control bg-dark text-white-50 mb-0", placeholder = isOptional(property) ? optionalText : ""}})
</div>
}
else
{
@Html.Label(property.Name, null, new { @class = "bg-primary pl-3 pr-3 p-2 mb-0 w-100" })
<div class="p-3 bg-dark">
@Html.Editor(property.Name, new { htmlAttributes = new { @class = "form-group form-control bg-dark text-white-50 mb-0", placeholder = isOptional(property) ? optionalText : "" } })
</div>
else
{
@Html.Label(property.Name, null, new {@class = "bg-primary pl-3 pr-3 p-2 mb-0 w-100"})
<div class="p-3 bg-dark">
@Html.Editor(property.Name, new {htmlAttributes = new {@class = "form-group form-control bg-dark text-white-50 mb-0", placeholder = isOptional(property) ? optionalText : ""}})
</div>
}
}
}
}
}
<button class="btn btn-primary btn-block">@saveText</button>
</form>
<button class="btn btn-primary btn-block">@saveText</button>
</form>
</div>
</div>
</div>
</div>
@section scripts {
<environment include="Development">
<script type="text/javascript" src="~/js/configuration.js"></script>
</environment>
}
}