diff --git a/backend/db/main.go b/backend/db/main.go index 12c4550..c20cd46 100644 --- a/backend/db/main.go +++ b/backend/db/main.go @@ -6,6 +6,8 @@ import ( var db *sql.DB +const DB_VERSION = 1 + func InitDB(driver string, connStr string) error { var err error db, err = sql.Open(driver, connStr) @@ -14,16 +16,13 @@ func InitDB(driver string, connStr string) error { } _, err = db.Exec(` + CREATE TABLE IF NOT EXISTS schema_version ( + version INTEGER PRIMARY KEY, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); CREATE TABLE IF NOT EXISTS projects ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT - ); - CREATE TABLE IF NOT EXISTS lists ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - project_id INTEGER, - title TEXT, - color TEXT, - FOREIGN KEY(project_id) REFERENCES projects(id) ); CREATE TABLE IF NOT EXISTS cards ( id INTEGER PRIMARY KEY AUTOINCREMENT, @@ -61,13 +60,47 @@ func InitDB(driver string, connStr string) error { primary_tag_id INTEGER, secondary_tag_id INTEGER, title TEXT, + sort_tag_id INTEGER, + sort_direction INTEGER, FOREIGN KEY(project_id) REFERENCES projects(id), FOREIGN KEY(primary_tag_id) REFERENCES tags(id), FOREIGN KEY(secondary_tag_id) REFERENCES tags(id) ); - `) + + INSERT INTO schema_version (version) + SELECT ? WHERE NOT EXISTS (SELECT 1 FROM schema_version); + `, DB_VERSION) + if err != nil { return err } + + return updateDB() +} + +func updateDB() error { + + var currentVersion int + + err := db.QueryRow("SELECT MAX(version) FROM schema_version").Scan(¤tVersion) + if err != nil { + return err + } + + if currentVersion < 2 { + _, err := db.Exec(` + ALTER TABLE views + ADD COLUMN sort_tag_id INTEGER; + ALTER TABLE views + ADD COLUMN sort_direction INTEGER; + + INSERT INTO schema_version (version) + SELECT ? WHERE NOT EXISTS (SELECT 1 FROM schema_version WHERE version = ?); + `, 2, 2) + if err != nil { + return err + } + } + return nil } diff --git a/backend/db/views.go b/backend/db/views.go index 2e7c1fe..d400ad2 100644 --- a/backend/db/views.go +++ b/backend/db/views.go @@ -3,7 +3,7 @@ package db import "git.bhasher.com/bhasher/focus/backend/types" func CreateView(v types.View) (int, error) { - res, err := db.Exec("INSERT INTO views (project_id, primary_tag_id, secondary_tag_id, title) VALUES (?, ?, ?, ?)", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title) + res, err := db.Exec("INSERT INTO views (project_id, primary_tag_id, secondary_tag_id, title, sort_tag_id, sort_direction) VALUES (?, ?, ?, ?, ?, ?)", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.SortTagID, v.SortDirection) if err != nil { return 0, err } @@ -26,7 +26,7 @@ func GetProjectViews(projectID int) ([]types.View, error) { var views []types.View for rows.Next() { var v types.View - if err := rows.Scan(&v.ID, &v.ProjectID, &v.PrimaryTagID, &v.SecondaryTagID, &v.Title); err != nil { + if err := rows.Scan(&v.ID, &v.ProjectID, &v.PrimaryTagID, &v.SecondaryTagID, &v.Title, &v.SortTagID, &v.SortDirection); err != nil { return nil, err } @@ -52,13 +52,13 @@ func GetView(id int) (*types.View, error) { } var v types.View - rows.Scan(&v.ID, &v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title) + rows.Scan(&v.ID, &v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.SortTagID, v.SortDirection) return &v, nil } func UpdateView(v types.View) (int64, error) { - res, err := db.Exec("UPDATE views SET project_id = ?, primary_tag_id = ?, secondary_tag_id = ?, title = ? WHERE id = ?", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.ID) + res, err := db.Exec("UPDATE views SET project_id = ?, primary_tag_id = ?, secondary_tag_id = ?, title = ?, sort_tag_id = ?, sort_direction = ? WHERE id = ?", v.ProjectID, v.PrimaryTagID, v.SecondaryTagID, v.Title, v.SortTagID, v.SortDirection, v.ID) if err != nil { return 0, err } diff --git a/backend/types/cardtag.go b/backend/types/cardtag.go index 49fc7d6..7fac1de 100644 --- a/backend/types/cardtag.go +++ b/backend/types/cardtag.go @@ -1,17 +1,17 @@ package types type CardTag struct { - CardID int `json:"card_id"` - TagID int `json:"tag_id"` - OptionID int `json:"option_id"` - Value string `json:"value"` + CardID int `json:"card_id"` + TagID int `json:"tag_id"` + OptionID *int `json:"option_id"` + Value *string `json:"value"` } type FullCardTag struct { - CardID int `json:"card_id"` - TagID int `json:"tag_id"` - TagTitle string `json:"tag_title"` - TagType int `json:"tag_type"` - OptionID int `json:"option_id"` - Value string `json:"value"` + CardID int `json:"card_id"` + TagID int `json:"tag_id"` + TagTitle string `json:"tag_title"` + TagType int `json:"tag_type"` + OptionID *int `json:"option_id"` + Value *string `json:"value"` } diff --git a/backend/types/list.go b/backend/types/list.go deleted file mode 100644 index 4c93005..0000000 --- a/backend/types/list.go +++ /dev/null @@ -1,8 +0,0 @@ -package types - -type List struct { - ID int `json:"id"` - ProjectID int `json:"project_id"` - Title string `json:"title"` - Color string `json:"color"` -} diff --git a/backend/types/view.go b/backend/types/view.go index ec966de..851d6cd 100644 --- a/backend/types/view.go +++ b/backend/types/view.go @@ -1,9 +1,11 @@ package types type View struct { - ID int `json:"id"` - ProjectID int `json:"project_id"` - PrimaryTagID int `json:"primary_tag_id"` - SecondaryTagID int `json:"secondary_tag_id"` - Title string `json:"title"` + ID int `json:"id"` + ProjectID int `json:"project_id"` + Title string `json:"title"` + PrimaryTagID *int `json:"primary_tag_id"` + SecondaryTagID *int `json:"secondary_tag_id"` + SortTagID *int `json:"sort_tag_id"` + SortDirection *string `json:"sort_direction"` } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 441383d..c623709 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,7 +15,6 @@ "devDependencies": { "@playwright/test": "^1.28.1", "@sveltejs/adapter-auto": "^3.0.0", - "@sveltejs/adapter-static": "^3.0.1", "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "@types/eslint": "8.56.0", @@ -836,15 +835,6 @@ "@sveltejs/kit": "^2.0.0" } }, - "node_modules/@sveltejs/adapter-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz", - "integrity": "sha512-6lMvf7xYEJ+oGeR5L8DFJJrowkefTK6ZgA4JiMqoClMkKq0s6yvsd3FZfCFvX1fQ0tpCD7fkuRVHsnUVgsHyNg==", - "dev": true, - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, "node_modules/@sveltejs/kit": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.0.6.tgz", diff --git a/frontend/src/api/cards.ts b/frontend/src/api/cards.ts index 105969e..aeb8387 100644 --- a/frontend/src/api/cards.ts +++ b/frontend/src/api/cards.ts @@ -60,8 +60,8 @@ export async function deleteCardApi(cardID: number): Promise { export async function createCardTagApi( cardId: number, tagId: number, - optionId: number, - value: string + optionId: number | null, + value: string | null ): Promise { const response = await api.post(`/v1/cards/${cardId}/tags/${tagId}`, { option_id: optionId, @@ -76,15 +76,24 @@ export async function createCardTagApi( return true; } +export async function deleteCardTagApi(cardID: number, tagID: number): Promise { + const response = await api.delete(`/v1/cards/${cardID}/tags/${tagID}`); + + if (response.status !== status.NoContent) { + processError(response, 'Failed to delete tag'); + return Promise.reject(); + } +} + export async function updateCardTagApi( cardID: number, tagID: number, - option_id: number, - value: string + option_id: number | null, + value: string | null ): Promise { const response = await api.put(`/v1/cards/${cardID}/tags/${tagID}`, { - option_id: option_id, - value: value + option_id: option_id == -1 ? null : option_id, + value: value == '' ? null : value }); if (response.status !== status.NoContent) { diff --git a/frontend/src/components/project/card/card.svelte b/frontend/src/components/project/card/card.svelte index 155661e..18fe130 100644 --- a/frontend/src/components/project/card/card.svelte +++ b/frontend/src/components/project/card/card.svelte @@ -24,7 +24,7 @@ {#if card.tags}
{#each card.tags as tag} - {#if tag.option_id && tag.option_id !== -1} + {#if tag.option_id} {#if $projectTags[tag.tag_id]} {$projectTags[tag.tag_id]?.options.find((o) => o.id == tag.option_id)?.value} @@ -39,7 +39,7 @@ -
diff --git a/frontend/src/components/project/card/modal_tag/select_tags.svelte b/frontend/src/components/project/card/modal_tag/select_tags.svelte index a9b0c95..6fcff9a 100644 --- a/frontend/src/components/project/card/modal_tag/select_tags.svelte +++ b/frontend/src/components/project/card/modal_tag/select_tags.svelte @@ -1,4 +1,5 @@ diff --git a/frontend/src/components/project/header.svelte b/frontend/src/components/project/header.svelte index ffa11d4..000e3d6 100644 --- a/frontend/src/components/project/header.svelte +++ b/frontend/src/components/project/header.svelte @@ -1,5 +1,4 @@