Browse Source

Only show part of members on orgnization dashboard and add paging for orgnization members page (#9092)

* Only show part of members on orgnization dashboard and add paging for orgnization members page

* fix test

* fix typo
tags/v1.11.0-rc1
Lunny Xiao 4 years ago
parent
commit
e3081c667a
No account linked to committer's email address

+ 1
- 0
docs/content/doc/advanced/config-cheat-sheet.en-us.md View File



- `EXPLORE_PAGING_NUM`: **20**: Number of repositories that are shown in one explore page. - `EXPLORE_PAGING_NUM`: **20**: Number of repositories that are shown in one explore page.
- `ISSUE_PAGING_NUM`: **10**: Number of issues that are shown in one page (for all pages that list issues). - `ISSUE_PAGING_NUM`: **10**: Number of issues that are shown in one page (for all pages that list issues).
- `MEMBERS_PAGING_NUM`: **20**: Number of members that are shown in organization members.
- `FEED_MAX_COMMIT_NUM`: **5**: Number of maximum commits shown in one activity feed. - `FEED_MAX_COMMIT_NUM`: **5**: Number of maximum commits shown in one activity feed.
- `GRAPH_MAX_COMMIT_NUM`: **100**: Number of maximum commits shown in the commit graph. - `GRAPH_MAX_COMMIT_NUM`: **100**: Number of maximum commits shown in the commit graph.
- `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install. - `DEFAULT_THEME`: **gitea**: \[gitea, arc-green\]: Set the default theme for the Gitea install.

+ 1
- 0
docs/content/doc/advanced/config-cheat-sheet.zh-cn.md View File



- `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。 - `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。
- `ISSUE_PAGING_NUM`: 工单页面每页显示的工单数量。 - `ISSUE_PAGING_NUM`: 工单页面每页显示的工单数量。
- `MEMBERS_PAGING_NUM`: **20**: 组织成员页面每页显示的成员数量。
- `FEED_MAX_COMMIT_NUM`: 活动流页面显示的最大提交数量。 - `FEED_MAX_COMMIT_NUM`: 活动流页面显示的最大提交数量。


### UI - Admin (`ui.admin`) ### UI - Admin (`ui.admin`)

+ 45
- 12
models/org.go View File

} }


// GetMembers returns all members of organization. // GetMembers returns all members of organization.
func (org *User) GetMembers() error {
ous, err := GetOrgUsersByOrgID(org.ID)
func (org *User) GetMembers() (err error) {
org.Members, org.MembersIsPublic, err = FindOrgMembers(FindOrgMembersOpts{
OrgID: org.ID,
})
return
}

// FindOrgMembersOpts represensts find org members condtions
type FindOrgMembersOpts struct {
OrgID int64
PublicOnly bool
Start int
Limit int
}

// CountOrgMembers counts the organization's members
func CountOrgMembers(opts FindOrgMembersOpts) (int64, error) {
sess := x.Where("org_id=?", opts.OrgID)
if opts.PublicOnly {
sess.And("is_public = ?", true)
}
return sess.Count(new(OrgUser))
}

// FindOrgMembers loads organization members according conditions
func FindOrgMembers(opts FindOrgMembersOpts) (UserList, map[int64]bool, error) {
ous, err := GetOrgUsersByOrgID(opts.OrgID, opts.PublicOnly, opts.Start, opts.Limit)
if err != nil { if err != nil {
return err
return nil, nil, err
} }


var ids = make([]int64, len(ous)) var ids = make([]int64, len(ous))
ids[i] = ou.UID ids[i] = ou.UID
idsIsPublic[ou.UID] = ou.IsPublic idsIsPublic[ou.UID] = ou.IsPublic
} }
org.MembersIsPublic = idsIsPublic
org.Members, err = GetUsersByIDs(ids)
return err

users, err := GetUsersByIDs(ids)
if err != nil {
return nil, nil, err
}
return users, idsIsPublic, nil
} }


// AddMember adds new member to organization. // AddMember adds new member to organization.
} }


// GetOrgUsersByOrgID returns all organization-user relations by organization ID. // GetOrgUsersByOrgID returns all organization-user relations by organization ID.
func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) {
return getOrgUsersByOrgID(x, orgID)
func GetOrgUsersByOrgID(orgID int64, publicOnly bool, start, limit int) ([]*OrgUser, error) {
return getOrgUsersByOrgID(x, orgID, publicOnly, start, limit)
} }


func getOrgUsersByOrgID(e Engine, orgID int64) ([]*OrgUser, error) {
func getOrgUsersByOrgID(e Engine, orgID int64, publicOnly bool, start, limit int) ([]*OrgUser, error) {
ous := make([]*OrgUser, 0, 10) ous := make([]*OrgUser, 0, 10)
err := e.
Where("org_id=?", orgID).
Find(&ous)
sess := e.Where("org_id=?", orgID)
if publicOnly {
sess.And("is_public = ?", true)
}
if limit > 0 {
sess.Limit(limit, start)
}
err := sess.Find(&ous)
return ous, err return ous, err
} }



+ 2
- 2
models/org_test.go View File

func TestGetOrgUsersByOrgID(t *testing.T) { func TestGetOrgUsersByOrgID(t *testing.T) {
assert.NoError(t, PrepareTestDatabase()) assert.NoError(t, PrepareTestDatabase())


orgUsers, err := GetOrgUsersByOrgID(3)
orgUsers, err := GetOrgUsersByOrgID(3, false, 0, 0)
assert.NoError(t, err) assert.NoError(t, err)
if assert.Len(t, orgUsers, 3) { if assert.Len(t, orgUsers, 3) {
assert.Equal(t, OrgUser{ assert.Equal(t, OrgUser{
IsPublic: false}, *orgUsers[1]) IsPublic: false}, *orgUsers[1])
} }


orgUsers, err = GetOrgUsersByOrgID(NonexistentID)
orgUsers, err = GetOrgUsersByOrgID(NonexistentID, false, 0, 0)
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, orgUsers, 0) assert.Len(t, orgUsers, 0)
} }

+ 2
- 0
modules/setting/setting.go View File

ExplorePagingNum int ExplorePagingNum int
IssuePagingNum int IssuePagingNum int
RepoSearchPagingNum int RepoSearchPagingNum int
MembersPagingNum int
FeedMaxCommitNum int FeedMaxCommitNum int
GraphMaxCommitNum int GraphMaxCommitNum int
CodeCommentLines int CodeCommentLines int
ExplorePagingNum: 20, ExplorePagingNum: 20,
IssuePagingNum: 10, IssuePagingNum: 10,
RepoSearchPagingNum: 10, RepoSearchPagingNum: 10,
MembersPagingNum: 20,
FeedMaxCommitNum: 5, FeedMaxCommitNum: 5,
GraphMaxCommitNum: 100, GraphMaxCommitNum: 100,
CodeCommentLines: 4, CodeCommentLines: 4,

+ 7
- 24
routers/api/v1/org/member.go View File

// listMembers list an organization's members // listMembers list an organization's members
func listMembers(ctx *context.APIContext, publicOnly bool) { func listMembers(ctx *context.APIContext, publicOnly bool) {
var members []*models.User var members []*models.User
if publicOnly {
orgUsers, err := models.GetOrgUsersByOrgID(ctx.Org.Organization.ID)
if err != nil {
ctx.Error(500, "GetOrgUsersByOrgID", err)
return
}

memberIDs := make([]int64, 0, len(orgUsers))
for _, orgUser := range orgUsers {
if orgUser.IsPublic {
memberIDs = append(memberIDs, orgUser.UID)
}
}

if members, err = models.GetUsersByIDs(memberIDs); err != nil {
ctx.Error(500, "GetUsersByIDs", err)
return
}
} else {
if err := ctx.Org.Organization.GetMembers(); err != nil {
ctx.Error(500, "GetMembers", err)
return
}
members = ctx.Org.Organization.Members
members, _, err := models.FindOrgMembers(models.FindOrgMembersOpts{
OrgID: ctx.Org.Organization.ID,
PublicOnly: publicOnly,
})
if err != nil {
ctx.Error(500, "GetUsersByIDs", err)
return
} }


apiMembers := make([]*api.User, len(members)) apiMembers := make([]*api.User, len(members))

+ 35
- 5
routers/org/members.go View File

ctx.Data["Title"] = org.FullName ctx.Data["Title"] = org.FullName
ctx.Data["PageIsOrgMembers"] = true ctx.Data["PageIsOrgMembers"] = true


if err := org.GetMembers(); err != nil {
page := ctx.QueryInt("page")
if page <= 1 {
page = 1
}

var opts = models.FindOrgMembersOpts{
OrgID: org.ID,
PublicOnly: true,
}

if ctx.User != nil {
isMember, err := ctx.Org.Organization.IsOrgMember(ctx.User.ID)
if err != nil {
ctx.Error(500, "IsOrgMember")
return
}
opts.PublicOnly = !isMember
}

total, err := models.CountOrgMembers(opts)
if err != nil {
ctx.Error(500, "CountOrgMembers")
return
}

pager := context.NewPagination(int(total), setting.UI.MembersPagingNum, page, 5)
opts.Start = (page - 1) * setting.UI.MembersPagingNum
opts.Limit = setting.UI.MembersPagingNum
members, membersIsPublic, err := models.FindOrgMembers(opts)
if err != nil {
ctx.ServerError("GetMembers", err) ctx.ServerError("GetMembers", err)
return return
} }
ctx.Data["Members"] = org.Members
ctx.Data["MembersIsPublicMember"] = org.MembersIsPublic
ctx.Data["MembersIsUserOrgOwner"] = org.Members.IsUserOrgOwner(org.ID)
ctx.Data["MembersTwoFaStatus"] = org.Members.GetTwoFaStatus()
ctx.Data["Page"] = pager
ctx.Data["Members"] = members
ctx.Data["MembersIsPublicMember"] = membersIsPublic
ctx.Data["MembersIsUserOrgOwner"] = members.IsUserOrgOwner(org.ID)
ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus()


ctx.HTML(200, tplMembers) ctx.HTML(200, tplMembers)
} }

+ 26
- 3
routers/user/home.go View File

return return
} }


if err := org.GetMembers(); err != nil {
ctx.ServerError("GetMembers", err)
var opts = models.FindOrgMembersOpts{
OrgID: org.ID,
PublicOnly: true,
Limit: 25,
}

if ctx.User != nil {
isMember, err := org.IsOrgMember(ctx.User.ID)
if err != nil {
ctx.Error(500, "IsOrgMember")
return
}
opts.PublicOnly = !isMember
}

members, _, err := models.FindOrgMembers(opts)
if err != nil {
ctx.ServerError("FindOrgMembers", err)
return
}

membersCount, err := models.CountOrgMembers(opts)
if err != nil {
ctx.ServerError("CountOrgMembers", err)
return return
} }


ctx.Data["Repos"] = repos ctx.Data["Repos"] = repos
ctx.Data["Total"] = count ctx.Data["Total"] = count
ctx.Data["Members"] = org.Members
ctx.Data["MembersTotal"] = membersCount
ctx.Data["Members"] = members
ctx.Data["Teams"] = org.Teams ctx.Data["Teams"] = org.Teams


pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5) pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)

+ 2
- 0
templates/org/member/members.tmpl View File

</div> </div>
{{end}} {{end}}
</div> </div>

{{template "base/paginate" .}}
</div> </div>
</div> </div>
{{template "base/footer" .}} {{template "base/footer" .}}

Loading…
Cancel
Save