feat(09-04): compile ordered Winter list schemas
- Typed columns, actions, default sort, search term, and page sizes - Omitted sortable defaults to true and empty collections marshal as arrays - Unknown keys, bad defaults, and path escape fail before routes are served
This commit is contained in:
@@ -2,6 +2,97 @@ package cabana
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// ListSort is the compiled default sort. Direction is exactly asc or desc.
|
||||
type ListSort struct {
|
||||
Column string `json:"column"`
|
||||
Direction string `json:"direction"`
|
||||
}
|
||||
|
||||
// ListColumn is one compiled columns.yaml entry, in file order.
|
||||
// Omitted sortable defaults to true, matching Winter; searchable defaults to false.
|
||||
type ListColumn struct {
|
||||
Key string `json:"key"`
|
||||
Label string `json:"label"`
|
||||
Searchable bool `json:"searchable"`
|
||||
Sortable bool `json:"sortable"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Relation string `json:"relation,omitempty"`
|
||||
Select string `json:"select,omitempty"`
|
||||
}
|
||||
|
||||
// ListFilter is one compiled config_filter scope. Values stay typed scalars.
|
||||
type ListFilter struct {
|
||||
Name string `json:"name"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Column string `json:"column,omitempty"`
|
||||
Scope string `json:"scope,omitempty"`
|
||||
ModelClass string `json:"modelClass,omitempty"`
|
||||
NameFrom string `json:"nameFrom,omitempty"`
|
||||
Options []FormOption `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// RowAction is a per-record link derived from recordUrl.
|
||||
type RowAction struct {
|
||||
Name string `json:"name"`
|
||||
Label string `json:"label,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// BulkAction is a checkbox action. It carries no SQL.
|
||||
type BulkAction struct {
|
||||
Name string `json:"name"`
|
||||
Label string `json:"label,omitempty"`
|
||||
}
|
||||
|
||||
// ListSchema is the boot-compiled list contract for one controller.
|
||||
// Labels stay as source keys until a request localizes a copy.
|
||||
type ListSchema struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
ModelClass string `json:"modelClass,omitempty"`
|
||||
RecordURL string `json:"recordUrl,omitempty"`
|
||||
NoRecordsMessage string `json:"noRecordsMessage,omitempty"`
|
||||
RecordsPerPage int `json:"recordsPerPage"`
|
||||
PerPageOptions []int `json:"perPageOptions"`
|
||||
ShowSearch bool `json:"showSearch"`
|
||||
ShowSetup bool `json:"showSetup"`
|
||||
ShowCheckboxes bool `json:"showCheckboxes"`
|
||||
ShowSorting bool `json:"showSorting"`
|
||||
SearchTerm string `json:"searchTerm"`
|
||||
SearchPrompt string `json:"searchPrompt,omitempty"`
|
||||
DefaultSort *ListSort `json:"defaultSort,omitempty"`
|
||||
ToolbarButtons []string `json:"toolbarButtons"`
|
||||
Columns []ListColumn `json:"columns"`
|
||||
Filters []ListFilter `json:"filters"`
|
||||
RowActions []RowAction `json:"rowActions"`
|
||||
BulkActions []BulkAction `json:"bulkActions"`
|
||||
}
|
||||
|
||||
// MarshalJSON keeps omitted collections as arrays so a partial copy cannot emit null.
|
||||
func (s ListSchema) MarshalJSON() ([]byte, error) {
|
||||
type alias ListSchema
|
||||
out := alias(s)
|
||||
if out.PerPageOptions == nil {
|
||||
out.PerPageOptions = []int{}
|
||||
}
|
||||
if out.ToolbarButtons == nil {
|
||||
out.ToolbarButtons = []string{}
|
||||
}
|
||||
if out.Columns == nil {
|
||||
out.Columns = []ListColumn{}
|
||||
}
|
||||
if out.Filters == nil {
|
||||
out.Filters = []ListFilter{}
|
||||
}
|
||||
if out.RowActions == nil {
|
||||
out.RowActions = []RowAction{}
|
||||
}
|
||||
if out.BulkActions == nil {
|
||||
out.BulkActions = []BulkAction{}
|
||||
}
|
||||
return json.Marshal(out)
|
||||
}
|
||||
|
||||
// FormSchema is the locale-neutral form contract compiled once at boot.
|
||||
// Display strings stay as source keys until a request localizes a copy.
|
||||
type FormSchema struct {
|
||||
|
||||
Reference in New Issue
Block a user