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 %}