feat(ui): add a progress loading screen and lazy project list

The loading screen shows live scan progress from the server, with a pulsing outline of the dashboard. The server now reports how many repositories the running scan has finished.

The project list renders 20 rows first and adds more as the end scrolls into view. Groups on very wide screens fill two balanced columns, the fact figures sit in a row under the health strip, and the headline counts match the rows listed below it.
This commit is contained in:
2026-10-02 04:50:38 +01:00
parent 1852ea0885
commit a56a12a6e0
19 changed files with 552 additions and 60 deletions
+5 -1
View File
@@ -45,7 +45,7 @@ func testView() collector.View {
}
bare := model.Repo{FullName: "o/bare", URL: "https://github.com/o/bare", ReleasesURL: "https://github.com/o/bare/releases", Err: "boom"}
return collector.View{
Now: now, LastRefresh: now.Add(-time.Hour), Interval: 6 * time.Hour, Loaded: true, Crit: 1, Warn: 1,
Now: now, LastRefresh: now.Add(-time.Hour), Interval: 6 * time.Hour, Loaded: true, Crit: 1, Warn: 1, ScanDone: 5, ScanTotal: 9,
Thresholds: config.Thresholds{PRWarnAfter: 48 * time.Hour, PRCritAfter: 168 * time.Hour, IssueStaleAfter: 720 * time.Hour},
Repos: []model.Repo{repo, bare},
Alerts: []model.Alert{
@@ -125,6 +125,7 @@ func TestStateJSONContract(t *testing.T) {
Repos []map[string]any
Alerts []map[string]any
Counts struct{ Crit, Warn int }
Scan struct{ Done, Total int }
Thresholds struct{ PRWarnSeconds, PRCritSeconds int64 }
IntervalSeconds int64
Loaded bool
@@ -133,6 +134,9 @@ func TestStateJSONContract(t *testing.T) {
if err := json.Unmarshal(rec.Body.Bytes(), &got); err != nil {
t.Fatal(err)
}
if got.Scan.Done != 5 || got.Scan.Total != 9 {
t.Fatalf("scan: %+v", got.Scan)
}
if got.IntervalSeconds != 21600 || !got.Loaded || !got.ManualRefresh || got.Counts.Crit != 1 || got.Counts.Warn != 1 {
t.Fatalf("top level: %+v", got)
}