feat: values updaters

This commit is contained in:
2022-05-10 22:31:17 +02:00
parent 08476e5346
commit 0e7e955a58
16 changed files with 415 additions and 155 deletions

View File

@ -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
}
}

View File

@ -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))
}
}

View File

@ -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
}

View File

@ -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,
}
}