organizationApiKeyDetails.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import {browserHistory, RouteComponentProps} from 'react-router';
  2. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  3. import ApiForm from 'sentry/components/forms/apiForm';
  4. import MultipleCheckbox from 'sentry/components/forms/controls/multipleCheckbox';
  5. import TextareaField from 'sentry/components/forms/fields/textareaField';
  6. import TextField from 'sentry/components/forms/fields/textField';
  7. import FormField from 'sentry/components/forms/formField';
  8. import {Panel, PanelBody, PanelHeader} from 'sentry/components/panels';
  9. import {API_ACCESS_SCOPES} from 'sentry/constants';
  10. import {t} from 'sentry/locale';
  11. import {Organization} from 'sentry/types';
  12. import recreateRoute from 'sentry/utils/recreateRoute';
  13. import routeTitleGen from 'sentry/utils/routeTitle';
  14. import withOrganization from 'sentry/utils/withOrganization';
  15. import AsyncView from 'sentry/views/asyncView';
  16. import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader';
  17. import {DeprecatedApiKey} from './types';
  18. type RouteParams = {
  19. apiKey: string;
  20. };
  21. type Props = RouteComponentProps<RouteParams, {}> & {
  22. organization: Organization;
  23. };
  24. type State = AsyncView['state'] & {
  25. apiKey: DeprecatedApiKey;
  26. };
  27. class OrganizationApiKeyDetails extends AsyncView<Props, State> {
  28. getEndpoints(): ReturnType<AsyncView['getEndpoints']> {
  29. const {organization} = this.props;
  30. return [
  31. [
  32. 'apiKey',
  33. `/organizations/${organization.slug}/api-keys/${this.props.params.apiKey}/`,
  34. ],
  35. ];
  36. }
  37. getTitle() {
  38. return routeTitleGen(t('Edit API Key'), this.props.organization.slug, false);
  39. }
  40. handleSubmitSuccess = () => {
  41. addSuccessMessage('Saved changes');
  42. // Go back to API list
  43. browserHistory.push(
  44. recreateRoute('', {
  45. stepBack: -1,
  46. routes: this.props.routes,
  47. params: this.props.params,
  48. })
  49. );
  50. };
  51. handleSubmitError = () => {
  52. addErrorMessage('Unable to save changes. Please try again.');
  53. };
  54. renderBody() {
  55. const {organization} = this.props;
  56. return (
  57. <div>
  58. <SettingsPageHeader title={t('Edit API Key')} />
  59. <Panel>
  60. <PanelHeader>{t('API Key')}</PanelHeader>
  61. <ApiForm
  62. apiMethod="PUT"
  63. apiEndpoint={`/organizations/${organization.slug}/api-keys/${this.props.params.apiKey}/`}
  64. initialData={this.state.apiKey}
  65. onSubmitSuccess={this.handleSubmitSuccess}
  66. onSubmitError={this.handleSubmitError}
  67. onCancel={() =>
  68. browserHistory.push(
  69. recreateRoute('', {
  70. stepBack: -1,
  71. routes: this.props.routes,
  72. params: this.props.params,
  73. })
  74. )
  75. }
  76. >
  77. <PanelBody>
  78. <TextField label={t('Label')} name="label" />
  79. <TextField label={t('API Key')} name="key" disabled />
  80. <FormField name="scope_list" label={t('Scopes')} inline={false} required>
  81. {({name, value, onChange}) => (
  82. <MultipleCheckbox value={value} onChange={onChange} name={name}>
  83. {API_ACCESS_SCOPES.map(scope => (
  84. <MultipleCheckbox.Item value={scope} key={scope}>
  85. {scope}
  86. </MultipleCheckbox.Item>
  87. ))}
  88. </MultipleCheckbox>
  89. )}
  90. </FormField>
  91. <TextareaField
  92. label={t('Allowed Domains')}
  93. name="allowed_origins"
  94. placeholder="e.g. example.com or https://example.com"
  95. help="Separate multiple entries with a newline"
  96. />
  97. </PanelBody>
  98. </ApiForm>
  99. </Panel>
  100. </div>
  101. );
  102. }
  103. }
  104. export default withOrganization(OrganizationApiKeyDetails);