-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
wip: API for projects and boards #20208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 89 commits
091b549
ce3dbfd
781b1cc
7103a2c
45f44cb
d32ab45
fa3dc73
a7f1f6a
31c847c
3814116
db82c7c
33eb19b
be710da
1890c80
2b86075
b010ac6
e0b93f5
559b2bf
957836f
053c5f6
4d769e5
392f27f
92aede0
176015c
c59d9c4
b9fbab3
0b19a3b
1a33414
a94f127
6fb081b
e192014
c060beb
cef8c54
ed8543a
649042f
03d146c
c759cb9
a6f1d33
498dd78
264f02d
3b81e40
16d9f5c
3916df6
23d883f
9a9ae85
62a3eb0
1fd61f8
23e5fd0
11a55a0
b73c091
e26057d
d3e7f2c
8bf5e48
503d2c1
8804733
6fbcb6e
855758b
2023f56
21d1dfb
317a361
8fd34df
252ecd8
b9a3748
c64e6b6
b5d9130
857225e
221b659
8ffbea8
12b2816
f10c990
8f93aa6
8c6d45c
c5880c7
dd364c9
22959c4
9161303
461950e
f2c55f6
88f7ae0
187e27b
edc3446
78aa83b
0f4be83
58ef609
79667a3
479014c
85e0a0b
e8769cd
dd422c3
f2369e4
93ee056
957f0a3
bdb217c
ff5a443
2fce167
f3b5447
89914eb
aa7e2a4
f1aa661
43ff02a
a9d6f0d
4b99ba2
2570b39
ce9a62a
2fb7328
c552a56
e405015
eb0d417
edeed31
bc4420c
47ce10c
7d68621
575c3b1
db684a9
92722d8
3d0a4e9
1676b4d
ff9ac96
22177d4
732727c
ac02a7c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,49 @@ | ||||||
// Copyright 2020 The Gitea Authors. All rights reserved. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
... |
||||||
// SPDX-License-Identifier: MIT | ||||||
package project | ||||||
dineshsalunke marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
import ( | ||||||
"context" | ||||||
"fmt" | ||||||
|
||||||
repo_model "code.gitea.io/gitea/models/repo" | ||||||
user_model "code.gitea.io/gitea/models/user" | ||||||
) | ||||||
|
||||||
// List is a list of projects | ||||||
type List []*Project | ||||||
|
||||||
// LoadAttributes load repos and creators of projects. | ||||||
func (pl List) LoadAttributes(ctx context.Context) (err error) { | ||||||
repos := make(map[int64]*repo_model.Repository) | ||||||
creators := make(map[int64]*user_model.User) | ||||||
var ok bool | ||||||
|
||||||
for i := range pl { | ||||||
if pl[i].Repo == nil { | ||||||
pl[i].Repo, ok = repos[pl[i].RepoID] | ||||||
if !ok { | ||||||
repo, err := repo_model.GetRepositoryByID(ctx, pl[i].RepoID) | ||||||
if err != nil { | ||||||
return fmt.Errorf("getRepositoryByID [%d]: %v", pl[i].RepoID, err) | ||||||
} | ||||||
pl[i].Repo = repo | ||||||
repos[pl[i].RepoID] = repo | ||||||
} | ||||||
} | ||||||
|
||||||
if pl[i].Creator == nil { | ||||||
pl[i].Creator, ok = creators[pl[i].CreatorID] | ||||||
if !ok { | ||||||
creator, err := user_model.GetUserByID(ctx, pl[i].CreatorID) | ||||||
if err != nil { | ||||||
return fmt.Errorf("getUserByID [%d]: %v", pl[i].CreatorID, err) | ||||||
} | ||||||
pl[i].Creator = creator | ||||||
creators[pl[i].CreatorID] = creator | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
return nil | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright 2023 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package structs | ||
|
||
import "time" | ||
|
||
// swagger:model | ||
type NewProjectPayload struct { | ||
// required:true | ||
Title string `json:"title" binding:"Required"` | ||
// required:true | ||
BoardType uint8 `json:"board_type"` | ||
Description string `json:"description"` | ||
} | ||
|
||
// swagger:model | ||
type UpdateProjectPayload struct { | ||
// required:true | ||
Title string `json:"title" binding:"Required"` | ||
Description string `json:"description"` | ||
} | ||
|
||
type Project struct { | ||
ID int64 `json:"id"` | ||
Title string `json:"title"` | ||
Description string `json:"description"` | ||
BoardType uint8 `json:"board_type"` | ||
IsClosed bool `json:"is_closed"` | ||
// swagger:strfmt date-time | ||
Created time.Time `json:"created_at"` | ||
// swagger:strfmt date-time | ||
Updated time.Time `json:"updated_at"` | ||
// swagger:strfmt date-time | ||
Closed time.Time `json:"closed_at"` | ||
|
||
Repo *RepositoryMeta `json:"repository"` | ||
Creator *User `json:"creator"` | ||
} | ||
|
||
type ProjectBoard struct { | ||
ID int64 `json:"id"` | ||
Title string `json:"title"` | ||
Default bool `json:"default"` | ||
Color string `json:"color"` | ||
Sorting int8 `json:"sorting"` | ||
Project *Project `json:"project"` | ||
Creator *User `json:"creator"` | ||
// swagger:strfmt date-time | ||
Created time.Time `json:"created_at"` | ||
// swagger:strfmt date-time | ||
Updated time.Time `json:"updated_at"` | ||
} | ||
|
||
// swagger:model | ||
type NewProjectBoardPayload struct { | ||
// required:true | ||
Title string `json:"title"` | ||
Default bool `json:"default"` | ||
Color string `json:"color"` | ||
Sorting int8 `json:"sorting"` | ||
} | ||
|
||
// swagger:model | ||
type UpdateProjectBoardPayload struct { | ||
Title string `json:"title"` | ||
Color string `json:"color"` | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -985,6 +985,11 @@ func Routes(ctx gocontext.Context) *web.Route { | |
}, mustEnableAttachments) | ||
}) | ||
}, mustEnableIssuesOrPulls) | ||
m.Group("/projects", func() { | ||
m.Combo(""). | ||
Get(reqToken(auth_model.AccessTokenScopeRepo), repo.ListRepositoryProjects). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've used Repo Scope for project boards, but this probably needs to be reviewed as to which scope is most appropriate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these all possible Scopes? There is nothing else except |
||
Post(reqToken(auth_model.AccessTokenScopeRepo), mustNotBeArchived, bind(api.NewProjectPayload{}), repo.CreateRepositoryProject) | ||
}) | ||
m.Group("/labels", func() { | ||
m.Combo("").Get(repo.ListLabels). | ||
Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.CreateLabelOption{}), repo.CreateLabel) | ||
|
@@ -1226,6 +1231,27 @@ func Routes(ctx gocontext.Context) *web.Route { | |
m.Group("/topics", func() { | ||
m.Get("/search", repo.TopicSearch) | ||
}) | ||
|
||
// Projects | ||
m.Group("/projects", func() { | ||
m.Group("/{id}", func() { | ||
m.Combo(""). | ||
Get(reqToken(auth_model.AccessTokenScopeRepo), reqRepoReader(unit.TypeProjects), repo.GetProject). | ||
Patch(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeProjects), bind(api.UpdateProjectPayload{}), repo.UpdateProject). | ||
Delete(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeProjects), repo.DeleteProject) | ||
|
||
m.Combo("/boards"). | ||
Post(reqToken(auth_model.AccessTokenScopeRepo), reqRepoWriter(unit.TypeProjects), bind(api.NewProjectBoardPayload{}), repo.CreateProjectBoard). | ||
Get(reqToken(auth_model.AccessTokenScopeRepo), reqRepoReader(unit.TypeProjects), repo.ListProjectBoards) | ||
}) | ||
|
||
m.Group("/boards", func() { | ||
m.Combo("/{id}"). | ||
Get(reqToken(auth_model.AccessTokenScopeRepo), repo.GetProjectBoard). | ||
Patch(reqToken(auth_model.AccessTokenScopeRepo), bind(api.UpdateProjectBoardPayload{}), repo.UpdateProjectBoard). | ||
Delete(reqToken(auth_model.AccessTokenScopeRepo), repo.DeleteProjectBoard) | ||
}) | ||
dineshsalunke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) | ||
}, sudo()) | ||
|
||
return m | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?