package widget import "fmt" type Type string const ( Stat Type = "stat" Timeseries Type = "timeseries" Gauge Type = "gauge" RankedList Type = "ranked-list" StatusGrid Type = "status-grid" Table Type = "table" Heatmap Type = "heatmap" EventTimeline Type = "event-timeline" StorageMap Type = "storage-map" Topology Type = "topology" ServiceMatrix Type = "service-matrix" AlertSummary Type = "alert-summary" Text Type = "text" QueryInspector Type = "query-inspector" ) type State string const ( Loading State = "loading" Empty State = "empty" Error State = "error" Stale State = "stale" ) type Size struct{ MinW, MinH, PreferredW, PreferredH int } type Definition struct { Type Type Title string States map[State]string Size Size Capabilities []string } type Registry struct { definitions map[Type]Definition unknown Definition } func NewRegistry(definitions []Definition) (Registry, error) { r := Registry{definitions: make(map[Type]Definition), unknown: Definition{Type: "unknown", Title: "Onbekende widget", States: map[State]string{Loading: "Widget laden", Empty: "Geen gegevens", Error: "Widget niet beschikbaar", Stale: "Gegevens zijn verouderd"}, Size: Size{MinW: 1, MinH: 1, PreferredW: 2, PreferredH: 2}}} for _, d := range definitions { if err := d.Validate(); err != nil { return Registry{}, err } if _, ok := r.definitions[d.Type]; ok { return Registry{}, fmt.Errorf("duplicate widget type %q", d.Type) } r.definitions[d.Type] = d } return r, nil } func (d Definition) Validate() error { if d.Type == "" || d.Title == "" { return fmt.Errorf("widget type and title are required") } for _, state := range []State{Loading, Empty, Error, Stale} { if d.States[state] == "" { return fmt.Errorf("widget %q missing %s state", d.Type, state) } } if d.Size.MinW < 1 || d.Size.MinH < 1 || d.Size.PreferredW < d.Size.MinW || d.Size.PreferredH < d.Size.MinH { return fmt.Errorf("widget %q has invalid sizes", d.Type) } return nil } func (r Registry) Get(t Type) Definition { if d, ok := r.definitions[t]; ok { return d } return r.unknown } func (r Registry) Catalog() []Definition { result := make([]Definition, 0, len(r.definitions)) for _, definition := range r.definitions { result = append(result, definition) } for i := 0; i < len(result); i++ { for j := i + 1; j < len(result); j++ { if result[j].Type < result[i].Type { result[i], result[j] = result[j], result[i] } } } return result } func DefaultDefinitions() []Definition { types := []Type{Stat, Timeseries, Gauge, RankedList, StatusGrid, Table, Heatmap, EventTimeline, StorageMap, Topology, ServiceMatrix, AlertSummary, Text, QueryInspector} result := make([]Definition, 0, len(types)) for _, t := range types { result = append(result, Definition{Type: t, Title: string(t), States: map[State]string{Loading: "Laden", Empty: "Geen gegevens", Error: "Fout", Stale: "Verouderd"}, Size: Size{MinW: 1, MinH: 1, PreferredW: 2, PreferredH: 2}}) } return result }