index.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {
  2. addErrorMessage,
  3. addLoadingMessage,
  4. addSuccessMessage,
  5. } from 'sentry/actionCreators/indicator';
  6. import LoadingError from 'sentry/components/loadingError';
  7. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  8. import {t} from 'sentry/locale';
  9. import {
  10. setApiQueryData,
  11. useApiQuery,
  12. useMutation,
  13. useQueryClient,
  14. } from 'sentry/utils/queryClient';
  15. import useApi from 'sentry/utils/useApi';
  16. import {useNavigate} from 'sentry/utils/useNavigate';
  17. import useOrganization from 'sentry/utils/useOrganization';
  18. import OrganizationApiKeysList from './organizationApiKeysList';
  19. import type {DeprecatedApiKey} from './types';
  20. /**
  21. * API Keys are deprecated, but there may be some legacy customers that still use it
  22. */
  23. function OrganizationApiKeys() {
  24. const api = useApi();
  25. const organization = useOrganization();
  26. const navigate = useNavigate();
  27. const queryClient = useQueryClient();
  28. const {
  29. data: apiKeys = [],
  30. isPending,
  31. isError,
  32. refetch,
  33. } = useApiQuery<DeprecatedApiKey[]>([`/organizations/${organization.slug}/api-keys/`], {
  34. staleTime: 0,
  35. });
  36. const removeMutation = useMutation({
  37. mutationFn: ({removedId}: {removedId: string}) => {
  38. return api.requestPromise(
  39. `/organizations/${organization.slug}/api-keys/${removedId}/`,
  40. {
  41. method: 'DELETE',
  42. data: {},
  43. }
  44. );
  45. },
  46. onMutate: () => {
  47. addLoadingMessage(t('Removing API key'));
  48. },
  49. onSuccess: (_data, {removedId}) => {
  50. setApiQueryData<DeprecatedApiKey[]>(
  51. queryClient,
  52. [`/organizations/${organization.slug}/api-keys/`],
  53. oldData => {
  54. if (!oldData) {
  55. return oldData;
  56. }
  57. return oldData.filter(({id}) => id !== removedId);
  58. }
  59. );
  60. },
  61. onError: () => {
  62. addErrorMessage(t('Error removing key'));
  63. },
  64. });
  65. const addMutation = useMutation({
  66. mutationFn: (): Promise<DeprecatedApiKey> => {
  67. return api.requestPromise(`/organizations/${organization.slug}/api-keys/`, {
  68. method: 'POST',
  69. data: {},
  70. });
  71. },
  72. onSuccess: data => {
  73. if (!data) {
  74. return;
  75. }
  76. navigate(`/settings/${organization.slug}/api-keys/${data.id}/`);
  77. addSuccessMessage(t('Created a new API key "%s"', data.label));
  78. },
  79. onError: () => {
  80. addErrorMessage(t('Error creating key'));
  81. },
  82. });
  83. if (isError) {
  84. return <LoadingError onRetry={refetch} />;
  85. }
  86. return (
  87. <SentryDocumentTitle title={t('Api Keys')} orgSlug={organization.slug}>
  88. <OrganizationApiKeysList
  89. organization={organization}
  90. loading={isPending}
  91. busy={addMutation.isPending}
  92. keys={apiKeys}
  93. onRemove={id => removeMutation.mutateAsync({removedId: id})}
  94. onAddApiKey={addMutation.mutateAsync}
  95. />
  96. </SentryDocumentTitle>
  97. );
  98. }
  99. export default OrganizationApiKeys;