fix(admin): datetime popover clock, unsaved confirm, inferred list dates

BM UAT on v0.1.1 showed a date-only calendar for datetime fields, a stuck discard dialog, and raw ISO timestamps when columns.yaml omitted type. The picker now edits time in the popover, confirm sits above the calendar, and omitted time.Time / Date / TimeOfDay columns compile as datetime / date / time.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jakub Zych
2026-10-03 05:58:24 +02:00
parent 8031fd1c16
commit 55314e41f8
14 changed files with 227 additions and 32 deletions

View File

@@ -219,9 +219,15 @@ func compileColumns(pluginID string, ctl pact.AdminController, fsys fs.FS, colPa
if err := decodeStrict(encoded, &spec); err != nil {
return nil, bootErr(pluginID, ctl.ID(), colPath, fmt.Errorf("column %s: %w", key, err))
}
if spec.Type != "" {
if _, known := listColumnTypes[spec.Type]; !known {
return nil, bootErr(pluginID, ctl.ID(), colPath, fmt.Errorf("unsupported column type %s", spec.Type))
typ := spec.Type
if typ == "" && checkModel {
if inferred := modelCols[key]; inferred != "" && inferred != "text" {
typ = inferred
}
}
if typ != "" {
if _, known := listColumnTypes[typ]; !known {
return nil, bootErr(pluginID, ctl.ID(), colPath, fmt.Errorf("unsupported column type %s", typ))
}
}
if spec.Relation != "" || spec.Select != "" {
@@ -250,7 +256,7 @@ func compileColumns(pluginID string, ctl pact.AdminController, fsys fs.FS, colPa
Label: spec.Label,
Searchable: spec.Searchable,
Sortable: sortable,
Type: spec.Type,
Type: typ,
Relation: spec.Relation,
Select: spec.Select,
})
@@ -379,7 +385,7 @@ func compileDefaultSort(doc *listSortDocument, columns []ListColumn) (*ListSort,
return &ListSort{Column: doc.Column, Direction: doc.Direction}, nil
}
func listModelContract(ctl pact.AdminController) (map[string]struct{}, map[string]struct{}, bool) {
func listModelContract(ctl pact.AdminController) (map[string]string, map[string]struct{}, bool) {
src, ok := ctl.(pact.AdminRecordSource)
if !ok || src == nil {
return nil, nil, false
@@ -395,7 +401,7 @@ func listModelContract(ctl pact.AdminController) (map[string]struct{}, map[strin
if t == nil || t.Kind() != reflect.Struct {
return nil, nil, false
}
cols := map[string]struct{}{}
cols := map[string]string{}
rels := map[string]struct{}{}
for _, mf := range modelFields(t) {
field := mf.Field
@@ -410,11 +416,30 @@ func listModelContract(ctl pact.AdminController) (map[string]struct{}, map[strin
if name == "" {
name = field.Name
}
cols[name] = struct{}{}
cols[name] = listColumnKind(field.Type)
}
return cols, rels, true
}
// listColumnKind is the Winter list type of a model field when columns.yaml
// omits type: datetime for time.Time, date for lagoon.Date, time for
// lagoon.TimeOfDay. Everything else stays text (the admin's default).
func listColumnKind(t reflect.Type) string {
for t.Kind() == reflect.Pointer {
t = t.Elem()
}
switch t {
case reflect.TypeOf(time.Time{}):
return "datetime"
case dateGoType:
return "date"
case timeOfDayGoType:
return "time"
default:
return "text"
}
}
func isListRelation(t reflect.Type) bool {
for t.Kind() == reflect.Pointer {
t = t.Elem()