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
This commit is contained in:
parent
77730db257
commit
e3081c667a
9 changed files with 121 additions and 46 deletions
|
@ -113,6 +113,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
|
||||||
|
|
||||||
- `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.
|
||||||
|
|
|
@ -37,6 +37,7 @@ menu:
|
||||||
|
|
||||||
- `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`)
|
||||||
|
|
|
@ -68,10 +68,35 @@ func (org *User) GetTeams() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMembers returns all members of organization.
|
// GetMembers returns all members of organization.
|
||||||
func (org *User) GetMembers() error {
|
func (org *User) GetMembers() (err error) {
|
||||||
ous, err := GetOrgUsersByOrgID(org.ID)
|
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))
|
||||||
|
@ -80,9 +105,12 @@ func (org *User) GetMembers() error {
|
||||||
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)
|
users, err := GetUsersByIDs(ids)
|
||||||
return err
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return users, idsIsPublic, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddMember adds new member to organization.
|
// AddMember adds new member to organization.
|
||||||
|
@ -467,15 +495,20 @@ func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
|
// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
|
||||||
func GetOrgUsersByOrgID(orgID int64) ([]*OrgUser, error) {
|
func GetOrgUsersByOrgID(orgID int64, publicOnly bool, start, limit int) ([]*OrgUser, error) {
|
||||||
return getOrgUsersByOrgID(x, orgID)
|
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.
|
sess := e.Where("org_id=?", orgID)
|
||||||
Where("org_id=?", orgID).
|
if publicOnly {
|
||||||
Find(&ous)
|
sess.And("is_public = ?", true)
|
||||||
|
}
|
||||||
|
if limit > 0 {
|
||||||
|
sess.Limit(limit, start)
|
||||||
|
}
|
||||||
|
err := sess.Find(&ous)
|
||||||
return ous, err
|
return ous, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -395,7 +395,7 @@ func TestGetOrgUsersByUserID(t *testing.T) {
|
||||||
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{
|
||||||
|
@ -410,7 +410,7 @@ func TestGetOrgUsersByOrgID(t *testing.T) {
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,7 @@ var (
|
||||||
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
|
||||||
|
@ -191,6 +192,7 @@ var (
|
||||||
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,
|
||||||
|
|
|
@ -18,31 +18,14 @@ import (
|
||||||
// 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 {
|
members, _, err := models.FindOrgMembers(models.FindOrgMembersOpts{
|
||||||
orgUsers, err := models.GetOrgUsersByOrgID(ctx.Org.Organization.ID)
|
OrgID: ctx.Org.Organization.ID,
|
||||||
|
PublicOnly: publicOnly,
|
||||||
|
})
|
||||||
if err != nil {
|
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)
|
ctx.Error(500, "GetUsersByIDs", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if err := ctx.Org.Organization.GetMembers(); err != nil {
|
|
||||||
ctx.Error(500, "GetMembers", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
members = ctx.Org.Organization.Members
|
|
||||||
}
|
|
||||||
|
|
||||||
apiMembers := make([]*api.User, len(members))
|
apiMembers := make([]*api.User, len(members))
|
||||||
for i, member := range members {
|
for i, member := range members {
|
||||||
|
|
|
@ -25,14 +25,44 @@ func Members(ctx *context.Context) {
|
||||||
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["Page"] = pager
|
||||||
ctx.Data["MembersIsPublicMember"] = org.MembersIsPublic
|
ctx.Data["Members"] = members
|
||||||
ctx.Data["MembersIsUserOrgOwner"] = org.Members.IsUserOrgOwner(org.ID)
|
ctx.Data["MembersIsPublicMember"] = membersIsPublic
|
||||||
ctx.Data["MembersTwoFaStatus"] = org.Members.GetTwoFaStatus()
|
ctx.Data["MembersIsUserOrgOwner"] = members.IsUserOrgOwner(org.ID)
|
||||||
|
ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus()
|
||||||
|
|
||||||
ctx.HTML(200, tplMembers)
|
ctx.HTML(200, tplMembers)
|
||||||
}
|
}
|
||||||
|
|
|
@ -537,14 +537,37 @@ func showOrgProfile(ctx *context.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := org.GetMembers(); err != nil {
|
var opts = models.FindOrgMembersOpts{
|
||||||
ctx.ServerError("GetMembers", err)
|
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)
|
||||||
|
|
|
@ -57,6 +57,8 @@
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{template "base/paginate" .}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{template "base/footer" .}}
|
{{template "base/footer" .}}
|
||||||
|
|
Reference in a new issue