mirror of
https://github.com/LD-Reborn/Berufsschule_HAM.git
synced 2025-12-20 06:51:55 +00:00
Added presets
This commit is contained in:
@@ -36,6 +36,14 @@ public class SettingsController : Controller
|
|||||||
return View(adminSettingsModel);
|
return View(adminSettingsModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize]
|
||||||
|
[HttpGet("Presets")]
|
||||||
|
public async Task<Dictionary<string, Preset>> PresetsAsync()
|
||||||
|
{
|
||||||
|
AdminSettingsModel adminSettingsModel = await _ldap.GetAdminSettingsModelAsync();
|
||||||
|
return adminSettingsModel.Presets;
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize(Roles = "CanManageSettings")]
|
[Authorize(Roles = "CanManageSettings")]
|
||||||
[HttpPut("Admin")]
|
[HttpPut("Admin")]
|
||||||
public async Task<AdminUpdateResponseModel> UpdateAdminAsync([FromBody]AdminUpdateRequestModel adminSettingsRequestModel)
|
public async Task<AdminUpdateResponseModel> UpdateAdminAsync([FromBody]AdminUpdateRequestModel adminSettingsRequestModel)
|
||||||
|
|||||||
@@ -43,7 +43,13 @@
|
|||||||
<data name="Error loading locations" xml:space="preserve">
|
<data name="Error loading locations" xml:space="preserve">
|
||||||
<value>Fehler beim Laden der Orte</value>
|
<value>Fehler beim Laden der Orte</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error loading presets" xml:space="preserve">
|
||||||
|
<value>Fehler beim Laden der Vorlagen</value>
|
||||||
|
</data>
|
||||||
<data name="Select user" xml:space="preserve">
|
<data name="Select user" xml:space="preserve">
|
||||||
<value>Benutzer auswählen</value>
|
<value>Benutzer auswählen</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Select preset" xml:space="preserve">
|
||||||
|
<value>Vorlage auswählen</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|||||||
@@ -192,6 +192,18 @@
|
|||||||
|
|
||||||
<hr class="my-3" />
|
<hr class="my-3" />
|
||||||
|
|
||||||
|
<h4 class="fw-bold">@T["Preset"]</h4>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<select class="form-select" name="Preset" aria-label="@T["Preset"]" id="createPresetSelect">
|
||||||
|
<option value="">@T["Select preset"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<button type="button" id="createPresetApply" class="btn btn-sm btn-warning">@T["Apply preset"]</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class="my-3" />
|
||||||
|
|
||||||
<!-- Description Section -->
|
<!-- Description Section -->
|
||||||
<h4 class="fw-bold">@T["Description"]</h4>
|
<h4 class="fw-bold">@T["Description"]</h4>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@@ -254,7 +266,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script defer>
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
// Open modal if URL contains parameter: CreateModal=true
|
// Open modal if URL contains parameter: CreateModal=true
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
@@ -803,11 +815,77 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
createModal.addEventListener('show.bs.modal', async () => {
|
createModal.addEventListener('show.bs.modal', async () => {
|
||||||
const selectLocations = createModal.querySelector('#createLocationSelect');
|
const selectLocations = createModal.querySelector('#createLocationSelect');
|
||||||
await loadLocationsIntoSelect(selectLocations);
|
await loadLocationsIntoSelect(selectLocations);
|
||||||
|
const selectPresets = createModal.querySelector('#createPresetSelect');
|
||||||
|
await loadPresetsIntoSelect(selectPresets);
|
||||||
const selectUsers = createModal.querySelector('#createUsersSelect');
|
const selectUsers = createModal.querySelector('#createUsersSelect');
|
||||||
await loadUsersIntoSelect(selectUsers);
|
await loadUsersIntoSelect(selectUsers);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const presetApplyButton = document.getElementById('createPresetApply');
|
||||||
|
presetApplyButton.addEventListener('click', async () => {
|
||||||
|
const response = await fetch('/Settings/Presets');
|
||||||
|
const responseJson = await response.json();
|
||||||
|
const presetSelect = document.getElementById('createPresetSelect');
|
||||||
|
const presetSelectValue = presetSelect.value;
|
||||||
|
if (responseJson[presetSelectValue]) {
|
||||||
|
const attributesContainer = document.getElementById('attributesContainer');
|
||||||
|
var attributes = responseJson[presetSelectValue].attribute;
|
||||||
|
for (var attributeKey in attributes) {
|
||||||
|
var attributeValue = attributes[attributeKey];
|
||||||
|
if (attributeKey == "Type" || attributeKey == "@T["Type"]") {
|
||||||
|
document.getElementById("createType").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Make" || attributeKey == "@T["Make"]") {
|
||||||
|
document.getElementById("createMake").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Model" || attributeKey == "@T["Model"]") {
|
||||||
|
document.getElementById("createModel").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Purchase Date" || attributeKey == "@T["Purchase Date"]") {
|
||||||
|
document.getElementById("createPurchaseDate").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Purchase Value" || attributeKey == "@T["Purchase Value"]") {
|
||||||
|
document.getElementById("createPurchaseValue").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Purchased At" || attributeKey == "@T["Purchased At"]") {
|
||||||
|
document.getElementById("createPurchaseAt").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Purchased By" || attributeKey == "@T["Purchased By"]") {
|
||||||
|
document.getElementById("createPurchaseBy").setAttribute("value", attributeValue);
|
||||||
|
} else if (attributeKey == "Location" || attributeKey == "@T["Location"]") {
|
||||||
|
document.getElementById("createLocationSelect-ts-control").value = attributeValue;
|
||||||
|
document.getElementById("createLocationSelect").value = attributeValue;
|
||||||
|
} else if (attributeKey == "User" || attributeKey == "@T["User"]") {
|
||||||
|
document.getElementById("createUsersSelect-ts-control").value = attributeValue;
|
||||||
|
document.getElementById("createUsersSelect").value = attributeValue;
|
||||||
|
} else if (attributeKey == "Name" || attributeKey == "@T["Name"]") {
|
||||||
|
document.getElementById("createName").value = attributeValue;
|
||||||
|
} else if (attributeKey == "Serial Number" || attributeKey == "@T["Serial Number"]") {
|
||||||
|
document.getElementById("createSerialNumber").value = attributeValue;
|
||||||
|
} else {
|
||||||
|
var nameInputs = attributesContainer.querySelectorAll("input[data-attr-name]");
|
||||||
|
var anyEquals = false;
|
||||||
|
var anyEqualsElement = null;
|
||||||
|
nameInputs.forEach(element => {
|
||||||
|
if (element.value == attributeKey) {
|
||||||
|
anyEquals = true;
|
||||||
|
anyEqualsElement = element.nextElementSibling;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (anyEquals) {
|
||||||
|
anyEqualsElement.value = attributeValue;
|
||||||
|
} else {
|
||||||
|
const row = document.createElement('div');
|
||||||
|
row.className = 'd-flex gap-2 align-items-center attribute-row';
|
||||||
|
row.innerHTML = `
|
||||||
|
<input type="text" class="form-control" placeholder="@T["Attribute name"]" data-attr-name value="${attributeKey}" />
|
||||||
|
<input type="text" class="form-control" placeholder="@T["Attribute value"]" data-attr-value value="${attributeValue}" />
|
||||||
|
<button type="button" class="btn btn-danger btn-sm btn-remove-attribute">@T["Remove"]</button>
|
||||||
|
`;
|
||||||
|
attributesContainer.appendChild(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<!-- TomSelect dropdowns -->
|
<!-- TomSelect dropdowns -->
|
||||||
<script>
|
<script>
|
||||||
@@ -859,6 +937,28 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
initUsersSelect(createUsersSelect);
|
initUsersSelect(createUsersSelect);
|
||||||
initUsersSelect(updateUsersSelect);
|
initUsersSelect(updateUsersSelect);
|
||||||
|
|
||||||
|
const createPresetsSelect = document.getElementById('createPresetsSelect');
|
||||||
|
|
||||||
|
async function initPresetsSelect(selectElement) {
|
||||||
|
if (!selectElement) return;
|
||||||
|
await loadPresetsIntoSelect(selectElement);
|
||||||
|
new TomSelect(selectElement, {
|
||||||
|
plugins: ['clear_button'],
|
||||||
|
create: false,
|
||||||
|
sortField: { field: 'text', direction: 'asc' },
|
||||||
|
placeholder: '@T["Select user"]',
|
||||||
|
maxOptions: 500, // avoid performance hit if there are many
|
||||||
|
render: {
|
||||||
|
no_results: function(data, escape) {
|
||||||
|
return `<div class="no-results">@T["No presets found"]</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initPresetsSelect(createPresetsSelect);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
<button type="submit" class="btn btn-warning float-end mt-3">@T["Apply settings and update presets"]</button>
|
<button type="submit" class="btn btn-warning float-end mt-3">@T["Apply settings and update presets"]</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script defer>
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
const updateForm = document.getElementById('updateSettings');
|
const updateForm = document.getElementById('updateSettings');
|
||||||
updateForm.addEventListener('submit', async e => {
|
updateForm.addEventListener('submit', async e => {
|
||||||
|
|||||||
@@ -25,7 +25,9 @@
|
|||||||
selectLocation: '@T["Select location"]',
|
selectLocation: '@T["Select location"]',
|
||||||
errorLoadingLocations: '@T["Error loading locations"]',
|
errorLoadingLocations: '@T["Error loading locations"]',
|
||||||
selectUser: '@T["Select user"]',
|
selectUser: '@T["Select user"]',
|
||||||
errorLoadingUsers: '@T["Error loading users"]'
|
selectPreset: '@T["Select preset"]',
|
||||||
|
errorLoadingUsers: '@T["Error loading users"]',
|
||||||
|
errorLoadingPresets: '@T["Error loading presets"]'
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -270,3 +270,35 @@ function unflatten(obj) {
|
|||||||
function sleep(ms) {
|
function sleep(ms) {
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
return new Promise(resolve => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadPresetsIntoSelect(selectElement, selectedValue = null) {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/Settings/Presets');
|
||||||
|
const responseJson = await response.json();
|
||||||
|
var presets = [];
|
||||||
|
for (var key in responseJson) {
|
||||||
|
presets.push(key);
|
||||||
|
}
|
||||||
|
console.log(presets);
|
||||||
|
const ts = selectElement.tomselect;
|
||||||
|
if (!ts) {
|
||||||
|
selectElement.innerHTML = `<option value="">${appTranslations.selectPreset}</option>`;
|
||||||
|
presets.forEach(u => {
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.value = u;
|
||||||
|
opt.textContent = u;
|
||||||
|
selectElement.appendChild(opt);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ts.clearOptions();
|
||||||
|
ts.addOption(presets.map(u => ({ value: u, text: u })));
|
||||||
|
ts.refreshOptions(false);
|
||||||
|
|
||||||
|
if (selectedValue) ts.setValue(selectedValue);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error loading presets:', err);
|
||||||
|
showToast(appTranslations.errorLoadingPresets, 'danger');
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user