organizationApiKeyDetails.tsx 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  2. import ApiForm from 'sentry/components/forms/apiForm';
  3. import MultipleCheckbox from 'sentry/components/forms/controls/multipleCheckbox';
  4. import TextareaField from 'sentry/components/forms/fields/textareaField';
  5. import TextField from 'sentry/components/forms/fields/textField';
  6. import FormField from 'sentry/components/forms/formField';
  7. import LoadingError from 'sentry/components/loadingError';
  8. import LoadingIndicator from 'sentry/components/loadingIndicator';
  9. import Panel from 'sentry/components/panels/panel';
  10. import PanelBody from 'sentry/components/panels/panelBody';
  11. import PanelHeader from 'sentry/components/panels/panelHeader';
  12. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  13. import {API_ACCESS_SCOPES} from 'sentry/constants';
  14. import {t} from 'sentry/locale';
  15. import {useApiQuery} from 'sentry/utils/queryClient';
  16. import {useNavigate} from 'sentry/utils/useNavigate';
  17. import useOrganization from 'sentry/utils/useOrganization';
  18. import {useParams} from 'sentry/utils/useParams';
  19. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  20. import type {DeprecatedApiKey} from './types';
  21. type RouteParams = {
  22. apiKey: string;
  23. };
  24. function OrganizationApiKeyDetails() {
  25. const organization = useOrganization();
  26. const params = useParams<RouteParams>();
  27. const navigate = useNavigate();
  28. const {
  29. data: apiKey,
  30. isPending,
  31. isError,
  32. refetch,
  33. } = useApiQuery<DeprecatedApiKey>(
  34. [`/organizations/${organization.slug}/api-keys/${params.apiKey}/`],
  35. {
  36. staleTime: 0,
  37. }
  38. );
  39. const handleSubmitSuccess = () => {
  40. addSuccessMessage('Saved changes');
  41. // Go back to API list
  42. navigate(`/settings/${organization.slug}/api-keys/`);
  43. };
  44. const handleSubmitError = () => {
  45. addErrorMessage('Unable to save changes. Please try again.');
  46. };
  47. if (isError) {
  48. return <LoadingError onRetry={refetch} />;
  49. }
  50. if (isPending) {
  51. return <LoadingIndicator />;
  52. }
  53. return (
  54. <div>
  55. <SentryDocumentTitle title={t('Edit API Key')} orgSlug={organization.slug} />
  56. <SettingsPageHeader title={t('Edit API Key')} />
  57. <Panel>
  58. <PanelHeader>{t('API Key')}</PanelHeader>
  59. <ApiForm
  60. apiMethod="PUT"
  61. apiEndpoint={`/organizations/${organization.slug}/api-keys/${params.apiKey}/`}
  62. initialData={apiKey}
  63. onSubmitSuccess={handleSubmitSuccess}
  64. onSubmitError={handleSubmitError}
  65. onCancel={() => navigate(`/settings/${organization.slug}/api-keys/`)}
  66. >
  67. <PanelBody>
  68. <TextField label={t('Label')} name="label" />
  69. <TextField label={t('API Key')} name="key" disabled />
  70. <FormField name="scope_list" label={t('Scopes')} inline={false} required>
  71. {({name, value, onChange}: any) => (
  72. <MultipleCheckbox value={value} onChange={onChange} name={name}>
  73. {API_ACCESS_SCOPES.map(scope => (
  74. <MultipleCheckbox.Item value={scope} key={scope}>
  75. {scope}
  76. </MultipleCheckbox.Item>
  77. ))}
  78. </MultipleCheckbox>
  79. )}
  80. </FormField>
  81. <TextareaField
  82. label={t('Allowed Domains')}
  83. name="allowed_origins"
  84. placeholder="e.g. example.com or https://example.com"
  85. help="Separate multiple entries with a newline"
  86. />
  87. </PanelBody>
  88. </ApiForm>
  89. </Panel>
  90. </div>
  91. );
  92. }
  93. export default OrganizationApiKeyDetails;