additional enhancements to widget editor.

This commit is contained in:
DESKTOP-T0O5CDB\DESK-555BD 2024-11-04 08:37:38 -07:00
parent d6b6600ce9
commit 48f0e16fde
6 changed files with 143 additions and 1 deletions

View File

@ -523,6 +523,27 @@ namespace CarCareTracker.Controllers
}
return PartialView("_VehicleSelector", vehiclesStored);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpGet]
public IActionResult GetCustomWidgetEditor()
{
var customWidgetData = _fileHelper.GetWidgets();
return PartialView("_WidgetEditor", customWidgetData);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult SaveCustomWidgets(string widgetsData)
{
var saveResult = _fileHelper.SaveWidgets(widgetsData);
return Json(saveResult);
}
[Authorize(Roles = nameof(UserData.IsRootUser))]
[HttpPost]
public IActionResult DeleteCustomWidgets()
{
var deleteResult = _fileHelper.DeleteWidgets();
return Json(deleteResult);
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{

View File

@ -18,6 +18,8 @@ namespace CarCareTracker.Helper
int ClearUnlinkedDocuments(List<string> linkedDocuments);
string GetWidgets();
bool WidgetsExist();
bool SaveWidgets(string widgetsData);
bool DeleteWidgets();
}
public class FileHelper : IFileHelper
{
@ -392,5 +394,35 @@ namespace CarCareTracker.Helper
{
return File.Exists(StaticHelper.AdditionalWidgetsPath);
}
public bool SaveWidgets(string widgetsData)
{
try
{
//Delete Widgets if exists
DeleteWidgets();
File.WriteAllText(StaticHelper.AdditionalWidgetsPath, widgetsData);
return true;
} catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
public bool DeleteWidgets()
{
try
{
if (File.Exists(StaticHelper.AdditionalWidgetsPath))
{
File.Delete(StaticHelper.AdditionalWidgetsPath);
}
return true;
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return false;
}
}
}
}

View File

@ -335,6 +335,12 @@
</div>
</div>
</div>
<div class="modal fade" data-bs-focus="false" id="customWidgetModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="customWidgetModalContent">
</div>
</div>
</div>
<div class="modal fade" data-bs-focus="false" id="tabReorderModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content" id="tabReorderModalContent">

View File

@ -0,0 +1,28 @@
@using CarCareTracker.Helper
@inject IConfigHelper config
@inject ITranslationHelper translator
@model string
@{
var userConfig = config.GetUserConfig(User);
var userLanguage = userConfig.UserLanguage;
}
<div class="modal-header">
<h5 class="modal-title" id="widgetEditorModalLabel">@translator.Translate(userLanguage, "Custom Widgets Editor")</h5>
<button type="button" class="btn-close" onclick="hideCustomWidgets()" aria-label="Close"></button>
</div>
<div class="modal-body" onkeydown="handleEnter(this)">
<form class="form-inline">
<div class="form-group" style="height:50vh; overflow-x:hidden; overflow-y:auto;">
<div class="row">
<div class="col-12" style="height:48vh;">
<textarea id="widgetEditor" style="width:100%; height:100%;">@Model</textarea>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger me-auto" onclick="deleteCustomWidgets()">@translator.Translate(userLanguage, "Delete")</button>
<button type="button" class="btn btn-secondary" onclick="hideCustomWidgets()">@translator.Translate(userLanguage, "Cancel")</button>
<button type="button" class="btn btn-primary" onclick="saveCustomWidgets()">@translator.Translate(userLanguage, "Save")</button>
</div>

File diff suppressed because one or more lines are too long

View File

@ -351,4 +351,59 @@ function resetTabOrder() {
$(elem).css('order', -1);
})
updateSettings();
}
function hideCustomWidgets() {
$("#customWidgetModal").modal('hide');
}
function saveCustomWidgets() {
$.post('/Home/SaveCustomWidgets', { widgetsData: $("#widgetEditor").val() }, function (data) {
if (data) {
successToast("Custom Widgets Saved!");
updateSettings();
} else {
errorToast(genericErrorMessage());
}
})
}
function deleteCustomWidgets() {
$.post('/Home/DeleteCustomWidgets', function (data) {
if (data) {
successToast("Custom Widgets Deleted!");
updateSettings();
} else {
errorToast(genericErrorMessage());
}
})
}
function showCustomWidgets() {
Swal.fire({
title: 'Warning',
icon: "warning",
html: `
<span>
You are about to use the Custom Widgets Editor, this is a developer-focused feature that can lead to security vulnerabilities if you don't understand what you're doing.
<br />Zero support will be provided from the developer(s) of LubeLogger regarding Custom Widgets, Read the Documentation.
<br />By proceeding, you acknowledge that you are solely responsible for all consequences from utilizing the Custom Widgets Editor.
<br />To proceed, enter 'acknowledge' into the text field below.
</span>
<input type="text" id="inputAcknowledge" class="swal2-input" placeholder="acknowledge" onkeydown="handleSwalEnter(event)">
`,
confirmButtonText: 'Proceed',
focusConfirm: false,
preConfirm: () => {
const userAcknowledge = $("#inputAcknowledge").val();
if (!userAcknowledge || userAcknowledge != 'acknowledge') {
Swal.showValidationMessage(`Please acknowledge before proceeding.`)
}
return { userAcknowledge }
},
}).then(function (result) {
if (result.isConfirmed) {
$.get('/Home/GetCustomWidgetEditor', function (data) {
$("#customWidgetModalContent").html(data);
$("#customWidgetModal").modal('show');
});
}
});
}