8000 feat: add members settings page for organizations by aslilac · Pull Request #13817 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

feat: add members settings page for organizations #13817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
whatever I have so far
  • Loading branch information
aslilac committed Jul 8, 2024
commit c09f530e8a24456a49892d3ccea9126b7d8f2e65
14 changes: 4 additions & 10 deletions coderd/apidoc/docs.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 4 additions & 10 deletions coderd/apidoc/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion coderd/apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) {
return
}

httpapi.Write(ctx, rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
}

// @Summary Get token config
Expand Down
6 changes: 5 additions & 1 deletion coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion coderd/database/queries/organizationmembers.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
-- - Use both to get a specific org member row
SELECT
sqlc.embed(organization_members),
users.username
users.username, users.avatar_url, users.name
FROM
organization_members
INNER JOIN
Expand Down
2 changes: 1 addition & 1 deletion coderd/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (api *API) putDeploymentHealthSettings(rw http.ResponseWriter, r *http.Requ

if bytes.Equal(settingsJSON, []byte(currentSettingsJSON)) {
// See: https://www.rfc-editor.org/rfc/rfc7231#section-6.3.5
httpapi.Write(r.Context(), rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
return
}

Expand Down
2 changes: 1 addition & 1 deletion coderd/externalauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func (api *API) postExternalAuthDeviceByID(rw http.ResponseWriter, r *http.Reque
return
}
}
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
}

// @Summary Get external auth device by ID.
Expand Down
2 changes: 1 addition & 1 deletion coderd/identityprovider/revoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ func RevokeApp(db database.Store) http.HandlerFunc {
httpapi.InternalServerError(rw, err)
return
}
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
}
}
16 changes: 9 additions & 7 deletions coderd/members.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (api *API) postOrganizationMember(rw http.ResponseWriter, r *http.Request)
// @Tags Members
// @Param organization path string true "Organization ID"
// @Param user path string true "User ID, name, or me"
// @Success 200 {object} codersdk.OrganizationMember
// @Success 204
// @Router /organizations/{organization}/members/{user} [delete]
func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request) {
var (
Expand Down Expand Up @@ -118,7 +118,7 @@ func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request
}

aReq.New = database.AuditableOrganizationMember{}
httpapi.Write(ctx, rw, http.StatusOK, "organization member removed")
rw.WriteHeader(http.StatusNoContent)
}

// @Summary List organization members
Expand All @@ -127,7 +127,7 @@ func (api *API) deleteOrganizationMember(rw http.ResponseWriter, r *http.Request
// @Produce json
// @Tags Members
// @Param organization path string true "Organization ID"
// @Success 200 {object} []codersdk.OrganizationMemberWithName
// @Success 200 {object} []codersdk.OrganizationMemberWithUserData
// @Router /organizations/{organization}/members [get]
func (api *API) listMembers(rw http.ResponseWriter, r *http.Request) {
var (
Expand All @@ -148,7 +148,7 @@ func (api *API) listMembers(rw http.ResponseWriter, r *http.Request) {
return
}

resp, err := convertOrganizationMemberRows(ctx, api.Database, members)
resp, err := convertOrganizationMembersWithUserData(ctx, api.Database, members)
if err != nil {
httpapi.InternalServerError(rw, err)
return
Expand Down Expand Up @@ -292,7 +292,7 @@ func convertOrganizationMembers(ctx context.Context, db database.Store, mems []d
return converted, nil
}

func convertOrganizationMemberRows(ctx context.Context, db database.Store, rows []database.OrganizationMembersRow) ([]codersdk.OrganizationMemberWithName, error) {
func convertOrganizationMembersWithUserData(ctx context.Context, db database.Store, rows []database.OrganizationMembersRow) ([]codersdk.OrganizationMemberWithUserData, error) {
members := make([]database.OrganizationMember, 0)
for _, row := range rows {
members = append(members, row.OrganizationMember)
Expand All @@ -306,10 +306,12 @@ func convertOrganizationMemberRows(ctx context.Context, db database.Store, rows
return nil, xerrors.Errorf("conversion failed, mismatch slice lengths")
}

converted := make([]codersdk.OrganizationMemberWithName, 0)
converted := make([]codersdk.OrganizationMemberWithUserData, 0)
for i := range convertedMembers {
converted = append(converted, codersdk.OrganizationMemberWithName{
converted = append(converted, codersdk.OrganizationMemberWithUserData{
Username: rows[i].Username,
AvatarURL: rows[i].AvatarURL,
Name: rows[i].Name,
OrganizationMember: convertedMembers[i],
})
}
Expand Down
4 changes: 2 additions & 2 deletions coderd/oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func (api *API) deleteOAuth2ProviderApp(rw http.ResponseWriter, r *http.Request)
})
return
}
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
}

// @Summary Get OAuth2 application secrets.
Expand Down Expand Up @@ -324,7 +324,7 @@ func (api *API) deleteOAuth2ProviderAppSecret(rw http.ResponseWriter, r *http.Re
})
return
}
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
}

// @Summary OAuth2 authorization request.
Expand Down
2 changes: 1 addition & 1 deletion coderd/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {

if updated.UpdatedAt.IsZero() {
aReq.New = template
httpapi.Write(ctx, rw, http.StatusNotModified, nil)
rw.WriteHeader(http.StatusNotModified)
return
}
aReq.New = updated
Expand Down
8 changes: 3 additions & 5 deletions coderd/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) {
// @Produce json
// @Tags Users
// @Param user path string true "User ID, name, or me"
// @Success 200 {object} codersdk.User
// @Success 204
// @Router /users/{user} [delete]
func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
Expand Down Expand Up @@ -558,9 +558,7 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) {
}
user.Deleted = true
aReq.New = user
httpapi.Write(ctx, rw, http.StatusOK, codersdk.Response{
Message: "User has been deleted!",
})
rw.WriteHeader(http.StatusNoContent)
}

// Returns the parameterized user requested. All validation
Expand Down Expand Up @@ -1008,7 +1006,7 @@ func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) {
newUser.HashedPassword = []byte(hashedPassword)
aReq.New = newUser

httpapi.Write(ctx, rw, http.StatusNoContent, nil)
rw.WriteHeader(http.StatusNoContent)
}

