Update
This commit is contained in:
parent
9b5be193db
commit
6dfd8b29e7
@ -13,8 +13,6 @@ RUN bash scripts/db-push.sh
|
||||
|
||||
RUN go build -o /main main.go
|
||||
|
||||
RUN go build -o /create-user cli/create-user_gen.go
|
||||
|
||||
FROM alpine
|
||||
|
||||
ARG USER=default
|
||||
@ -31,7 +29,6 @@ USER $USER
|
||||
WORKDIR $HOME
|
||||
|
||||
COPY --from=build --chown=default:default /main ./main
|
||||
COPY --from=build --chown=default:default /create-user ./create-user
|
||||
COPY --from=build --chown=default:default /app/.env .env
|
||||
COPY --chown=default:default views/ ./views
|
||||
COPY --chown=default:default static/ ./static/
|
||||
|
||||
14
crud/tracing.go
Normal file
14
crud/tracing.go
Normal file
@ -0,0 +1,14 @@
|
||||
package crud
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Trace(object any) string {
|
||||
marshalled, err := json.Marshal(object)
|
||||
if err != nil {
|
||||
return fmt.Sprint(object)
|
||||
}
|
||||
return string(marshalled)
|
||||
}
|
||||
7
crud/util.go
Normal file
7
crud/util.go
Normal file
@ -0,0 +1,7 @@
|
||||
package crud
|
||||
|
||||
import "strings"
|
||||
|
||||
func FirstLetterToUpper(name string) string {
|
||||
return strings.ToUpper(name[:1]) + name[1:]
|
||||
}
|
||||
@ -26,7 +26,7 @@ type PersonStruct struct {
|
||||
func AddTablePrototype(e *Echo) {
|
||||
items := getPrototypeStructs()
|
||||
e.GET(tablePrototypePath, func(c Context) error {
|
||||
table := Table{
|
||||
table := GohtmlTable{
|
||||
Headers: []string{"Name", "Age", "Profession", "Member Since"},
|
||||
Rows: prototypeStructsToTableRows(items),
|
||||
EntityUrl: tablePrototypePath,
|
||||
@ -120,7 +120,7 @@ func ParseDateTime(since string) time.Time {
|
||||
}
|
||||
|
||||
func returnRenderTable(c Context, items []PersonStruct) error {
|
||||
table := Table{
|
||||
table := GohtmlTable{
|
||||
Headers: []string{"Name", "Age", "Profession", "Member Since"},
|
||||
Rows: prototypeStructsToTableRows(items),
|
||||
EntityUrl: tablePrototypePath,
|
||||
|
||||
@ -31,7 +31,7 @@ type Pagination struct {
|
||||
NextPage int
|
||||
}
|
||||
|
||||
type Table struct {
|
||||
type GohtmlTable struct {
|
||||
Headers []string
|
||||
Rows []TableRow
|
||||
EntityUrl string
|
||||
|
||||
@ -25,6 +25,7 @@ model user {
|
||||
model todo {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @default("")
|
||||
completed Boolean @default(false)
|
||||
user_id Int @default(0)
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @default(now()) @updatedAt
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
#!/bin/bash
|
||||
go run github.com/steebchen/prisma-client-go db push
|
||||
go run github.com/steebchen/prisma-client-go db push --skip-generate
|
||||
|
||||
@ -37,6 +37,7 @@ func (r *TodoRepository) Create(todo Todo) (int, error) {
|
||||
|
||||
"updated_at": time.Now(),
|
||||
"name": todo.Name,
|
||||
"completed": todo.Completed,
|
||||
"user_id": todo.UserId,
|
||||
}).
|
||||
Returning("id").
|
||||
@ -78,7 +79,7 @@ func (e TodoAlreadyExistsError) Error() string {
|
||||
|
||||
func (r *TodoRepository) getSelectColumns() []any {
|
||||
return []any{"id", "created_at", "updated_at",
|
||||
"name", "user_id",
|
||||
"name", "completed", "user_id",
|
||||
}
|
||||
}
|
||||
|
||||
@ -121,6 +122,7 @@ func (r *TodoRepository) rowToItem(rows pgx.Rows, rowId bool) (Todo, int, error)
|
||||
&item.CreatedAt,
|
||||
&item.UpdatedAt,
|
||||
&item.Name,
|
||||
&item.Completed,
|
||||
&item.UserId,
|
||||
)
|
||||
if err != nil {
|
||||
@ -132,6 +134,7 @@ func (r *TodoRepository) rowToItem(rows pgx.Rows, rowId bool) (Todo, int, error)
|
||||
&item.CreatedAt,
|
||||
&item.UpdatedAt,
|
||||
&item.Name,
|
||||
&item.Completed,
|
||||
&item.UserId,
|
||||
)
|
||||
if err != nil {
|
||||
@ -143,6 +146,7 @@ func (r *TodoRepository) rowToItem(rows pgx.Rows, rowId bool) (Todo, int, error)
|
||||
CreatedAt: item.CreatedAt,
|
||||
UpdatedAt: item.UpdatedAt,
|
||||
Name: item.Name,
|
||||
Completed: item.Completed,
|
||||
UserId: item.UserId,
|
||||
}, item.Count, nil
|
||||
}
|
||||
@ -154,6 +158,7 @@ func (r *TodoRepository) Update(userId int, todo Todo) error {
|
||||
|
||||
"updated_at": time.Now(),
|
||||
"name": todo.Name,
|
||||
"completed": todo.Completed,
|
||||
"user_id": todo.UserId,
|
||||
}).
|
||||
Where(goqu.Ex{
|
||||
@ -200,7 +205,8 @@ func (r *TodoRepository) Delete(userId int, id int) error {
|
||||
type TodoField string
|
||||
|
||||
const (
|
||||
TodoFieldName TodoField = "name"
|
||||
TodoFieldName TodoField = "name"
|
||||
TodoFieldCompleted TodoField = "completed"
|
||||
)
|
||||
|
||||
type TodoNameFilter struct {
|
||||
@ -208,6 +214,11 @@ type TodoNameFilter struct {
|
||||
Value string
|
||||
}
|
||||
|
||||
type TodoCompletedFilter struct {
|
||||
Active bool
|
||||
Value bool
|
||||
}
|
||||
|
||||
type TodoOrderDirection string
|
||||
|
||||
const (
|
||||
@ -227,6 +238,8 @@ type TodoPaginationParams struct {
|
||||
|
||||
NameFilter TodoNameFilter
|
||||
|
||||
CompletedFilter TodoCompletedFilter
|
||||
|
||||
References TodoReferences
|
||||
}
|
||||
|
||||
@ -296,6 +309,12 @@ func (r *TodoRepository) addPageFilters(params TodoPaginationParams, whereExpres
|
||||
})
|
||||
}
|
||||
|
||||
if params.CompletedFilter.Active {
|
||||
whereExpressions = append(whereExpressions, goqu.Ex{
|
||||
"completed": params.CompletedFilter.Value,
|
||||
})
|
||||
}
|
||||
|
||||
return whereExpressions
|
||||
}
|
||||
|
||||
@ -306,7 +325,3 @@ func (r *TodoRepository) jsonToString(jsonData any) string {
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func (r *TodoRepository) FirstLetterToUpper(name string) string {
|
||||
return strings.ToUpper(name[:1]) + name[1:]
|
||||
}
|
||||
|
||||
@ -57,6 +57,8 @@ func (i *TodoCrud) GetItem(c Context) error {
|
||||
Columns: []ItemDisplayColumn{
|
||||
|
||||
{Label: "Name", Value: item.Name, Type: ItemDisplayTypeText},
|
||||
|
||||
{Label: "Completed", Value: fmt.Sprint(item.Completed), Type: ItemDisplayTypeText},
|
||||
},
|
||||
SubItems: i.getSubItemDisplays(item, c),
|
||||
EditItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/", item.Id, "/edit", queryString),
|
||||
@ -80,7 +82,7 @@ func (i *TodoCrud) getSubItemDisplays(item Todo, c Context) []ItemDisplaySubItem
|
||||
|
||||
type TodoDisplay struct {
|
||||
IsTable bool
|
||||
Table Table
|
||||
Table GohtmlTable
|
||||
IsDisplay bool
|
||||
ItemDisplay ItemDisplay
|
||||
IsEdit bool
|
||||
@ -115,6 +117,8 @@ func (i *TodoCrud) CreateNewItemInputs(c Context) error {
|
||||
inputs := []EditItemInputs{
|
||||
|
||||
{Label: "Name", Value: "", Name: "Name", Type: InputTypeText, Options: []SelectInputOption{}},
|
||||
|
||||
{Label: "Completed", Value: "", Name: "Completed", Type: InputTypeBool, Options: []SelectInputOption{}},
|
||||
}
|
||||
|
||||
url := fmt.Sprint(i.GetEntityUrl(c), "?", c.QueryString())
|
||||
@ -140,6 +144,8 @@ func (i *TodoCrud) CreateItem(c Context) error {
|
||||
UserId: userId,
|
||||
|
||||
Name: c.FormValue("Name"),
|
||||
|
||||
Completed: ParseCheckboxWithDefault(c.FormValue("Completed"), false),
|
||||
}
|
||||
_, err := i.repo.Create(item)
|
||||
if err != nil {
|
||||
@ -158,6 +164,8 @@ func (i *TodoCrud) EditItem(c Context) error {
|
||||
inputs := []EditItemInputs{
|
||||
|
||||
{Label: "Name", Value: item.Name, Name: "Name", Type: InputTypeText, Options: []SelectInputOption{}},
|
||||
|
||||
{Label: "Completed", Value: fmt.Sprint(item.Completed), Name: "Completed", Type: InputTypeBool, Options: []SelectInputOption{}},
|
||||
}
|
||||
path := fmt.Sprint(i.GetEntityUrl(c), "/", item.Id)
|
||||
queryString := GetCurrentUrlQueryParams(c)
|
||||
@ -193,6 +201,8 @@ func (i *TodoCrud) UpdateItem(c Context) error {
|
||||
|
||||
item.Name = c.FormValue("Name")
|
||||
|
||||
item.Completed = ParseCheckboxWithDefault(c.FormValue("Completed"), false)
|
||||
|
||||
err = i.repo.Update(userId, item)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -236,7 +246,7 @@ func (i *TodoCrud) returnRenderTable(c Context, items []Todo, count int) error {
|
||||
return i.html.RenderComponent(c, "table", table)
|
||||
}
|
||||
|
||||
func (i *TodoCrud) itemsToTable(c Context, items []Todo, count int) Table {
|
||||
func (i *TodoCrud) itemsToTable(c Context, items []Todo, count int) GohtmlTable {
|
||||
filter := c.FormValue("filter")
|
||||
page := ParseIntWithDefault(c.FormValue("pageNumber"), 1)
|
||||
index := (page - 1) * 5
|
||||
@ -244,10 +254,12 @@ func (i *TodoCrud) itemsToTable(c Context, items []Todo, count int) Table {
|
||||
if itemEnd > count {
|
||||
itemEnd = count
|
||||
}
|
||||
return Table{
|
||||
return GohtmlTable{
|
||||
Headers: []string{
|
||||
|
||||
"Name",
|
||||
|
||||
"Completed",
|
||||
},
|
||||
Rows: i.structsToTableRows(c, items),
|
||||
EntityUrl: i.GetEntityUrl(c),
|
||||
@ -262,6 +274,8 @@ func (i *TodoCrud) itemsToTable(c Context, items []Todo, count int) Table {
|
||||
Options: []SelectInputOption{
|
||||
|
||||
{Label: "Name filter", Value: "Name", Selected: filter == "Name"},
|
||||
|
||||
{Label: "Completed filter", Value: "Completed", Selected: filter == "Completed"},
|
||||
},
|
||||
},
|
||||
Pagination: Pagination{
|
||||
@ -293,6 +307,8 @@ func (i *TodoCrud) structToRow(c Context, item Todo) TableRow {
|
||||
Columns: []TableColumn{
|
||||
|
||||
{Value: item.Name, Type: TableColumnTypeText},
|
||||
|
||||
{Value: fmt.Sprint(item.Completed), Type: TableColumnTypeText},
|
||||
},
|
||||
EntityUrl: i.GetEntityUrl(c),
|
||||
EditItemUrl: fmt.Sprint(i.GetEntityUrl(c), "/", item.Id, "/edit"),
|
||||
@ -324,6 +340,11 @@ func (i *TodoCrud) getPage(c Context) ([]Todo, int, error) {
|
||||
Value: filterValue,
|
||||
},
|
||||
|
||||
CompletedFilter: TodoCompletedFilter{
|
||||
Active: filter == "Completed",
|
||||
Value: ParseBoolWithDefault(filterValue, false),
|
||||
},
|
||||
|
||||
References: TodoReferences{
|
||||
UserId: userId,
|
||||
},
|
||||
|
||||
@ -11,15 +11,17 @@ import (
|
||||
type Todo struct {
|
||||
Id int `db:"id"`
|
||||
Name string `db:"name"`
|
||||
Completed bool `db:"completed"`
|
||||
UserId int `db:"user_id"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
func (s *Todo) String() string {
|
||||
func (s Todo) String() string {
|
||||
return fmt.Sprint("Todo{ ",
|
||||
"Id: ", s.Id, ", ",
|
||||
"Name: ", s.Name, ", ",
|
||||
"Completed: ", s.Completed, ", ",
|
||||
"UserId: ", s.UserId, ", ",
|
||||
"CreatedAt: ", s.CreatedAt, ", ",
|
||||
"UpdatedAt: ", s.UpdatedAt, ", ",
|
||||
|
||||
@ -309,10 +309,6 @@ func (r *UserRepository) jsonToString(jsonData any) string {
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func (r *UserRepository) FirstLetterToUpper(name string) string {
|
||||
return strings.ToUpper(name[:1]) + name[1:]
|
||||
}
|
||||
|
||||
func (u *UserRepository) DoesUserEmailExist(email string) (bool, error) {
|
||||
sql, args, _ := u.dialect.From("user").
|
||||
Prepared(true).
|
||||
|
||||
@ -16,7 +16,7 @@ type User struct {
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
func (s *User) String() string {
|
||||
func (s User) String() string {
|
||||
return fmt.Sprint("User{ ",
|
||||
"Id: ", s.Id, ", ",
|
||||
"Email: ", s.Email, ", ",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user