@clerk/shared
Version:
Internal package utils used by the Clerk SDKs
270 lines (268 loc) • 9.59 kB
JavaScript
const require_method_called = require('../../telemetry/events/method-called.js');
const require_contexts = require('../contexts.js');
const require_stable_keys = require('../stable-keys.js');
const require_createCacheKeys = require('./createCacheKeys.js');
const require_usePagesOrInfinite_shared = require('./usePagesOrInfinite.shared.js');
const require_usePagesOrInfinite = require('./usePagesOrInfinite.js');
const require_useUserBase = require('./base/useUserBase.js');
const require_useAttemptToEnableOrganizations = require('./useAttemptToEnableOrganizations.js');
//#region src/react/hooks/useOrganizationList.tsx
const undefinedPaginatedResource = {
data: void 0,
count: void 0,
error: void 0,
isLoading: false,
isFetching: false,
isError: false,
page: void 0,
pageCount: void 0,
fetchPage: void 0,
fetchNext: void 0,
fetchPrevious: void 0,
hasNextPage: false,
hasPreviousPage: false,
revalidate: void 0,
setData: void 0
};
/**
* The `useOrganizationList()` hook provides access to the current user's organization memberships, invitations, and suggestions. It also includes methods for creating new organizations and managing the active organization.
*
* @example
* ### Expanding and paginating attributes
*
* To keep network usage to a minimum, developers are required to opt-in by specifying which resource they need to fetch and paginate through. So by default, the `userMemberships`, `userInvitations`, and `userSuggestions` attributes are not populated. You must pass true or an object with the desired properties to fetch and paginate the data.
*
* ```tsx
* // userMemberships.data will never be populated
* const { userMemberships } = useOrganizationList()
*
* // Use default values to fetch userMemberships, such as initialPage = 1 and pageSize = 10
* const { userMemberships } = useOrganizationList({
* userMemberships: true,
* })
*
* // Pass your own values to fetch userMemberships
* const { userMemberships } = useOrganizationList({
* userMemberships: {
* pageSize: 20,
* initialPage: 2, // skips the first page
* },
* })
*
* // Aggregate pages in order to render an infinite list
* const { userMemberships } = useOrganizationList({
* userMemberships: {
* infinite: true,
* },
* })
* ```
*
* @example
* ### Infinite pagination
*
* The following example demonstrates how to use the `infinite` property to fetch and append new data to the existing list. The `userMemberships` attribute will be populated with the first page of the user's Organization memberships. When the "Load more" button is clicked, the `fetchNext` helper function will be called to append the next page of memberships to the list.
*
* ```tsx {{ filename: 'src/components/JoinedOrganizations.tsx' }}
* import { useOrganizationList } from '@clerk/react'
* import React from 'react'
*
* const JoinedOrganizations = () => {
* const { isLoaded, setActive, userMemberships } = useOrganizationList({
* userMemberships: {
* infinite: true,
* },
* })
*
* if (!isLoaded) {
* return <>Loading</>
* }
*
* return (
* <>
* <ul>
* {userMemberships.data?.map((mem) => (
* <li key={mem.id}>
* <span>{mem.organization.name}</span>
* <button onClick={() => setActive({ organization: mem.organization.id })}>Select</button>
* </li>
* ))}
* </ul>
*
* <button disabled={!userMemberships.hasNextPage} onClick={() => userMemberships.fetchNext()}>
* Load more
* </button>
* </>
* )
* }
*
* export default JoinedOrganizations
* ```
*
* @example
* ### Simple pagination
*
* The following example demonstrates how to use the `fetchPrevious` and `fetchNext` helper functions to paginate through the data. The `userInvitations` attribute will be populated with the first page of invitations. When the "Previous page" or "Next page" button is clicked, the `fetchPrevious` or `fetchNext` helper function will be called to fetch the previous or next page of invitations.
*
* Notice the difference between this example's pagination and the infinite pagination example above.
*
* ```tsx {{ filename: 'src/components/UserInvitationsTable.tsx' }}
* import { useOrganizationList } from '@clerk/react'
* import React from 'react'
*
* const UserInvitationsTable = () => {
* const { isLoaded, userInvitations } = useOrganizationList({
* userInvitations: {
* infinite: true,
* keepPreviousData: true,
* },
* })
*
* if (!isLoaded || userInvitations.isLoading) {
* return <>Loading</>
* }
*
* return (
* <>
* <table>
* <thead>
* <tr>
* <th>Email</th>
* <th>Org name</th>
* </tr>
* </thead>
*
* <tbody>
* {userInvitations.data?.map((inv) => (
* <tr key={inv.id}>
* <th>{inv.emailAddress}</th>
* <th>{inv.publicOrganizationData.name}</th>
* </tr>
* ))}
* </tbody>
* </table>
*
* <button disabled={!userInvitations.hasPreviousPage} onClick={userInvitations.fetchPrevious}>
* Prev
* </button>
* <button disabled={!userInvitations.hasNextPage} onClick={userInvitations.fetchNext}>
* Next
* </button>
* </>
* )
* }
*
* export default UserInvitationsTable
* ```
*/
function useOrganizationList(params) {
const { userMemberships, userInvitations, userSuggestions } = params || {};
require_contexts.useAssertWrappedByClerkProvider("useOrganizationList");
require_useAttemptToEnableOrganizations.useAttemptToEnableOrganizations("useOrganizationList");
const userMembershipsSafeValues = require_usePagesOrInfinite_shared.useWithSafeValues(userMemberships, {
initialPage: 1,
pageSize: 10,
keepPreviousData: false,
infinite: false
});
const userInvitationsSafeValues = require_usePagesOrInfinite_shared.useWithSafeValues(userInvitations, {
initialPage: 1,
pageSize: 10,
status: "pending",
keepPreviousData: false,
infinite: false
});
const userSuggestionsSafeValues = require_usePagesOrInfinite_shared.useWithSafeValues(userSuggestions, {
initialPage: 1,
pageSize: 10,
status: "pending",
keepPreviousData: false,
infinite: false
});
const clerk = require_contexts.useClerkInstanceContext();
const user = require_useUserBase.useUserBase();
clerk.telemetry?.record(require_method_called.eventMethodCalled("useOrganizationList"));
const userMembershipsParams = typeof userMemberships === "undefined" ? void 0 : {
initialPage: userMembershipsSafeValues.initialPage,
pageSize: userMembershipsSafeValues.pageSize
};
const userInvitationsParams = typeof userInvitations === "undefined" ? void 0 : {
initialPage: userInvitationsSafeValues.initialPage,
pageSize: userInvitationsSafeValues.pageSize,
status: userInvitationsSafeValues.status
};
const userSuggestionsParams = typeof userSuggestions === "undefined" ? void 0 : {
initialPage: userSuggestionsSafeValues.initialPage,
pageSize: userSuggestionsSafeValues.pageSize,
status: userSuggestionsSafeValues.status
};
const isClerkLoaded = !!(clerk.loaded && user);
const memberships = require_usePagesOrInfinite.usePagesOrInfinite({
fetcher: user?.getOrganizationMemberships,
config: {
keepPreviousData: userMembershipsSafeValues.keepPreviousData,
infinite: userMembershipsSafeValues.infinite,
enabled: !!userMembershipsParams,
isSignedIn: user !== null,
initialPage: userMembershipsSafeValues.initialPage,
pageSize: userMembershipsSafeValues.pageSize
},
keys: require_createCacheKeys.createCacheKeys({
stablePrefix: require_stable_keys.STABLE_KEYS.USER_MEMBERSHIPS_KEY,
authenticated: true,
tracked: { userId: user?.id },
untracked: { args: userMembershipsParams }
})
});
const invitations = require_usePagesOrInfinite.usePagesOrInfinite({
fetcher: user?.getOrganizationInvitations,
config: {
keepPreviousData: userInvitationsSafeValues.keepPreviousData,
infinite: userInvitationsSafeValues.infinite,
enabled: !!userInvitationsParams,
isSignedIn: user !== null,
initialPage: userInvitationsSafeValues.initialPage,
pageSize: userInvitationsSafeValues.pageSize
},
keys: require_createCacheKeys.createCacheKeys({
stablePrefix: require_stable_keys.STABLE_KEYS.USER_INVITATIONS_KEY,
authenticated: true,
tracked: { userId: user?.id },
untracked: { args: userInvitationsParams }
})
});
const suggestions = require_usePagesOrInfinite.usePagesOrInfinite({
fetcher: user?.getOrganizationSuggestions,
config: {
keepPreviousData: userSuggestionsSafeValues.keepPreviousData,
infinite: userSuggestionsSafeValues.infinite,
enabled: !!userSuggestionsParams,
isSignedIn: user !== null,
initialPage: userSuggestionsSafeValues.initialPage,
pageSize: userSuggestionsSafeValues.pageSize
},
keys: require_createCacheKeys.createCacheKeys({
stablePrefix: require_stable_keys.STABLE_KEYS.USER_SUGGESTIONS_KEY,
authenticated: true,
tracked: { userId: user?.id },
untracked: { args: userSuggestionsParams }
})
});
if (!isClerkLoaded) return {
isLoaded: false,
createOrganization: void 0,
setActive: void 0,
userMemberships: undefinedPaginatedResource,
userInvitations: undefinedPaginatedResource,
userSuggestions: undefinedPaginatedResource
};
return {
isLoaded: isClerkLoaded,
setActive: clerk.setActive,
createOrganization: clerk.createOrganization,
userMemberships: memberships,
userInvitations: invitations,
userSuggestions: suggestions
};
}
//#endregion
exports.useOrganizationList = useOrganizationList;