feat(dashboard): Kosten-Kachel zeigt den aktuellen Monat
Die Kachel heißt jetzt API-Kosten aktueller Monat (Läufe des Monats und Lebenszeit-Summe klein in der Unterzeile) statt der nackten Gesamtsumme. Datenquelle ist der Statistik-Endpoint in einem Aufruf. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -1121,7 +1121,7 @@
|
||||
</div>
|
||||
|
||||
<script src="/static/js/a11y.js?v=20260725a"></script>
|
||||
<script src="/static/js/app.js?v=20260725n"></script>
|
||||
<script src="/static/js/app.js?v=20260725o"></script>
|
||||
<script src="/static/js/sources.js?v=20260522x2"></script>
|
||||
<script src="/static/js/x-scraper.js?v=20260522a"></script>
|
||||
<script src="/static/js/source-health.js?v=20260509l"></script>
|
||||
|
||||
@@ -1249,15 +1249,24 @@ function onNewOrgLicPeriodChange() {
|
||||
|
||||
async function loadDashboardTokenStats() {
|
||||
try {
|
||||
const data = await API.get('/api/token-usage/overview');
|
||||
// Aktueller Monat im Vordergrund, Lebenszeit-Summe klein darunter.
|
||||
// months=0 liefert beides in einem Aufruf (kpi = gesamt, Serien je Monat).
|
||||
const data = await API.get('/api/statistik?months=0');
|
||||
const grid = document.getElementById('statsGrid');
|
||||
if (grid && data.length > 0) {
|
||||
const totals = data.reduce(function(acc, org) {
|
||||
return {
|
||||
cost: acc.cost + (org.total_cost_usd || 0),
|
||||
refreshes: acc.refreshes + (org.total_refreshes || 0),
|
||||
};
|
||||
}, { cost: 0, refreshes: 0 });
|
||||
if (grid && data && data.kpi) {
|
||||
const jetzt = new Date();
|
||||
const monat = jetzt.getFullYear() + '-' + String(jetzt.getMonth() + 1).padStart(2, '0');
|
||||
let monatKosten = 0;
|
||||
(data.monat_quelle || []).forEach(function(r) {
|
||||
if (r.monat === monat) monatKosten += r.kosten || 0;
|
||||
});
|
||||
let monatLaeufe = 0;
|
||||
(data.monat_betrieb || []).forEach(function(r) {
|
||||
if (r.monat === monat) monatLaeufe = r.completed || 0;
|
||||
});
|
||||
const fmtUsd = function(n) {
|
||||
return '$' + Number(n || 0).toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
};
|
||||
|
||||
// Sprung-Kachel zum Statistik-Tab. Handler direkt anhaengen, denn die
|
||||
// Kachel entsteht NACH wireStatCardLinks() (ein erneuter Aufruf dort
|
||||
@@ -1267,9 +1276,9 @@ async function loadDashboardTokenStats() {
|
||||
card.setAttribute('role', 'link');
|
||||
card.setAttribute('tabindex', '0');
|
||||
card.title = 'Zur Statistik';
|
||||
card.innerHTML = '<div class="stat-label">API-Kosten gesamt</div>' +
|
||||
'<div class="stat-value">$' + totals.cost.toFixed(2) + '</div>' +
|
||||
'<div class="stat-sub">' + totals.refreshes + ' Refreshes</div>';
|
||||
card.innerHTML = '<div class="stat-label">API-Kosten aktueller Monat</div>' +
|
||||
'<div class="stat-value">' + fmtUsd(monatKosten) + '</div>' +
|
||||
'<div class="stat-sub">' + monatLaeufe.toLocaleString('de-DE') + ' Läufe · gesamt ' + fmtUsd(data.kpi.kosten_usd) + '</div>';
|
||||
const springe = () => gotoSection('statistik');
|
||||
card.addEventListener('click', springe);
|
||||
card.addEventListener('keydown', (e) => {
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren