index.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import {Fragment} from 'react';
  2. import type {RouteComponentProps} from 'react-router';
  3. import {browserHistory} from 'react-router';
  4. import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
  5. import {removeTeam, updateTeamSuccess} from 'sentry/actionCreators/teams';
  6. import {hasEveryAccess} from 'sentry/components/acl/access';
  7. import {Button} from 'sentry/components/button';
  8. import Confirm from 'sentry/components/confirm';
  9. import FieldGroup from 'sentry/components/forms/fieldGroup';
  10. import type {FormProps} from 'sentry/components/forms/form';
  11. import Form from 'sentry/components/forms/form';
  12. import JsonForm from 'sentry/components/forms/jsonForm';
  13. import Panel from 'sentry/components/panels/panel';
  14. import PanelHeader from 'sentry/components/panels/panelHeader';
  15. import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
  16. import teamSettingsFields from 'sentry/data/forms/teamSettingsFields';
  17. import {IconDelete} from 'sentry/icons';
  18. import {t, tct} from 'sentry/locale';
  19. import type {Team} from 'sentry/types';
  20. import useApi from 'sentry/utils/useApi';
  21. import useOrganization from 'sentry/utils/useOrganization';
  22. import {normalizeUrl} from 'sentry/utils/withDomainRequired';
  23. import PermissionAlert from 'sentry/views/settings/project/permissionAlert';
  24. interface TeamSettingsProps extends RouteComponentProps<{teamId: string}, {}> {
  25. team: Team;
  26. }
  27. function TeamSettings({team, params}: TeamSettingsProps) {
  28. const organization = useOrganization();
  29. const api = useApi();
  30. const handleSubmitSuccess: FormProps['onSubmitSuccess'] = (resp: Team, _model, id) => {
  31. // Use the old slug when triggering the update so we correctly replace the
  32. // previous team in the store
  33. updateTeamSuccess(team.slug, resp);
  34. if (id === 'slug') {
  35. addSuccessMessage(t('Team name changed'));
  36. browserHistory.replace(
  37. normalizeUrl(`/settings/${organization.slug}/teams/${resp.slug}/settings/`)
  38. );
  39. }
  40. };
  41. const handleRemoveTeam = async () => {
  42. try {
  43. await removeTeam(api, {orgId: organization.slug, teamId: params.teamId});
  44. browserHistory.replace(normalizeUrl(`/settings/${organization.slug}/teams/`));
  45. } catch {
  46. // removeTeam already displays an error message
  47. }
  48. };
  49. const idpProvisioned = team.flags['idp:provisioned'];
  50. const orgRoleList = organization.orgRoleList;
  51. const hasOrgRoleFlag = organization.features.includes('org-roles-for-teams');
  52. const hasTeamWrite = hasEveryAccess(['team:write'], {organization, team});
  53. const hasTeamAdmin = hasEveryAccess(['team:admin'], {organization, team});
  54. const hasOrgAdmin = hasEveryAccess(['org:admin'], {organization});
  55. return (
  56. <Fragment>
  57. <SentryDocumentTitle title={t('Team Settings')} orgSlug={organization.slug} />
  58. <PermissionAlert access={['team:write']} team={team} />
  59. <Form
  60. apiMethod="PUT"
  61. apiEndpoint={`/teams/${organization.slug}/${team.slug}/`}
  62. saveOnBlur
  63. allowUndo
  64. onSubmitSuccess={handleSubmitSuccess}
  65. onSubmitError={() => addErrorMessage(t('Unable to save change'))}
  66. initialData={{
  67. name: team.name,
  68. slug: team.slug,
  69. orgRole: team.orgRole,
  70. }}
  71. >
  72. <JsonForm
  73. additionalFieldProps={{
  74. idpProvisioned,
  75. hasOrgRoleFlag,
  76. hasTeamWrite,
  77. hasOrgAdmin,
  78. orgRoleList,
  79. }}
  80. forms={teamSettingsFields}
  81. />
  82. </Form>
  83. <Panel>
  84. <PanelHeader>{t('Team Administration')}</PanelHeader>
  85. <FieldGroup
  86. label={t('Remove Team')}
  87. help={t(
  88. "This may affect team members' access to projects and associated alert delivery."
  89. )}
  90. >
  91. <div>
  92. <Confirm
  93. disabled={!hasTeamAdmin}
  94. onConfirm={handleRemoveTeam}
  95. priority="danger"
  96. message={tct('Are you sure you want to remove the team [team]?', {
  97. team: `#${team.slug}`,
  98. })}
  99. >
  100. <Button
  101. icon={<IconDelete />}
  102. priority="danger"
  103. data-test-id="button-remove-team"
  104. >
  105. {t('Remove Team')}
  106. </Button>
  107. </Confirm>
  108. </div>
  109. </FieldGroup>
  110. </Panel>
  111. </Fragment>
  112. );
  113. }
  114. export default TeamSettings;