Browse Source

feat(settings): Convert team settings to functional (#54183)

Scott Cooper 1 year ago
parent
commit
427fd8d9b3

+ 17 - 37
static/app/views/settings/organizationTeams/teamSettings/index.spec.tsx

@@ -71,18 +71,13 @@ describe('TeamSettings', function () {
         orgRole: 'owner',
       },
     });
-
-    const context = TestStubs.routerContext([
-      {
-        organization: TestStubs.Organization({
-          access: ['org:admin'],
-          features: ['org-roles-for-teams'],
-        }),
-      },
-    ]);
+    const organization = TestStubs.Organization({
+      access: ['org:admin'],
+      features: ['org-roles-for-teams'],
+    });
 
     render(<TeamSettings {...routerProps} team={team} params={{teamId: team.slug}} />, {
-      context,
+      organization,
     });
 
     // set org role
@@ -117,15 +112,10 @@ describe('TeamSettings', function () {
 
   it('needs team:admin in order to see an enabled Remove Team button', function () {
     const team = TestStubs.Team();
-
-    const context = TestStubs.routerContext([
-      {
-        organization: TestStubs.Organization({access: []}),
-      },
-    ]);
+    const organization = TestStubs.Organization({access: []});
 
     render(<TeamSettings {...routerProps} team={team} params={{teamId: team.slug}} />, {
-      context,
+      organization,
     });
 
     expect(screen.getByTestId('button-remove-team')).toBeDisabled();
@@ -133,18 +123,13 @@ describe('TeamSettings', function () {
 
   it('needs org:admin in order to set team org-role', function () {
     const team = TestStubs.Team();
-
-    const context = TestStubs.routerContext([
-      {
-        organization: TestStubs.Organization({
-          access: [],
-          features: ['org-roles-for-teams'],
-        }),
-      },
-    ]);
+    const organization = TestStubs.Organization({
+      access: [],
+      features: ['org-roles-for-teams'],
+    });
 
     render(<TeamSettings {...routerProps} team={team} params={{teamId: team.slug}} />, {
-      context,
+      organization,
     });
 
     expect(screen.getByRole('textbox', {name: 'Organization Role'})).toBeDisabled();
@@ -152,18 +137,13 @@ describe('TeamSettings', function () {
 
   it('cannot set team org-role for idp:provisioned team', function () {
     const team = TestStubs.Team({flags: {'idp:provisioned': true}});
-
-    const context = TestStubs.routerContext([
-      {
-        organization: TestStubs.Organization({
-          access: ['org:admin'],
-          features: ['org-roles-for-teams'],
-        }),
-      },
-    ]);
+    const organization = TestStubs.Organization({
+      access: ['org:admin'],
+      features: ['org-roles-for-teams'],
+    });
 
     render(<TeamSettings {...routerProps} team={team} params={{teamId: team.slug}} />, {
-      context,
+      organization,
     });
 
     expect(screen.getByRole('textbox', {name: 'Organization Role'})).toBeDisabled();

+ 77 - 88
static/app/views/settings/organizationTeams/teamSettings/index.tsx

@@ -11,125 +11,114 @@ import Form, {FormProps} from 'sentry/components/forms/form';
 import JsonForm from 'sentry/components/forms/jsonForm';
 import Panel from 'sentry/components/panels/panel';
 import PanelHeader from 'sentry/components/panels/panelHeader';
+import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import teamSettingsFields from 'sentry/data/forms/teamSettingsFields';
 import {IconDelete} from 'sentry/icons';
 import {t, tct} from 'sentry/locale';
-import {Organization, Team} from 'sentry/types';
+import {Team} from 'sentry/types';
+import useApi from 'sentry/utils/useApi';
+import useOrganization from 'sentry/utils/useOrganization';
 import {normalizeUrl} from 'sentry/utils/withDomainRequired';
-import withOrganization from 'sentry/utils/withOrganization';
-import DeprecatedAsyncView from 'sentry/views/deprecatedAsyncView';
 import PermissionAlert from 'sentry/views/settings/project/permissionAlert';
 
-type Props = RouteComponentProps<{teamId: string}, {}> & {
-  organization: Organization;
+interface TeamSettingsProps extends RouteComponentProps<{teamId: string}, {}> {
   team: Team;
-};
-
-type State = DeprecatedAsyncView['state'];
-
-class TeamSettings extends DeprecatedAsyncView<Props, State> {
-  getTitle() {
-    return 'Team Settings';
-  }
-
-  getEndpoints() {
-    return [];
-  }
+}
 
-  handleSubmitSuccess: FormProps['onSubmitSuccess'] = (resp, _model, id) => {
-    const {organization} = this.props;
+function TeamSettings({team, params}: TeamSettingsProps) {
+  const organization = useOrganization();
+  const api = useApi();
 
+  const handleSubmitSuccess: FormProps['onSubmitSuccess'] = (resp: Team, _model, id) => {
     // Use the old slug when triggering the update so we correctly replace the
     // previous team in the store
-    updateTeamSuccess(this.props.team.slug, resp);
+    updateTeamSuccess(team.slug, resp);
     if (id === 'slug') {
       addSuccessMessage(t('Team name changed'));
       browserHistory.replace(
         normalizeUrl(`/settings/${organization.slug}/teams/${resp.slug}/settings/`)
       );
-      this.setState({loading: true});
     }
   };
 
-  handleRemoveTeam = async () => {
-    const {organization, params} = this.props;
+  const handleRemoveTeam = async () => {
     try {
-      await removeTeam(this.api, {orgId: organization.slug, teamId: params.teamId});
+      await removeTeam(api, {orgId: organization.slug, teamId: params.teamId});
       browserHistory.replace(normalizeUrl(`/settings/${organization.slug}/teams/`));
     } catch {
       // removeTeam already displays an error message
     }
   };
 
-  renderBody() {
-    const {organization, team} = this.props;
-    const idpProvisioned = team.flags['idp:provisioned'];
-    const orgRoleList = organization.orgRoleList;
-    const hasOrgRoleFlag = organization.features.includes('org-roles-for-teams');
+  const idpProvisioned = team.flags['idp:provisioned'];
+  const orgRoleList = organization.orgRoleList;
+  const hasOrgRoleFlag = organization.features.includes('org-roles-for-teams');
 
-    const hasTeamWrite = hasEveryAccess(['team:write'], {organization, team});
-    const hasTeamAdmin = hasEveryAccess(['team:admin'], {organization, team});
-    const hasOrgAdmin = hasEveryAccess(['org:admin'], {organization});
+  const hasTeamWrite = hasEveryAccess(['team:write'], {organization, team});
+  const hasTeamAdmin = hasEveryAccess(['team:admin'], {organization, team});
+  const hasOrgAdmin = hasEveryAccess(['org:admin'], {organization});
 
-    return (
-      <Fragment>
-        <PermissionAlert access={['team:write']} team={team} />
+  return (
+    <Fragment>
+      <SentryDocumentTitle title={t('Team Settings')} orgSlug={organization.slug} />
 
-        <Form
-          apiMethod="PUT"
-          apiEndpoint={`/teams/${organization.slug}/${team.slug}/`}
-          saveOnBlur
-          allowUndo
-          onSubmitSuccess={this.handleSubmitSuccess}
-          onSubmitError={() => addErrorMessage(t('Unable to save change'))}
-          initialData={{
-            name: team.name,
-            slug: team.slug,
-            orgRole: team.orgRole,
+      <PermissionAlert access={['team:write']} team={team} />
+
+      <Form
+        apiMethod="PUT"
+        apiEndpoint={`/teams/${organization.slug}/${team.slug}/`}
+        saveOnBlur
+        allowUndo
+        onSubmitSuccess={handleSubmitSuccess}
+        onSubmitError={() => addErrorMessage(t('Unable to save change'))}
+        initialData={{
+          name: team.name,
+          slug: team.slug,
+          orgRole: team.orgRole,
+        }}
+      >
+        <JsonForm
+          additionalFieldProps={{
+            idpProvisioned,
+            hasOrgRoleFlag,
+            hasTeamWrite,
+            hasOrgAdmin,
+            orgRoleList,
           }}
-        >
-          <JsonForm
-            additionalFieldProps={{
-              idpProvisioned,
-              hasOrgRoleFlag,
-              hasTeamWrite,
-              hasOrgAdmin,
-              orgRoleList,
-            }}
-            forms={teamSettingsFields}
-          />
-        </Form>
+          forms={teamSettingsFields}
+        />
+      </Form>
 
-        <Panel>
-          <PanelHeader>{t('Team Administration')}</PanelHeader>
-          <FieldGroup
-            label={t('Remove Team')}
-            help={t(
-              "This may affect team members' access to projects and associated alert delivery."
-            )}
-          >
-            <div>
-              <Confirm
-                disabled={!hasTeamAdmin}
-                onConfirm={this.handleRemoveTeam}
+      <Panel>
+        <PanelHeader>{t('Team Administration')}</PanelHeader>
+        <FieldGroup
+          label={t('Remove Team')}
+          help={t(
+            "This may affect team members' access to projects and associated alert delivery."
+          )}
+        >
+          <div>
+            <Confirm
+              disabled={!hasTeamAdmin}
+              onConfirm={handleRemoveTeam}
+              priority="danger"
+              message={tct('Are you sure you want to remove the team [team]?', {
+                team: `#${team.slug}`,
+              })}
+            >
+              <Button
+                icon={<IconDelete />}
                 priority="danger"
-                message={tct('Are you sure you want to remove the team [team]?', {
-                  team: `#${team.slug}`,
-                })}
+                data-test-id="button-remove-team"
               >
-                <Button
-                  icon={<IconDelete />}
-                  priority="danger"
-                  data-test-id="button-remove-team"
-                >
-                  {t('Remove Team')}
-                </Button>
-              </Confirm>
-            </div>
-          </FieldGroup>
-        </Panel>
-      </Fragment>
-    );
-  }
+                {t('Remove Team')}
+              </Button>
+            </Confirm>
+          </div>
+        </FieldGroup>
+      </Panel>
+    </Fragment>
+  );
 }
-export default withOrganization(TeamSettings);
+
+export default TeamSettings;