// @Summary Get user roles
Expand Down
4 changes: 1 addition & 3 deletions coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -927,9 +927,7 @@ func (api *API) putWorkspaceDormant(rw http.ResponseWriter, r *http.Request) {

// If the workspace is already in the desired state do nothing!
if workspace.DormantAt.Valid == req.Dormant {
httpapi.Write(ctx, rw, http.StatusNotModified, codersdk.Response{
Message: "Nothing to do!",
})
rw.WriteHeader(http.StatusNotModified)
return
}

Expand Down
4 changes: 3 additions & 1 deletion codersdk/organizations.go
Original file line number Diff lin 72A8 e number Diff line change
Expand Up @@ -65,8 +65,10 @@ type OrganizationMember struct {
Roles []SlimRole `table:"organization_roles" json:"roles"`
}

type OrganizationMemberWithName struct {
type OrganizationMemberWithUserData struct {
Username string `table:"username,default_sort" json:"username"`
Name string `table:"name" json:"name"`
AvatarURL string `json:"avatar_url"`
OrganizationMember `table:"m,recursive_inline"`
}

Expand Down
4 changes: 2 additions & 2 deletions codersdk/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ func (c *Client) DeleteOrganizationMember(ctx context.Context, organizationID uu
}

// OrganizationMembers lists all members in an organization
func (c *Client) OrganizationMembers(ctx context.Context, organizationID uuid.UUID) ([]OrganizationMemberWithName, error) {
func (c *Client) OrganizationMembers(ctx context.Context, organizationID uuid.UUID) ([]OrganizationMemberWithUserData, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/members/", organizationID), nil)
if err != nil {
return nil, err
Expand All @@ -418,7 +418,7 @@ func (c *Client) OrganizationMembers(ctx context.Context, organizationID uuid.UU
if res.StatusCode != http.StatusOK {
return nil, ReadBodyAsError(res)
}
var members []OrganizationMemberWithName
var members []OrganizationMemberWithUserData
return members, json.NewDecoder(res.Body).Decode(&members)
}

Expand Down
27 changes: 3 additions & 24 deletions docs/api/members.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 3 additions & 31 deletions docs/api/users.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions site/src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,22 @@ class ApiMethods {
return response.data;
};

getOrganizationMembers = async (organizationId: string) => {
const response = await this.axios.get<
TypesGen.OrganizationMemberWithName[]
>(`/api/v2/organizations/${organizationId}/members`);

return response.data;
};

addOrganizationMember = async (organizationId: string, userId: string) => {
const response = await this.axios.post<TypesGen.OrganizationMember>(
`/api/v2/organizations/${organizationId}/members/${userId}`,
);

return response.data;
};

getOrganizations = async (): Promise<TypesGen.Organization[]> => {
const response = await this.axios.get<TypesGen.Organization[]>(
"/api/v2/users/me/organizations",
Expand Down
Loading
Loading
0