mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 20:36:07 +01:00 
			
		
		
		
	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:
		@@ -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 New Issue
	
	Block a user