index.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import {useCallback, useEffect, useMemo} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import {loadStats} from 'sentry/actionCreators/projects';
  4. import LoadingError from 'sentry/components/loadingError';
  5. import LoadingIndicator from 'sentry/components/loadingIndicator';
  6. import {t} from 'sentry/locale';
  7. import TeamStore from 'sentry/stores/teamStore';
  8. import type {AccessRequest} from 'sentry/types/organization';
  9. import {
  10. type ApiQueryKey,
  11. setApiQueryData,
  12. useApiQuery,
  13. useQueryClient,
  14. } from 'sentry/utils/queryClient';
  15. import useApi from 'sentry/utils/useApi';
  16. import useOrganization from 'sentry/utils/useOrganization';
  17. import OrganizationTeams from './organizationTeams';
  18. export function OrganizationTeamsContainer(props: RouteComponentProps<{}, {}>) {
  19. const api = useApi();
  20. const organization = useOrganization({allowNull: true});
  21. const queryClient = useQueryClient();
  22. const queryKey: ApiQueryKey = useMemo(
  23. () => [`/organizations/${organization?.slug}/access-requests/`],
  24. [organization?.slug]
  25. );
  26. const {
  27. isLoading,
  28. isError,
  29. data: requestList = [],
  30. } = useApiQuery<AccessRequest[]>(queryKey, {
  31. staleTime: 0,
  32. retry: false,
  33. enabled: !!organization?.slug,
  34. });
  35. useEffect(() => {
  36. if (!organization?.slug) {
  37. return;
  38. }
  39. loadStats(api, {
  40. orgId: organization?.slug,
  41. query: {
  42. since: (new Date().getTime() / 1000 - 3600 * 24).toString(),
  43. stat: 'generated',
  44. group: 'project',
  45. },
  46. });
  47. }, [organization?.slug, api]);
  48. const handleRemoveAccessRequest = useCallback(
  49. (id: string, isApproved: boolean) => {
  50. const requestToRemove = requestList.find(request => request.id === id);
  51. const newRequestList = requestList.filter(request => request.id !== id);
  52. // Update the cache with the new value
  53. setApiQueryData(queryClient, queryKey, newRequestList);
  54. // To be safer, trigger a refetch to ensure data is correct
  55. queryClient.invalidateQueries(queryKey);
  56. if (isApproved && requestToRemove) {
  57. const team = requestToRemove.team;
  58. TeamStore.onUpdateSuccess(team.slug, {
  59. ...team,
  60. memberCount: team.memberCount + 1,
  61. });
  62. }
  63. },
  64. [requestList, queryKey, queryClient]
  65. );
  66. // Can't do anything if we don't have an organization
  67. if (!organization) {
  68. return <LoadingError message={t('Organization not found')} />;
  69. }
  70. if (isLoading) {
  71. return <LoadingIndicator />;
  72. }
  73. if (isError) {
  74. return <LoadingError />;
  75. }
  76. return (
  77. <OrganizationTeams
  78. {...props}
  79. access={new Set(organization?.access)}
  80. features={new Set(organization?.features)}
  81. organization={organization}
  82. requestList={requestList}
  83. onRemoveAccessRequest={handleRemoveAccessRequest}
  84. />
  85. );
  86. }
  87. export default OrganizationTeamsContainer;