repair
This commit is contained in:
@@ -259,8 +259,8 @@
|
||||
const requestOptions = options && typeof options === 'object' ? { ...options } : {};
|
||||
const debugEnabled = !!debugBus.enabled;
|
||||
const timeoutMs = typeof requestOptions.timeoutMs === 'number'
|
||||
? (debugEnabled ? Math.max(requestOptions.timeoutMs, 20000) : requestOptions.timeoutMs)
|
||||
: (debugEnabled ? 20000 : 8000);
|
||||
? (debugEnabled ? Math.max(requestOptions.timeoutMs, 30000) : requestOptions.timeoutMs)
|
||||
: (debugEnabled ? 30000 : 20000);
|
||||
delete requestOptions.timeoutMs;
|
||||
|
||||
const controller = new AbortController();
|
||||
@@ -1203,7 +1203,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function loadBootstrap(key) {
|
||||
async function loadBootstrap(key, options) {
|
||||
const suppressError = !!(options && options.suppressError);
|
||||
const cacheKey = `${key}:${activeTab || 'overview'}`;
|
||||
const cachedPayload = bootstrapCacheRef.current.get(cacheKey) || null;
|
||||
|
||||
@@ -1219,18 +1220,20 @@
|
||||
loadGuardTriggered = true;
|
||||
setLoading(false);
|
||||
setPayload((previous) => previous || cachedPayload || normalizeBootstrap(null, key));
|
||||
setError((previous) => previous || 'Bootstrap-Request haengt oder braucht zu lange.');
|
||||
}, 12000);
|
||||
if (!suppressError) {
|
||||
setError((previous) => previous || 'Bootstrap-Request haengt oder braucht zu lange.');
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
try {
|
||||
if (schemaStatus.missing_count > 0 || schemaStatus.pending_upgrade_count > 0) {
|
||||
setPayload(normalizeBootstrap(null, key));
|
||||
setError('Mining-Checker Schema ist noch nicht initialisiert. Bitte im Tab Settings die Datenbank initialisieren.');
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({ view: activeTab || 'overview' });
|
||||
const data = await request(`${apiBase}/projects/${encodeURIComponent(key)}/bootstrap?${params.toString()}`, { timeoutMs: 10000 });
|
||||
const data = await request(`${apiBase}/projects/${encodeURIComponent(key)}/bootstrap?${params.toString()}`, { timeoutMs: 25000 });
|
||||
const normalized = normalizeBootstrap(data, key);
|
||||
bootstrapCacheRef.current.set(cacheKey, normalized);
|
||||
setPayload(normalized);
|
||||
@@ -1251,9 +1254,13 @@
|
||||
...previous,
|
||||
currency: normalized.settings.currencies?.[0]?.code || previous.currency || 'EUR',
|
||||
}));
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
if (!suppressError) {
|
||||
setError(err.message);
|
||||
}
|
||||
setPayload(normalizeBootstrap(null, key));
|
||||
return false;
|
||||
} finally {
|
||||
window.clearTimeout(loadGuard);
|
||||
if (!loadGuardTriggered) {
|
||||
@@ -1262,6 +1269,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function reloadBootstrapAfterMutation(successMessage) {
|
||||
const refreshed = await loadBootstrap(projectKey, { suppressError: true });
|
||||
if (!refreshed) {
|
||||
setError('Speichern war erfolgreich, aber die Ansicht konnte nicht automatisch aktualisiert werden.');
|
||||
if (successMessage) {
|
||||
setMessage(successMessage);
|
||||
}
|
||||
}
|
||||
return refreshed;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadBootstrap(projectKey);
|
||||
}, [projectKey, activeTab]);
|
||||
@@ -1415,7 +1433,7 @@
|
||||
source: 'manual',
|
||||
});
|
||||
setOcrPreview(null);
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation(fromPreview ? 'OCR-Vorschlag bestaetigt und gespeichert.' : 'Messpunkt gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1444,7 +1462,7 @@
|
||||
});
|
||||
setMessage('Wallet-Snapshot gespeichert.');
|
||||
setOcrPreview(null);
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Wallet-Snapshot gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1469,7 +1487,7 @@
|
||||
method: 'DELETE',
|
||||
});
|
||||
setMessage('Messpunkt geloescht.');
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Messpunkt geloescht.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1500,7 +1518,7 @@
|
||||
if (!result.error_count) {
|
||||
setImportForm((previous) => ({ ...previous, rows_text: '' }));
|
||||
}
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation(`Import abgeschlossen: ${summary}.`);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1561,7 +1579,7 @@
|
||||
}),
|
||||
});
|
||||
setMessage('Dashboard gespeichert.');
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Dashboard gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1590,7 +1608,7 @@
|
||||
}),
|
||||
});
|
||||
setMessage('Settings gespeichert.');
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Settings gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1647,7 +1665,7 @@
|
||||
setMessage('Ziel gespeichert.');
|
||||
setTargetForm({ label: '', target_amount_fiat: '', currency: currencies[0]?.code || 'EUR', miner_offer_id: '', is_active: true, sort_order: 0 });
|
||||
setTargetModalOpen(false);
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Ziel gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1668,7 +1686,7 @@
|
||||
method: 'DELETE',
|
||||
});
|
||||
setMessage('Ziel geloescht.');
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Ziel geloescht.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1690,7 +1708,7 @@
|
||||
body: JSON.stringify({ auto_renew: !row.auto_renew }),
|
||||
});
|
||||
setMessage(`Automatische Verlängerung ${row.auto_renew ? 'deaktiviert' : 'aktiviert'}.`);
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation(`Automatische Verlaengerung ${row.auto_renew ? 'deaktiviert' : 'aktiviert'}.`);
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1725,7 +1743,7 @@
|
||||
is_active: true,
|
||||
});
|
||||
setCostPlanModalOpen(false);
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Miner gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
@@ -1746,7 +1764,7 @@
|
||||
setMessage('Auszahlung gespeichert.');
|
||||
setPayoutForm({ payout_at: '', coins_amount: '', payout_currency: currentSettings.crypto_currency || 'DOGE', note: '' });
|
||||
setPayoutModalOpen(false);
|
||||
await loadBootstrap(projectKey);
|
||||
await reloadBootstrapAfterMutation('Auszahlung gespeichert.');
|
||||
} catch (err) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
|
||||
@@ -21,7 +21,7 @@ final class Router
|
||||
{
|
||||
private const BOOTSTRAP_MEASUREMENT_LIMIT = 150;
|
||||
private const BOOTSTRAP_SNAPSHOT_LIMIT = 40;
|
||||
private const LONG_REQUEST_BUDGET_SECONDS = 8.0;
|
||||
private const LONG_REQUEST_BUDGET_SECONDS = 20.0;
|
||||
private const OVERVIEW_WINDOW_DAYS = 15;
|
||||
private const FX_FETCH_MAX_AGE_HOURS = 3.0;
|
||||
private const BASE_OFFER_SPEEDS = [
|
||||
|
||||
Reference in New Issue
Block a user