Browse Source

fix(ui): Fix incomplete list of member's teams (#29134)

David Wang 3 years ago
parent
commit
4a4df614e9

+ 7 - 1
static/app/views/settings/components/teamSelect.tsx

@@ -9,6 +9,7 @@ import {Item} from 'app/components/dropdownAutoComplete/types';
 import DropdownButton from 'app/components/dropdownButton';
 import TeamBadge from 'app/components/idBadge/teamBadge';
 import Link from 'app/components/links/link';
+import LoadingIndicator from 'app/components/loadingIndicator';
 import {Panel, PanelBody, PanelHeader, PanelItem} from 'app/components/panels';
 import {DEFAULT_DEBOUNCE_DURATION} from 'app/constants';
 import {IconSubtract} from 'app/icons';
@@ -45,6 +46,10 @@ type Props = {
    * if empty no confirm will be displayed.
    */
   confirmLastTeamRemoveMessage?: string;
+  /**
+   * Used to determine whether we should show a loading state while waiting for teams
+   */
+  loadingTeams?: boolean;
 };
 
 function TeamSelect({
@@ -55,6 +60,7 @@ function TeamSelect({
   onAddTeam,
   onRemoveTeam,
   confirmLastTeamRemoveMessage,
+  loadingTeams,
 }: Props) {
   const {teams, onSearch, fetching} = useTeams();
 
@@ -126,7 +132,7 @@ function TeamSelect({
         </DropdownAutoComplete>
       </PanelHeader>
 
-      <PanelBody>{renderBody()}</PanelBody>
+      <PanelBody>{loadingTeams ? <LoadingIndicator /> : renderBody()}</PanelBody>
     </Panel>
   );
 }

+ 15 - 13
static/app/views/settings/organizationMembers/organizationMemberDetail.tsx

@@ -25,8 +25,8 @@ import space from 'app/styles/space';
 import {Member, Organization, Team} from 'app/types';
 import isMemberDisabledFromLimit from 'app/utils/isMemberDisabledFromLimit';
 import recreateRoute from 'app/utils/recreateRoute';
+import Teams from 'app/utils/teams';
 import withOrganization from 'app/utils/withOrganization';
-import withTeams from 'app/utils/withTeams';
 import AsyncView from 'app/views/asyncView';
 import Field from 'app/views/settings/components/forms/field';
 import SettingsPageHeader from 'app/views/settings/components/settingsPageHeader';
@@ -48,7 +48,6 @@ type RouteParams = {
 
 type Props = {
   organization: Organization;
-  teams: Team[];
 } & RouteComponentProps<RouteParams, {}>;
 
 type State = {
@@ -234,7 +233,7 @@ class OrganizationMemberDetail extends AsyncView<Props, State> {
   }
 
   renderBody() {
-    const {organization, teams} = this.props;
+    const {organization} = this.props;
     const {member} = this.state;
 
     if (!member) {
@@ -362,15 +361,18 @@ class OrganizationMemberDetail extends AsyncView<Props, State> {
           setRole={slug => this.setState({member: {...member, role: slug}})}
         />
 
-        <TeamSelect
-          organization={organization}
-          selectedTeams={member.teams
-            .map(teamSlug => teams.find(team => team.slug === teamSlug)!)
-            .filter(team => team !== undefined)}
-          disabled={!canEdit}
-          onAddTeam={this.handleAddTeam}
-          onRemoveTeam={this.handleRemoveTeam}
-        />
+        <Teams slugs={member.teams}>
+          {({teams, initiallyLoaded}) => (
+            <TeamSelect
+              organization={organization}
+              selectedTeams={teams}
+              disabled={!canEdit}
+              onAddTeam={this.handleAddTeam}
+              onRemoveTeam={this.handleRemoveTeam}
+              loadingTeams={!initiallyLoaded}
+            />
+          )}
+        </Teams>
 
         <Footer>
           <Button
@@ -387,7 +389,7 @@ class OrganizationMemberDetail extends AsyncView<Props, State> {
   }
 }
 
-export default withTeams(withOrganization(OrganizationMemberDetail));
+export default withOrganization(OrganizationMemberDetail);
 
 const ExtraHeaderText = styled('div')`
   color: ${p => p.theme.gray300};