Support entity edits.
This commit is contained in:
parent
b8d8184bda
commit
60afbb18c0
8 changed files with 108 additions and 49 deletions
|
|
@ -3,7 +3,9 @@ package admin
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
|
@ -36,15 +38,14 @@ func (h *Handler) Create(ctx echo.Context, entityType string) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Handler) Get(ctx echo.Context, entityType string, id int) error {
|
||||
// TODO
|
||||
func (h *Handler) Get(ctx echo.Context, entityType string, id int) (url.Values, error) {
|
||||
switch entityType {
|
||||
case "PasswordToken":
|
||||
return h.PasswordTokenGet(ctx, id)
|
||||
case "User":
|
||||
return h.UserGet(ctx, id)
|
||||
default:
|
||||
return fmt.Errorf("unsupported entity type: %s", entityType)
|
||||
return nil, fmt.Errorf("unsupported entity type: %s", entityType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -157,14 +158,16 @@ func (h *Handler) PasswordTokenList(ctx echo.Context) (*EntityList, error) {
|
|||
return list, err
|
||||
}
|
||||
|
||||
func (h *Handler) PasswordTokenGet(ctx echo.Context, id int) error {
|
||||
_, err := h.client.PasswordToken.Get(ctx.Request().Context(), id)
|
||||
func (h *Handler) PasswordTokenGet(ctx echo.Context, id int) (url.Values, error) {
|
||||
entity, err := h.client.PasswordToken.Get(ctx.Request().Context(), id)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO
|
||||
return nil
|
||||
v := url.Values{}
|
||||
v.Set("user_id", fmt.Sprint(entity.UserID))
|
||||
v.Set("created_at", entity.CreatedAt.Format(time.RFC3339))
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (h *Handler) UserCreate(ctx echo.Context) error {
|
||||
|
|
@ -248,14 +251,17 @@ func (h *Handler) UserList(ctx echo.Context) (*EntityList, error) {
|
|||
return list, err
|
||||
}
|
||||
|
||||
func (h *Handler) UserGet(ctx echo.Context, id int) error {
|
||||
_, err := h.client.User.Get(ctx.Request().Context(), id)
|
||||
func (h *Handler) UserGet(ctx echo.Context, id int) (url.Values, error) {
|
||||
entity, err := h.client.User.Get(ctx.Request().Context(), id)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO
|
||||
return nil
|
||||
v := url.Values{}
|
||||
v.Set("name", entity.Name)
|
||||
v.Set("email", entity.Email)
|
||||
v.Set("verified", fmt.Sprint(entity.Verified))
|
||||
return v, err
|
||||
}
|
||||
|
||||
func (h *Handler) getOffset(ctx echo.Context) int {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
|
|
@ -42,15 +43,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
func (h *Handler) Get(ctx echo.Context, entityType string, id int) error {
|
||||
// TODO
|
||||
func (h *Handler) Get(ctx echo.Context, entityType string, id int) (url.Values, error) {
|
||||
switch entityType {
|
||||
{{- range $n := $.Nodes }}
|
||||
case "{{ $n.Name }}":
|
||||
return h.{{ $n.Name }}Get(ctx, id)
|
||||
{{- end }}
|
||||
default:
|
||||
return fmt.Errorf("unsupported entity type: %s", entityType)
|
||||
return nil, fmt.Errorf("unsupported entity type: %s", entityType)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -186,14 +186,25 @@
|
|||
return list, err
|
||||
}
|
||||
|
||||
func (h *Handler) {{ $n.Name }}Get(ctx echo.Context, id int) error {
|
||||
_, err := h.client.{{ $n.Name }}.Get(ctx.Request().Context(), id)
|
||||
func (h *Handler) {{ $n.Name }}Get(ctx echo.Context, id int) (url.Values, error) {
|
||||
entity, err := h.client.{{ $n.Name }}.Get(ctx.Request().Context(), id)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// TODO
|
||||
return nil
|
||||
v := url.Values{}
|
||||
{{- range $f := $n.Fields }}
|
||||
{{- if and (not $f.Sensitive) (not $f.Immutable) }}
|
||||
{{- if eq $f.Type.String "string" }}
|
||||
v.Set("{{ $f.Name }}", entity.{{ fieldName $f.Name }})
|
||||
{{- else if eq $f.Type.String "time.Time" }}
|
||||
v.Set("{{ $f.Name }}", entity.{{ fieldName $f.Name }}.Format(time.RFC3339))
|
||||
{{- else }}
|
||||
v.Set("{{ $f.Name }}", fmt.Sprint(entity.{{ fieldName $f.Name }}))
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
return v, err
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,8 @@ func (c *PasswordTokenClient) QueryUser(pt *PasswordToken) *UserQuery {
|
|||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *PasswordTokenClient) Hooks() []Hook {
|
||||
return c.hooks.PasswordToken
|
||||
hooks := c.hooks.PasswordToken
|
||||
return append(hooks[:len(hooks):len(hooks)], passwordtoken.Hooks[:]...)
|
||||
}
|
||||
|
||||
// Interceptors returns the client interceptors.
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ package passwordtoken
|
|||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
|
|
@ -51,7 +52,13 @@ func ValidColumn(column string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// Note that the variables below are initialized by the runtime
|
||||
// package on the initialization of the application. Therefore,
|
||||
// it should be imported in the main as follows:
|
||||
//
|
||||
// import _ "github.com/mikestefanello/pagoda/ent/runtime"
|
||||
var (
|
||||
Hooks [1]ent.Hook
|
||||
// HashValidator is a validator for the "hash" field. It is called by the builders before save.
|
||||
HashValidator func(string) error
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
|
|
|
|||
|
|
@ -59,7 +59,9 @@ func (ptc *PasswordTokenCreate) Mutation() *PasswordTokenMutation {
|
|||
|
||||
// Save creates the PasswordToken in the database.
|
||||
func (ptc *PasswordTokenCreate) Save(ctx context.Context) (*PasswordToken, error) {
|
||||
ptc.defaults()
|
||||
if err := ptc.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, ptc.sqlSave, ptc.mutation, ptc.hooks)
|
||||
}
|
||||
|
||||
|
|
@ -86,11 +88,15 @@ func (ptc *PasswordTokenCreate) ExecX(ctx context.Context) {
|
|||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (ptc *PasswordTokenCreate) defaults() {
|
||||
func (ptc *PasswordTokenCreate) defaults() error {
|
||||
if _, ok := ptc.mutation.CreatedAt(); !ok {
|
||||
if passwordtoken.DefaultCreatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized passwordtoken.DefaultCreatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := passwordtoken.DefaultCreatedAt()
|
||||
ptc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import (
|
|||
// (default values, validators, hooks and policies) and stitches it
|
||||
// to their package variables.
|
||||
func init() {
|
||||
passwordtokenHooks := schema.PasswordToken{}.Hooks()
|
||||
passwordtoken.Hooks[0] = passwordtokenHooks[0]
|
||||
passwordtokenFields := schema.PasswordToken{}.Fields()
|
||||
_ = passwordtokenFields
|
||||
// passwordtokenDescHash is the schema descriptor for hash field.
|
||||
|
|
|
|||
|
|
@ -52,12 +52,18 @@ func (h *Admin) Routes(g *echo.Group) {
|
|||
// TODO: can we generate something we can loop instead?
|
||||
for _, n := range h.graph.Nodes {
|
||||
ng := entities.Group(fmt.Sprintf("/%s", strings.ToLower(n.Name)))
|
||||
ng.GET("", h.EntityList(n)).Name = routenames.AdminEntityList(n.Name)
|
||||
ng.POST("", h.EntityList(n)).Name = routenames.AdminEntityListSubmit(n.Name)
|
||||
ng.GET("/add", h.EntityAdd(n)).Name = routenames.AdminEntityAdd(n.Name)
|
||||
ng.POST("/add", h.EntityAddSubmit(n)).Name = routenames.AdminEntityAddSubmit(n.Name)
|
||||
//ng.GET("/:id/edit", h.EntityEdit(n), h.entityPluginMiddleware(n.Name)).Name = RouteNameEdit(n.Name)
|
||||
//ng.POST("/:id/edit", h.EntityEditSubmit(n), h.entityPluginMiddleware(n.Name)).Name = RouteNameEditSubmit(n.Name)
|
||||
ng.GET("", h.EntityList(n)).
|
||||
Name = routenames.AdminEntityList(n.Name)
|
||||
ng.POST("", h.EntityList(n)).
|
||||
Name = routenames.AdminEntityListSubmit(n.Name)
|
||||
ng.GET("/add", h.EntityAdd(n)).
|
||||
Name = routenames.AdminEntityAdd(n.Name)
|
||||
ng.POST("/add", h.EntityAddSubmit(n)).
|
||||
Name = routenames.AdminEntityAddSubmit(n.Name)
|
||||
ng.GET("/:id/edit", h.EntityEdit(n), h.middlewareEntityLoad(n)).
|
||||
Name = routenames.AdminEntityEdit(n.Name)
|
||||
ng.POST("/:id/edit", h.EntityEditSubmit(n), h.middlewareEntityLoad(n)).
|
||||
Name = routenames.AdminEntityEditSubmit(n.Name)
|
||||
ng.GET("/:id/delete", h.EntityDelete(n), h.middlewareEntityLoad(n)).
|
||||
Name = routenames.AdminEntityDelete(n.Name)
|
||||
ng.POST("/:id/delete", h.EntityDeleteSubmit(n), h.middlewareEntityLoad(n)).
|
||||
|
|
@ -74,11 +80,11 @@ func (h *Admin) middlewareEntityLoad(n *gen.Type) echo.MiddlewareFunc {
|
|||
return echo.NewHTTPError(http.StatusBadRequest, "invalid entity ID")
|
||||
}
|
||||
|
||||
err = h.admin.Get(ctx, n.Name, id)
|
||||
entity, err := h.admin.Get(ctx, n.Name, id)
|
||||
switch {
|
||||
case err == nil:
|
||||
ctx.Set(entityIDContextKey, id)
|
||||
//ctx.Set(entityContextKey, entityValues)
|
||||
ctx.Set(entityContextKey, map[string][]string(entity))
|
||||
return next(ctx)
|
||||
case ent.IsNotFound(err):
|
||||
return echo.NewHTTPError(http.StatusNotFound, "entity not found")
|
||||
|
|
@ -106,7 +112,7 @@ func (h *Admin) EntityList(n *gen.Type) echo.HandlerFunc {
|
|||
|
||||
func (h *Admin) EntityAdd(n *gen.Type) echo.HandlerFunc {
|
||||
return func(ctx echo.Context) error {
|
||||
return pages.AdminEntityForm(ctx, h.getEntitySchema(n), nil)
|
||||
return pages.AdminEntityForm(ctx, true, h.getEntitySchema(n), nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -127,20 +133,31 @@ func (h *Admin) EntityAddSubmit(n *gen.Type) echo.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
//func (h *Admin) EntityEdit(n *gen.Type) echo.HandlerFunc {
|
||||
// return func(ctx echo.Context) error {
|
||||
// v := ctx.Get(entityContextKey).(map[string][]string)
|
||||
// return pages.AdminEntityForm(ctx, h.getEntitySchema(n), v)
|
||||
// }
|
||||
//}
|
||||
func (h *Admin) EntityEdit(n *gen.Type) echo.HandlerFunc {
|
||||
return func(ctx echo.Context) error {
|
||||
v := ctx.Get(entityContextKey).(map[string][]string)
|
||||
return pages.AdminEntityForm(ctx, false, h.getEntitySchema(n), v)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Admin) EntityEditSubmit(n *gen.Type) echo.HandlerFunc {
|
||||
return func(ctx echo.Context) error {
|
||||
id := ctx.Get(entityIDContextKey).(int)
|
||||
err := h.admin.Update(ctx, n.Name, id)
|
||||
if err != nil {
|
||||
msg.Danger(ctx, err.Error())
|
||||
return h.EntityEdit(n)(ctx)
|
||||
}
|
||||
|
||||
msg.Success(ctx, fmt.Sprintf("Updated %s.", n.Name))
|
||||
|
||||
return redirect.
|
||||
New(ctx).
|
||||
Route(routenames.AdminEntityList(n.Name)).
|
||||
Go()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//func (h *Admin) EntityEditSubmit(p AdminEntityPlugin) echo.HandlerFunc {
|
||||
// return func(ctx echo.Context) error {
|
||||
// return nil
|
||||
// }
|
||||
//}
|
||||
//
|
||||
func (h *Admin) EntityDelete(n *gen.Type) echo.HandlerFunc {
|
||||
return func(ctx echo.Context) error {
|
||||
return pages.AdminEntityDelete(ctx, n.Name)
|
||||
|
|
|
|||
|
|
@ -39,9 +39,14 @@ func AdminEntityDelete(ctx echo.Context, entityTypeName string) error {
|
|||
return r.Render(layouts.Admin, form)
|
||||
}
|
||||
|
||||
func AdminEntityForm(ctx echo.Context, schema *load.Schema, values url.Values) error {
|
||||
func AdminEntityForm(ctx echo.Context, isNew bool, schema *load.Schema, values url.Values) error {
|
||||
r := ui.NewRequest(ctx)
|
||||
if isNew {
|
||||
r.Title = fmt.Sprintf("Add %s", schema.Name)
|
||||
} else {
|
||||
r.Title = fmt.Sprintf("Edit %s", schema.Name)
|
||||
}
|
||||
|
||||
nodes := make(Group, 0)
|
||||
|
||||
label := func(name string) string {
|
||||
|
|
@ -67,6 +72,10 @@ func AdminEntityForm(ctx echo.Context, schema *load.Schema, values url.Values) e
|
|||
|
||||
for _, f := range schema.Fields {
|
||||
// TODO cardinality?
|
||||
if !isNew && f.Immutable {
|
||||
continue
|
||||
}
|
||||
// TODO sensitive edits
|
||||
switch f.Info.Type {
|
||||
case field.TypeString:
|
||||
inputType := "text"
|
||||
|
|
@ -100,7 +109,7 @@ func AdminEntityForm(ctx echo.Context, schema *load.Schema, values url.Values) e
|
|||
nodes = append(nodes, Checkbox(CheckboxParams{
|
||||
Name: f.Name,
|
||||
Label: label(f.Name),
|
||||
Checked: getValue(f.Name) != "",
|
||||
Checked: getValue(f.Name) == "true",
|
||||
}))
|
||||
case field.TypeEnum:
|
||||
// TODO
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue