Update settings to use new fragments.
This commit is contained in:
parent
86b95a521b
commit
55ee74bcb6
1 changed files with 110 additions and 102 deletions
|
|
@ -2,12 +2,118 @@
|
||||||
|
|
||||||
{% block title %}{{ title }}{% endblock %}
|
{% 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 %}
|
{% block content %}
|
||||||
<form id="settingsForm">
|
<form id="settingsForm">
|
||||||
{{ breadcrumbs.breadcrumb_header(
|
|
||||||
title=title,
|
|
||||||
save_button=True
|
|
||||||
) }}
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="card mb-3">
|
<div class="card mb-3">
|
||||||
|
|
@ -140,69 +246,11 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% 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 modal = document.getElementById('roomEditor');
|
||||||
const saveButton = document.getElementById('saveButton')
|
|
||||||
const editorSaveButton = document.getElementById('editorSaveButton');
|
const editorSaveButton = document.getElementById('editorSaveButton');
|
||||||
const cancelButton = document.getElementById('roomEditorCancelButton');
|
const cancelButton = document.getElementById('roomEditorCancelButton');
|
||||||
const form = document.getElementById('settingsForm');
|
const form = document.getElementById('settingsForm');
|
||||||
|
|
||||||
|
|
||||||
modal.addEventListener('roomEditor:prepare', (event) => {
|
modal.addEventListener('roomEditor:prepare', (event) => {
|
||||||
const { id, name, sectionId, functionId } = event.detail;
|
const { id, name, sectionId, functionId } = event.detail;
|
||||||
document.getElementById('roomId').value = id;
|
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', () => {
|
editorSaveButton.addEventListener('click', () => {
|
||||||
const name = document.getElementById('roomName').value.trim();
|
const name = document.getElementById('roomName').value.trim();
|
||||||
const sectionVal = document.getElementById('roomSection').value;
|
const sectionVal = document.getElementById('roomSection').value;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue