diff --git a/routers/api/v1/org/project.go b/routers/api/v1/org/project.go index a687f51d9b..065752b843 100644 --- a/routers/api/v1/org/project.go +++ b/routers/api/v1/org/project.go @@ -10,11 +10,11 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" - attachment_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/optional" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/convert" ) // CreateProject creates a new project @@ -41,28 +41,7 @@ func CreateProject(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, project) -} - -// ChangeProjectStatus updates the status of a project between "open" and "close" -func ChangeProjectStatus(ctx *context.APIContext) { - var toClose bool - switch ctx.PathParam(":action") { - case "open": - toClose = false - case "close": - toClose = true - default: - ctx.NotFound("ChangeProjectStatus", nil) - return - } - id := ctx.PathParamInt64(":id") - - if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, 0, id, toClose); err != nil { - ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err) - return - } - ctx.JSON(http.StatusOK, map[string]any{"message": "project status updated successfully"}) + ctx.JSON(http.StatusCreated, convert.ToProject(ctx, project)) } // Projects renders the home page of projects @@ -90,7 +69,7 @@ func GetProjects(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, projects) + ctx.JSON(http.StatusOK, convert.ToProjects(ctx, projects)) } // TODO: Send issues as well @@ -118,55 +97,20 @@ func GetProject(ctx *context.APIContext) { return } - if project.CardType != project_model.CardTypeTextOnly { - issuesAttachmentMap := make(map[int64][]*attachment_model.Attachment) - for _, issuesList := range issuesMap { - for _, issue := range issuesList { - if issueAttachment, err := attachment_model.GetAttachmentsByIssueIDImagesLatest(ctx, issue.ID); err == nil { - issuesAttachmentMap[issue.ID] = issueAttachment - } - } - } - ctx.Data["issuesAttachmentMap"] = issuesAttachmentMap - } - - linkedPrsMap := make(map[int64][]*issues_model.Issue) - for _, issuesList := range issuesMap { - for _, issue := range issuesList { - var referencedIDs []int64 - for _, comment := range issue.Comments { - if comment.RefIssueID != 0 && comment.RefIsPull { - referencedIDs = append(referencedIDs, comment.RefIssueID) - } - } - - if len(referencedIDs) > 0 { - if linkedPrs, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{ - IssueIDs: referencedIDs, - IsPull: optional.Some(true), - }); err == nil { - linkedPrsMap[issue.ID] = linkedPrs - } - } - } - } - - issues := make(map[int64][]*issues_model.Issue) + issues := issues_model.IssueList{} for _, column := range columns { if empty := issuesMap[column.ID]; len(empty) == 0 { continue } - issues[column.ID] = issuesMap[column.ID] - + issues = append(issues, issuesMap[column.ID]...) } - data := map[string]any{ - "project": project, - "columns": columns, - } - - ctx.JSON(http.StatusOK, data) + ctx.JSON(http.StatusOK, map[string]any{ + "project": convert.ToProject(ctx, project), + "columns": convert.ToColumns(ctx, columns), + "issues": convert.ToAPIIssueList(ctx, ctx.Doer, issues), + }) } // EditProject updates a project @@ -193,7 +137,7 @@ func EditProject(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, p) + ctx.JSON(http.StatusOK, convert.ToProject(ctx, p)) } // DeleteProject delete a project @@ -218,6 +162,27 @@ func DeleteProject(ctx *context.APIContext) { ctx.JSON(http.StatusOK, map[string]any{"message": "project deleted successfully"}) } +// ChangeProjectStatus updates the status of a project between "open" and "close" +func ChangeProjectStatus(ctx *context.APIContext) { + var toClose bool + switch ctx.PathParam(":action") { + case "open": + toClose = false + case "close": + toClose = true + default: + ctx.NotFound("ChangeProjectStatus", nil) + return + } + id := ctx.PathParamInt64(":id") + + if err := project_model.ChangeProjectStatusByRepoIDAndID(ctx, 0, id, toClose); err != nil { + ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err) + return + } + ctx.JSON(http.StatusOK, map[string]any{"message": "project status updated successfully"}) +} + // AddColumnToProject adds a new column to a project func AddColumnToProject(ctx *context.APIContext) { project, err := project_model.GetProjectByID(ctx, ctx.PathParamInt64(":id")) @@ -243,7 +208,7 @@ func AddColumnToProject(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, column) + ctx.JSON(http.StatusCreated, convert.ToColumn(ctx, column)) } // CheckProjectColumnChangePermissions check permission @@ -303,7 +268,7 @@ func EditProjectColumn(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, column) + ctx.JSON(http.StatusOK, convert.ToColumn(ctx, column)) } // DeleteProjectColumn allows for the deletion of a project column diff --git a/routers/api/v1/repo/project.go b/routers/api/v1/repo/project.go index aa81407c85..d0bc3fcdf8 100644 --- a/routers/api/v1/repo/project.go +++ b/routers/api/v1/repo/project.go @@ -12,13 +12,13 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/perm" project_model "code.gitea.io/gitea/models/project" - attachment_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/optional" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/context" + "code.gitea.io/gitea/services/convert" ) // CreateProject creates a new project @@ -40,7 +40,7 @@ func CreateProject(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, project) + ctx.JSON(http.StatusCreated, convert.ToProject(ctx, project)) } // Projects renders the home page of projects @@ -63,7 +63,7 @@ func GetProjects(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, projects) + ctx.JSON(http.StatusOK, convert.ToProjects(ctx, projects)) } // TODO: Send issues as well @@ -91,55 +91,20 @@ func GetProject(ctx *context.APIContext) { return } - if project.CardType != project_model.CardTypeTextOnly { - issuesAttachmentMap := make(map[int64][]*attachment_model.Attachment) - for _, issuesList := range issuesMap { - for _, issue := range issuesList { - if issueAttachment, err := attachment_model.GetAttachmentsByIssueIDImagesLatest(ctx, issue.ID); err == nil { - issuesAttachmentMap[issue.ID] = issueAttachment - } - } - } - ctx.Data["issuesAttachmentMap"] = issuesAttachmentMap - } - - linkedPrsMap := make(map[int64][]*issues_model.Issue) - for _, issuesList := range issuesMap { - for _, issue := range issuesList { - var referencedIDs []int64 - for _, comment := range issue.Comments { - if comment.RefIssueID != 0 && comment.RefIsPull { - referencedIDs = append(referencedIDs, comment.RefIssueID) - } - } - - if len(referencedIDs) > 0 { - if linkedPrs, err := issues_model.Issues(ctx, &issues_model.IssuesOptions{ - IssueIDs: referencedIDs, - IsPull: optional.Some(true), - }); err == nil { - linkedPrsMap[issue.ID] = linkedPrs - } - } - } - } - - issues := make(map[int64][]*issues_model.Issue) + issues := issues_model.IssueList{} for _, column := range columns { if empty := issuesMap[column.ID]; len(empty) == 0 { continue } - issues[column.ID] = issuesMap[column.ID] - + issues = append(issues, issuesMap[column.ID]...) } - data := map[string]any{ - "project": project, - "columns": columns, - } - - ctx.JSON(http.StatusOK, data) + ctx.JSON(http.StatusOK, map[string]any{ + "project": convert.ToProject(ctx, project), + "columns": convert.ToColumns(ctx, columns), + "issues": convert.ToAPIIssueList(ctx, ctx.Doer, issues), + }) } // EditProject updates a project @@ -166,7 +131,7 @@ func EditProject(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, p) + ctx.JSON(http.StatusOK, convert.ToProject(ctx, p)) } // DeleteProject delete a project @@ -240,7 +205,7 @@ func AddColumnToProject(ctx *context.APIContext) { return } - ctx.JSON(http.StatusCreated, column) + ctx.JSON(http.StatusCreated, convert.ToColumn(ctx, column)) } // CheckProjectColumnChangePermissions check permission @@ -307,7 +272,7 @@ func EditProjectColumn(ctx *context.APIContext) { return } - ctx.JSON(http.StatusOK, column) + ctx.JSON(http.StatusOK, convert.ToColumn(ctx, column)) } // DeleteProjectColumn allows for the deletion of a project column diff --git a/services/convert/project.go b/services/convert/project.go new file mode 100644 index 0000000000..db3d7991b5 --- /dev/null +++ b/services/convert/project.go @@ -0,0 +1,39 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package convert + +import ( + "context" + + project_model "code.gitea.io/gitea/models/project" + api "code.gitea.io/gitea/modules/structs" +) + +// ToProject converts a models.Project to api.Project +func ToProject(ctx context.Context, project *project_model.Project) *api.Project { + if project == nil { + return nil + } + + return &api.Project{ + ID: project.ID, + Title: project.Title, + Description: project.Description, + TemplateType: uint8(project.TemplateType), + CardType: uint8(project.CardType), + } +} + +// ToProjects converts a slice of models.Project to a slice of api.Project +func ToProjects(ctx context.Context, projects []*project_model.Project) []*api.Project { + if projects == nil { + return nil + } + + result := make([]*api.Project, len(projects)) + for i, project := range projects { + result[i] = ToProject(ctx, project) + } + return result +} diff --git a/services/convert/project_column.go b/services/convert/project_column.go new file mode 100644 index 0000000000..bcd9632c01 --- /dev/null +++ b/services/convert/project_column.go @@ -0,0 +1,36 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package convert + +import ( + "context" + + column_model "code.gitea.io/gitea/models/project" + api "code.gitea.io/gitea/modules/structs" +) + +// ToProject converts a models.Project to api.Project +func ToColumn(ctx context.Context, column *column_model.Column) *api.Column { + if column == nil { + return nil + } + + return &api.Column{ + ID: column.ID, + Title: column.Title, + Color: column.Color, + } +} + +func ToColumns(ctx context.Context, columns column_model.ColumnList) []*api.Column { + if columns == nil { + return nil + } + + var apiColumns []*api.Column + for _, column := range columns { + apiColumns = append(apiColumns, ToColumn(ctx, column)) + } + return apiColumns +}