diff --git a/database/postgres/project.go b/database/postgres/project.go
index 04e25dc..f820690 100644
--- a/database/postgres/project.go
+++ b/database/postgres/project.go
@@ -7,6 +7,8 @@ import (
"github.com/gissleh/stufflog/internal/slerrors"
"github.com/gissleh/stufflog/models"
"github.com/jmoiron/sqlx"
+ "github.com/lib/pq"
+ "time"
)
type projectRepository struct {
@@ -14,17 +16,17 @@ type projectRepository struct {
}
func (r *projectRepository) Find(ctx context.Context, id string) (*models.Project, error) {
- res := models.Project{}
+ res := projectDBO{}
err := r.db.GetContext(ctx, &res, "SELECT * FROM project WHERE project_id=$1", id)
if err != nil {
if err == sql.ErrNoRows {
- return nil, slerrors.NotFound("Log")
+ return nil, slerrors.NotFound("Project")
}
return nil, err
}
- return &res, nil
+ return res.ToProject(), nil
}
func (r *projectRepository) List(ctx context.Context, filter models.ProjectFilter) ([]*models.Project, error) {
@@ -60,26 +62,35 @@ func (r *projectRepository) List(ctx context.Context, filter models.ProjectFilte
return nil, err
}
- res := make([]*models.Project, 0, 8)
+ res := make([]*projectDBO, 0, 8)
err = r.db.SelectContext(ctx, &res, query, args...)
if err != nil {
if err == sql.ErrNoRows {
- return res, nil
+ return []*models.Project{}, nil
}
return nil, err
}
- return res, nil
+ res2 := make([]*models.Project, len(res))
+ for i, v := range res {
+ res2[i] = v.ToProject()
+ }
+
+ return res2, nil
}
func (r *projectRepository) Insert(ctx context.Context, project models.Project) error {
+ if project.Tags == nil {
+ project.Tags = []string{}
+ }
+
_, err := r.db.NamedExecContext(ctx, `
INSERT INTO project(
- project_id, user_id, name, description, icon, active, created_time, start_time, end_time, subtract_amount, status_tag, favorite
+ project_id, user_id, name, description, icon, active, created_time, start_time, end_time, subtract_amount, status_tag, favorite, tags
) VALUES (
- :project_id, :user_id, :name, :description, :icon, :active, :created_time, :start_time, :end_time, :subtract_amount, :status_tag, :favorite
+ :project_id, :user_id, :name, :description, :icon, :active, :created_time, :start_time, :end_time, :subtract_amount, :status_tag, :favorite, :tags
)
- `, &project)
+ `, toProjectDBO(project))
if err != nil {
return err
}
@@ -88,6 +99,10 @@ func (r *projectRepository) Insert(ctx context.Context, project models.Project)
}
func (r *projectRepository) Update(ctx context.Context, project models.Project) error {
+ if project.Tags == nil {
+ project.Tags = []string{}
+ }
+
_, err := r.db.NamedExecContext(ctx, `
UPDATE project SET
name = :name,
@@ -98,9 +113,10 @@ func (r *projectRepository) Update(ctx context.Context, project models.Project)
end_time = :end_time,
subtract_amount = :subtract_amount,
status_tag = :status_tag,
- favorite = :favorite
+ favorite = :favorite,
+ tags = :tags
WHERE project_id=:project_id
- `, &project)
+ `, toProjectDBO(project))
if err != nil {
return err
}
@@ -124,3 +140,55 @@ func (r *projectRepository) Delete(ctx context.Context, project models.Project)
return nil
}
+
+type projectDBO struct {
+ ID string `json:"id" db:"project_id"`
+ UserID string `json:"-" db:"user_id"`
+ Name string `json:"name" db:"name"`
+ Description string `json:"description" db:"description"`
+ Icon string `json:"icon" db:"icon"`
+ Active bool `json:"active" db:"active"`
+ CreatedTime time.Time `json:"createdTime" db:"created_time"`
+ StartTime *time.Time `json:"startTime" db:"start_time"`
+ EndTime *time.Time `json:"endTime" db:"end_time"`
+ SubtractAmount int `json:"subtractAmount" db:"subtract_amount"`
+ StatusTag *string `json:"statusTag" db:"status_tag"`
+ Favorite bool `json:"favorite" db:"favorite"`
+ Tags pq.StringArray `json:"tags" db:"tags"`
+}
+
+func toProjectDBO(project models.Project) *projectDBO {
+ return &projectDBO{
+ ID: project.ID,
+ UserID: project.UserID,
+ Name: project.Name,
+ Description: project.Description,
+ Icon: project.Icon,
+ Active: project.Active,
+ CreatedTime: project.CreatedTime,
+ StartTime: project.StartTime,
+ EndTime: project.EndTime,
+ SubtractAmount: project.SubtractAmount,
+ StatusTag: project.StatusTag,
+ Favorite: project.Favorite,
+ Tags: project.Tags,
+ }
+}
+
+func (d *projectDBO) ToProject() *models.Project {
+ return &models.Project{
+ ID: d.ID,
+ UserID: d.UserID,
+ Name: d.Name,
+ Description: d.Description,
+ Icon: d.Icon,
+ Active: d.Active,
+ CreatedTime: d.CreatedTime,
+ StartTime: d.StartTime,
+ EndTime: d.EndTime,
+ SubtractAmount: d.SubtractAmount,
+ StatusTag: d.StatusTag,
+ Favorite: d.Favorite,
+ Tags: d.Tags,
+ }
+}
diff --git a/migrations/postgres/20210418164739_add_project_column_tags.sql b/migrations/postgres/20210418164739_add_project_column_tags.sql
new file mode 100644
index 0000000..cc0df2d
--- /dev/null
+++ b/migrations/postgres/20210418164739_add_project_column_tags.sql
@@ -0,0 +1,11 @@
+-- +goose Up
+-- +goose StatementBegin
+ALTER TABLE project
+ ADD COLUMN tags TEXT[] DEFAULT ARRAY[]::TEXT[];
+-- +goose StatementEnd
+
+-- +goose Down
+-- +goose StatementBegin
+ALTER TABLE project
+ DROP COLUMN tags;
+-- +goose StatementEnd
diff --git a/models/project.go b/models/project.go
index 1d5946d..894d84d 100644
--- a/models/project.go
+++ b/models/project.go
@@ -18,6 +18,7 @@ type Project struct {
SubtractAmount int `json:"subtractAmount" db:"subtract_amount"`
StatusTag *string `json:"statusTag" db:"status_tag"`
Favorite bool `json:"favorite" db:"favorite"`
+ Tags []string `json:"tags" db:"tags"`
}
func (project *Project) Update(update ProjectUpdate) {
@@ -62,6 +63,9 @@ func (project *Project) Update(update ProjectUpdate) {
if update.Favorite != nil {
project.Favorite = *update.Favorite
}
+ if update.SetTags != nil {
+ project.Tags = update.SetTags
+ }
if project.StatusTag != nil && project.Active {
project.StatusTag = nil
@@ -80,6 +84,7 @@ type ProjectUpdate struct {
SubtractAmount *int `json:"subtractAmount"`
StatusTag *string `json:"statusTag"`
ClearStatusTag bool `json:"clearStatusTag"`
+ SetTags []string `json:"setTags"`
Favorite *bool `json:"favorite"`
}
diff --git a/models/projectgroup.go b/models/projectgroup.go
new file mode 100644
index 0000000..b0a7fd8
--- /dev/null
+++ b/models/projectgroup.go
@@ -0,0 +1,30 @@
+package models
+
+import "context"
+
+type ProjectGroup struct {
+ ID string `json:"id" db:"id"`
+ UserID string `json:"-" db:"user_id"`
+ Name string `json:"name" db:"name"`
+ Abbreviation string `json:"abbreviation" db:"abbreviation"`
+ CategoryNames map[string]string `json:"categoryNames" db:"category_names"`
+}
+
+type ProjectGroupUpdate struct {
+ Name *string `json:"name"`
+ Abbreviation *string `json:"abbreviation"`
+ SetCategoryNames map[string]string `json:"setCategoryNames"`
+ ResetCategoryName *string `json:"resetCategoryName"`
+}
+
+type ProjectGroupFilter struct {
+ UserID string `json:"userId"`
+}
+
+type ProjectGroupRepository interface {
+ Find(ctx context.Context, id string) (*ProjectGroup, error)
+ List(ctx context.Context, filter ProjectGroupFilter) ([]*ProjectGroup, error)
+ Insert(ctx context.Context, group ProjectGroup) error
+ Update(ctx context.Context, group ProjectGroup) error
+ Delete(ctx context.Context, group ProjectGroup) error
+}
diff --git a/svelte-ui/src/components/ParentEntry.svelte b/svelte-ui/src/components/ParentEntry.svelte
index 637f855..5af3956 100644
--- a/svelte-ui/src/components/ParentEntry.svelte
+++ b/svelte-ui/src/components/ParentEntry.svelte
@@ -92,6 +92,7 @@ import TimeProgress from "./TimeProgress.svelte";