mirror of
https://github.com/LD-Reborn/Berufsschule_HAM.git
synced 2025-12-20 06:51:55 +00:00
Moved unflatten to site.js, implemented Admin.cshtml view
This commit is contained in:
@@ -1 +1,289 @@
|
||||
<h3>Empty view lol</h3>
|
||||
@using Berufsschule_HAM.Services
|
||||
@using Microsoft.AspNetCore.Html
|
||||
@using Microsoft.AspNetCore.Mvc.Localization
|
||||
@using Berufsschule_HAM.Models
|
||||
@using System.Buffers.Text
|
||||
@using System.Text.Json;
|
||||
@using System.Text.Json.Serialization;
|
||||
@model AdminSettingsModel
|
||||
@inject IViewLocalizer T
|
||||
@inject LdapService ldap
|
||||
@{
|
||||
ViewData["Title"] = T["Users"];
|
||||
}
|
||||
|
||||
<form id="updateSettings">
|
||||
<div class="row g-3">
|
||||
<h4 class="fw-bold">@T["General settings"]</h4>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="updateHashAlgorithm">@T["Default hash algorithm"]</label>
|
||||
<select type="text" name="DefaultHashAlgorithm" id="updateHashAlgorithm" class="form-control">
|
||||
@foreach (string algorithm in ldap.HashAlgorithms.Keys)
|
||||
{
|
||||
bool selected = algorithm == Model.DefaultHashAlgorithm;
|
||||
<option value="@algorithm" selected="@selected">@algorithm</option>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="updateBarcodeType">@T["Barcode type"]</label>
|
||||
<select type="text" name="BarcodeType" id="updateBarcodeType" class="form-control" />
|
||||
<option selected="@(Model.BarcodeType == "code128c")" value="code128c">CODE128C</option>
|
||||
<option selected="@(Model.BarcodeType == "ean13")" value="ean13">EAN13</option>
|
||||
<option selected="@(Model.BarcodeType == "ean8")" value="ean8">EAN8</option>
|
||||
<option selected="@(Model.BarcodeType == "upc")" value="upc">UPC</option>
|
||||
<option selected="@(Model.BarcodeType == "itf14")" value="itf14">ITF14</option>
|
||||
<option selected="@(Model.BarcodeType == "itf")" value="itf">ITF</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="updateBarcodeText">@T["Barcode text"]</label>
|
||||
<input type="text" name="BarcodeText" id="updateBarcodeText" class="form-control" value="@Model.BarcodeText" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="updateMaxDownloadableUserImageSize">@T["Max downloadable user image size"]</label>
|
||||
<input type="number" id="updateMaxDownloadableUserImageSize" name="MaxDownloadableUserImageSize" class="form-control" value="@Model.MaxDownloadableUserImageSize" />
|
||||
</div>
|
||||
<div class="col-md-6 mt-3">
|
||||
<h4 class="fw-bold">@T["Presets"]</h4>
|
||||
|
||||
@foreach (var preset in Model.Presets)
|
||||
{
|
||||
<div class="border rounded p-3 mb-3" data-preset-id="@(preset.Key)">
|
||||
<label class="form-label" for="Presets.@(preset.Key).Key">@T["Preset name"]</label>
|
||||
<input class="form-control mb-3" id="Presets.@(preset.Key).Key" name="Presets.@(preset.Key).Key" value="@preset.Key"/>
|
||||
<label class="form-label">@T["Attributes"]</label>
|
||||
@foreach (var attr in preset.Value.Attribute)
|
||||
{
|
||||
<div class="row mb-2" data-type="attribute">
|
||||
<div class="col-md-3">
|
||||
<input class="form-control"
|
||||
name="Presets.@(preset.Key).Attribute.@(attr.Key).Key"
|
||||
value="@attr.Key" placeholder="@T["Name"]" aria-label="@T["Name"]" />
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input class="form-control"
|
||||
name="Presets.@(preset.Key).Attribute.@(attr.Key).Value"
|
||||
value="@attr.Value" placeholder="@T["Value"]" aria-label="@T["Value"]" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-danger" data-type="deleteAttribute">@T["Delete attribute"]</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-danger" data-type="deletePreset">@T["Delete preset"]</button>
|
||||
</div>
|
||||
<div class="col-md-4 ms-auto">
|
||||
<button type="button" class="btn btn-primary" data-type="addAttribute">@T["Add attribute"]</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-primary" data-type="addPreset">@T["Add preset"]</button>
|
||||
</div>
|
||||
</div>
|
||||
<form id="updateSettings" method="post" asp-controller="Settings" asp-action="Admin">
|
||||
<button type="submit" class="btn btn-warning">@T["Update"]</button>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const updateForm = document.getElementById('updateSettings');
|
||||
updateForm.addEventListener('submit', async e => {
|
||||
e.preventDefault();
|
||||
const url = `/Settings/Admin`;
|
||||
const dataFromEntries = Object.fromEntries(new FormData(updateForm).entries());
|
||||
var data = unflatten(dataFromEntries);
|
||||
var presets = {};
|
||||
for (var preset in data.Presets) {
|
||||
for (var attribute in data.Presets[preset].Attribute) {
|
||||
var key = data.Presets[preset].Attribute[attribute].Key;
|
||||
var value = data.Presets[preset].Attribute[attribute].Value;
|
||||
delete(data.Presets[preset].Attribute[attribute]);
|
||||
data.Presets[preset].Attribute[key] = value;
|
||||
}
|
||||
var presetKey = data.Presets[preset].Key;
|
||||
delete(data.Presets[preset].Key);
|
||||
var tempPreset = data.Presets[preset];
|
||||
delete(data.Presets[preset]);
|
||||
data.Presets[presetKey] = tempPreset;
|
||||
}
|
||||
var temp = data;
|
||||
data = {};
|
||||
data.AdminSettingsModel = temp;
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.Success) {
|
||||
showToast('@T["Settings updated successfully"]', 'success');
|
||||
} else {
|
||||
showToast(`${result.reason}: ${result.exception || '@T["Unknown error"]'}`, 'danger');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
showToast('@T["Error contacting server"]', 'danger');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function addAttribute(presetContainer, presetKey) {
|
||||
const attributeId = crypto.randomUUID();
|
||||
|
||||
const row = document.createElement('div');
|
||||
row.classList.add('row', 'mb-2');
|
||||
|
||||
row.innerHTML = `
|
||||
<div class="col-md-3">
|
||||
<input class="form-control"
|
||||
name="Presets.${presetKey}.Attribute.${attributeId}.Key"
|
||||
value="" />
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input class="form-control"
|
||||
name="Presets.${presetKey}.Attribute.${attributeId}.Value"
|
||||
value="" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-danger btn-delete-attr">
|
||||
${presetContainer.dataset.deleteAttributeText}
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
presetContainer.querySelector('.attributes').appendChild(row);
|
||||
}
|
||||
|
||||
document.querySelectorAll('button[data-type="addAttribute"]').forEach(btn => {
|
||||
addAddAttributeEventListener(btn);
|
||||
});
|
||||
|
||||
document.querySelectorAll('button[data-type="deleteAttribute"]').forEach(btn => {
|
||||
addRemoveAttributeEventListener(btn);
|
||||
});
|
||||
|
||||
document.querySelectorAll('button[data-type="deletePreset"]').forEach(btn => {
|
||||
addDeletePresetEventListener(btn);
|
||||
});
|
||||
|
||||
document.querySelectorAll('button[data-type="addPreset"]').forEach(btn => {
|
||||
addAddPresetEventListener(btn);
|
||||
});
|
||||
|
||||
function addAddAttributeEventListener(button) {
|
||||
button.addEventListener('click', e => {
|
||||
const presetContainer = e.target.closest('.border.rounded.p-3.mb-3');
|
||||
if (!presetContainer) return;
|
||||
|
||||
const presetKey = presetContainer.getAttribute("data-preset-id"); //presetContainer.querySelector('input')?.value;
|
||||
if (!presetKey) return;
|
||||
|
||||
// Container für Attribute suchen
|
||||
let attributesContainer = presetContainer.querySelector('.attributes');
|
||||
if (!attributesContainer) {
|
||||
// Falls nicht vorhanden -> dynamisch anlegen (optional)
|
||||
attributesContainer = document.createElement('div');
|
||||
attributesContainer.classList.add('attributes');
|
||||
presetContainer.insertBefore(attributesContainer, presetContainer.querySelector('.row.mb-4'));
|
||||
}
|
||||
|
||||
const attributeId = crypto.randomUUID();
|
||||
|
||||
const row = document.createElement('div');
|
||||
row.classList.add('row', 'mb-2');
|
||||
row.setAttribute('data-type', 'attribute');
|
||||
|
||||
row.innerHTML = `
|
||||
<div class="col-md-3">
|
||||
<input class="form-control"
|
||||
name="Presets.${presetKey}.Attribute.${attributeId}.Key"
|
||||
value="" />
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input class="form-control"
|
||||
name="Presets.${presetKey}.Attribute.${attributeId}.Value"
|
||||
value="" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-danger" data-type="deleteAttribute">
|
||||
${presetContainer.dataset.deleteAttributeText || 'Delete attribute'}
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
attributesContainer.appendChild(row);
|
||||
|
||||
// Delete-Button Eventlistener aktivieren
|
||||
const deleteButton = row.querySelector('button[data-type="deleteAttribute"]');
|
||||
addRemoveAttributeEventListener(deleteButton);
|
||||
});
|
||||
}
|
||||
|
||||
function addRemoveAttributeEventListener(button) {
|
||||
button.addEventListener('click', e => {
|
||||
const row = e.target.closest('div[data-type="attribute"]');
|
||||
row.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function addDeletePresetEventListener(button) {
|
||||
button.addEventListener('click', e => {
|
||||
const presetContainer = e.target.closest('.border.rounded.p-3.mb-3');
|
||||
if (!presetContainer) return;
|
||||
presetContainer.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function addAddPresetEventListener(button) {
|
||||
button.addEventListener('click', e => {
|
||||
// Presets-Container: der nächste Block über dem Button, der die Presets enthält
|
||||
const presetsButton = button.closest('button[data-type="addPreset"]');
|
||||
if (!presetsButton) return;
|
||||
|
||||
const presetId = crypto.randomUUID();
|
||||
|
||||
// Preset-Block erstellen
|
||||
const presetDiv = document.createElement('div');
|
||||
presetDiv.classList.add('border', 'rounded', 'p-3', 'mb-3');
|
||||
presetDiv.setAttribute('data-preset-id', presetId);
|
||||
presetDiv.innerHTML = `
|
||||
<label class="form-label" for="Presets.${presetId}.Key">@T["Preset name"]</label>
|
||||
<input class="form-control mb-3" id="Presets.${presetId}.Key" name="Presets.${presetId}.Key" value=""/>
|
||||
<label class="form-label">@T["Attributes"]</label>
|
||||
<div class="attributes"></div>
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-4">
|
||||
<button type="button" class="btn btn-danger" data-type="deletePreset">Delete preset</button>
|
||||
</div>
|
||||
<div class="col-md-4 ms-auto">
|
||||
<button type="button" class="btn btn-primary" data-type="addAttribute">Add attribute</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Einfach ans Ende der Container-Liste hängen
|
||||
presetsButton.parentElement.parentElement.insertBefore(presetDiv, presetsButton.parentElement);
|
||||
|
||||
// Eventlistener für den neuen Preset-Block aktivieren
|
||||
const addAttrBtn = presetDiv.querySelector('button[data-type="addAttribute"]');
|
||||
const deletePresetBtn = presetDiv.querySelector('button[data-type="deletePreset"]');
|
||||
|
||||
addAddAttributeEventListener(addAttrBtn);
|
||||
addDeletePresetEventListener(deletePresetBtn);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user