Browse Source

ref(ui): Remove unused state from team details (#38727)

Scott Cooper 2 years ago
parent
commit
5a471cc04c

+ 59 - 0
static/app/views/settings/organizationTeams/teamDetails.spec.jsx

@@ -0,0 +1,59 @@
+import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
+
+import {Client} from 'sentry/api';
+import TeamStore from 'sentry/stores/teamStore';
+import TeamDetails from 'sentry/views/settings/organizationTeams/teamDetails';
+
+describe('TeamMembers', () => {
+  let joinMock;
+
+  const organization = TestStubs.Organization();
+  const team = TestStubs.Team({hasAccess: false});
+  const teamHasAccess = TestStubs.Team({id: '1337', slug: 'django', hasAccess: true});
+  const context = TestStubs.routerContext();
+
+  beforeEach(() => {
+    TeamStore.init();
+    TeamStore.loadInitialData([team, teamHasAccess]);
+    joinMock = Client.addMockResponse({
+      url: `/organizations/${organization.slug}/members/me/teams/${team.slug}/`,
+      method: 'POST',
+    });
+  });
+
+  afterEach(() => {
+    Client.clearMockResponses();
+    TeamStore.reset();
+  });
+
+  it('can request membership', () => {
+    render(
+      <TeamDetails params={{orgId: organization.slug, teamId: team.slug}}>
+        <div data-test-id="test" />
+      </TeamDetails>,
+      {
+        organization,
+        context,
+      }
+    );
+
+    userEvent.click(screen.getByRole('button', {name: 'Request Access'}));
+    expect(joinMock).toHaveBeenCalled();
+
+    expect(screen.queryByTestId('test')).not.toBeInTheDocument();
+  });
+
+  it('displays children', () => {
+    render(
+      <TeamDetails params={{orgId: organization.slug, teamId: teamHasAccess.slug}}>
+        <div data-test-id="test" />
+      </TeamDetails>,
+      {
+        organization,
+        context,
+      }
+    );
+
+    expect(screen.getByTestId('test')).toBeInTheDocument();
+  });
+});

+ 41 - 73
static/app/views/settings/organizationTeams/teamDetails.tsx

@@ -1,5 +1,5 @@
 import {cloneElement, isValidElement, useState} from 'react';
 import {cloneElement, isValidElement, useState} from 'react';
-import {browserHistory, RouteComponentProps} from 'react-router';
+import type {RouteComponentProps} from 'react-router';
 import styled from '@emotion/styled';
 import styled from '@emotion/styled';
 
 
 import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
 import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator';
@@ -12,8 +12,6 @@ import LoadingIndicator from 'sentry/components/loadingIndicator';
 import NavTabs from 'sentry/components/navTabs';
 import NavTabs from 'sentry/components/navTabs';
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
 import {t, tct} from 'sentry/locale';
 import {t, tct} from 'sentry/locale';
-import TeamStore from 'sentry/stores/teamStore';
-import {Team} from 'sentry/types';
 import recreateRoute from 'sentry/utils/recreateRoute';
 import recreateRoute from 'sentry/utils/recreateRoute';
 import useApi from 'sentry/utils/useApi';
 import useApi from 'sentry/utils/useApi';
 import useTeams from 'sentry/utils/useTeams';
 import useTeams from 'sentry/utils/useTeams';
@@ -24,29 +22,24 @@ type Props = {
 
 
 function TeamDetails({children, ...props}: Props) {
 function TeamDetails({children, ...props}: Props) {
   const api = useApi();
   const api = useApi();
-  const [currentTeam, setCurrentTeam] = useState(
-    TeamStore.getBySlug(props.params.teamId)
-  );
   const [requesting, setRequesting] = useState(false);
   const [requesting, setRequesting] = useState(false);
+  const {teams, initiallyLoaded} = useTeams({slugs: [props.params.teamId]});
+  const team = teams.find(({slug}) => slug === props.params.teamId);
 
 
-  function handleRequestAccess(team: Team) {
-    if (!team) {
-      return;
-    }
-
+  function handleRequestAccess(teamSlug: string) {
     setRequesting(true);
     setRequesting(true);
 
 
     joinTeam(
     joinTeam(
       api,
       api,
       {
       {
         orgId: props.params.orgId,
         orgId: props.params.orgId,
-        teamId: team.slug,
+        teamId: teamSlug,
       },
       },
       {
       {
         success: () => {
         success: () => {
           addSuccessMessage(
           addSuccessMessage(
             tct('You have requested access to [team]', {
             tct('You have requested access to [team]', {
-              team: `#${team.slug}`,
+              team: `#${teamSlug}`,
             })
             })
           );
           );
           setRequesting(false);
           setRequesting(false);
@@ -54,7 +47,7 @@ function TeamDetails({children, ...props}: Props) {
         error: () => {
         error: () => {
           addErrorMessage(
           addErrorMessage(
             tct('Unable to request access to [team]', {
             tct('Unable to request access to [team]', {
-              team: `#${team.slug}`,
+              team: `#${teamSlug}`,
             })
             })
           );
           );
           setRequesting(false);
           setRequesting(false);
@@ -63,15 +56,6 @@ function TeamDetails({children, ...props}: Props) {
     );
     );
   }
   }
 
 
-  function onTeamChange(data: Team) {
-    if (currentTeam !== data) {
-      const orgId = props.params.orgId;
-      browserHistory.replace(`/organizations/${orgId}/teams/${data.slug}/settings/`);
-    } else {
-      setCurrentTeam({...currentTeam, ...data});
-    }
-  }
-
   // `/organizations/${orgId}/teams/${teamId}`;
   // `/organizations/${orgId}/teams/${teamId}`;
   const routePrefix = recreateRoute('', {
   const routePrefix = recreateRoute('', {
     routes: props.routes,
     routes: props.routes,
@@ -94,62 +78,46 @@ function TeamDetails({children, ...props}: Props) {
     </ListLink>,
     </ListLink>,
   ];
   ];
 
 
-  const {teams, initiallyLoaded} = useTeams({slugs: [props.params.teamId]});
+  if (!initiallyLoaded) {
+    return <LoadingIndicator />;
+  }
+
+  if (!team) {
+    return (
+      <Alert type="warning">
+        <div>{t('You do not have access to this team.')}</div>
+      </Alert>
+    );
+  }
 
 
   return (
   return (
     <div>
     <div>
-      {initiallyLoaded ? (
-        teams.length ? (
-          teams.map((team, i) => {
-            if (!team || !team.hasAccess) {
-              return (
-                <Alert type="warning">
-                  {team ? (
-                    <RequestAccessWrapper>
-                      {tct('You do not have access to the [teamSlug] team.', {
-                        teamSlug: <strong>{`#${team.slug}`}</strong>,
-                      })}
-                      <Button
-                        disabled={requesting || team.isPending}
-                        size="sm"
-                        onClick={() => handleRequestAccess(team)}
-                      >
-                        {team.isPending ? t('Request Pending') : t('Request Access')}
-                      </Button>
-                    </RequestAccessWrapper>
-                  ) : (
-                    <div>{t('You do not have access to this team.')}</div>
-                  )}
-                </Alert>
-              );
-            }
-            return (
-              <div key={i}>
-                <SentryDocumentTitle
-                  title={t('Team Details')}
-                  orgSlug={props.params.orgId}
-                />
-                <h3>
-                  <IdBadge hideAvatar team={team} avatarSize={36} />
-                </h3>
+      <SentryDocumentTitle title={t('Team Details')} orgSlug={props.params.orgId} />
+      {team.hasAccess ? (
+        <div>
+          <h3>
+            <IdBadge hideAvatar team={team} avatarSize={36} />
+          </h3>
 
 
-                <NavTabs underlined>{navigationTabs}</NavTabs>
+          <NavTabs underlined>{navigationTabs}</NavTabs>
 
 
-                {isValidElement(children) &&
-                  cloneElement<any>(children, {
-                    team,
-                    onTeamChange: () => onTeamChange(team),
-                  })}
-              </div>
-            );
-          })
-        ) : (
-          <Alert type="warning">
-            <div>{t('You do not have access to this team.')}</div>
-          </Alert>
-        )
+          {isValidElement(children) ? cloneElement<any>(children, {team}) : null}
+        </div>
       ) : (
       ) : (
-        <LoadingIndicator />
+        <Alert type="warning">
+          <RequestAccessWrapper>
+            {tct('You do not have access to the [teamSlug] team.', {
+              teamSlug: <strong>{`#${team.slug}`}</strong>,
+            })}
+            <Button
+              disabled={requesting || team.isPending}
+              size="sm"
+              onClick={() => handleRequestAccess(team.slug)}
+            >
+              {team.isPending ? t('Request Pending') : t('Request Access')}
+            </Button>
+          </RequestAccessWrapper>
+        </Alert>
       )}
       )}
     </div>
     </div>
   );
   );

+ 3 - 15
static/app/views/settings/organizationTeams/teamSettings/teamSettings.spec.jsx

@@ -24,11 +24,7 @@ describe('TeamSettings', function () {
     });
     });
 
 
     const wrapper = mountWithTheme(
     const wrapper = mountWithTheme(
-      <TeamSettings
-        team={team}
-        onTeamChange={() => {}}
-        params={{orgId: 'org', teamId: team.slug}}
-      />
+      <TeamSettings team={team} params={{orgId: 'org', teamId: team.slug}} />
     );
     );
 
 
     wrapper
     wrapper
@@ -57,11 +53,7 @@ describe('TeamSettings', function () {
     const team = TestStubs.Team();
     const team = TestStubs.Team();
 
 
     const wrapper = mountWithTheme(
     const wrapper = mountWithTheme(
-      <TeamSettings
-        team={team}
-        onTeamChange={() => {}}
-        params={{orgId: 'org', teamId: team.slug}}
-      />,
+      <TeamSettings team={team} params={{orgId: 'org', teamId: team.slug}} />,
       TestStubs.routerContext([
       TestStubs.routerContext([
         {
         {
           organization: TestStubs.Organization({access: []}),
           organization: TestStubs.Organization({access: []}),
@@ -86,11 +78,7 @@ describe('TeamSettings', function () {
     ]);
     ]);
 
 
     const wrapper = mountWithTheme(
     const wrapper = mountWithTheme(
-      <TeamSettings
-        params={{orgId: 'org', teamId: team.slug}}
-        team={team}
-        onTeamChange={() => {}}
-      />
+      <TeamSettings params={{orgId: 'org', teamId: team.slug}} team={team} />
     );
     );
 
 
     // Click "Remove Team button
     // Click "Remove Team button