diff --git a/frontend/index.html b/frontend/index.html
index 5b6c917..aeed274 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -106,7 +106,16 @@ textarea { resize: vertical; min-height: 120px; }
Live Widgets
-
+
@@ -358,33 +367,20 @@ textarea { resize: vertical; min-height: 120px; }
tickWidgets();
/* Widgets */
- const widgetOrder = ['countdown','repoAtAGlance'];
- const widgetRegistry = {
- countdown: () => ({ title: 'Live clock', html: '
—
' }),
- repoAtAGlance: async () => {
- const el = qs('#repo-mix');
- if (!el) return { title:'Repo mix', html:'Unavailable
' };
- try {
- const res = await fetch('/api/v1/context', { headers: { Accept: 'application/json' } });
- const data = await res.json();
- const repos = data.repos || [];
- const issues = (data.issues||[]).filter(i=>i.state==='open');
- const prs = data.pull_requests || [];
- el.innerHTML = 'Repos
' + repos.length + '
Open issues
' + issues.length + '
Open PRs
' + prs.length + '
';
- } catch (e) { el.innerHTML = 'Widget unavailable.
'; }
- return { title:'Repo mix', html:'Loading…
' };
- },
- };
- const widgetsEl = qs('#widgets');
- function paintWidgets() {
- widgetsEl.innerHTML = '';
- widgetOrder.forEach(async k => {
- const w = await widgetRegistry[k]();
- const node = document.createElement('div'); node.className='widget'; node.innerHTML = '' + escapeHtml(w.title) + '
' + w.html;
- widgetsEl.appendChild(node);
- });
+ async function updateRepoMix() {
+ const el = qs('#repo-mix');
+ try {
+ const res = await fetch('/api/v1/context', { headers: { Accept: 'application/json' } });
+ const data = await res.json();
+ const repos = data.repos || [];
+ const issues = (data.issues||[]).filter(i=>i.state==='open');
+ const prs = data.pull_requests || [];
+ el.innerHTML = 'Repos
' + repos.length + '
Open issues
' + issues.length + '
Open PRs
' + prs.length + '
';
+ } catch (e) {
+ el.innerHTML = 'Widget unavailable.
';
+ }
}
- paintWidgets();
+ updateRepoMix();
function widgetTick() { const el=qs('#widget-clock'); if(el) el.textContent = fmt(new Date()); }
setInterval(widgetTick, 1000);
diff --git a/tests/test_widgets.py b/tests/test_widgets.py
new file mode 100644
index 0000000..adeca85
--- /dev/null
+++ b/tests/test_widgets.py
@@ -0,0 +1,11 @@
+import pytest
+
+from src.views import dashboard
+
+
+@pytest.mark.anyio
+async def test_dashboard_renders_repo_mix_placeholder_before_javascript_runs():
+ html = await dashboard()
+ server_rendered_html = html.split("