Skip to content

Commit

Permalink
Simple object deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
pelusa-v committed May 5, 2024
1 parent 55be710 commit 535e0cf
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 60 deletions.
1 change: 1 addition & 0 deletions src/pkg/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (admin *Admin) RegisterModel(model any) {
admin.registerModelObjectDetailPage(modelType)
admin.registerModelObjectCreatePage(modelType)
admin.registerModelObjectCreateEndpoint(modelType)
admin.registerModelObjectDeleteEndpoint(modelType)
}

func (admin *Admin) Configure(name string) {
Expand Down
8 changes: 8 additions & 0 deletions src/pkg/admin/registers.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,11 @@ func (admin *Admin) registerModelObjectCreateEndpoint(modelType reflect.Type) {
return dbModel.CreateObject(data)
})
}

func (admin *Admin) registerModelObjectDeleteEndpoint(modelType reflect.Type) {
dbModel := data.NewDbModel(modelType, admin.GormDB)
modelObjectDeleteRoute := fmt.Sprintf("/admin/%s/actions/delete/:pk", modelType.Name())
admin.Handler.RegisterDeleteEndpoint(modelObjectDeleteRoute, func(pk interface{}) error {
return dbModel.DeleteObject(pk)
})
}
39 changes: 36 additions & 3 deletions src/pkg/admin/templates/ModelDetail.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ <h2>Model: {{.Model}}</h2>
<tbody>
{{range .ModelObjects}}
<tr>
<td><a href="{{ .DetailURL}}">Go</a></td>
<td><a href="{{ .DetailURL}}">Edit</a></td>
<td><a href="{{ .DetailURL}}">Delete</a></td>
<td><a id="{{ .Pk}}-detail" href="{{ .DetailURL}}">Go</a></td>
<td><a id="{{ .Pk}}-update" href="{{ .DetailURL}}">Edit</a></td>
<td><a id="{{ .Pk}}-delete" href="#">Delete</a></td>
{{range .FieldsValues}}
<td>{{.}}</td>
{{end}}
Expand All @@ -36,4 +36,37 @@ <h2>Model: {{.Model}}</h2>
</div>
</div>
</body>

<script>

"{{range .ModelObjects}}"
document.getElementById("{{ .Pk}}-delete").addEventListener("click", (e) => {
e.preventDefault();

fetch("{{ .DeleteURL}}", {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
})
.then(response => {
console.log(response)
if(response.status >= 200) {
location.reload()
}
return response.json()
})
.catch(err => {
return err.json()
})
.then(json => {
console.log(json)
const errorMessage = document.getElementById('errorMessage');
errorMessage.textContent = json["error"]
errorMessage.classList.remove("hidden")
})
})
"{{end}}"
</script>

</html>
6 changes: 6 additions & 0 deletions src/pkg/data/db_model.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,9 @@ func (m *DbModel) CreateObject(newObject interface{}) error {
res := m.db.Create(newObject)
return res.Error
}

func (m *DbModel) DeleteObject(pk interface{}) error {
concreteObject := reflect.New(m.modelType).Interface()
res := m.db.Delete(concreteObject, pk)
return res.Error
}
75 changes: 35 additions & 40 deletions src/pkg/data/templates_actions.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,41 @@
package data

import (
"fmt"
"reflect"
)
// func (manager *TemplateManager) CreateModelObjectAction(objectType reflect.Type, objectData map[string]interface{}) {
// // Check if the type is a struct or a pointer to a struct
// if objectType.Kind() != reflect.Struct {
// if objectType.Kind() == reflect.Ptr && objectType.Elem().Kind() == reflect.Struct {
// objectType = objectType.Elem()
// } else {
// panic("provided type is not a struct and not a pointer to a struct")
// }
// }

