mirror of
https://github.com/Bornholm/formidable.git
synced 2025-09-07 11:38:27 +02:00
feat: values updaters
This commit is contained in:
@ -11,6 +11,7 @@ type Option struct {
|
||||
Schema *jsonschema.Schema
|
||||
Values interface{}
|
||||
Defaults interface{}
|
||||
OnUpdate OnUpdateFunc
|
||||
}
|
||||
|
||||
type OptionFunc func(*Option)
|
||||
@ -47,3 +48,9 @@ func WithDefaults(defaults interface{}) OptionFunc {
|
||||
opt.Defaults = defaults
|
||||
}
|
||||
}
|
||||
|
||||
func WithOnUpdate(onUpdate OnUpdateFunc) OptionFunc {
|
||||
return func(opt *Option) {
|
||||
opt.OnUpdate = onUpdate
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package route
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
@ -12,68 +12,72 @@ import (
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
)
|
||||
|
||||
func createRenderFormHandlerFunc(schema *jsonschema.Schema, defaults, values interface{}) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
data := &template.FormItemData{
|
||||
Parent: nil,
|
||||
Schema: schema,
|
||||
Property: "",
|
||||
Defaults: defaults,
|
||||
Values: values,
|
||||
func (s *Server) serveFormReq(w http.ResponseWriter, r *http.Request) {
|
||||
data := &template.FormItemData{
|
||||
Parent: nil,
|
||||
Schema: s.schema,
|
||||
Property: "",
|
||||
Defaults: s.defaults,
|
||||
Values: s.values,
|
||||
}
|
||||
|
||||
if err := s.schema.Validate(data.Values); err != nil {
|
||||
validationErr, ok := err.(*jsonschema.ValidationError)
|
||||
if !ok {
|
||||
panic(errors.Wrap(err, "could not validate values"))
|
||||
}
|
||||
|
||||
if err := schema.Validate(data.Values); err != nil {
|
||||
validationErr, ok := err.(*jsonschema.ValidationError)
|
||||
if !ok {
|
||||
panic(errors.Wrap(err, "could not validate values"))
|
||||
}
|
||||
data.Error = validationErr
|
||||
}
|
||||
|
||||
data.Error = validationErr
|
||||
}
|
||||
|
||||
if err := template.Exec("index.html.tmpl", w, data); err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
if err := template.Exec("index.html.tmpl", w, data); err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
}
|
||||
|
||||
func createHandleFormHandlerFunc(schema *jsonschema.Schema, defaults, values interface{}) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
data := &template.FormItemData{
|
||||
Parent: nil,
|
||||
Schema: schema,
|
||||
Property: "",
|
||||
Defaults: defaults,
|
||||
Values: values,
|
||||
}
|
||||
func (s *Server) handleFormReq(w http.ResponseWriter, r *http.Request) {
|
||||
data := &template.FormItemData{
|
||||
Parent: nil,
|
||||
Schema: s.schema,
|
||||
Property: "",
|
||||
Defaults: s.defaults,
|
||||
Values: s.values,
|
||||
}
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
} else {
|
||||
values, err = handleForm(r.Form, schema, values)
|
||||
if err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
var values interface{}
|
||||
|
||||
data.Values = values
|
||||
}
|
||||
|
||||
if err := schema.Validate(data.Values); err != nil {
|
||||
validationErr, ok := err.(*jsonschema.ValidationError)
|
||||
if !ok {
|
||||
panic(errors.Wrap(err, "could not validate values"))
|
||||
}
|
||||
|
||||
data.Error = validationErr
|
||||
}
|
||||
|
||||
if data.Error == nil {
|
||||
data.SuccessMessage = "Data updated."
|
||||
}
|
||||
|
||||
if err := template.Exec("index.html.tmpl", w, data); err != nil {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
} else {
|
||||
values, err = handleForm(r.Form, s.schema, values)
|
||||
if err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
|
||||
data.Values = values
|
||||
}
|
||||
|
||||
if err := s.schema.Validate(data.Values); err != nil {
|
||||
validationErr, ok := err.(*jsonschema.ValidationError)
|
||||
if !ok {
|
||||
panic(errors.Wrap(err, "could not validate values"))
|
||||
}
|
||||
|
||||
data.Error = validationErr
|
||||
}
|
||||
|
||||
if data.Error == nil {
|
||||
if s.onUpdate != nil {
|
||||
if err := s.onUpdate(data.Values); err != nil {
|
||||
panic(errors.Wrap(err, "could not update values"))
|
||||
}
|
||||
}
|
||||
|
||||
data.SuccessMessage = "Data updated."
|
||||
}
|
||||
|
||||
if err := template.Exec("index.html.tmpl", w, data); err != nil {
|
||||
panic(errors.WithStack(err))
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
package route
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
)
|
||||
|
||||
func NewHandler(schema *jsonschema.Schema, defaults, values interface{}, assetsHandler http.Handler) (*chi.Mux, error) {
|
||||
router := chi.NewRouter()
|
||||
|
||||
router.Use(middleware.RequestID)
|
||||
// router.Use(middleware.Logger)
|
||||
|
||||
router.Get("/", createRenderFormHandlerFunc(schema, defaults, values))
|
||||
router.Post("/", createHandleFormHandlerFunc(schema, defaults, values))
|
||||
|
||||
router.Handle("/assets/*", assetsHandler)
|
||||
|
||||
return router, nil
|
||||
}
|
@ -7,8 +7,8 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"forge.cadoles.com/wpetit/formidable/internal/server/route"
|
||||
"forge.cadoles.com/wpetit/formidable/internal/server/template"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/santhosh-tekuri/jsonschema/v5"
|
||||
)
|
||||
@ -19,8 +19,11 @@ type Server struct {
|
||||
schema *jsonschema.Schema
|
||||
defaults interface{}
|
||||
values interface{}
|
||||
onUpdate OnUpdateFunc
|
||||
}
|
||||
|
||||
type OnUpdateFunc func(values interface{}) error
|
||||
|
||||
func (s *Server) Start(ctx context.Context) (<-chan net.Addr, <-chan error) {
|
||||
errs := make(chan error)
|
||||
addrs := make(chan net.Addr)
|
||||
@ -71,16 +74,15 @@ func (s *Server) run(parentCtx context.Context, addrs chan net.Addr, errs chan e
|
||||
assets := getEmbeddedAssets()
|
||||
assetsHandler := http.FileServer(http.FS(assets))
|
||||
|
||||
handler, err := route.NewHandler(s.schema, s.defaults, s.values, assetsHandler)
|
||||
if err != nil {
|
||||
errs <- errors.WithStack(err)
|
||||
router := chi.NewRouter()
|
||||
|
||||
return
|
||||
}
|
||||
router.Get("/", s.serveFormReq)
|
||||
router.Post("/", s.handleFormReq)
|
||||
router.Handle("/assets/*", assetsHandler)
|
||||
|
||||
log.Println("http server listening")
|
||||
|
||||
if err := http.Serve(listener, handler); err != nil && !errors.Is(err, net.ErrClosed) {
|
||||
if err := http.Serve(listener, router); err != nil && !errors.Is(err, net.ErrClosed) {
|
||||
errs <- errors.WithStack(err)
|
||||
}
|
||||
|
||||
@ -99,5 +101,6 @@ func New(funcs ...OptionFunc) *Server {
|
||||
schema: opt.Schema,
|
||||
defaults: opt.Defaults,
|
||||
values: opt.Values,
|
||||
onUpdate: opt.OnUpdate,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user