useUserTeams.tsx 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import {useEffect, useMemo} from 'react';
  2. import OrganizationStore from 'sentry/stores/organizationStore';
  3. import TeamStore from 'sentry/stores/teamStore';
  4. import {useLegacyStore} from 'sentry/stores/useLegacyStore';
  5. import type {Team} from 'sentry/types';
  6. import {isActiveSuperuser} from 'sentry/utils/isActiveSuperuser';
  7. import type {ApiQueryKey} from 'sentry/utils/queryClient';
  8. import {useApiQuery} from 'sentry/utils/queryClient';
  9. interface UseTeamsResult {
  10. isError: boolean | null;
  11. isLoading: boolean;
  12. teams: Team[];
  13. }
  14. function buildUserTeamsQueryKey(orgSlug: string): ApiQueryKey {
  15. return [`/organizations/${orgSlug}/user-teams/`];
  16. }
  17. /**
  18. * Fetches the user's teams if they aren't already in the TeamStore.
  19. * @returns an array of user's teams, isLoading, and isError
  20. *
  21. * example usage:
  22. * ```ts
  23. * const {teams, isLoading, isError} = useUserTeams();
  24. * ```
  25. */
  26. export function useUserTeams(): UseTeamsResult {
  27. const {organization} = useLegacyStore(OrganizationStore);
  28. const storeState = useLegacyStore(TeamStore);
  29. // Wait until the store has loaded to start fetching
  30. const shouldConsiderFetching = !!organization?.slug && !storeState.loading;
  31. // Only fetch if there are missing teams
  32. const hasMissing = !storeState.loadedUserTeams;
  33. const queryEnabled = shouldConsiderFetching && hasMissing;
  34. const {
  35. data: additionalTeams = [],
  36. isLoading,
  37. isError,
  38. } = useApiQuery<Team[]>(buildUserTeamsQueryKey(organization?.slug ?? ''), {
  39. staleTime: 0,
  40. enabled: queryEnabled,
  41. });
  42. // Save fetched teams to the team store
  43. useEffect(() => {
  44. if (additionalTeams.length > 0) {
  45. TeamStore.loadUserTeams(additionalTeams);
  46. }
  47. }, [additionalTeams]);
  48. const isSuperuser = isActiveSuperuser();
  49. const isOrgOwner = organization?.access.includes('org:admin');
  50. const teams = useMemo<Team[]>(() => {
  51. return isSuperuser || isOrgOwner
  52. ? storeState.teams
  53. : storeState.teams.filter(t => t.isMember);
  54. }, [isSuperuser, isOrgOwner, storeState.teams]);
  55. return {
  56. teams,
  57. isLoading: queryEnabled ? isLoading : storeState.loading,
  58. isError: queryEnabled ? isError : null,
  59. };
  60. }