func (manager *TemplateManager) CreateModelObjectAction(objectType reflect.Type, objectData map[string]interface{}) {
// Check if the type is a struct or a pointer to a struct
if objectType.Kind() != reflect.Struct {
if objectType.Kind() == reflect.Ptr && objectType.Elem().Kind() == reflect.Struct {
objectType = objectType.Elem()
} else {
panic("provided type is not a struct and not a pointer to a struct")
}
}
// // Create a new struct of the provided type
// newObject := reflect.New(objectType).Elem()

// Create a new struct of the provided type
newObject := reflect.New(objectType).Elem()
// // Iterate through the map and set field values
// for fieldName, value := range objectData {
// fieldVal := newObject.FieldByName(fieldName)
// if !fieldVal.IsValid() {
// fmt.Printf("No such field: %s in obj\n", fieldName)
// continue
// }
// if !fieldVal.CanSet() {
// fmt.Printf("Cannot set %s field value\n", fieldName)
// continue
// }

// Iterate through the map and set field values
for fieldName, value := range objectData {
fieldVal := newObject.FieldByName(fieldName)
if !fieldVal.IsValid() {
fmt.Printf("No such field: %s in obj\n", fieldName)
continue
}
if !fieldVal.CanSet() {
fmt.Printf("Cannot set %s field value\n", fieldName)
continue
}
// fieldValue := reflect.ValueOf(value)
// if fieldVal.Type() != fieldValue.Type() {
// // Types do not match, attempt to convert types
// if fieldValue.Type().ConvertibleTo(fieldVal.Type()) {
// fieldValue = fieldValue.Convert(fieldVal.Type())
// } else {
// fmt.Printf("Provided value type didn't match obj field type and could not be converted\n")
// continue
// }
// }

fieldValue := reflect.ValueOf(value)
if fieldVal.Type() != fieldValue.Type() {
// Types do not match, attempt to convert types
if fieldValue.Type().ConvertibleTo(fieldVal.Type()) {
fieldValue = fieldValue.Convert(fieldVal.Type())
} else {
fmt.Printf("Provided value type didn't match obj field type and could not be converted\n")
continue
}
}

fieldVal.Set(fieldValue)
}
}
// fieldVal.Set(fieldValue)
// }
// }
4 changes: 4 additions & 0 deletions src/pkg/data/templates_data.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ type ModelObjectCreatePageData struct {
}

type ModelObject struct {
Pk interface{}
Fields []reflect.StructField
FieldsValues []reflect.Value
DetailURL string
DeleteURL string
}

type Model struct {
Expand Down Expand Up @@ -133,5 +135,7 @@ func MapModelObject(o interface{}) ModelObject {
Fields: objectFields,
FieldsValues: objectFieldsValues,
DetailURL: fmt.Sprintf("/admin/%s/%v", objectValue.Type().Name(), objectValue.FieldByName(pkField.Name)),
DeleteURL: fmt.Sprintf("/admin/%s/actions/delete/%v", objectValue.Type().Name(), objectValue.FieldByName(pkField.Name)),
Pk: objectValue.FieldByName(pkField.Name),
}
}
3 changes: 2 additions & 1 deletion src/pkg/handlers/app_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ type AppHandler interface {
RegisterSimplePage(tmpl *template.Template, templateName string, route string, tmplDataFunc func() any)
RegisterPkPage(tmpl *template.Template, templateName string, route string, tmplDataFunc func(pk string) any)
RegisterStatic(fs fs.FS)
RegisterCreateEndpoint(route string, typeToCreate reflect.Type, actionCreateFunc func(data interface{}) error)
RegisterCreateEndpoint(route string, typeToCreate reflect.Type, actionFunc func(data interface{}) error)
RegisterDeleteEndpoint(route string, actionFunc func(pk interface{}) error)
// RegisterHomePage(tmpl *template.Template)
// RegisterModelDetailPage(modelType reflect.Type, tmpl *template.Template)
}
Expand Down
41 changes: 25 additions & 16 deletions src/pkg/handlers/fiber_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package handlers

