Skip to content

Commit 67c888c

Browse files
author
Laurie T. Malau
committed
show team members
1 parent 5c3e131 commit 67c888c

File tree

2 files changed

+33
-22
lines changed

2 files changed

+33
-22
lines changed

components/dashboard/src/admin/TeamDetail.tsx

+5-14
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,19 @@
55
*/
66

77
import moment from "moment";
8-
import { useEffect, useState } from "react";
8+
import { useState } from "react";
99
import { Team, TeamMemberInfo, TeamMemberRole } from "@gitpod/gitpod-protocol";
1010
import { getGitpodService } from "../service/service";
1111
import { Item, ItemField, ItemsList } from "../components/ItemsList";
1212
import DropDown from "../components/DropDown";
1313
import { Link } from "react-router-dom";
1414
import Label from "./Label";
1515

16-
export default function TeamDetail(props: { team: Team }) {
17-
const { team } = props;
18-
const [teamMembers, setTeamMembers] = useState<TeamMemberInfo[] | undefined>(undefined);
16+
export default function TeamDetail(props: { team: Team, members: TeamMemberInfo[] }) {
17+
const { team, members } = props;
18+
const [teamMembers, setTeamMembers] = useState<TeamMemberInfo[] | undefined>(members);
1919
const [searchText, setSearchText] = useState<string>('');
2020

21-
useEffect(() => {
22-
(async () => {
23-
const members = await getGitpodService().server.adminGetTeamMembers(team.id);
24-
if (members.length > 0) {
25-
setTeamMembers(members)
26-
}
27-
})();
28-
}, [team]);
29-
3021
const filteredMembers = teamMembers?.filter(m => {
3122
const memberSearchText = `${m.fullName || ''}${m.primaryEmail || ''}`.toLocaleLowerCase();
3223
if (!memberSearchText.includes(searchText.toLocaleLowerCase())) {
@@ -74,7 +65,7 @@ export default function TeamDetail(props: { team: Team }) {
7465
<span className="flex-grow">Role</span>
7566
</ItemField>
7667
</Item>
77-
{!team.markedDeleted || (!filteredMembers || filteredMembers.length === 0)
68+
{team.markedDeleted || (!filteredMembers || filteredMembers.length === 0)
7869
? <p className="pt-16 text-center">No members found</p>
7970
: filteredMembers && filteredMembers.map(m => <Item className="grid grid-cols-3" key={m.userId}>
8071
<ItemField className="flex items-center my-auto">

components/dashboard/src/admin/TeamsSearch.tsx

+28-8
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { Link, Redirect } from "react-router-dom";
1414
import { UserContext } from "../user-context";
1515
import { getGitpodService } from "../service/service";
1616
import { PageWithSubMenu } from "../components/PageWithSubMenu";
17-
import { AdminGetListResult, Team } from "@gitpod/gitpod-protocol";
17+
import { AdminGetListResult, Team, TeamMemberInfo } from "@gitpod/gitpod-protocol";
1818
import Label from "./Label";
1919

2020
export default function TeamsSearchPage() {
@@ -32,6 +32,7 @@ export function TeamsSearch() {
3232
const [searchTerm, setSearchTerm] = useState('');
3333
const [currentTeam, setCurrentTeam] = useState<Team | undefined>(undefined);
3434
const [searchResult, setSearchResult] = useState<AdminGetListResult<Team>>({ total: 0, rows: [] });
35+
const [teamMembers, setTeamMembers] = useState<Record<string, TeamMemberInfo[]>>({});
3536

3637
useEffect(() => {
3738
const teamId = location.pathname.split('/')[3];
@@ -49,12 +50,29 @@ export function TeamsSearch() {
4950
}
5051
}, [location]);
5152

53+
useEffect(() => {
54+
if (!searchResult) {
55+
return;
56+
}
57+
(async () => {
58+
const members: Record<string, TeamMemberInfo[]> = {};
59+
await Promise.all(searchResult.rows.map(async (team) => {
60+
try {
61+
members[team.id] = await getGitpodService().server.adminGetTeamMembers(team.id);
62+
} catch (error) {
63+
console.error('Could not retrieve team members', team, error);
64+
}
65+
}));
66+
setTeamMembers(members);
67+
})();
68+
}, [ searchResult ]);
69+
5270
if (!user || !user?.rolesOrPermissions?.includes('admin')) {
5371
return <Redirect to="/"/>
5472
}
5573

5674
if (currentTeam) {
57-
return <TeamDetail team={currentTeam} />;
75+
return <TeamDetail team={currentTeam} members={teamMembers[currentTeam.id]} />;
5876
}
5977

6078
const search = async () => {
@@ -95,21 +113,23 @@ export function TeamsSearch() {
95113

96114

97115
</div>
98-
{searchResult.rows.map(team => <TeamResultItem team={team} />)}
116+
{searchResult.rows.map(team => <TeamResultItem team={team} members={teamMembers[team.id]} />)}
99117
</div>
100118
</>
101119

102-
function TeamResultItem(props: { team: Team }) {
120+
function TeamResultItem(props: { team: Team, members: TeamMemberInfo[]}) {
121+
const { team, members } = props;
103122
return (
104-
<Link key={'pr-' + props.team.name} to={'/admin/teams/' + props.team.id} data-analytics='{"button_type":"sidebar_menu"}'>
123+
<Link key={'pr-' + team.name} to={'/admin/teams/' + team.id} data-analytics='{"button_type":"sidebar_menu"}'>
105124
<div className="rounded-xl whitespace-nowrap flex py-6 px-6 w-full justify-between hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gitpod-kumquat-light group">
106125
<div className="flex flex-col w-7/12 truncate">
107-
<div className="font-medium text-gray-800 dark:text-gray-100 truncate">{props.team.name}
108-
{props.team.markedDeleted && <Label text='Deleted' color="red"/>}
126+
<div className="font-medium text-gray-800 dark:text-gray-100 truncate">{team.name}
127+
{team.markedDeleted && <Label text='Deleted' color="red"/>}
128+
{members?.length > 0 && <p>{`${members?.length} ${members?.length > 1 ? `members` : `member`}`}</p>}
109129
</div>
110130
</div>
111131
<div className="flex w-5/12 self-center">
112-
<div className="text-sm w-full text-gray-400 truncate">{moment(props.team.creationTime).format('MMM D, YYYY')}</div>
132+
<div className="text-sm w-full text-gray-400 truncate">{moment(team.creationTime).format('MMM D, YYYY')}</div>
113133
</div>
114134
</div>
115135
</Link>

0 commit comments

Comments
 (0)