d821d392/test/test-rest-crud_gen.go
1970-01-01 00:00:00 +00:00

401 lines
9.7 KiB
Go

package test
import (
"errors"
"fmt"
"github.com/google/uuid"
. "github.com/labstack/echo/v4"
"test/crud"
. "test/html_components"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
const TestPath = "/test"
type TestCrud struct {
e *Echo
repo *TestRepository
html *GoHtmlHandler
}
func NewTestCrud(e *Echo, repo *TestRepository, html *GoHtmlHandler) *TestCrud {
return &TestCrud{e: e, repo: repo, html: html}
}
func (i *TestCrud) AddRoutes() {
crud.Debug("Adding Test crud routes")
g := i.e.Group(TestPath)
g.GET("", i.GetItems)
g.GET("/:id", i.GetItem)
g.GET("/create", i.CreateNewItemInputs)
g.POST("", i.CreateItem)
g.GET("/:id/edit", i.EditItem)
g.PUT("/:id", i.UpdateItem)
g.DELETE("/:id", i.DeleteItem)
}
func (i *TestCrud) readItem(c Context) (Test, error) {
userId := c.Get("userId").(int)
id := ParseIntWithDefault(c.Param("id"), 1)
return i.repo.Read(userId, id)
}
func (i *TestCrud) GetItem(c Context) error {
item, err := i.readItem(c)
if err != nil {
return err
}
queryString := GetCurrentUrlQueryParams(c)
itemDisplay := ItemDisplay{
Columns: []ItemDisplayColumn{
{Label: "Name", Value: item.Name, Type: ItemDisplayTypeText},
{Label: "Checked", Value: fmt.Sprint(item.Checked), Type: ItemDisplayTypeText},
},
SubItems: i.getSubItemDisplays(item, c),
EditItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/", item.Id, "/edit", queryString),
DeleteItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/", item.Id, queryString),
DeletePushUrl: fmt.Sprint(i.GetEntityUrl(c), queryString),
HasImages: false,
BackUrl: fmt.Sprint(i.GetEntityUrl(c), queryString),
ItemId: item.Id,
}
return i.html.RenderPage(c, "test", TestDisplay{
IsDisplay: true,
ItemDisplay: itemDisplay,
})
}
func (i *TestCrud) getSubItemDisplays(item Test, c Context) []ItemDisplaySubItem {
var items []ItemDisplaySubItem
return items
}
type TestDisplay struct {
IsTable bool
Table Table
IsDisplay bool
ItemDisplay ItemDisplay
IsEdit bool
EditItem EditItem
}
func (i *TestCrud) GetItems(c Context) error {
page, count, err := i.getPage(c)
if err != nil {
return err
}
table := i.itemsToTable(c, page, count)
return i.html.RenderPage(c, "test", TestDisplay{
IsTable: true,
Table: table,
})
}
func (i *TestCrud) GetEntityUrl(c Context) string {
return TestPath
}
func (i *TestCrud) GetParentEntityUrl(c Context) string {
return ""
}
func (i *TestCrud) CreateNewItemInputs(c Context) error {
inputs := []EditItemInputs{
{Label: "Name", Value: "", Name: "Name", Type: InputTypeText, Options: []SelectInputOption{}},
{Label: "Checked", Value: "", Name: "Checked", Type: InputTypeBool, Options: []SelectInputOption{}},
}
url := fmt.Sprint(i.GetEntityUrl(c), "?", c.QueryString())
s := EditItem{
Id: "",
Title: "Create test",
Url: url,
CancelUrl: url,
IsCreate: true,
SubmitButtonLabel: "Create",
Inputs: inputs,
HasFileUpload: false,
}
return i.html.RenderPage(c, "test", TestDisplay{
IsEdit: true,
EditItem: s,
})
}
func (i *TestCrud) CreateItem(c Context) error {
userId := c.Get("userId").(int)
item := Test{
UserId: userId,
Name: c.FormValue("Name"),
Checked: ParseCheckboxWithDefault(c.FormValue("Checked"), false),
}
_, err := i.repo.Create(item)
if err != nil {
return err
}
return i.GetItems(c)
}
func (i *TestCrud) EditItem(c Context) error {
userId := c.Get("userId").(int)
id := ParseIntWithDefault(c.Param("id"), 1)
item, err := i.repo.Read(userId, id)
if err != nil {
return err
}
inputs := []EditItemInputs{
{Label: "Name", Value: item.Name, Name: "Name", Type: InputTypeText, Options: []SelectInputOption{}},
{Label: "Checked", Value: fmt.Sprint(item.Checked), Name: "Checked", Type: InputTypeBool, Options: []SelectInputOption{}},
}
path := fmt.Sprint(i.GetEntityUrl(c), "/", item.Id)
queryString := GetCurrentUrlQueryParams(c)
url := fmt.Sprint(path, queryString)
cancelUrl := url
if HasFromTableHeader(c) {
cancelUrl = fmt.Sprint(i.GetEntityUrl(c), queryString)
}
s := EditItem{
Id: fmt.Sprint(id),
Title: fmt.Sprint("Update test ", id),
Url: url,
CancelUrl: cancelUrl,
IsCreate: false,
SubmitButtonLabel: "Update",
Inputs: inputs,
HasFileUpload: false,
FromTable: HasFromTableHeader(c),
}
return i.html.RenderPage(c, "test", TestDisplay{
IsEdit: true,
EditItem: s,
})
}
func (i *TestCrud) UpdateItem(c Context) error {
userId := c.Get("userId").(int)
id := ParseIntWithDefault(c.Param("id"), 1)
item, err := i.repo.Read(userId, id)
if err != nil {
return err
}
item.Name = c.FormValue("Name")
item.Checked = ParseCheckboxWithDefault(c.FormValue("Checked"), false)
err = i.repo.Update(userId, item)
if err != nil {
return err
}
if HasFromTableHeader(c) {
return i.GetItems(c)
}
return i.GetItem(c)
}
func (i *TestCrud) DeleteItem(c Context) error {
userId := c.Get("userId").(int)
id := ParseIntWithDefault(c.Param("id"), 1)
err := i.repo.Delete(userId, id)
if err != nil {
return err
}
return i.GetItems(c)
}
func (i *TestCrud) parseDateTime(since string) time.Time {
t, err := time.Parse("2006-01-02T15:04", since)
if err != nil {
return time.Now()
}
return t
}
func (i *TestCrud) renderPage(c Context, repo *TestRepository) error {
page, count, err := i.getPage(c)
if err != nil {
return err
}
table := i.itemsToTable(c, page, count)
return i.html.RenderPage(c, "test", table)
}
func (i *TestCrud) returnRenderTable(c Context, items []Test, count int) error {
table := i.itemsToTable(c, items, count)
return i.html.RenderComponent(c, "table", table)
}
func (i *TestCrud) itemsToTable(c Context, items []Test, count int) Table {
filter := c.FormValue("filter")
page := ParseIntWithDefault(c.FormValue("pageNumber"), 1)
index := (page - 1) * 5
itemEnd := index + 5
if itemEnd > count {
itemEnd = count
}
return Table{
Headers: []string{
"Name",
"Checked",
},
Rows: i.structsToTableRows(c, items),
EntityUrl: i.GetEntityUrl(c),
CreateItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/create?", c.QueryString()),
OrderBy: string(i.getOrderBy(c)),
OrderDirection: string(i.getOrderDirection(c)),
FilterValue: c.FormValue("filterValue"),
FilterSelect: SelectInput{
Label: "Filter by",
Name: "filter",
HideLabel: true,
Options: []SelectInputOption{
{Label: "Name filter", Value: "Name", Selected: filter == "Name"},
{Label: "Checked filter", Value: "Checked", Selected: filter == "Checked"},
},
},
Pagination: Pagination{
CurrenItemStart: index + 1,
CurrentItemEnd: index + 10,
TotalNumberOfItems: count,
PreviousDisabled: index == 0,
NextDisabled: index+10 >= count,
Page: page,
PreviousPage: page - 1,
NextPage: page + 1,
},
ShowBack: false,
BackUrl: i.GetParentEntityUrl(c),
}
}
func (i *TestCrud) structsToTableRows(c Context, items []Test) []TableRow {
var rows []TableRow
for _, item := range items {
rows = append(rows, i.structToRow(c, item))
}
return rows
}
func (i *TestCrud) structToRow(c Context, item Test) TableRow {
return TableRow{
Id: fmt.Sprint(item.Id),
Columns: []TableColumn{
{Value: item.Name, Type: TableColumnTypeText},
{Value: fmt.Sprint(item.Checked), Type: TableColumnTypeText},
},
EntityUrl: i.GetEntityUrl(c),
EditItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/", item.Id, "/edit"),
DeleteItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/", item.Id),
}
}
func (i *TestCrud) formatDateRangeInputTimeStamp(time time.Time) string {
return time.Format("2006-01-02T15:04")
}
func (i *TestCrud) dateDisplay(time time.Time) string {
return time.Format("2006-01-02 15:04:05")
}
func (i *TestCrud) getPage(c Context) ([]Test, int, error) {
userId := c.Get("userId").(int)
filter := c.FormValue("filter")
filterValue := c.FormValue("filterValue")
page := ParseIntWithDefault(c.FormValue("pageNumber"), 1)
return i.repo.GetPage(TestPaginationParams{
RowId: (page - 1) * 10,
PageSize: 10,
OrderBy: i.getOrderBy(c),
OrderDirection: i.getOrderDirection(c),
NameFilter: TestNameFilter{
Active: filter == "Name",
Value: filterValue,
},
CheckedFilter: TestCheckedFilter{
Active: filter == "Checked",
Value: ParseBoolWithDefault(filterValue, false),
},
References: TestReferences{
UserId: userId,
},
})
}
func (i *TestCrud) getOrderBy(c Context) TestField {
orderBy := c.QueryParam("orderBy")
if orderBy == "" {
return TestFieldName
}
return TestField(strings.ToLower(orderBy))
}
func (i *TestCrud) getOrderDirection(c Context) TestOrderDirection {
orderDirection := c.QueryParam("orderDirection")
if orderDirection == "" {
return TestOrderDirectionAsc
}
return TestOrderDirection(orderDirection)
}
func (i *TestCrud) saveFileAndReturnFileName(c Context, name string, currentFilename string) string {
file, err := c.FormFile(name)
if errors.Is(err, http.ErrMissingFile) {
return currentFilename
}
if err != nil {
crud.Error("Failed to save file from input", name, "with error", err)
return currentFilename
}
src, err := file.Open()
if err != nil {
crud.Error("Failed to save file from input", name, "with error", err)
return currentFilename
}
defer src.Close()
err = os.MkdirAll("files", os.ModePerm)
if err != nil {
crud.Error("Failed to save file from input", name, "with error", err)
return currentFilename
}
extension := filepath.Ext(file.Filename)
filename := fmt.Sprint(uuid.New().String(), extension)
err = CreateFile("files/"+filename, src)
if err != nil {
crud.Error("Failed to save file from input", name, "with error", err)
return currentFilename
}
return filename
}