From efaa6cec26c3e77077e09e63d18243c2a09bef4c Mon Sep 17 00:00:00 2001 From: Denys Konovalov Date: Sun, 17 Mar 2024 22:40:09 +0100 Subject: [PATCH 01/19] set default board for new projects --- custom/conf/app.example.ini | 2 ++ docs/content/administration/config-cheat-sheet.en-us.md | 2 ++ models/project/board.go | 9 ++++++++- modules/setting/project.go | 2 ++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index b4b4f3a8a2be..7ca093ba7a9c 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1162,6 +1162,8 @@ LEVEL = Info ;; Default templates for project boards ;PROJECT_BOARD_BASIC_KANBAN_TYPE = To Do, In Progress, Done ;PROJECT_BOARD_BUG_TRIAGE_TYPE = Needs Triage, High Priority, Low Priority, Closed +;; Title of default project board in new empty project +;PROJECT_BOARD_DEFAULT = Uncategorized ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 04923acdcb9a..912bd2d21ab5 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -829,6 +829,8 @@ Default templates for project boards: - `PROJECT_BOARD_BASIC_KANBAN_TYPE`: **To Do, In Progress, Done** - `PROJECT_BOARD_BUG_TRIAGE_TYPE`: **Needs Triage, High Priority, Low Priority, Closed** +- `PROJECT_BOARD_DEFAULT`: **Uncategorized**: Title of default project board in new empty project + ## Issue and pull request attachments (`attachment`) - `ENABLED`: **true**: Whether issue and pull request attachments are enabled. diff --git a/models/project/board.go b/models/project/board.go index c0e6529880c3..a61594774abe 100644 --- a/models/project/board.go +++ b/models/project/board.go @@ -118,7 +118,14 @@ func createBoardsForProjectsType(ctx context.Context, project *Project) error { items = setting.Project.ProjectBoardBasicKanbanType case BoardTypeNone: - fallthrough + board := Board{ + CreatedUnix: timeutil.TimeStampNow(), + CreatorID: project.CreatorID, + Title: setting.Project.ProjectBoardDefault, + ProjectID: project.ID, + Default: true, + } + return db.Insert(ctx, board) default: return nil } diff --git a/modules/setting/project.go b/modules/setting/project.go index 803e933b887e..d0f170eca507 100644 --- a/modules/setting/project.go +++ b/modules/setting/project.go @@ -8,9 +8,11 @@ var ( Project = struct { ProjectBoardBasicKanbanType []string ProjectBoardBugTriageType []string + ProjectBoardDefault string }{ ProjectBoardBasicKanbanType: []string{"To Do", "In Progress", "Done"}, ProjectBoardBugTriageType: []string{"Needs Triage", "High Priority", "Low Priority", "Closed"}, + ProjectBoardDefault: "Uncategorized", } ) From b82fdbdfd793ec9d90eb58a54383cffa622d9288 Mon Sep 17 00:00:00 2001 From: Denys Konovalov Date: Mon, 18 Mar 2024 09:42:27 +0100 Subject: [PATCH 02/19] rename uncategorized to backlog --- custom/conf/app.example.ini | 2 +- docs/content/administration/config-cheat-sheet.en-us.md | 2 +- modules/setting/project.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 7ca093ba7a9c..166ea557b0cc 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1163,7 +1163,7 @@ LEVEL = Info ;PROJECT_BOARD_BASIC_KANBAN_TYPE = To Do, In Progress, Done ;PROJECT_BOARD_BUG_TRIAGE_TYPE = Needs Triage, High Priority, Low Priority, Closed ;; Title of default project board in new empty project -;PROJECT_BOARD_DEFAULT = Uncategorized +;PROJECT_BOARD_DEFAULT = Backlog ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 912bd2d21ab5..73e4d37fbf59 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -829,7 +829,7 @@ Default templates for project boards: - `PROJECT_BOARD_BASIC_KANBAN_TYPE`: **To Do, In Progress, Done** - `PROJECT_BOARD_BUG_TRIAGE_TYPE`: **Needs Triage, High Priority, Low Priority, Closed** -- `PROJECT_BOARD_DEFAULT`: **Uncategorized**: Title of default project board in new empty project +- `PROJECT_BOARD_DEFAULT`: **Backlog**: Title of default project board in new empty project ## Issue and pull request attachments (`attachment`) diff --git a/modules/setting/project.go b/modules/setting/project.go index d0f170eca507..101499ec8961 100644 --- a/modules/setting/project.go +++ b/modules/setting/project.go @@ -12,7 +12,7 @@ var ( }{ ProjectBoardBasicKanbanType: []string{"To Do", "In Progress", "Done"}, ProjectBoardBugTriageType: []string{"Needs Triage", "High Priority", "Low Priority", "Closed"}, - ProjectBoardDefault: "Uncategorized", + ProjectBoardDefault: "Backlog", } ) From 156991031a809850da794b0234373dca5104acec Mon Sep 17 00:00:00 2001 From: Denys Konovalov Date: Mon, 18 Mar 2024 22:41:56 +0100 Subject: [PATCH 03/19] remove unchangable pseudo-board, remove setting --- custom/conf/app.example.ini | 2 - .../config-cheat-sheet.en-us.md | 2 - models/issues/issue_project.go | 19 ++--- models/migrations/migrations.go | 2 + models/migrations/v1_22/v292.go | 72 +++++++++++++++++++ models/project/board.go | 21 +++--- modules/setting/project.go | 2 - options/locale/locale_en-US.ini | 2 - routers/web/org/projects.go | 15 ---- routers/web/repo/projects.go | 15 ---- routers/web/web.go | 2 - templates/projects/view.tmpl | 15 ++-- web_src/js/features/repo-projects.js | 1 - 13 files changed, 93 insertions(+), 77 deletions(-) create mode 100644 models/migrations/v1_22/v292.go diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 166ea557b0cc..b4b4f3a8a2be 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1162,8 +1162,6 @@ LEVEL = Info ;; Default templates for project boards ;PROJECT_BOARD_BASIC_KANBAN_TYPE = To Do, In Progress, Done ;PROJECT_BOARD_BUG_TRIAGE_TYPE = Needs Triage, High Priority, Low Priority, Closed -;; Title of default project board in new empty project -;PROJECT_BOARD_DEFAULT = Backlog ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 73e4d37fbf59..04923acdcb9a 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -829,8 +829,6 @@ Default templates for project boards: - `PROJECT_BOARD_BASIC_KANBAN_TYPE`: **To Do, In Progress, Done** - `PROJECT_BOARD_BUG_TRIAGE_TYPE`: **Needs Triage, High Priority, Low Priority, Closed** -- `PROJECT_BOARD_DEFAULT`: **Backlog**: Title of default project board in new empty project - ## Issue and pull request attachments (`attachment`) - `ENABLED`: **true**: Whether issue and pull request attachments are enabled. diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go index cc7ffb356a6c..907a5a17b9f2 100644 --- a/models/issues/issue_project.go +++ b/models/issues/issue_project.go @@ -49,18 +49,13 @@ func (issue *Issue) ProjectBoardID(ctx context.Context) int64 { // LoadIssuesFromBoard load issues assigned to this board func LoadIssuesFromBoard(ctx context.Context, b *project_model.Board) (IssueList, error) { - issueList := make(IssueList, 0, 10) - - if b.ID > 0 { - issues, err := Issues(ctx, &IssuesOptions{ - ProjectBoardID: b.ID, - ProjectID: b.ProjectID, - SortType: "project-column-sorting", - }) - if err != nil { - return nil, err - } - issueList = issues + issueList, err := Issues(ctx, &IssuesOptions{ + ProjectBoardID: b.ID, + ProjectID: b.ProjectID, + SortType: "project-column-sorting", + }) + if err != nil { + return nil, err } if b.Default { diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 87fddefb8824..b6b44d8b39c6 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -568,6 +568,8 @@ var migrations = []Migration{ NewMigration("Add PayloadVersion to HookTask", v1_22.AddPayloadVersionToHookTaskTable), // v291 -> v292 NewMigration("Add Index to attachment.comment_id", v1_22.AddCommentIDIndexofAttachment), + // v292 -> v293 + NewMigration("Add default column to projects without one", v1_22.AddDefaultProjectColumn), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_22/v292.go b/models/migrations/v1_22/v292.go new file mode 100644 index 000000000000..ab3beac6a57a --- /dev/null +++ b/models/migrations/v1_22/v292.go @@ -0,0 +1,72 @@ +// Copyright 2024 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "code.gitea.io/gitea/models/project" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +func AddDefaultProjectColumn(x *xorm.Engine) error { + sess := x.NewSession() + defer sess.Close() + + if err := sess.Begin(); err != nil { + return err + } + + limit := setting.Database.IterateBufferSize + if limit <= 0 { + limit = 50 + } + + start := 0 + + for { + var projects []*project.Project + if err := sess.Select("id, creator_id").Limit(limit, start).Find(&projects); err != nil { + return err + } + + if len(projects) == 0 { + break + } + start += len(projects) + + for _, p := range projects { + var board project.Board + exist, err := sess.Where("project_id=? AND `default`=?", p.ID, true).Get(&board) + if err != nil { + return err + } + + if !exist { + b := project.Board{ + CreatedUnix: timeutil.TimeStampNow(), + CreatorID: p.CreatorID, + Title: "Backlog", + ProjectID: p.ID, + Default: true, + } + if _, err := sess.Insert(b); err != nil { + return err + } + } + } + + if start%1000 == 0 { + if err := sess.Commit(); err != nil { + return err + } + if err := sess.Begin(); err != nil { + return err + } + } + } + + return sess.Commit() +} diff --git a/models/project/board.go b/models/project/board.go index a61594774abe..d0184ef63b25 100644 --- a/models/project/board.go +++ b/models/project/board.go @@ -121,7 +121,7 @@ func createBoardsForProjectsType(ctx context.Context, project *Project) error { board := Board{ CreatedUnix: timeutil.TimeStampNow(), CreatorID: project.CreatorID, - Title: setting.Project.ProjectBoardDefault, + Title: "Backlog", ProjectID: project.ID, Default: true, } @@ -183,6 +183,10 @@ func deleteBoardByID(ctx context.Context, boardID int64) error { return err } + if board.Default { + return fmt.Errorf("deleteBoardByID: cannot delete default board") + } + if err = board.removeIssues(ctx); err != nil { return err } @@ -235,7 +239,6 @@ func UpdateBoard(ctx context.Context, board *Board) error { } // GetBoards fetches all boards related to a project -// if no default board set, first board is a temporary "Uncategorized" board func (p *Project) GetBoards(ctx context.Context) (BoardList, error) { boards := make([]*Board, 0, 5) @@ -262,16 +265,10 @@ func (p *Project) getDefaultBoard(ctx context.Context) (*Board, error) { return &board, nil } - // represents a board for issues not assigned to one - return &Board{ - ProjectID: p.ID, - Title: "Uncategorized", - Default: true, - }, nil + return nil, fmt.Errorf("getDefaultBoard: no default board found") } // SetDefaultBoard represents a board for issues not assigned to one -// if boardID is 0 unset default func SetDefaultBoard(ctx context.Context, projectID, boardID int64) error { _, err := db.GetEngine(ctx).Where(builder.Eq{ "project_id": projectID, @@ -281,10 +278,8 @@ func SetDefaultBoard(ctx context.Context, projectID, boardID int64) error { return err } - if boardID > 0 { - _, err = db.GetEngine(ctx).ID(boardID).Where(builder.Eq{"project_id": projectID}). - Cols("`default`").Update(&Board{Default: true}) - } + _, err = db.GetEngine(ctx).ID(boardID).Where(builder.Eq{"project_id": projectID}). + Cols("`default`").Update(&Board{Default: true}) return err } diff --git a/modules/setting/project.go b/modules/setting/project.go index 101499ec8961..803e933b887e 100644 --- a/modules/setting/project.go +++ b/modules/setting/project.go @@ -8,11 +8,9 @@ var ( Project = struct { ProjectBoardBasicKanbanType []string ProjectBoardBugTriageType []string - ProjectBoardDefault string }{ ProjectBoardBasicKanbanType: []string{"To Do", "In Progress", "Done"}, ProjectBoardBugTriageType: []string{"Needs Triage", "High Priority", "Low Priority", "Closed"}, - ProjectBoardDefault: "Backlog", } ) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 6622a25efd3b..9841774f1088 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1397,8 +1397,6 @@ projects.column.new_submit = "Create Column" projects.column.new = "New Column" projects.column.set_default = "Set Default" projects.column.set_default_desc = "Set this column as default for uncategorized issues and pulls" -projects.column.unset_default = "Unset Default" -projects.column.unset_default_desc = "Unset this column as default" projects.column.delete = "Delete Column" projects.column.deletion_desc = "Deleting a project column moves all related issues to 'Uncategorized'. Continue?" projects.column.color = "Color" diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go index 928676a52b53..fe33b72577ae 100644 --- a/routers/web/org/projects.go +++ b/routers/web/org/projects.go @@ -636,21 +636,6 @@ func SetDefaultProjectBoard(ctx *context.Context) { ctx.JSONOK() } -// UnsetDefaultProjectBoard unset default board for uncategorized issues/pulls -func UnsetDefaultProjectBoard(ctx *context.Context) { - project, _ := CheckProjectBoardChangePermissions(ctx) - if ctx.Written() { - return - } - - if err := project_model.SetDefaultBoard(ctx, project.ID, 0); err != nil { - ctx.ServerError("SetDefaultBoard", err) - return - } - - ctx.JSONOK() -} - // MoveIssues moves or keeps issues in a column and sorts them inside that column func MoveIssues(ctx *context.Context) { if ctx.Doer == nil { diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go index 2cba5c0970b7..7839e6e2a465 100644 --- a/routers/web/repo/projects.go +++ b/routers/web/repo/projects.go @@ -583,21 +583,6 @@ func SetDefaultProjectBoard(ctx *context.Context) { ctx.JSONOK() } -// UnSetDefaultProjectBoard unset default board for uncategorized issues/pulls -func UnSetDefaultProjectBoard(ctx *context.Context) { - project, _ := checkProjectBoardChangePermissions(ctx) - if ctx.Written() { - return - } - - if err := project_model.SetDefaultBoard(ctx, project.ID, 0); err != nil { - ctx.ServerError("SetDefaultBoard", err) - return - } - - ctx.JSONOK() -} - // MoveIssues moves or keeps issues in a column and sorts them inside that column func MoveIssues(ctx *context.Context) { if ctx.Doer == nil { diff --git a/routers/web/web.go b/routers/web/web.go index fc1432873f0d..e28deb19c818 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -1008,7 +1008,6 @@ func registerRoutes(m *web.Route) { m.Put("", web.Bind(forms.EditProjectBoardForm{}), org.EditProjectBoard) m.Delete("", org.DeleteProjectBoard) m.Post("/default", org.SetDefaultProjectBoard) - m.Post("/unsetdefault", org.UnsetDefaultProjectBoard) m.Post("/move", org.MoveIssues) }) @@ -1348,7 +1347,6 @@ func registerRoutes(m *web.Route) { m.Put("", web.Bind(forms.EditProjectBoardForm{}), repo.EditProjectBoard) m.Delete("", repo.DeleteProjectBoard) m.Post("/default", repo.SetDefaultProjectBoard) - m.Post("/unsetdefault", repo.UnSetDefaultProjectBoard) m.Post("/move", repo.MoveIssues) }) diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index a6e84024bc43..56b5b4f9cc1b 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -74,7 +74,7 @@ {{.Title}} - {{if and $canWriteProject (ne .ID 0)}} + {{if $canWriteProject}}