Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 76a1c65

Browse files
authored
feat(plg): Use react-query for team management (#63267)
1 parent db7a268 commit 76a1c65

File tree

14 files changed

+273
-295
lines changed

14 files changed

+273
-295
lines changed

client/web/BUILD.bazel

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ ts_project(
279279
"src/cody/sidebar/useSidebarSize.tsx",
280280
"src/cody/subscription/CodySubscriptionPage.tsx",
281281
"src/cody/subscription/queries.tsx",
282-
"src/cody/subscription/subscriptionSummary.ts",
283282
"src/cody/switch-account/CodySwitchAccountPage.tsx",
284283
"src/cody/team/CodyManageTeamPage.tsx",
285284
"src/cody/team/InviteUsers.tsx",

client/web/src/cody/management/CodyManagementPage.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ import { AcceptInviteBanner } from '../invites/AcceptInviteBanner'
2525
import { isCodyEnabled } from '../isCodyEnabled'
2626
import { CodyOnboarding, type IEditor } from '../onboarding/CodyOnboarding'
2727
import { USER_CODY_PLAN, USER_CODY_USAGE } from '../subscription/queries'
28-
import { useCodySubscriptionSummaryData } from '../subscription/subscriptionSummary'
2928
import { getManageSubscriptionPageURL } from '../util'
3029

30+
import { useSubscriptionSummary } from './api/react-query/subscriptions'
3131
import { SubscriptionStats } from './SubscriptionStats'
3232
import { UseCodyInEditorSection } from './UseCodyInEditorSection'
3333

@@ -74,8 +74,8 @@ export const CodyManagementPage: React.FunctionComponent<CodyManagementPageProps
7474
{}
7575
)
7676

77-
const [codySubscriptionSummary] = useCodySubscriptionSummaryData()
78-
const isAdmin = codySubscriptionSummary?.userRole === 'admin'
77+
const subscriptionSummaryQueryResult = useSubscriptionSummary()
78+
const isAdmin = subscriptionSummaryQueryResult?.data?.userRole === 'admin'
7979

8080
const [selectedEditor, setSelectedEditor] = React.useState<IEditor | null>(null)
8181
const [selectedEditorStep, setSelectedEditorStep] = React.useState<EditorStep | null>(null)

client/web/src/cody/management/api/client.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,28 @@ export module Client {
5252
return { method: 'GET', urlSuffix: '/team/current/members' }
5353
}
5454

55+
export function updateTeamMember(requestBody: types.UpdateTeamMembersRequest): Call<unknown> {
56+
return { method: 'PATCH', urlSuffix: '/team/current/members', requestBody }
57+
}
58+
5559
// Invites
5660

5761
export function getInvite(teamId: string, inviteId: string): Call<types.TeamInvite> {
5862
return { method: 'GET', urlSuffix: `/team/${teamId}/invites/${inviteId}` }
5963
}
6064

65+
export function getTeamInvites(): Call<types.ListTeamInvitesResponse> {
66+
return { method: 'GET', urlSuffix: '/team/current/invites' }
67+
}
68+
69+
export function sendInvite(requestBody: types.CreateTeamInviteRequest): Call<types.ListTeamInvitesResponse> {
70+
return { method: 'POST', urlSuffix: '/team/current/invites', requestBody }
71+
}
72+
73+
export function resendInvite(inviteId: string): Call<unknown> {
74+
return { method: 'POST', urlSuffix: `/team/current/invites/${inviteId}/resend` }
75+
}
76+
6177
export function acceptInvite(teamId: string, inviteId: string): Call<unknown> {
6278
return { method: 'POST', urlSuffix: `/team/${teamId}/invites/${inviteId}/accept` }
6379
}
@@ -76,7 +92,7 @@ export module Client {
7692
}
7793

7894
// Call is the bundle of data necessary for making an API request.
79-
// This is a sort of "meta request" in the same veign as the `gql`
95+
// This is a sort of "meta request" in the same vein as the `gql`
8096
// template tag, see: https://github.com/apollographql/graphql-tag
8197
export interface Call<Resp> {
8298
method: 'GET' | 'POST' | 'PATCH' | 'DELETE'

client/web/src/cody/management/api/react-query/invites.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
} from '@tanstack/react-query'
88

99
import { Client } from '../client'
10-
import type { TeamInvite } from '../teamInvites'
10+
import type { TeamInvite, ListTeamInvitesResponse, CreateTeamInviteRequest } from '../types'
1111

1212
import { callCodyProApi } from './callCodyProApi'
1313
import { queryKeys } from './queryKeys'
@@ -27,6 +27,36 @@ export const useInvite = ({
2727
},
2828
})
2929

30+
export const useTeamInvites = (): UseQueryResult<Omit<TeamInvite, 'sentBy'>[] | undefined> =>
31+
useQuery({
32+
queryKey: queryKeys.invites.teamInvites(),
33+
queryFn: async () => {
34+
const response = await callCodyProApi(Client.getTeamInvites())
35+
return ((await response.json()) as ListTeamInvitesResponse).invites
36+
},
37+
})
38+
39+
export const useSendInvite = (): UseMutationResult<Omit<TeamInvite, 'sentBy'>, Error, CreateTeamInviteRequest> => {
40+
const queryClient = useQueryClient()
41+
return useMutation({
42+
mutationFn: async requestBody => (await callCodyProApi(Client.sendInvite(requestBody))).json(),
43+
onSuccess: (newInvite: Omit<TeamInvite, 'sentBy'>) => {
44+
queryClient.setQueryData(queryKeys.invites.teamInvites(), (prevInvites: Omit<TeamInvite, 'sentBy'>[]) => [
45+
...prevInvites,
46+
newInvite,
47+
])
48+
},
49+
})
50+
}
51+
52+
export const useResendInvite = (): UseMutationResult<unknown, Error, { inviteId: string }> => {
53+
const queryClient = useQueryClient()
54+
return useMutation({
55+
mutationFn: async ({ inviteId }) => callCodyProApi(Client.resendInvite(inviteId)),
56+
onSuccess: () => queryClient.invalidateQueries({ queryKey: queryKeys.invites.teamInvites() }),
57+
})
58+
}
59+
3060
export const useAcceptInvite = (): UseMutationResult<unknown, Error, { teamId: string; inviteId: string }> => {
3161
const queryClient = useQueryClient()
3262
return useMutation({
@@ -44,7 +74,9 @@ export const useCancelInvite = (): UseMutationResult<unknown, Error, { teamId: s
4474
const queryClient = useQueryClient()
4575
return useMutation({
4676
mutationFn: async ({ teamId, inviteId }) => callCodyProApi(Client.cancelInvite(teamId, inviteId)),
47-
onSuccess: (_, { teamId, inviteId }) =>
48-
queryClient.invalidateQueries({ queryKey: queryKeys.invites.invite(teamId, inviteId) }),
77+
onSuccess: (_, { inviteId }) =>
78+
queryClient.setQueryData(queryKeys.invites.teamInvites(), (prevInvites: TeamInvite[]) =>
79+
prevInvites.filter(invite => invite.id !== inviteId)
80+
),
4981
})
5082
}

client/web/src/cody/management/api/react-query/queryKeys.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ export const queryKeys = {
1414
invites: {
1515
all: ['invite'] as const,
1616
invite: (teamId: string, inviteId: string) => [...queryKeys.invites.all, teamId, inviteId] as const,
17+
teamInvites: () => [...queryKeys.invites.all, 'team-invites'] as const,
1718
},
1819
}

client/web/src/cody/management/api/react-query/subscriptions.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import type {
1616
SubscriptionSummary,
1717
UpdateSubscriptionRequest,
1818
GetSubscriptionInvoicesResponse,
19-
} from '../teamSubscriptions'
19+
ListTeamMembersResponse,
20+
ListTeamInvitesResponse,
21+
} from '../types'
2022

2123
import { callCodyProApi } from './callCodyProApi'
2224
import { queryKeys } from './queryKeys'
@@ -26,7 +28,7 @@ export const useCurrentSubscription = (): UseQueryResult<Subscription | undefine
2628
queryKey: queryKeys.subscriptions.subscription(),
2729
queryFn: async () => {
2830
const response = await callCodyProApi(Client.getCurrentSubscription())
29-
return response?.json()
31+
return response.json()
3032
},
3133
})
3234

