Datepickers on native time.Time / lagoon.Date fields, file uploads on materials, readings and class sessions managed from the course form (course_id made nullable).
57 lines
1.4 KiB
Go
57 lines
1.4 KiB
Go
package controllers
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/cabana"
|
|
"git.golem15.com/jakub/sm-bm-plugin/models"
|
|
)
|
|
|
|
// Permission codes of the plugin's admin screens.
|
|
const (
|
|
PermCourses = "jz.bm.access_courses"
|
|
PermSchedule = "jz.bm.access_schedule"
|
|
PermMaterials = "jz.bm.access_materials"
|
|
)
|
|
|
|
// temporalHooks checks the order of a model's dates before every admin save
|
|
// and answers a bad value as a 422 on its field. lagoon.Validate cannot
|
|
// compare two fields, so the model checks them itself
|
|
// (models.TemporalValidator).
|
|
type temporalHooks struct{}
|
|
|
|
func (temporalHooks) FormBeforeCreate(_ context.Context, model any) error {
|
|
return checkTemporal(model)
|
|
}
|
|
|
|
func (temporalHooks) FormBeforeUpdate(_ context.Context, model any) error {
|
|
return checkTemporal(model)
|
|
}
|
|
|
|
func checkTemporal(model any) error {
|
|
v, ok := model.(models.TemporalValidator)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
msgs := v.TemporalErrors()
|
|
if len(msgs) == 0 {
|
|
return nil
|
|
}
|
|
details := make(map[string]any, len(msgs))
|
|
for field, m := range msgs {
|
|
details[field] = m
|
|
}
|
|
return &cabana.ValidationError{Details: details}
|
|
}
|
|
|
|
// courseRelation is the belongsTo picker of a course_id column.
|
|
func courseRelation(foreignKey string) cabana.FieldRelationContract {
|
|
return cabana.FieldRelationContract{
|
|
Field: "course",
|
|
Kind: "belongsTo",
|
|
NewRelated: func() any { return &models.Course{} },
|
|
ForeignKey: foreignKey,
|
|
LabelColumn: "name",
|
|
}
|
|
}
|