import (
"bytes"
"fmt"
"html/template"
"io/fs"
"net/http"
Expand All @@ -20,7 +19,8 @@ type FiberHandler struct {

// Handle /admin/Product/1 route, (:id)
func (handler *FiberHandler) RegisterSimplePage(tmpl *template.Template, templateName string, route string, tmplDataFunc func() any) {
handler.App.Get(route, func(c *fiber.Ctx) error {

registerFiberEndpoint(route, GET, handler, func(c *fiber.Ctx) error {
var tmplOutput bytes.Buffer
// err := tmpl.Execute(&tmplOutput, tmplDataFunc())
err := tmpl.ExecuteTemplate(&tmplOutput, templateName, tmplDataFunc())
Expand All @@ -34,7 +34,8 @@ func (handler *FiberHandler) RegisterSimplePage(tmpl *template.Template, templat
}

func (handler *FiberHandler) RegisterPkPage(tmpl *template.Template, templateName string, route string, tmplDataFunc func(pk string) any) {
handler.App.Get(route, func(c *fiber.Ctx) error {

registerFiberEndpoint(route, GET, handler, func(c *fiber.Ctx) error {
pk := c.Params("pk")

var tmplOutput bytes.Buffer
Expand All @@ -48,43 +49,51 @@ func (handler *FiberHandler) RegisterPkPage(tmpl *template.Template, templateNam
})
}

func (handler *FiberHandler) RegisterCreateEndpoint(route string, typeToCreate reflect.Type, actionCreateFunc func(data interface{}) error) {

RegisterFiberEndpoint(route, POST, handler, func(c *fiber.Ctx) error {
// dataToCreate := reflect.New(typeToCreate).Elem()
// fmt.Println(dataToCreate)
// fmt.Println(string(c.Body()))
// if err := c.BodyParser(dataToCreate.Addr().Interface()); err != nil {
// panic(err)
// }
func (handler *FiberHandler) RegisterCreateEndpoint(route string, typeToCreate reflect.Type, actionFunc func(data interface{}) error) {

registerFiberEndpoint(route, POST, handler, func(c *fiber.Ctx) error {
dataToCreate, err := data.GetObjectInstanceFromBytes(c.Body(), typeToCreate)
if err != nil {
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Cannot parse JSON",
})
}
fmt.Println(dataToCreate)
// fmt.Println(dataToCreate)

err = actionCreateFunc(dataToCreate)
err = actionFunc(dataToCreate)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": err.Error(),
})
}

fmt.Println("Created...")
// fmt.Println("Created...")
return c.SendStatus(201)
})
}

func (handler *FiberHandler) RegisterDeleteEndpoint(route string, actionFunc func(pk interface{}) error) {

registerFiberEndpoint(route, DELETE, handler, func(c *fiber.Ctx) error {
pk := c.Params("pk")
err := actionFunc(pk)
if err != nil {
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": err.Error(),
})
}

return c.SendStatus(200)
})
}

func (handler *FiberHandler) RegisterStatic(fs fs.FS) {
handler.App.Use("/gorm-admin-statics", filesystem.New(filesystem.Config{
Root: http.FS(fs),
}))
}

func RegisterFiberEndpoint(route string, method RequestMethod, appHandler *FiberHandler, controller fiber.Handler) {
func registerFiberEndpoint(route string, method RequestMethod, appHandler *FiberHandler, controller fiber.Handler) {
switch method.Name {
case GET.Name:
appHandler.App.Get(route, controller)
Expand Down
3 changes: 3 additions & 0 deletions src/pkg/handlers/gin_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ func (handler *GinHandler) RegisterStatic(fs fs.FS) {

func (handler *GinHandler) RegisterCreateEndpoint(route string, typeToCreate reflect.Type, actionCreateFunc func(data interface{}) error) {
}

func (handler *GinHandler) RegisterDeleteEndpoint(route string, actionFunc func(pk interface{}) error) {
}
3 changes: 3 additions & 0 deletions src/pkg/handlers/http_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ func (handler *BuiltInHandler) RegisterStatic(fs fs.FS) {

func (handler *BuiltInHandler) RegisterCreateEndpoint(route string, typeToCreate reflect.Type, actionCreateFunc func(data interface{}) error) {
}

func (handler *BuiltInHandler) RegisterDeleteEndpoint(route string, actionFunc func(pk interface{}) error) {
}

0 comments on commit 535e0cf

Please sign in to comment.