Update settings to use new fragments.

This commit is contained in:
Yaro Kasear 2025-07-15 11:38:00 -05:00
parent 86b95a521b
commit 55ee74bcb6

View file

@ -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 %}
<form id="settingsForm">
{{ breadcrumbs.breadcrumb_header(
title=title,
save_button=True
) }}
<div class="container">
<div class="card mb-3">
@ -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;