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

This commit is contained in:
2026-05-01 03:13:29 +02:00
parent 29e2724cd8
commit 5a154f896b
3 changed files with 63 additions and 119 deletions

View File

@@ -7,10 +7,8 @@
const page = JSON.parse(root.dataset.page || '{}');
const settings = page.settings || {};
const nodes = {
ratesBody: root.querySelector('[data-bind="rates-body"]'),
historyHead: root.querySelector('[data-bind="history-head"]'),
historyBody: root.querySelector('[data-bind="history-body"]'),
fetchesBody: root.querySelector('[data-bind="fetches-body"]'),
convertResult: root.querySelector('[data-bind="convert-result"]'),
convertFrom: root.querySelector('select[name="convert_from"]'),
convertTo: root.querySelector('select[name="convert_to"]'),
@@ -99,51 +97,12 @@
});
};
const renderSnapshot = (snapshot) => {
const rates = snapshot && snapshot.rates ? snapshot.rates : null;
const entries = rates ? Object.entries(rates) : [];
const visibleCurrencies = preferredCurrencies.length
? new Set(preferredCurrencies)
: null;
if (!nodes.ratesBody) {
return;
}
const filteredEntries = visibleCurrencies
? entries.filter(([code]) => visibleCurrencies.has(String(code || '').trim().toUpperCase()))
: entries;
if (!filteredEntries.length) {
nodes.ratesBody.innerHTML = '<tr><td colspan="2">Noch keine Wechselkurse fuer die ausgewaehlten Waehrungen gespeichert.</td></tr>';
return;
}
nodes.ratesBody.innerHTML = filteredEntries.map(([code, rate]) => {
const formatted = typeof rate === 'number'
? rate.toLocaleString('de-DE', { maximumFractionDigits: 8 })
: 'n/a';
return `<tr><td>${code}</td><td>${formatted}</td></tr>`;
}).join('');
};
const renderFetches = (fetches) => {
if (!nodes.fetchesBody) {
return;
}
const entries = Array.isArray(fetches) ? fetches : [];
if (!entries.length) {
nodes.fetchesBody.innerHTML = '<tr><td colspan="4">Noch keine Abrufe vorhanden.</td></tr>';
return;
}
nodes.fetchesBody.innerHTML = entries.map((entry) => `
<tr>
<td>${entry?.fetched_at_display || entry?.fetched_at || ''}</td>
<td>${entry?.base_currency || ''}</td>
<td>${entry?.provider || ''}</td>
<td>${entry?.trigger_source_label || entry?.trigger_source || ''}</td>
</tr>
`).join('');
};
const escapeHtml = (value) => String(value || '')
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#39;');
const renderHistory = (rows, currencies) => {
if (!nodes.historyHead || !nodes.historyBody) {
@@ -172,7 +131,19 @@
nodes.historyBody.innerHTML = entries.map((entry) => `
<tr>
<td>${entry.label}</td>
<td>
<div class="fx-history-date">
<span>${entry.label}</span>
${entry.fetch ? `
<button
type="button"
class="fx-info-button"
title="${escapeHtml(`Basis: ${entry.fetch.base_currency || '-'} | Provider: ${entry.fetch.provider || '-'} | Ausloeser: ${entry.fetch.trigger_source_label || entry.fetch.trigger_source || '-'}`)}"
aria-label="${escapeHtml(`Abrufinfo fuer ${entry.label}`)}"
>i</button>
` : ''}
</div>
</td>
${series.map((currency) => {
const value = entry.rates?.[currency];
if (typeof value !== 'number' || !Number.isFinite(value)) {
@@ -201,21 +172,6 @@
return payload.data;
};
const loadLatest = async () => {
const base = String(
settings.display_base_currency || settings.default_base_currency || 'EUR'
).trim().toUpperCase();
const query = new URLSearchParams();
query.set('base', base);
if (preferredCurrencies.length) {
query.set('symbols', preferredCurrencies.join(','));
}
const data = await request(`/latest?${query.toString()}`);
renderSnapshot(data);
return data;
};
const loadHistory = async () => {
const base = String(
settings.display_base_currency || settings.default_base_currency || 'EUR'
@@ -236,7 +192,21 @@
return { currency, rows: Array.isArray(rows) ? rows : [] };
}));
const recentFetches = Array.isArray(page.recent_fetches) ? page.recent_fetches : [];
const byDate = new Map();
recentFetches.forEach((fetch) => {
const key = String(fetch?.fetched_at || '').trim();
if (!key || byDate.has(key)) {
return;
}
byDate.set(key, {
sortKey: key,
label: fetch?.fetched_at_display || fetch?.fetched_at || key,
fetch,
rates: base !== '' ? { [base]: 1 } : {},
});
});
histories.forEach(({ currency, rows }) => {
rows.forEach((row) => {
const key = String(row?.fetched_at || row?.rate_date || '').trim();
@@ -247,6 +217,7 @@
byDate.set(key, {
sortKey: key,
label: row?.fetched_at_display || row?.fetched_at || row?.rate_date || key,
fetch: recentFetches.find((fetch) => String(fetch?.fetched_at || '').trim() === key) || null,
rates: base !== '' ? { [base]: 1 } : {},
});
}
@@ -258,7 +229,8 @@
});
const mergedRows = Array.from(byDate.values())
.sort((left, right) => String(left.sortKey).localeCompare(String(right.sortKey)));
.sort((left, right) => String(right.sortKey).localeCompare(String(left.sortKey)))
.slice(0, 15);
renderHistory(mergedRows, selectedCurrencies);
};
@@ -305,10 +277,8 @@
});
});
renderFetches(page.recent_fetches || []);
bindManualRefreshAction();
loadLatest().catch(() => {});
loadHistory().catch(() => {
renderHistory([], preferredCurrencies);
});