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. | ||||
| - `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. | ||||
| - `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. | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ menu: | |||
| 
 | ||||
| - `EXPLORE_PAGING_NUM`: 探索页面每页显示的仓库数量。 | ||||
| - `ISSUE_PAGING_NUM`: 工单页面每页显示的工单数量。 | ||||
| - `MEMBERS_PAGING_NUM`: **20**: 组织成员页面每页显示的成员数量。 | ||||
| - `FEED_MAX_COMMIT_NUM`: 活动流页面显示的最大提交数量。 | ||||
| 
 | ||||
| ### UI - Admin (`ui.admin`) | ||||
|  |  | |||
|  | @ -68,10 +68,35 @@ func (org *User) GetTeams() error { | |||
| } | ||||
| 
 | ||||
| // 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 { | ||||
| 		return err | ||||
| 		return nil, nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	var ids = make([]int64, len(ous)) | ||||
|  | @ -80,9 +105,12 @@ func (org *User) GetMembers() error { | |||
| 		ids[i] = ou.UID | ||||
| 		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.
 | ||||
|  | @ -467,15 +495,20 @@ func GetOrgUsersByUserID(uid int64, all bool) ([]*OrgUser, error) { | |||
| } | ||||
| 
 | ||||
| // 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) | ||||
| 	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 | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -395,7 +395,7 @@ func TestGetOrgUsersByUserID(t *testing.T) { | |||
| func TestGetOrgUsersByOrgID(t *testing.T) { | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 
 | ||||
| 	orgUsers, err := GetOrgUsersByOrgID(3) | ||||
| 	orgUsers, err := GetOrgUsersByOrgID(3, false, 0, 0) | ||||
| 	assert.NoError(t, err) | ||||
| 	if assert.Len(t, orgUsers, 3) { | ||||
| 		assert.Equal(t, OrgUser{ | ||||
|  | @ -410,7 +410,7 @@ func TestGetOrgUsersByOrgID(t *testing.T) { | |||
| 			IsPublic: false}, *orgUsers[1]) | ||||
| 	} | ||||
| 
 | ||||
| 	orgUsers, err = GetOrgUsersByOrgID(NonexistentID) | ||||
| 	orgUsers, err = GetOrgUsersByOrgID(NonexistentID, false, 0, 0) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Len(t, orgUsers, 0) | ||||
| } | ||||
|  |  | |||
|  | @ -159,6 +159,7 @@ var ( | |||
| 		ExplorePagingNum      int | ||||
| 		IssuePagingNum        int | ||||
| 		RepoSearchPagingNum   int | ||||
| 		MembersPagingNum      int | ||||
| 		FeedMaxCommitNum      int | ||||
| 		GraphMaxCommitNum     int | ||||
| 		CodeCommentLines      int | ||||
|  | @ -191,6 +192,7 @@ var ( | |||
| 		ExplorePagingNum:    20, | ||||
| 		IssuePagingNum:      10, | ||||
| 		RepoSearchPagingNum: 10, | ||||
| 		MembersPagingNum:    20, | ||||
| 		FeedMaxCommitNum:    5, | ||||
| 		GraphMaxCommitNum:   100, | ||||
| 		CodeCommentLines:    4, | ||||
|  |  | |||
|  | @ -18,30 +18,13 @@ import ( | |||
| // listMembers list an organization's members
 | ||||
| func listMembers(ctx *context.APIContext, publicOnly bool) { | ||||
| 	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)) | ||||
|  |  | |||
|  | @ -25,14 +25,44 @@ func Members(ctx *context.Context) { | |||
| 	ctx.Data["Title"] = org.FullName | ||||
| 	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) | ||||
| 		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) | ||||
| } | ||||
|  |  | |||
|  | @ -537,14 +537,37 @@ func showOrgProfile(ctx *context.Context) { | |||
| 		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 | ||||
| 	} | ||||
| 
 | ||||
| 	ctx.Data["Repos"] = repos | ||||
| 	ctx.Data["Total"] = count | ||||
| 	ctx.Data["Members"] = org.Members | ||||
| 	ctx.Data["MembersTotal"] = membersCount | ||||
| 	ctx.Data["Members"] = members | ||||
| 	ctx.Data["Teams"] = org.Teams | ||||
| 
 | ||||
| 	pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5) | ||||
|  |  | |||
|  | @ -57,6 +57,8 @@ | |||
| 				</div> | ||||
| 			{{end}} | ||||
| 		</div> | ||||
| 
 | ||||
| 		{{template "base/paginate" .}} | ||||
| 	</div> | ||||
| </div> | ||||
| {{template "base/footer" .}} | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue