Skip to content

Commit 07ede0f

Browse files
committedSep 26, 2023
feat(shared): Introduce invitations and deprecate invitationList from useOrganization
1 parent c61ddf5 commit 07ede0f

File tree

3 files changed

+73
-24
lines changed

3 files changed

+73
-24
lines changed
 

‎.changeset/fast-books-kiss.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@clerk/shared': patch
3+
---
4+
5+
Introduce `invitations` in useOrganization, which enables to fetch invitations as paginated lists.
6+
Deprecate `invitationList` in favor of the above introduction.

‎packages/clerk-js/src/ui/components/OrganizationProfile/InvitedMembersList.tsx

+13-22
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,44 @@ import type { OrganizationInvitationResource } from '@clerk/types';
22

33
import { useCoreOrganization } from '../../contexts';
44
import { localizationKeys, Td, Text } from '../../customizables';
5-
import { ThreeDotsMenu, useCardState, usePagination, UserPreview } from '../../elements';
5+
import { ThreeDotsMenu, useCardState, UserPreview } from '../../elements';
66
import { handleError, roleLocalizationKey } from '../../utils';
77
import { DataTable, RowContainer } from './MemberListTable';
88

9-
const ITEMS_PER_PAGE = 10;
10-
119
export const InvitedMembersList = () => {
1210
const card = useCardState();
13-
const { page, changePage } = usePagination();
14-
const { organization, invitationList, ...rest } = useCoreOrganization({
15-
invitationList: { offset: (page - 1) * ITEMS_PER_PAGE, limit: ITEMS_PER_PAGE },
11+
const { organization, invitations } = useCoreOrganization({
12+
invitations: true,
1613
});
1714

18-
const mutateSwrState = () => {
19-
const unstable__mutate = (rest as any).unstable__mutate;
20-
if (unstable__mutate && typeof unstable__mutate === 'function') {
21-
unstable__mutate();
22-
}
23-
};
24-
2515
if (!organization) {
2616
return null;
2717
}
2818

2919
const revoke = (invitation: OrganizationInvitationResource) => () => {
3020
return card
31-
.runAsync(invitation.revoke)
32-
.then(mutateSwrState)
33-
.then(() => changePage(1))
21+
.runAsync(async () => {
22+
await invitation.revoke();
23+
await (invitations as any).unstable__mutate?.();
24+
})
3425
.catch(err => handleError(err, [], card.setError));
3526
};
3627

3728
return (
3829
<DataTable
39-
page={page}
40-
onPageChange={changePage}
41-
itemCount={organization.pendingInvitationsCount}
42-
itemsPerPage={ITEMS_PER_PAGE}
43-
isLoading={!invitationList}
30+
page={invitations?.page || 1}
31+
onPageChange={invitations?.fetchPage || (() => null)}
32+
itemCount={invitations?.count || 0}
33+
pageCount={invitations?.pageCount || 0}
34+
isLoading={invitations?.isLoading}
4435
emptyStateLocalizationKey={localizationKeys('organizationProfile.membersPage.invitationsTab.table__emptyRow')}
4536
headers={[
4637
localizationKeys('organizationProfile.membersPage.activeMembersTab.tableHeader__user'),
4738
localizationKeys('organizationProfile.membersPage.invitedMembersTab.tableHeader__invited'),
4839
localizationKeys('organizationProfile.membersPage.activeMembersTab.tableHeader__role'),
4940
localizationKeys('organizationProfile.membersPage.activeMembersTab.tableHeader__actions'),
5041
]}
51-
rows={(invitationList || []).map(i => (
42+
rows={(invitations?.data || []).map(i => (
5243
<InvitationRow
5344
key={i.id}
5445
invitation={i}

‎packages/shared/src/hooks/useOrganization.tsx

+54-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
ClerkPaginationParams,
33
GetDomainsParams,
4+
GetInvitationsParams,
45
GetMembershipRequestParams,
56
GetMembershipsParams,
67
GetPendingInvitationsParams,
@@ -14,6 +15,7 @@ import type { ClerkPaginatedResponse } from '@clerk/types';
1415
import type { GetMembersParams } from '@clerk/types';
1516

1617
import { disableSWRDevtools } from './clerk-swr';
18+
1719
disableSWRDevtools();
1820
import { useSWR } from './clerk-swr';
1921
import { useClerkInstanceContext, useOrganizationContext, useSessionContext } from './contexts';
@@ -22,7 +24,7 @@ import { usePagesOrInfinite, useWithSafeValues } from './usePagesOrInfinite';
2224

2325
type UseOrganizationParams = {
2426
/**
25-
* @deprecated Use invitations instead
27+
* @deprecated Use `invitations` instead
2628
*/
2729
invitationList?: GetPendingInvitationsParams;
2830
/**
@@ -50,7 +52,7 @@ type UseOrganizationParams = {
5052

5153
invitations?:
5254
| true
53-
| (GetMembersParams & {
55+
| (GetInvitationsParams & {
5456
infinite?: boolean;
5557
keepPreviousData?: boolean;
5658
});
@@ -60,6 +62,9 @@ type UseOrganizationReturn =
6062
| {
6163
isLoaded: false;
6264
organization: undefined;
65+
/**
66+
* @deprecated Use `invitations` instead
67+
*/
6368
invitationList: undefined;
6469
/**
6570
* @deprecated Use `memberships` instead
@@ -69,10 +74,14 @@ type UseOrganizationReturn =
6974
domains: PaginatedResourcesWithDefault<OrganizationDomainResource>;
7075
membershipRequests: PaginatedResourcesWithDefault<OrganizationMembershipRequestResource>;
7176
memberships: PaginatedResourcesWithDefault<OrganizationMembershipResource>;
77+
invitations: PaginatedResourcesWithDefault<OrganizationInvitationResource>;
7278
}
7379
| {
7480
isLoaded: true;
7581
organization: OrganizationResource;
82+
/**
83+
* @deprecated Use `invitations` instead
84+
*/
7685
invitationList: undefined;
7786
/**
7887
* @deprecated Use `memberships` instead
@@ -82,10 +91,14 @@ type UseOrganizationReturn =
8291
domains: PaginatedResourcesWithDefault<OrganizationDomainResource>;
8392
membershipRequests: PaginatedResourcesWithDefault<OrganizationMembershipRequestResource>;
8493
memberships: PaginatedResourcesWithDefault<OrganizationMembershipResource>;
94+
invitations: PaginatedResourcesWithDefault<OrganizationInvitationResource>;
8595
}
8696
| {
8797
isLoaded: boolean;
8898
organization: OrganizationResource | null;
99+
/**
100+
* @deprecated Use `invitations` instead
101+
*/
89102
invitationList: OrganizationInvitationResource[] | null | undefined;
90103
/**
91104
* @deprecated Use `memberships` instead
@@ -95,6 +108,7 @@ type UseOrganizationReturn =
95108
domains: PaginatedResources<OrganizationDomainResource> | null;
96109
membershipRequests: PaginatedResources<OrganizationMembershipRequestResource> | null;
97110
memberships: PaginatedResources<OrganizationMembershipResource> | null;
111+
invitations: PaginatedResources<OrganizationInvitationResource> | null;
98112
};
99113

100114
type UseOrganization = (params?: UseOrganizationParams) => UseOrganizationReturn;
@@ -121,6 +135,7 @@ export const useOrganization: UseOrganization = params => {
121135
domains: domainListParams,
122136
membershipRequests: membershipRequestsListParams,
123137
memberships: membersListParams,
138+
invitations: invitationsListParams,
124139
} = params || {};
125140
const { organization, lastOrganizationMember, lastOrganizationInvitation } = useOrganizationContext();
126141
const session = useSessionContext();
@@ -149,6 +164,14 @@ export const useOrganization: UseOrganization = params => {
149164
infinite: false,
150165
});
151166

167+
const invitationsSafeValues = useWithSafeValues(invitationsListParams, {
168+
initialPage: 1,
169+
pageSize: 10,
170+
status: ['pending'],
171+
keepPreviousData: false,
172+
infinite: false,
173+
});
174+
152175
const clerk = useClerkInstanceContext();
153176

154177
const shouldFetch = !!(clerk.loaded && session && organization);
@@ -180,6 +203,15 @@ export const useOrganization: UseOrganization = params => {
180203
role: membersSafeValues.role,
181204
};
182205

206+
const invitationsParams =
207+
typeof invitationsListParams === 'undefined'
208+
? undefined
209+
: {
210+
initialPage: invitationsSafeValues.initialPage,
211+
pageSize: invitationsSafeValues.pageSize,
212+
status: invitationsSafeValues.status,
213+
};
214+
183215
const domains = usePagesOrInfinite<GetDomainsParams, ClerkPaginatedResponse<OrganizationDomainResource>>(
184216
{
185217
...domainParams,
@@ -232,6 +264,22 @@ export const useOrganization: UseOrganization = params => {
232264
},
233265
);
234266

267+
const invitations = usePagesOrInfinite<GetInvitationsParams, ClerkPaginatedResponse<OrganizationInvitationResource>>(
268+
{
269+
...invitationsParams,
270+
},
271+
organization?.getInvitations,
272+
{
273+
keepPreviousData: membersSafeValues.keepPreviousData,
274+
infinite: membersSafeValues.infinite,
275+
enabled: !!invitationsParams,
276+
},
277+
{
278+
type: 'invitations',
279+
organizationId: organization?.id,
280+
},
281+
);
282+
235283
// Some gymnastics to adhere to the rules of hooks
236284
// We need to make sure useSWR is called on every render
237285
const pendingInvitations = !clerk.loaded
@@ -274,6 +322,7 @@ export const useOrganization: UseOrganization = params => {
274322
domains: undefinedPaginatedResource,
275323
membershipRequests: undefinedPaginatedResource,
276324
memberships: undefinedPaginatedResource,
325+
invitations: undefinedPaginatedResource,
277326
};
278327
}
279328

@@ -287,6 +336,7 @@ export const useOrganization: UseOrganization = params => {
287336
domains: null,
288337
membershipRequests: null,
289338
memberships: null,
339+
invitations: null,
290340
};
291341
}
292342

@@ -301,6 +351,7 @@ export const useOrganization: UseOrganization = params => {
301351
domains: undefinedPaginatedResource,
302352
membershipRequests: undefinedPaginatedResource,
303353
memberships: undefinedPaginatedResource,
354+
invitations: undefinedPaginatedResource,
304355
};
305356
}
306357

@@ -317,6 +368,7 @@ export const useOrganization: UseOrganization = params => {
317368
domains,
318369
membershipRequests,
319370
memberships,
371+
invitations,
320372
};
321373
};
322374

0 commit comments

Comments
 (0)