WebUI: Trading beenden, ohne die Anwendung zu beenden
Umsetzung von #563. Entscheidung Richard, 13.09.2026: Beenden soll ueber das WebUI gehen, aber beschraenkt auf das Trading. Ein Ende der ganzen Anwendung naehme den Webserver mit; danach waere das WebUI nicht mehr erreichbar. POST /api/dashboard/stop-trading setzt Live- und Demo-Modus auf Inaktiv und schaltet die Pause ein. Damit halten CopyTrading und ResolutionFarming (#569) an, wie beim Ende der Anwendung. Offene Orders an der Boerse werden bewusst nicht storniert: Das tut auch das Beenden der App nicht, und ein Eingriff in die CLOB-Integration gehoert nicht in einen Notschalter. Der Dialog sagt das ausdruecklich. Die Route verlangt {"confirmed": true}. Ein Aufruf ohne Absicht, etwa aus einem alten Skript, beendet nichts. Der Vorgang wird als Warnung protokolliert, mit den Modi vorher. Im Dashboard steht unter der Notfall-Pause jetzt "Trading beenden ...". Der Dialog ist wie im Desktop 10 Sekunden gesperrt, Abbrechen und Esc gehen jederzeit. Wieder aufgenommen wird nur ueber die Modus-Schalter. Die Pause aufzuheben genuegt nicht, das haelt ein Test fest. Offen bis #570: Laufende Verkaufsleitern und der REST-Pre-Redeem pruefen die Pause nicht. Der Inaktiv-Modus, den dieser Knopf setzt, sperrt den Pre-Redeem bereits; die Leitern friert erst #570 ein. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,9 @@ let allLogs = [];
|
||||
|
||||
// Init on DOM ready
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape' && document.getElementById('modalStopTrading')?.style.display === 'flex') closeStopTradingModal();
|
||||
});
|
||||
initNavMenus();
|
||||
refreshNavModules();
|
||||
initSseLogs();
|
||||
@@ -269,6 +272,64 @@ async function togglePause() {
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// ==================== Trading beenden (#563) ====================
|
||||
|
||||
const STOP_TRADING_LOCK_SECONDS = 10;
|
||||
let stopTradingTimer = null;
|
||||
|
||||
function openStopTradingModal() {
|
||||
const modal = document.getElementById('modalStopTrading');
|
||||
const btn = document.getElementById('btnConfirmStopTrading');
|
||||
const err = document.getElementById('stopTradingError');
|
||||
if (!modal || !btn) return;
|
||||
|
||||
err.hidden = true;
|
||||
let remaining = STOP_TRADING_LOCK_SECONDS;
|
||||
btn.disabled = true;
|
||||
btn.textContent = `Trading beenden (${remaining} s)`;
|
||||
modal.style.display = 'flex';
|
||||
|
||||
clearInterval(stopTradingTimer);
|
||||
stopTradingTimer = setInterval(() => {
|
||||
remaining--;
|
||||
if (remaining > 0) {
|
||||
btn.textContent = `Trading beenden (${remaining} s)`;
|
||||
return;
|
||||
}
|
||||
clearInterval(stopTradingTimer);
|
||||
stopTradingTimer = null;
|
||||
btn.textContent = 'Trading beenden';
|
||||
btn.disabled = false;
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function closeStopTradingModal() {
|
||||
clearInterval(stopTradingTimer);
|
||||
stopTradingTimer = null;
|
||||
const modal = document.getElementById('modalStopTrading');
|
||||
if (modal) modal.style.display = 'none';
|
||||
}
|
||||
|
||||
async function confirmStopTrading() {
|
||||
const btn = document.getElementById('btnConfirmStopTrading');
|
||||
const err = document.getElementById('stopTradingError');
|
||||
btn.disabled = true;
|
||||
try {
|
||||
const res = await fetch('/api/dashboard/stop-trading', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ confirmed: true })
|
||||
});
|
||||
if (!res.ok) throw new Error(await errorText(res));
|
||||
closeStopTradingModal();
|
||||
refreshDashboard();
|
||||
} catch (e) {
|
||||
err.textContent = `Trading konnte nicht beendet werden: ${e.message}`;
|
||||
err.hidden = false;
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Dashboard Account-Übersicht
|
||||
async function loadDashboardAccounts() {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user