Phase 3a Frontend-Hygiene: Toast statt alert/confirm
- src/static/css/style.css: Toast-Styles (.toast-container, .toast,
Varianten info/success/warning/error, Animations)
- src/static/dashboard.html: <div id=toastContainer> vor </body>,
Cancel-Button im Confirm-Modal bekommt id=confirmCancelBtn
- src/static/js/app.js:
- showToast(msg, type) neu - links oben, autoclose 3.5s (error: 6s)
- showConfirm(title, text, callback?) jetzt Promise<boolean>-fähig
(Backwards-compat: Legacy-Callback wird bei OK weiter aufgerufen)
- Cancel/Close-Hooks am modalConfirm setzen Promise auf false
- alle 18 alert() in app.js / source-health.js / sources.js durch
showToast(msg, type) ersetzt (type je nach Kontext error/success/warning/info)
- 2 confirm() in source-health.js durch await showConfirm() ersetzt
Dieser Commit ist enthalten in:
@@ -268,7 +268,7 @@ async function changeRole(userId, role) {
|
||||
try {
|
||||
await API.put(`/api/users/${userId}/role?role=${role}`);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
}
|
||||
}
|
||||
@@ -278,7 +278,7 @@ async function toggleUser(userId, activate) {
|
||||
await API.put(`/api/users/${userId}/${activate ? "activate" : "deactivate"}`);
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +287,7 @@ async function toggleGlobeAccess(userId) {
|
||||
await API.put("/api/users/" + userId + "/globe-access");
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ async function toggleNetworkAccess(userId) {
|
||||
await API.put("/api/users/" + userId + "/network-access");
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
}
|
||||
}
|
||||
@@ -311,7 +311,7 @@ function confirmDeleteUser(userId, email) {
|
||||
await API.del(`/api/users/${userId}`);
|
||||
if (currentOrgId) loadOrgUsers(currentOrgId);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -353,7 +353,7 @@ async function extendLicense(licId) {
|
||||
await API.put(`/api/licenses/${licId}/extend?days=${parseInt(days)}`);
|
||||
if (currentOrgId) loadOrgLicenses(currentOrgId);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ function confirmRevokeLicense(licId) {
|
||||
await API.put(`/api/licenses/${licId}/revoke`);
|
||||
if (currentOrgId) loadOrgLicenses(currentOrgId);
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -523,7 +523,7 @@ function setupForms() {
|
||||
loadOrgs();
|
||||
loadDashboard();
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -541,7 +541,7 @@ function setupForms() {
|
||||
loadOrgs();
|
||||
loadDashboard();
|
||||
} catch (err) {
|
||||
alert(err.message);
|
||||
showToast(err.message, "error");
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -560,19 +560,56 @@ function closeModal(id) {
|
||||
// Confirm dialog
|
||||
let confirmCallback = null;
|
||||
|
||||
let confirmResolver = null;
|
||||
|
||||
function showConfirm(title, text, callback) {
|
||||
document.getElementById("confirmTitle").textContent = title;
|
||||
document.getElementById("confirmText").textContent = text;
|
||||
confirmCallback = callback;
|
||||
// Backward-compat: legacy Callback wird bei OK aufgerufen
|
||||
confirmCallback = callback || null;
|
||||
openModal("modalConfirm");
|
||||
return new Promise((resolve) => {
|
||||
if (confirmResolver) confirmResolver(false); // alten Resolver schliessen
|
||||
confirmResolver = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
function showToast(msg, type) {
|
||||
type = type || "info";
|
||||
const c = document.getElementById("toastContainer");
|
||||
if (!c) { console.log("[toast]", type, msg); return; }
|
||||
const el = document.createElement("div");
|
||||
el.className = "toast toast-" + type;
|
||||
el.textContent = msg;
|
||||
c.appendChild(el);
|
||||
setTimeout(() => {
|
||||
el.classList.add("toast-out");
|
||||
setTimeout(() => el.remove(), 220);
|
||||
}, type === "error" ? 6000 : 3500);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.getElementById("confirmOkBtn").addEventListener("click", async () => {
|
||||
closeModal("modalConfirm");
|
||||
if (confirmCallback) await confirmCallback();
|
||||
const cb = confirmCallback;
|
||||
const rs = confirmResolver;
|
||||
confirmCallback = null;
|
||||
confirmResolver = null;
|
||||
if (cb) {
|
||||
try { await cb(); } catch (e) { showToast(e.message || String(e), "error"); }
|
||||
}
|
||||
if (rs) rs(true);
|
||||
});
|
||||
|
||||
// Cancel/Close -> resolver(false)
|
||||
function _confirmCancel() {
|
||||
const rs = confirmResolver;
|
||||
confirmCallback = null;
|
||||
confirmResolver = null;
|
||||
if (rs) rs(false);
|
||||
}
|
||||
document.getElementById("confirmCancelBtn")?.addEventListener("click", _confirmCancel);
|
||||
document.querySelector("#modalConfirm .modal-close")?.addEventListener("click", _confirmCancel);
|
||||
});
|
||||
|
||||
// --- Utilities ---
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren