index.tsx 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import {Fragment} from 'react';
  2. import {browserHistory, RouteComponentProps} from 'react-router';
  3. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  4. import {removeTeam, updateTeamSuccess} from 'sentry/actionCreators/teams';
  5. import Button from 'sentry/components/button';
  6. import Confirm from 'sentry/components/confirm';
  7. import Field from 'sentry/components/forms/field';
  8. import Form, {FormProps} from 'sentry/components/forms/form';
  9. import JsonForm from 'sentry/components/forms/jsonForm';
  10. import {Panel, PanelHeader} from 'sentry/components/panels';
  11. import teamSettingsFields from 'sentry/data/forms/teamSettingsFields';
  12. import {IconDelete} from 'sentry/icons';
  13. import {t, tct} from 'sentry/locale';
  14. import {Organization, Scope, Team} from 'sentry/types';
  15. import withOrganization from 'sentry/utils/withOrganization';
  16. import AsyncView from 'sentry/views/asyncView';
  17. type Props = RouteComponentProps<{orgId: string; teamId: string}, {}> & {
  18. organization: Organization;
  19. team: Team;
  20. };
  21. type State = AsyncView['state'];
  22. class TeamSettings extends AsyncView<Props, State> {
  23. getTitle() {
  24. return 'Team Settings';
  25. }
  26. getEndpoints() {
  27. return [];
  28. }
  29. handleSubmitSuccess: FormProps['onSubmitSuccess'] = (resp, model, id) => {
  30. // Use the old slug when triggering the update so we correctly replace the
  31. // previous team in the store
  32. updateTeamSuccess(this.props.team.slug, resp);
  33. if (id === 'slug') {
  34. addSuccessMessage(t('Team name changed'));
  35. browserHistory.replace(
  36. `/settings/${this.props.params.orgId}/teams/${model.getValue(id)}/settings/`
  37. );
  38. this.setState({loading: true});
  39. }
  40. };
  41. handleRemoveTeam = async () => {
  42. await removeTeam(this.api, this.props.params);
  43. browserHistory.replace(`/settings/${this.props.params.orgId}/teams/`);
  44. };
  45. renderBody() {
  46. const {organization, team, params} = this.props;
  47. const access = new Set<Scope>(organization.access);
  48. return (
  49. <Fragment>
  50. <Form
  51. apiMethod="PUT"
  52. apiEndpoint={`/teams/${params.orgId}/${team.slug}/`}
  53. saveOnBlur
  54. allowUndo
  55. onSubmitSuccess={this.handleSubmitSuccess}
  56. onSubmitError={() => addErrorMessage(t('Unable to save change'))}
  57. initialData={{
  58. name: team.name,
  59. slug: team.slug,
  60. }}
  61. >
  62. <JsonForm access={access} forms={teamSettingsFields} />
  63. </Form>
  64. <Panel>
  65. <PanelHeader>{t('Remove Team')}</PanelHeader>
  66. <Field
  67. help={t(
  68. "This may affect team members' access to projects and associated alert delivery."
  69. )}
  70. >
  71. <div>
  72. <Confirm
  73. disabled={!access.has('team:admin')}
  74. onConfirm={this.handleRemoveTeam}
  75. priority="danger"
  76. message={tct('Are you sure you want to remove the team [team]?', {
  77. team: `#${team.slug}`,
  78. })}
  79. >
  80. <Button
  81. icon={<IconDelete />}
  82. priority="danger"
  83. disabled={!access.has('team:admin')}
  84. >
  85. {t('Remove Team')}
  86. </Button>
  87. </Confirm>
  88. </div>
  89. </Field>
  90. </Panel>
  91. </Fragment>
  92. );
  93. }
  94. }
  95. export default withOrganization(TeamSettings);