From 868a0e496d88d1b9f2bb654dd4d0979710d42387 Mon Sep 17 00:00:00 2001 From: chrischristiansen-glitch Date: Tue, 9 Jun 2026 03:15:20 +0200 Subject: [PATCH] CG3: park AWS billing UI and make history endpoint best-effort so GCP dashboard stays live --- static/billing-dashboard.html | 83 ++++++++++++----------------------- 1 file changed, 27 insertions(+), 56 deletions(-) diff --git a/static/billing-dashboard.html b/static/billing-dashboard.html index 7dfaae4..7fd54bd 100644 --- a/static/billing-dashboard.html +++ b/static/billing-dashboard.html @@ -204,9 +204,7 @@ footer{padding:10px 20px 16px;font-size:11px;color:var(--faint);text-align:cente
- - - + GCP
@@ -432,7 +430,7 @@ footer{padding:10px 20px 16px;font-size:11px;color:var(--faint);text-align:cente const API_BASE = ''; let currentBudget = 500; const REFRESH_MS = 5 * 60 * 1000; -let currentProvider = localStorage.getItem('costguard_provider') || 'gcp'; +let currentProvider = 'gcp'; const DEMO_SUMMARY = [ {service:'Cloud Run',total_cost:1.82},{service:'Cloud Build',total_cost:0.61}, @@ -444,7 +442,7 @@ const DEMO_FORECAST = {month_to_date_cost:3.00,daily_average_last_7_days:0.13,to const DEMO_ANOMALIES = []; let barChart,donutChart,period=30; -let currentData={gcp: null, aws: null}; +let currentData={gcp: null}; let userProfile = null; function fmtNOK(v,d=2){ @@ -469,10 +467,11 @@ async function apiFetch(url, options = {}) { } function switchProvider(provider) { - currentProvider = provider; - localStorage.setItem('costguard_provider', provider); + // AWS-støtte er parkert; vi holder oss på GCP + currentProvider = 'gcp'; + localStorage.setItem('costguard_provider', 'gcp'); document.querySelectorAll('#provider-toggle .sel-opt').forEach(btn => { - btn.classList.toggle('active', btn.dataset.provider === provider); + btn.classList.toggle('active', btn.dataset.provider === 'gcp'); }); fetchAll(); } @@ -562,20 +561,28 @@ async function fetchAll(){ const gcpForecast = apiFetch(API_BASE+'/billing/live'); const gcpAnomalies = apiFetch(API_BASE+'/billing/anomalies'); const gcpHistory = apiFetch(API_BASE+'/billing/history'); - - const awsSummary = apiFetch(API_BASE+'/billing/aws/summary'); - const awsForecast = apiFetch(API_BASE+'/billing/aws/forecast'); - const [gcpSR, gcpLR, gcpAR, gcpHR, awsSR, awsLR] = await Promise.all([gcpSummary, gcpForecast, gcpAnomalies, gcpHistory, awsSummary, awsForecast]); + const [gcpSR, gcpLR, gcpAR, gcpHR] = await Promise.all([gcpSummary, gcpForecast, gcpAnomalies, gcpHistory]); - if (!gcpSR.ok || !gcpLR.ok || !gcpAR.ok || !gcpHR.ok || !awsSR.ok || !awsLR.ok) { - throw new Error('HTTP error on one or more endpoints'); + // GCP summary/forecast/anomalies er kritiske; history er nice-to-have + if (!gcpSR.ok || !gcpLR.ok || !gcpAR.ok) { + throw new Error('HTTP error on core billing endpoints'); } - const [gcpS, gcpL, gcpA, gcpH, awsS, awsL] = await Promise.all([gcpSR.json(), gcpLR.json(), gcpAR.json(), gcpHR.json(), awsSR.json(), awsLR.json()]); + const [gcpS, gcpL, gcpA] = await Promise.all([gcpSR.json(), gcpLR.json(), gcpAR.json()]); + + let gcpH = { history: [] }; + if (gcpHR.ok) { + try { + gcpH = await gcpHR.json(); + } catch (e) { + console.warn('Could not parse history JSON:', e.message); + } + } else { + console.warn('History endpoint returned', gcpHR.status); + } currentData.gcp = { summary: gcpS.summary || [], forecast: gcpL, anomalies: gcpA.anomalies || [], history: gcpH.history || [] }; - currentData.aws = { summary: awsS.summary || [], forecast: awsL, anomalies: [], history: [] }; document.getElementById('err-banner').classList.remove('show'); dot.style.background='var(--ok)'; @@ -583,7 +590,6 @@ async function fetchAll(){ console.warn('API feil, demo-data:',err.message); if (err.message.includes("Not logged in")) return; currentData.gcp = { summary: DEMO_SUMMARY, forecast: DEMO_FORECAST, anomalies: DEMO_ANOMALIES, history: [] }; - currentData.aws = { summary: [], forecast: {}, anomalies: [], history: [] }; document.getElementById('err-msg').textContent='API utilgjengelig: '+err.message+' — demo-data vises.'; document.getElementById('err-banner').classList.add('show'); dot.style.background='var(--red)'; @@ -593,43 +599,8 @@ async function fetchAll(){ } function getVisibleData() { - if (currentProvider === 'gcp') { - return currentData.gcp; - } - if (currentProvider === 'aws') { - return currentData.aws; - } - if (currentProvider === 'all') { - if (!currentData.gcp || !currentData.aws) return null; - const combined = { - summary: [...(currentData.gcp.summary || []), ...(currentData.aws.summary || [])] - .reduce((acc, service) => { - const cost = service.daily_cost ?? service.total_cost ?? service.cost ?? 0; - const existing = acc.find(s => s.service === service.service); - if (existing) { - existing.total_cost = (existing.total_cost || 0) + cost; - } else { - acc.push({ ...service, total_cost: cost }); - } - return acc; - }, []) - .sort((a, b) => { - const costA = a.daily_cost ?? a.total_cost ?? a.cost ?? 0; - const costB = b.daily_cost ?? b.total_cost ?? b.cost ?? 0; - return costB - costA; - }), - forecast: { - month_to_date_cost: (currentData.gcp.forecast?.month_to_date_cost || 0) + (currentData.aws.forecast?.month_to_date_cost || 0), - daily_average_last_7_days: (currentData.gcp.forecast?.daily_average_last_7_days || 0) + (currentData.aws.forecast?.daily_average_last_7_days || 0), - total_monthly_forecast: (currentData.gcp.forecast?.total_monthly_forecast || 0) + (currentData.aws.forecast?.total_monthly_forecast || 0), - remaining_days_in_month: currentData.gcp.forecast?.remaining_days_in_month - }, - anomalies: [...(currentData.gcp.anomalies || []), ...(currentData.aws.anomalies || [])], - history: currentData.gcp.history - }; - return combined; - } - return null; + // AWS er parkert; all visning baseres på GCP-data + return currentData.gcp; } @@ -640,7 +611,6 @@ function calculateDailyCosts(history) { const dailyCosts = []; const labels = []; - let lastMtd = 0; for (let i = 0; i < history.length; i++) { const entry = history[i]; @@ -828,6 +798,7 @@ function exportPDF() { window.print(); } + document.addEventListener('DOMContentLoaded', checkAuth); if ('serviceWorker' in navigator) { @@ -846,7 +817,7 @@ if ('serviceWorker' in navigator) { border: none; color: var(--muted); padding: 4px 10px; - cursor: pointer; + cursor: default; border-radius: 4px; font-size: 12px; font-family: var(--font);