Enhance toast notifications and improve settings form submission; implement async handling and error reporting for better user feedback
This commit is contained in:
parent
5a3176cad1
commit
398800b681
3 changed files with 71 additions and 21 deletions
|
@ -1,3 +1,47 @@
|
|||
function renderToast({ message, type = 'info', timeout = 3000 }) {
|
||||
if (!message) {
|
||||
console.warn('renderToast was called without a message.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto-create the toast container if it doesn't exist
|
||||
let container = document.getElementById('toast-container');
|
||||
if (!container) {
|
||||
container = document.createElement('div');
|
||||
container.id = 'toast-container';
|
||||
container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
|
||||
const toastId = `toast-${Date.now()}`;
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = `
|
||||
<div id="${toastId}" class="toast align-items-center text-bg-${type}" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="d-flex">
|
||||
<div class="toast-body">
|
||||
${message}
|
||||
</div>
|
||||
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const toastElement = wrapper.firstElementChild;
|
||||
container.appendChild(toastElement);
|
||||
|
||||
const toast = new bootstrap.Toast(toastElement, { delay: timeout });
|
||||
toast.show();
|
||||
|
||||
toastElement.addEventListener('hidden.bs.toast', () => {
|
||||
toastElement.remove();
|
||||
|
||||
// Clean up container if empty
|
||||
if (container.children.length === 0) {
|
||||
container.remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const ComboBoxWidget = (() => {
|
||||
let tempIdCounter = 1;
|
||||
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Toast Container -->
|
||||
<div id="toast-container" class="toast-container position-fixed bottom-0 end-0 p-3"></div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.6/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-j1CDi7MgGQ12Z7Qab0qlWQ/Qqz24Gc6BM0thvEMVjHnfYGF0rmFCozFSxQBxwHKO"
|
||||
crossorigin="anonymous"></script>
|
||||
|
|
|
@ -221,33 +221,36 @@
|
|||
});
|
||||
});
|
||||
|
||||
form.addEventListener('submit', (event) => {
|
||||
form.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
try {
|
||||
const state = buildFormState();
|
||||
fetch('/api/settings', {
|
||||
|
||||
const response = await fetch('/api/settings', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(state)
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
return response.json().then(data => {
|
||||
throw new Error(data.errors?.join("\n") || "Unknown error");
|
||||
});
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log("Sync result:", data);
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Submission error:", err);
|
||||
});
|
||||
|
||||
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("Failed to build form state:", err);
|
||||
console.error("Submission error:", err);
|
||||
renderToast({ message: `Failed to update settings, ${err}`, type: 'danger' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue