feat: add a paginated organization members endpoint (#16835)

Closes
[coder/internal#460](https://github.com/coder/internal/issues/460)
This commit is contained in:
brettkolodny
2025-03-10 14:42:07 -04:00
committed by GitHub
parent 191b0efb80
commit 8c0350e20c
18 changed files with 548 additions and 1 deletions
+61
View File
@@ -142,6 +142,7 @@ func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request
rw.WriteHeader(http.StatusNoContent)
}
// @Deprecated use /organizations/{organization}/paginated-members [get]
// @Summary List organization members
// @ID list-organization-members
// @Security CoderSessionToken
@@ -178,6 +179,66 @@ func (api *API) listMembers(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusOK, resp)
}
// @Summary Paginated organization members
// @ID paginated-organization-members
// @Security CoderSessionToken
// @Produce json
// @Tags Members
// @Param organization path string true "Organization ID"
// @Param limit query int false "Page limit, if 0 returns all members"
// @Param offset query int false "Page offset"
// @Success 200 {object} []codersdk.PaginatedMembersResponse
// @Router /organizations/{organization}/paginated-members [get]
func (api *API) paginatedMembers(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()
organization = httpmw.OrganizationParam(r)
paginationParams, ok = parsePagination(rw, r)
)
if !ok {
return
}
paginatedMemberRows, err := api.Database.PaginatedOrganizationMembers(ctx, database.PaginatedOrganizationMembersParams{
OrganizationID: organization.ID,
LimitOpt: int32(paginationParams.Limit),
OffsetOpt: int32(paginationParams.Offset),
})
if httpapi.Is404Error(err) {
httpapi.ResourceNotFound(rw)
return
}
if err != nil {
httpapi.InternalServerError(rw, err)
return
}
memberRows := make([]database.OrganizationMembersRow, 0)
for _, pRow := range paginatedMemberRows {
row := database.OrganizationMembersRow{
OrganizationMember: pRow.OrganizationMember,
Username: pRow.Username,
AvatarURL: pRow.AvatarURL,
Name: pRow.Name,
Email: pRow.Email,
GlobalRoles: pRow.GlobalRoles,
}
memberRows = append(memberRows, row)
}
members, err := convertOrganizationMembersWithUserData(ctx, api.Database, memberRows)
if err != nil {
httpapi.InternalServerError(rw, err)
}
resp := codersdk.PaginatedMembersResponse{
Members: members,
Count: int(paginatedMemberRows[0].Count),
}
httpapi.Write(ctx, rw, http.StatusOK, resp)
}
// @Summary Assign role to organization member
// @ID assign-role-to-organization-member
// @Security CoderSessionToken