@@ -35,7 +37,7 @@ export const useSubscriptionSummary = (): UseQueryResult<SubscriptionSummary | u
3537
queryKey: queryKeys.subscriptions.subscriptionSummary(),
3638
queryFn: async () => {
3739
const response = await callCodyProApi(Client.getCurrentSubscriptionSummary())
38-
return response?.json()
40+
return response.json()
3941
},
4042
})
4143

@@ -48,6 +50,24 @@ export const useSubscriptionInvoices = (): UseQueryResult<GetSubscriptionInvoice
4850
},
4951
})
5052

53+
export const useTeamMembers = (): UseQueryResult<ListTeamMembersResponse | undefined> =>
54+
useQuery({
55+
queryKey: queryKeys.teams.teamMembers(),
56+
queryFn: async () => {
57+
const response = await callCodyProApi(Client.getCurrentTeamMembers())
58+
return response.ok ? response.json() : undefined
59+
},
60+
})
61+
62+
export const useTeamInvites = (): UseQueryResult<ListTeamInvitesResponse | undefined> =>
63+
useQuery({
64+
queryKey: queryKeys.invites.teamInvites(),
65+
queryFn: async () => {
66+
const response = await callCodyProApi(Client.getTeamInvites())
67+
return response.ok ? response.json() : undefined
68+
},
69+
})
70+
5171
export const useUpdateCurrentSubscription = (): UseMutationResult<
5272
Subscription | undefined,
5373
Error,
@@ -57,7 +77,7 @@ export const useUpdateCurrentSubscription = (): UseMutationResult<
5777
return useMutation({
5878
mutationFn: async requestBody => {
5979
const response = await callCodyProApi(Client.updateCurrentSubscription(requestBody))
60-
return response?.json()
80+
return response.json()
6181
},
6282
onSuccess: data => {
6383
// We get updated subscription data in response - no need to refetch subscription.

client/web/src/cody/management/api/react-query/teams.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
import { useQuery, type UseQueryResult } from '@tanstack/react-query'
1+
import {
2+
useMutation,
3+
useQuery,
4+
useQueryClient,
5+
type UseQueryResult,
6+
type UseMutationResult,
7+
} from '@tanstack/react-query'
28

39
import { Client } from '../client'
4-
import type { ListTeamMembersResponse } from '../teamMembers'
10+
import type { ListTeamMembersResponse, UpdateTeamMembersRequest } from '../types'
511

612
import { callCodyProApi } from './callCodyProApi'
713
import { queryKeys } from './queryKeys'
@@ -14,3 +20,11 @@ export const useTeamMembers = (): UseQueryResult<ListTeamMembersResponse | undef
1420
return response?.json()
1521
},
1622
})
23+
24+
export const useUpdateTeamMember = (): UseMutationResult<unknown, Error, UpdateTeamMembersRequest> => {
25+
const queryClient = useQueryClient()
26+
return useMutation({
27+
mutationFn: async requestBody => callCodyProApi(Client.updateTeamMember(requestBody)),
28+
onSuccess: () => queryClient.invalidateQueries({ queryKey: queryKeys.teams.teamMembers() }),
29+
})
30+
}

client/web/src/cody/management/api/teamInvites.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ export interface TeamInvite {
1111
status: TeamInviteStatus
1212
error?: string
1313

14-
sentAt: Date
14+
sentAt: string
1515
sentBy: string
16-
acceptedAt?: Date
16+
acceptedAt?: string
1717
}
1818

1919
export interface CreateTeamInviteRequest {

client/web/src/cody/management/api/teamMembers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ export type TeamRole = 'member' | 'admin'
33
export interface TeamMember {
44
accountId: string
55
displayName: string
6+
email: string
67
avatarUrl: string
7-
88
role: TeamRole
99
}
1010

@@ -19,7 +19,7 @@ export interface ListTeamMembersResponse {
1919
}
2020

2121
export interface UpdateTeamMembersRequest {
22-
addMembver?: TeamMemberRef
22+
addMember?: TeamMemberRef
2323
removeMember?: TeamMemberRef
2424
updateMemberRole?: TeamMemberRef
2525
}

client/web/src/cody/subscription/subscriptionSummary.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)