adasd
All checks were successful
Deploy / deploy-staging (push) Successful in 6s
Deploy / deploy-production (push) Has been skipped

This commit is contained in:
2026-06-03 00:43:33 +02:00
parent 66f9176ea8
commit 99cf5eaef2
3 changed files with 31 additions and 16 deletions

View File

@@ -5,7 +5,7 @@
} }
const h = React.createElement; const h = React.createElement;
const { useEffect, useMemo, useState } = React; const { useEffect, useMemo, useRef, useState } = React;
const apiBase = root.dataset.apiBase || '/api/mining-checker/v1'; const apiBase = root.dataset.apiBase || '/api/mining-checker/v1';
const initialProjectKey = root.dataset.defaultProjectKey || 'doge-main'; const initialProjectKey = root.dataset.defaultProjectKey || 'doge-main';
const initialActiveTab = String(root.dataset.activeView || 'overview').trim() || 'overview'; const initialActiveTab = String(root.dataset.activeView || 'overview').trim() || 'overview';
@@ -734,6 +734,7 @@
const [error, setError] = useState(''); const [error, setError] = useState('');
const [message, setMessage] = useState(''); const [message, setMessage] = useState('');
const [schemaStatus, setSchemaStatus] = useState(normalizeSchemaStatus(null)); const [schemaStatus, setSchemaStatus] = useState(normalizeSchemaStatus(null));
const bootstrapCacheRef = useRef(new Map());
const [initForm, setInitForm] = useState({ drop_existing: false }); const [initForm, setInitForm] = useState({ drop_existing: false });
const [sqlImportFile, setSqlImportFile] = useState(null); const [sqlImportFile, setSqlImportFile] = useState(null);
const [dbCheck, setDbCheck] = useState(null); const [dbCheck, setDbCheck] = useState(null);
@@ -1160,14 +1161,21 @@
} }
async function loadBootstrap(key) { async function loadBootstrap(key) {
setLoading(true); const cacheKey = `${key}:${activeTab || 'overview'}`;
const cachedPayload = bootstrapCacheRef.current.get(cacheKey) || null;
setLoading(!cachedPayload);
setError(''); setError('');
if (cachedPayload) {
setPayload(cachedPayload);
} else {
setPayload((previous) => previous || normalizeBootstrap(null, key)); setPayload((previous) => previous || normalizeBootstrap(null, key));
}
let loadGuardTriggered = false; let loadGuardTriggered = false;
const loadGuard = window.setTimeout(() => { const loadGuard = window.setTimeout(() => {
loadGuardTriggered = true; loadGuardTriggered = true;
setLoading(false); setLoading(false);
setPayload((previous) => previous || normalizeBootstrap(null, key)); setPayload((previous) => previous || cachedPayload || normalizeBootstrap(null, key));
setError((previous) => previous || 'Bootstrap-Request haengt oder braucht zu lange.'); setError((previous) => previous || 'Bootstrap-Request haengt oder braucht zu lange.');
}, 12000); }, 12000);
@@ -1181,6 +1189,7 @@
const params = new URLSearchParams({ view: activeTab || 'overview' }); 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: 10000 });
const normalized = normalizeBootstrap(data, key); const normalized = normalizeBootstrap(data, key);
bootstrapCacheRef.current.set(cacheKey, normalized);
setPayload(normalized); setPayload(normalized);
setSettingsForm({ setSettingsForm({
baseline_measured_at: normalized.settings.baseline_measured_at || '', baseline_measured_at: normalized.settings.baseline_measured_at || '',
@@ -1191,7 +1200,6 @@
setFxSelection(Array.isArray(normalized.settings.preferred_currencies) && normalized.settings.preferred_currencies.length setFxSelection(Array.isArray(normalized.settings.preferred_currencies) && normalized.settings.preferred_currencies.length
? normalized.settings.preferred_currencies ? normalized.settings.preferred_currencies
: ['DOGE', 'USD', 'EUR']); : ['DOGE', 'USD', 'EUR']);
loadFxHistory(key);
setTargetForm((previous) => ({ setTargetForm((previous) => ({
...previous, ...previous,
currency: normalized.settings.currencies?.[0]?.code || previous.currency || 'EUR', currency: normalized.settings.currencies?.[0]?.code || previous.currency || 'EUR',
@@ -1215,6 +1223,13 @@
loadBootstrap(projectKey); loadBootstrap(projectKey);
}, [projectKey, activeTab]); }, [projectKey, activeTab]);
useEffect(() => {
if (activeTab !== 'mining') {
return;
}
loadFxHistory(projectKey);
}, [activeTab, projectKey]);
useEffect(() => { useEffect(() => {
syncMiningCheckerTabButtons(activeTab); syncMiningCheckerTabButtons(activeTab);

View File

@@ -1234,9 +1234,13 @@ final class Router
return []; return [];
} }
$rows = in_array($view, ['overview', 'mining', 'measurements'], true) if (in_array($view, ['overview', 'mining'], true)) {
? $this->repository()->listRecentMeasurements($projectKey, self::BOOTSTRAP_MEASUREMENT_LIMIT) $rows = $this->repository()->listRecentMeasurements($projectKey, self::BOOTSTRAP_MEASUREMENT_LIMIT);
: $this->repository()->listMeasurements($projectKey, self::BOOTSTRAP_MEASUREMENT_LIMIT); } elseif ($view === 'measurements') {
$rows = $this->repository()->listRecentMeasurements($projectKey, 10);
} else {
$rows = $this->repository()->listMeasurements($projectKey, self::BOOTSTRAP_MEASUREMENT_LIMIT);
}
if (in_array($view, ['overview', 'mining'], true)) { if (in_array($view, ['overview', 'mining'], true)) {
$rows = $this->filterMeasurementsToRecentWindow($rows, self::OVERVIEW_WINDOW_DAYS); $rows = $this->filterMeasurementsToRecentWindow($rows, self::OVERVIEW_WINDOW_DAYS);
@@ -1278,13 +1282,12 @@ final class Router
private function bootstrapFxSnapshots(array $measurements, string $view): array private function bootstrapFxSnapshots(array $measurements, string $view): array
{ {
if (!in_array($view, ['overview', 'mining', 'measurements'], true)) { if (!in_array($view, ['overview', 'mining'], true)) {
return []; return [];
} }
$limit = match ($view) { $limit = match ($view) {
'overview' => 1, 'overview' => 1,
'measurements' => 10,
default => self::BOOTSTRAP_SNAPSHOT_LIMIT, default => self::BOOTSTRAP_SNAPSHOT_LIMIT,
}; };

View File

@@ -33,9 +33,7 @@ final class AnalyticsService
$previous = null; $previous = null;
$previousMeasuredTs = null; $previousMeasuredTs = null;
$previousIntervalRate = null; $previousIntervalRate = null;
$previousVisibleCoins = null;
$previousCoinCurrency = null; $previousCoinCurrency = null;
$previousCumulativePayouts = null;
$result = []; $result = [];
$payoutIndex = 0; $payoutIndex = 0;
$payoutsByAsset = []; $payoutsByAsset = [];
@@ -164,7 +162,7 @@ final class AnalyticsService
$normalizedFlags = is_array($decoded) ? $decoded : [$normalizedFlags]; $normalizedFlags = is_array($decoded) ? $decoded : [$normalizedFlags];
} }
$result[] = array_merge($row, [ $enrichedRow = array_merge($row, [
'coins_total_visible' => $this->roundOrNull($visibleCoinsTotal, 6), 'coins_total_visible' => $this->roundOrNull($visibleCoinsTotal, 6),
'coins_total_effective' => $this->roundOrNull($effectiveCoinsTotal, 6), 'coins_total_effective' => $this->roundOrNull($effectiveCoinsTotal, 6),
'coin_currency' => $coinCurrency, 'coin_currency' => $coinCurrency,
@@ -195,15 +193,14 @@ final class AnalyticsService
'measured_date' => substr((string) $row['measured_at'], 0, 10), 'measured_date' => substr((string) $row['measured_at'], 0, 10),
'ocr_flags' => is_array($normalizedFlags) ? $normalizedFlags : [], 'ocr_flags' => is_array($normalizedFlags) ? $normalizedFlags : [],
]); ]);
$result[] = $enrichedRow;
if ($perHourInterval !== null) { if ($perHourInterval !== null) {
$previousIntervalRate = $perHourInterval; $previousIntervalRate = $perHourInterval;
} }
$previous = $row; $previous = $enrichedRow;
$previousMeasuredTs = $measuredTs > 0 ? $measuredTs : null; $previousMeasuredTs = $measuredTs > 0 ? $measuredTs : null;
$previousVisibleCoins = $visibleCoinsTotal;
$previousCoinCurrency = $coinCurrency; $previousCoinCurrency = $coinCurrency;
$previousCumulativePayouts = $cumulativePayouts;
} }
return $result; return $result;