generated from coulomb/repo-seed
feat(dashboard): entity list UX — REF column, name cells, detail pages (CUST-WP-0030)
- ref-cell.js: REF column component — click=copy deeplink, dblclick=open
- field-help.js: field registry + fieldRow helper with help-tip decoration;
FK fields (task_id, workstream_id, repo_id) render as async-linked cells
with entity-title bubble-help on hover
- GET /token-events/{id} endpoint + get-by-id tests
- GET /repos/by-id/{repo_id} UUID lookup endpoint
- Landing pages: /token-events/[id], /workstreams/[id], /repos/[slug], /tasks/[id]
- token-cost.md: REF + Name columns on all three tables; parallel fetch of
workstreams/tasks for title resolution
- reference.md: entity detail page URL scheme documented
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
29
dashboard/src/data/repos/[slug].json.py
Normal file
29
dashboard/src/data/repos/[slug].json.py
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Observable data loader: fetches a single repo by slug."""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
API_BASE = os.environ.get("API_BASE", "http://127.0.0.1:8000").rstrip("/")
|
||||
|
||||
slug = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
|
||||
if not slug:
|
||||
print(json.dumps({"error": "No repo slug provided"}))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(f"{API_BASE}/repos/{slug}/", timeout=10) as resp:
|
||||
data = json.loads(resp.read())
|
||||
print(json.dumps(data))
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 404:
|
||||
print(json.dumps({"error": f"Repo {slug!r} not found"}))
|
||||
sys.exit(1)
|
||||
print(json.dumps({"error": f"HTTP {e.code}: {e.reason}"}))
|
||||
sys.exit(1)
|
||||
except urllib.error.URLError as e:
|
||||
print(json.dumps({"error": str(e)}))
|
||||
sys.exit(1)
|
||||
29
dashboard/src/data/token-events/[id].json.py
Normal file
29
dashboard/src/data/token-events/[id].json.py
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Observable data loader: fetches a single token event by ID."""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
API_BASE = os.environ.get("API_BASE", "http://127.0.0.1:8000").rstrip("/")
|
||||
|
||||
event_id = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
|
||||
if not event_id:
|
||||
print(json.dumps({"error": "No event ID provided"}))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(f"{API_BASE}/token-events/{event_id}", timeout=10) as resp:
|
||||
data = json.loads(resp.read())
|
||||
print(json.dumps(data))
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 404:
|
||||
print(json.dumps({"error": f"Token event {event_id!r} not found"}))
|
||||
sys.exit(1)
|
||||
print(json.dumps({"error": f"HTTP {e.code}: {e.reason}"}))
|
||||
sys.exit(1)
|
||||
except urllib.error.URLError as e:
|
||||
print(json.dumps({"error": str(e)}))
|
||||
sys.exit(1)
|
||||
29
dashboard/src/data/workstreams/[id].json.py
Normal file
29
dashboard/src/data/workstreams/[id].json.py
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Observable data loader: fetches a single workstream by ID."""
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.error
|
||||
|
||||
API_BASE = os.environ.get("API_BASE", "http://127.0.0.1:8000").rstrip("/")
|
||||
|
||||
ws_id = sys.argv[1] if len(sys.argv) > 1 else ""
|
||||
|
||||
if not ws_id:
|
||||
print(json.dumps({"error": "No workstream ID provided"}))
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
with urllib.request.urlopen(f"{API_BASE}/workstreams/{ws_id}", timeout=10) as resp:
|
||||
data = json.loads(resp.read())
|
||||
print(json.dumps(data))
|
||||
except urllib.error.HTTPError as e:
|
||||
if e.code == 404:
|
||||
print(json.dumps({"error": f"Workstream {ws_id!r} not found"}))
|
||||
sys.exit(1)
|
||||
print(json.dumps({"error": f"HTTP {e.code}: {e.reason}"}))
|
||||
sys.exit(1)
|
||||
except urllib.error.URLError as e:
|
||||
print(json.dumps({"error": str(e)}))
|
||||
sys.exit(1)
|
||||
Reference in New Issue
Block a user