diff --git a/hub/internal/web/configs.go b/hub/internal/web/configs.go index ad24c3c..f54f473 100644 --- a/hub/internal/web/configs.go +++ b/hub/internal/web/configs.go @@ -5,7 +5,9 @@ import ( "fmt" "net/http" "regexp" + "sort" "strings" + "time" "gitea.dooplex.hu/admin/felhom-hub/internal/configgen" "gitea.dooplex.hu/admin/felhom-hub/internal/store" @@ -13,7 +15,19 @@ import ( var validCustomerID = regexp.MustCompile(`^[a-zA-Z0-9.\-]+$`) -// handleConfigList shows all customer configurations. +// customerListEntry is a merged view of a customer from both configs and reports. +type customerListEntry struct { + CustomerID string + CustomerName string + Domain string + HasConfig bool + OverallStatus string // ok, warn, down, disabled, "" if no reports + ControllerVersion string + TimeSinceReport time.Duration + ConfigCreatedAt time.Time +} + +// handleConfigList shows all customers (merged from configs + reports). func (s *Server) handleConfigList(w http.ResponseWriter, r *http.Request) { configs, err := s.store.ListCustomerConfigs() if err != nil { @@ -22,12 +36,73 @@ func (s *Server) handleConfigList(w http.ResponseWriter, r *http.Request) { return } + customers, err := s.store.GetCustomers() + if err != nil { + s.logger.Printf("[ERROR] Failed to list customers: %v", err) + http.Error(w, "Internal error", http.StatusInternalServerError) + return + } + + // Build merged map keyed by customer_id + merged := make(map[string]*customerListEntry) + + for _, cfg := range configs { + merged[cfg.CustomerID] = &customerListEntry{ + CustomerID: cfg.CustomerID, + CustomerName: cfg.CustomerName, + Domain: cfg.Domain, + HasConfig: true, + ConfigCreatedAt: cfg.CreatedAt, + } + } + + for _, c := range customers { + status := "ok" + if c.HealthStatus == "disabled" { + status = "disabled" + } else if c.TimeSinceReport > time.Hour { + status = "down" + } else if c.TimeSinceReport > 30*time.Minute || c.HealthStatus == "warn" { + status = "warn" + } else if c.HealthStatus == "fail" { + status = "down" + } + + if entry, ok := merged[c.CustomerID]; ok { + // Config exists — enrich with report data + entry.OverallStatus = status + entry.ControllerVersion = c.ControllerVersion + entry.TimeSinceReport = c.TimeSinceReport + if entry.CustomerName == "" { + entry.CustomerName = c.CustomerName + } + } else { + // Report-only customer (no config) + merged[c.CustomerID] = &customerListEntry{ + CustomerID: c.CustomerID, + CustomerName: c.CustomerName, + OverallStatus: status, + ControllerVersion: c.ControllerVersion, + TimeSinceReport: c.TimeSinceReport, + } + } + } + + // Sort by customer_id + entries := make([]customerListEntry, 0, len(merged)) + for _, e := range merged { + entries = append(entries, *e) + } + sort.Slice(entries, func(i, j int) bool { + return entries[i].CustomerID < entries[j].CustomerID + }) + data := struct { - Configs []store.CustomerConfig + Customers []customerListEntry ActiveNav string Flash string }{ - Configs: configs, + Customers: entries, ActiveNav: "configs", Flash: r.URL.Query().Get("flash"), } diff --git a/hub/internal/web/templates/config_detail.html b/hub/internal/web/templates/config_detail.html index 5380af3..a53c303 100644 --- a/hub/internal/web/templates/config_detail.html +++ b/hub/internal/web/templates/config_detail.html @@ -12,11 +12,11 @@

Felhom Hub

- ← All Configurations + ← All customers {{if .Flash}}
@@ -123,7 +123,7 @@
diff --git a/hub/internal/web/templates/config_form.html b/hub/internal/web/templates/config_form.html index b7c5456..d530b8b 100644 --- a/hub/internal/web/templates/config_form.html +++ b/hub/internal/web/templates/config_form.html @@ -3,7 +3,7 @@ - Felhom Hub — {{if .IsNew}}New Configuration{{else}}Edit {{.Config.CustomerID}}{{end}} + Felhom Hub — {{if .IsNew}}Add Customer{{else}}Edit {{.Config.CustomerID}}{{end}} @@ -12,12 +12,12 @@

Felhom Hub

← Back -

{{if .IsNew}}New Customer Configuration{{else}}Edit: {{.Config.CustomerID}}{{end}}

+

{{if .IsNew}}Add Customer{{else}}Edit: {{.Config.CustomerID}}{{end}}

{{if .Error}}
{{.Error}}
diff --git a/hub/internal/web/templates/configs.html b/hub/internal/web/templates/configs.html index 7d78f17..6e7509f 100644 --- a/hub/internal/web/templates/configs.html +++ b/hub/internal/web/templates/configs.html @@ -3,7 +3,7 @@ - Felhom Hub — Configurations + Felhom Hub — Customers @@ -12,25 +12,25 @@

Felhom Hub

{{if .Flash}}
- {{if eq .Flash "deleted"}}Configuration deleted.{{end}} + {{if eq .Flash "deleted"}}Customer configuration deleted.{{end}}
{{end}}
-

Customer Configurations

- + New Configuration +

Customers

+ + Add Customer
- {{if not .Configs}} + {{if not .Customers}}
-

No customer configurations yet.

-

Create a configuration to pre-provision a customer node.

+

No customers yet.

+

Add a customer configuration or wait for a controller to report in.

{{else}} @@ -39,16 +39,32 @@ - + + + - {{range .Configs}} - + {{range .Customers}} + - + + + {{end}} @@ -56,7 +72,7 @@ {{end}} diff --git a/hub/internal/web/templates/customer.html b/hub/internal/web/templates/customer.html index 8769359..51b4a06 100644 --- a/hub/internal/web/templates/customer.html +++ b/hub/internal/web/templates/customer.html @@ -12,7 +12,7 @@
← Back to Dashboard

diff --git a/hub/internal/web/templates/dashboard.html b/hub/internal/web/templates/dashboard.html index 48de88e..0e66824 100644 --- a/hub/internal/web/templates/dashboard.html +++ b/hub/internal/web/templates/dashboard.html @@ -13,7 +13,7 @@

Felhom Hub

Customer ID Name DomainCreatedStatusVersionConfig
{{.CustomerID}} {{if .CustomerName}}{{.CustomerName}}{{else}}{{end}} {{if .Domain}}{{.Domain}}{{else}}{{end}}{{timeAgo .CreatedAt}} + {{if .OverallStatus}} + {{.OverallStatus}} + {{else}} + + {{end}} + {{if .ControllerVersion}}{{.ControllerVersion}}{{else}}{{end}} + {{if .HasConfig}} + managed + {{else}} + manual + {{end}} +