mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-17 04:11:24 +01:00
Merge pull request #721 from ywk253100/page
Add pagination support for listing projects
This commit is contained in:
commit
4977a2c77e
@ -154,13 +154,15 @@ func (p *ProjectAPI) Get() {
|
|||||||
|
|
||||||
// List ...
|
// List ...
|
||||||
func (p *ProjectAPI) List() {
|
func (p *ProjectAPI) List() {
|
||||||
var projectList []models.Project
|
var total int64
|
||||||
projectName := p.GetString("project_name")
|
|
||||||
if len(projectName) > 0 {
|
|
||||||
projectName = "%" + projectName + "%"
|
|
||||||
}
|
|
||||||
var public int
|
var public int
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
page, pageSize := p.getPaginationParams()
|
||||||
|
|
||||||
|
var projectList []models.Project
|
||||||
|
projectName := p.GetString("project_name")
|
||||||
|
|
||||||
isPublic := p.GetString("is_public")
|
isPublic := p.GetString("is_public")
|
||||||
if len(isPublic) > 0 {
|
if len(isPublic) > 0 {
|
||||||
public, err = strconv.Atoi(isPublic)
|
public, err = strconv.Atoi(isPublic)
|
||||||
@ -171,7 +173,16 @@ func (p *ProjectAPI) List() {
|
|||||||
}
|
}
|
||||||
isAdmin := false
|
isAdmin := false
|
||||||
if public == 1 {
|
if public == 1 {
|
||||||
projectList, err = dao.GetPublicProjects(projectName)
|
total, err = dao.GetTotalOfProjects(projectName, 1)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get total of projects: %v", err)
|
||||||
|
p.CustomAbort(http.StatusInternalServerError, "")
|
||||||
|
}
|
||||||
|
projectList, err = dao.GetProjects(projectName, 1, pageSize, pageSize*(page-1))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get projects: %v", err)
|
||||||
|
p.CustomAbort(http.StatusInternalServerError, "")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
//if the request is not for public projects, user must login or provide credential
|
//if the request is not for public projects, user must login or provide credential
|
||||||
p.userID = p.ValidateUser()
|
p.userID = p.ValidateUser()
|
||||||
@ -181,15 +192,30 @@ func (p *ProjectAPI) List() {
|
|||||||
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
}
|
}
|
||||||
if isAdmin {
|
if isAdmin {
|
||||||
projectList, err = dao.GetAllProjects(projectName)
|
total, err = dao.GetTotalOfProjects(projectName)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get total of projects: %v", err)
|
||||||
|
p.CustomAbort(http.StatusInternalServerError, "")
|
||||||
|
}
|
||||||
|
projectList, err = dao.GetProjects(projectName, pageSize, pageSize*(page-1))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get projects: %v", err)
|
||||||
|
p.CustomAbort(http.StatusInternalServerError, "")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
projectList, err = dao.GetUserRelevantProjects(p.userID, projectName)
|
total, err = dao.GetTotalOfUserRelevantProjects(p.userID, projectName)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get total of projects: %v", err)
|
||||||
|
p.CustomAbort(http.StatusInternalServerError, "")
|
||||||
|
}
|
||||||
|
projectList, err = dao.GetUserRelevantProjects(p.userID, projectName, pageSize, pageSize*(page-1))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to get projects: %v", err)
|
||||||
|
p.CustomAbort(http.StatusInternalServerError, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Error occured in get projects info, error: %v", err)
|
|
||||||
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
|
||||||
}
|
|
||||||
for i := 0; i < len(projectList); i++ {
|
for i := 0; i < len(projectList); i++ {
|
||||||
if public != 1 {
|
if public != 1 {
|
||||||
if isAdmin {
|
if isAdmin {
|
||||||
@ -201,6 +227,8 @@ func (p *ProjectAPI) List() {
|
|||||||
}
|
}
|
||||||
projectList[i].RepoCount = getRepoCountByProject(projectList[i].Name)
|
projectList[i].RepoCount = getRepoCountByProject(projectList[i].Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.setPaginationHeader(total, page, pageSize)
|
||||||
p.Data["json"] = projectList
|
p.Data["json"] = projectList
|
||||||
p.ServeJSON()
|
p.ServeJSON()
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ func (s *SearchAPI) Get() {
|
|||||||
var projects []models.Project
|
var projects []models.Project
|
||||||
|
|
||||||
if isSysAdmin {
|
if isSysAdmin {
|
||||||
projects, err = dao.GetAllProjects("")
|
projects, err = dao.GetProjects("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed to get all projects: %v", err)
|
log.Errorf("failed to get all projects: %v", err)
|
||||||
s.CustomAbort(http.StatusInternalServerError, "internal error")
|
s.CustomAbort(http.StatusInternalServerError, "internal error")
|
||||||
|
@ -45,7 +45,7 @@ func (s *StatisticAPI) Get() {
|
|||||||
}
|
}
|
||||||
var projectList []models.Project
|
var projectList []models.Project
|
||||||
if isAdmin {
|
if isAdmin {
|
||||||
projectList, err = dao.GetAllProjects("")
|
projectList, err = dao.GetProjects("")
|
||||||
} else {
|
} else {
|
||||||
projectList, err = dao.GetUserRelevantProjects(s.userID, "")
|
projectList, err = dao.GetUserRelevantProjects(s.userID, "")
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ func (s *StatisticAPI) Get() {
|
|||||||
proMap["public_project_count"] = 0
|
proMap["public_project_count"] = 0
|
||||||
proMap["public_repo_count"] = 0
|
proMap["public_repo_count"] = 0
|
||||||
var publicProjects []models.Project
|
var publicProjects []models.Project
|
||||||
publicProjects, err = dao.GetPublicProjects("")
|
publicProjects, err = dao.GetProjects("", 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error occured in QueryPublicProject, error: %v", err)
|
log.Errorf("Error occured in QueryPublicProject, error: %v", err)
|
||||||
s.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
s.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||||
|
@ -609,6 +609,17 @@ func TestProjectPermission(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetTotalOfUserRelevantProjects(t *testing.T) {
|
||||||
|
total, err := GetTotalOfUserRelevantProjects(currentUser.UserID, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get total of user relevant projects: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if total != 1 {
|
||||||
|
t.Errorf("unexpected total: %d != 1", total)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestGetUserRelevantProjects(t *testing.T) {
|
func TestGetUserRelevantProjects(t *testing.T) {
|
||||||
projects, err := GetUserRelevantProjects(currentUser.UserID, "")
|
projects, err := GetUserRelevantProjects(currentUser.UserID, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -622,8 +633,19 @@ func TestGetUserRelevantProjects(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetAllProjects(t *testing.T) {
|
func TestGetTotalOfProjects(t *testing.T) {
|
||||||
projects, err := GetAllProjects("")
|
total, err := GetTotalOfProjects("")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to get total of projects: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if total != 2 {
|
||||||
|
t.Errorf("unexpected total: %d != 2", total)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetProjects(t *testing.T) {
|
||||||
|
projects, err := GetProjects("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in GetAllProjects: %v", err)
|
t.Errorf("Error occurred in GetAllProjects: %v", err)
|
||||||
}
|
}
|
||||||
@ -636,7 +658,7 @@ func TestGetAllProjects(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGetPublicProjects(t *testing.T) {
|
func TestGetPublicProjects(t *testing.T) {
|
||||||
projects, err := GetPublicProjects("")
|
projects, err := GetProjects("", 1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Error occurred in getProjects: %v", err)
|
t.Errorf("Error occurred in getProjects: %v", err)
|
||||||
}
|
}
|
||||||
|
122
dao/project.go
122
dao/project.go
@ -182,66 +182,98 @@ func SearchProjects(userID int) ([]models.Project, error) {
|
|||||||
return projects, nil
|
return projects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserRelevantProjects returns the projects of the user which are not deleted and name like projectName
|
//GetTotalOfUserRelevantProjects returns the total count of
|
||||||
func GetUserRelevantProjects(userID int, projectName string) ([]models.Project, error) {
|
// user relevant projects
|
||||||
|
func GetTotalOfUserRelevantProjects(userID int, projectName string,
|
||||||
|
public ...int) (int64, error) {
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
sql := `select distinct
|
sql := `select count(*) from project p
|
||||||
p.project_id, p.owner_id, p.name,p.creation_time, p.update_time, p.public, pm.role role
|
left join project_member pm
|
||||||
from project p
|
on p.project_id = pm.project_id
|
||||||
left join project_member pm on p.project_id = pm.project_id
|
where p.deleted = 0 and pm.user_id= ?`
|
||||||
where p.deleted = 0 and pm.user_id= ?`
|
|
||||||
|
|
||||||
queryParam := make([]interface{}, 1)
|
queryParam := []interface{}{}
|
||||||
queryParam = append(queryParam, userID)
|
queryParam = append(queryParam, userID)
|
||||||
if projectName != "" {
|
if projectName != "" {
|
||||||
sql += " and p.name like ? "
|
sql += " and p.name like ? "
|
||||||
queryParam = append(queryParam, projectName)
|
queryParam = append(queryParam, "%"+projectName+"%")
|
||||||
}
|
}
|
||||||
sql += " order by p.name "
|
|
||||||
var r []models.Project
|
var total int64
|
||||||
_, err := o.Raw(sql, queryParam).QueryRows(&r)
|
err := o.Raw(sql, queryParam).QueryRow(&total)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return total, err
|
||||||
}
|
|
||||||
return r, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//GetPublicProjects returns all public projects whose name like projectName
|
// GetUserRelevantProjects returns the user relevant projects
|
||||||
func GetPublicProjects(projectName string) ([]models.Project, error) {
|
// args[0]: public, args[1]: limit, args[2]: offset
|
||||||
publicProjects, err := getProjects(1, projectName)
|
func GetUserRelevantProjects(userID int, projectName string, args ...int64) ([]models.Project, error) {
|
||||||
if err != nil {
|
return getProjects(userID, projectName, args...)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return publicProjects, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAllProjects returns all projects which are not deleted and name like projectName
|
// GetTotalOfProjects returns the total count of projects
|
||||||
func GetAllProjects(projectName string) ([]models.Project, error) {
|
func GetTotalOfProjects(name string, public ...int) (int64, error) {
|
||||||
allProjects, err := getProjects(0, projectName)
|
qs := GetOrmer().
|
||||||
if err != nil {
|
QueryTable(new(models.Project)).
|
||||||
return nil, err
|
Filter("Deleted", 0)
|
||||||
|
|
||||||
|
if len(name) > 0 {
|
||||||
|
qs = qs.Filter("Name__icontains", name)
|
||||||
}
|
}
|
||||||
return allProjects, nil
|
|
||||||
|
if len(public) > 0 {
|
||||||
|
qs = qs.Filter("Public", public[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return qs.Count()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProjects(public int, projectName string) ([]models.Project, error) {
|
// GetProjects returns project list
|
||||||
|
// args[0]: public, args[1]: limit, args[2]: offset
|
||||||
|
func GetProjects(name string, args ...int64) ([]models.Project, error) {
|
||||||
|
return getProjects(0, name, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProjects(userID int, name string, args ...int64) ([]models.Project, error) {
|
||||||
|
projects := []models.Project{}
|
||||||
|
|
||||||
o := GetOrmer()
|
o := GetOrmer()
|
||||||
sql := `select project_id, owner_id, creation_time, update_time, name, public
|
sql := ""
|
||||||
from project
|
queryParam := []interface{}{}
|
||||||
where deleted = 0`
|
|
||||||
queryParam := make([]interface{}, 1)
|
if userID != 0 { //get user's projects
|
||||||
if public == 1 {
|
sql = `select distinct p.project_id, p.owner_id, p.name,
|
||||||
sql += " and public = ? "
|
p.creation_time, p.update_time, p.public, pm.role role
|
||||||
queryParam = append(queryParam, public)
|
from project p
|
||||||
|
left join project_member pm
|
||||||
|
on p.project_id = pm.project_id
|
||||||
|
where p.deleted = 0 and pm.user_id= ?`
|
||||||
|
queryParam = append(queryParam, userID)
|
||||||
|
} else { // get all projects
|
||||||
|
sql = `select * from project p where p.deleted = 0 `
|
||||||
}
|
}
|
||||||
if len(projectName) > 0 {
|
|
||||||
sql += " and name like ? "
|
if name != "" {
|
||||||
queryParam = append(queryParam, projectName)
|
sql += ` and p.name like ? `
|
||||||
|
queryParam = append(queryParam, "%"+name+"%")
|
||||||
}
|
}
|
||||||
sql += " order by name "
|
|
||||||
var projects []models.Project
|
switch len(args) {
|
||||||
if _, err := o.Raw(sql, queryParam).QueryRows(&projects); err != nil {
|
case 1:
|
||||||
return nil, err
|
sql += ` and p.public = ?`
|
||||||
|
queryParam = append(queryParam, args[0])
|
||||||
|
sql += ` order by p.name `
|
||||||
|
case 2:
|
||||||
|
sql += ` order by p.name `
|
||||||
|
sql = paginateForRawSQL(sql, args[0], args[1])
|
||||||
|
case 3:
|
||||||
|
sql += ` and p.public = ?`
|
||||||
|
queryParam = append(queryParam, args[0])
|
||||||
|
sql += ` order by p.name `
|
||||||
|
sql = paginateForRawSQL(sql, args[1], args[2])
|
||||||
}
|
}
|
||||||
return projects, nil
|
|
||||||
|
_, err := o.Raw(sql, queryParam).QueryRows(&projects)
|
||||||
|
|
||||||
|
return projects, err
|
||||||
}
|
}
|
||||||
|
@ -336,13 +336,13 @@ func FilterRepJobs(policyID int64, repository, status string, startTime,
|
|||||||
qs = qs.Filter("CreationTime__lte", endTime)
|
qs = qs.Filter("CreationTime__lte", endTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
qs = qs.OrderBy("-UpdateTime")
|
|
||||||
|
|
||||||
total, err := qs.Count()
|
total, err := qs.Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return jobs, 0, err
|
return jobs, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qs = qs.OrderBy("-UpdateTime")
|
||||||
|
|
||||||
_, err = qs.Limit(limit).Offset(offset).All(&jobs)
|
_, err = qs.Limit(limit).Offset(offset).All(&jobs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return jobs, 0, err
|
return jobs, 0, err
|
||||||
|
@ -25,17 +25,17 @@ type Project struct {
|
|||||||
OwnerID int `orm:"column(owner_id)" json:"owner_id"`
|
OwnerID int `orm:"column(owner_id)" json:"owner_id"`
|
||||||
Name string `orm:"column(name)" json:"name"`
|
Name string `orm:"column(name)" json:"name"`
|
||||||
CreationTime time.Time `orm:"column(creation_time)" json:"creation_time"`
|
CreationTime time.Time `orm:"column(creation_time)" json:"creation_time"`
|
||||||
CreationTimeStr string `json:"creation_time_str"`
|
CreationTimeStr string `orm:"-" json:"creation_time_str"`
|
||||||
Deleted int `orm:"column(deleted)" json:"deleted"`
|
Deleted int `orm:"column(deleted)" json:"deleted"`
|
||||||
//UserID int `json:"UserId"`
|
//UserID int `json:"UserId"`
|
||||||
OwnerName string `json:"owner_name"`
|
OwnerName string `orm:"-" json:"owner_name"`
|
||||||
Public int `orm:"column(public)" json:"public"`
|
Public int `orm:"column(public)" json:"public"`
|
||||||
//This field does not have correspondent column in DB, this is just for UI to disable button
|
//This field does not have correspondent column in DB, this is just for UI to disable button
|
||||||
Togglable bool
|
Togglable bool `orm:"-"`
|
||||||
|
|
||||||
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
UpdateTime time.Time `orm:"update_time" json:"update_time"`
|
||||||
Role int `json:"current_user_role_id"`
|
Role int `orm:"-" json:"current_user_role_id"`
|
||||||
RepoCount int `json:"repo_count"`
|
RepoCount int `orm:"-" json:"repo_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProjectSorter holds an array of projects
|
// ProjectSorter holds an array of projects
|
||||||
|
Loading…
Reference in New Issue
Block a user