diff --git a/inventory/templates/settings.html b/inventory/templates/settings.html index ef360d9..1128b50 100644 --- a/inventory/templates/settings.html +++ b/inventory/templates/settings.html @@ -2,12 +2,118 @@ {% block title %}{{ title }}{% endblock %} +{% block precontent %} + {% set saveLogic %} + function isSerializable(obj) { + try { + JSON.stringify(obj); + return true; + } catch { + return false; + } + } + + function buildFormState() { + function extractOptions(id) { + const select = document.getElementById(`${id}-list`); + return Array.from(select.options).map(opt => { + const name = opt.textContent.trim(); + const rawId = opt.value?.trim(); + return { + name, + ...(rawId ? { id: /^\d+$/.test(rawId) ? parseInt(rawId, 10) : rawId } : {}) + }; + }); + } + + function sanitizeFk(val) { + if (val && val !== "null" && val !== "" && val !== "None") { + return /^\d+$/.test(val) ? parseInt(val, 10) : val; + } + return null; + } + + const roomOptions = Array.from(document.getElementById('room-list').options); + + const rooms = roomOptions.map(opt => { + const id = opt.value?.trim(); + const name = opt.textContent.trim(); + const sectionId = sanitizeFk(opt.dataset.sectionId); + const functionId = sanitizeFk(opt.dataset.functionId); + + const result = { + name, + ...(id ? { id } : {}), + section_id: sectionId, + function_id: functionId + }; + + return result; + }); + + return { + brands: extractOptions("brand"), + types: extractOptions("type"), + sections: extractOptions("section"), + functions: extractOptions("function"), + rooms + }; + } + + event.preventDefault(); + + const state = buildFormState(); + + if (!isSerializable(state)) { + console.warn("🚨 Payload is not serializable:", state); + alert("Invalid payload — check console."); + return; + } + + try { + const response = await fetch('/api/settings', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(state) + }); + + const contentType = response.headers.get("content-type"); + + if (!response.ok) { + if (contentType && contentType.includes("application/json")) { + const data = await response.json(); + throw new Error(data.errors?.join("\n") || "Unknown error"); + } else { + const text = await response.text(); + throw new Error("Unexpected response:\n" + text.slice(0, 200)); + } + } + + const data = await response.json(); + console.log("Sync result:", data); + renderToast({ message: 'Settings updated successfully.', type: 'success' }); + + } catch (err) { + console.error("Submission error:", err); + renderToast({ message: `Failed to update settings, ${err}`, type: 'danger' }); + } + {% endset %} + {{ toolbars.render_toolbar( + id='settings', + left=breadcrumbs.breadcrumb_header( + title=title + ), + right=buttons.render_button( + id='save', + icon='floppy', + logic=saveLogic + ) + ) }} +{% endblock %} + {% block content %}
- {{ breadcrumbs.breadcrumb_header( - title=title, - save_button=True - ) }} +
@@ -140,69 +246,11 @@ {% endblock %} {% block script %} - function isSerializable(obj) { - try { - JSON.stringify(obj); - return true; - } catch { - return false; - } - } - - function buildFormState() { - function extractOptions(id) { - const select = document.getElementById(`${id}-list`); - return Array.from(select.options).map(opt => { - const name = opt.textContent.trim(); - const rawId = opt.value?.trim(); - return { - name, - ...(rawId ? { id: /^\d+$/.test(rawId) ? parseInt(rawId, 10) : rawId } : {}) - }; - }); - } - - function sanitizeFk(val) { - if (val && val !== "null" && val !== "" && val !== "None") { - return /^\d+$/.test(val) ? parseInt(val, 10) : val; - } - return null; - } - - const roomOptions = Array.from(document.getElementById('room-list').options); - - const rooms = roomOptions.map(opt => { - const id = opt.value?.trim(); - const name = opt.textContent.trim(); - const sectionId = sanitizeFk(opt.dataset.sectionId); - const functionId = sanitizeFk(opt.dataset.functionId); - - const result = { - name, - ...(id ? { id } : {}), - section_id: sectionId, - function_id: functionId - }; - - return result; - }); - - return { - brands: extractOptions("brand"), - types: extractOptions("type"), - sections: extractOptions("section"), - functions: extractOptions("function"), - rooms - }; - } - const modal = document.getElementById('roomEditor'); - const saveButton = document.getElementById('saveButton') const editorSaveButton = document.getElementById('editorSaveButton'); const cancelButton = document.getElementById('roomEditorCancelButton'); const form = document.getElementById('settingsForm'); - modal.addEventListener('roomEditor:prepare', (event) => { const { id, name, sectionId, functionId } = event.detail; document.getElementById('roomId').value = id; @@ -234,46 +282,6 @@ }); }); - saveButton.addEventListener('click', async (event) => { - event.preventDefault(); - console.log("Test") - const state = buildFormState(); - - if (!isSerializable(state)) { - console.warn("🚨 Payload is not serializable:", state); - alert("Invalid payload — check console."); - return; - } - - try { - const response = await fetch('/api/settings', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(state) - }); - - const contentType = response.headers.get("content-type"); - - if (!response.ok) { - if (contentType && contentType.includes("application/json")) { - const data = await response.json(); - throw new Error(data.errors?.join("\n") || "Unknown error"); - } else { - const text = await response.text(); - throw new Error("Unexpected response:\n" + text.slice(0, 200)); - } - } - - const data = await response.json(); - console.log("Sync result:", data); - renderToast({ message: 'Settings updated successfully.', type: 'success' }); - - } catch (err) { - console.error("Submission error:", err); - renderToast({ message: `Failed to update settings, ${err}`, type: 'danger' }); - } - }); - editorSaveButton.addEventListener('click', () => { const name = document.getElementById('roomName').value.trim(); const sectionVal = document.getElementById('roomSection').value;