Skip to content

Commit e4b4d6f

Browse files
AlexTugarevgtsiolisLaurie T. Malau
committed
Mention username who added project in a team
Co-authored-by: George Tsiolis <[email protected]> Co-authored-by: Laurie T. Malau <[email protected]> Co-authored-by: Alex Tugarev <[email protected]>
1 parent db0143f commit e4b4d6f

File tree

6 files changed

+49
-10
lines changed

6 files changed

+49
-10
lines changed

components/dashboard/src/projects/NewProject.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,15 +316,17 @@ export default function NewProject() {
316316
<div key={`repo-${index}-${r.account}-${r.name}`} className="flex p-3 rounded-xl hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gitpod-kumquat-light transition ease-in-out group" >
317317

318318
<div className="flex-grow">
319-
<div className="text-base text-gray-900 dark:text-gray-50 font-medium rounded-xl whitespace-nowrap">{toSimpleName(r.name)}</div>
319+
<div className={"text-base text-gray-900 dark:text-gray-50 font-medium rounded-xl whitespace-nowrap" + (r.inUse ? " text-gray-400" : "text-gray-700")}>{toSimpleName(r.name)}</div>
320320
<p>Updated {moment(r.updatedAt).fromNow()}</p>
321321
</div>
322322
<div className="flex justify-end">
323-
<div className="h-full my-auto flex self-center opacity-0 group-hover:opacity-100">
323+
<div className="h-full my-auto flex self-center opacity-0 group-hover:opacity-100 items-center mr-2 text-right">
324324
{!r.inUse ? (
325325
<button className="primary" onClick={() => setSelectedRepo(r)}>Select</button>
326326
) : (
327-
<p className="my-auto">already taken</p>
327+
<p className="text-gray-500 font-medium">
328+
@{r.inUse.userName} already<br/>added this repo
329+
</p>
328330
)}
329331
</div>
330332
</div>

components/gitpod-db/src/project-db.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export const ProjectDB = Symbol('ProjectDB');
1010
export interface ProjectDB {
1111
findProjectById(projectId: string): Promise<Project | undefined>;
1212
findProjectByCloneUrl(cloneUrl: string): Promise<Project | undefined>;
13-
findProjectsByCloneUrls(cloneUrls: string[]): Promise<Project[]>;
13+
findProjectsByCloneUrls(cloneUrls: string[]): Promise<(Project & { teamOwners?: string[] })[]>;
1414
findTeamProjects(teamId: string): Promise<Project[]>;
1515
findUserProjects(userId: string): Promise<Project[]>;
1616
storeProject(project: Project): Promise<Project>;

components/gitpod-db/src/typeorm/project-db-impl.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,35 @@ export class ProjectDBImpl implements ProjectDB {
3333
return repo.findOne({ cloneUrl, markedDeleted: false });
3434
}
3535

36-
public async findProjectsByCloneUrls(cloneUrls: string[]): Promise<Project[]> {
36+
public async findProjectsByCloneUrls(cloneUrls: string[]): Promise<(Project & { teamOwners?: string[] })[]> {
3737
if (cloneUrls.length === 0) {
3838
return [];
3939
}
4040
const repo = await this.getRepo();
4141
const q = repo.createQueryBuilder("project")
4242
.where("project.markedDeleted = false")
4343
.andWhere(`project.cloneUrl in (${ cloneUrls.map(u => `'${u}'`).join(", ") })`)
44-
const result = await q.getMany();
44+
const projects = await q.getMany();
45+
46+
const teamIds = Array.from(new Set(projects.map(p => p.teamId).filter(id => !!id)));
47+
48+
if (teamIds.length === 0) {
49+
return [];
50+
}
51+
52+
const teamIdsAndOwners = (await (await this.getEntityManager()).query(`
53+
SELECT member.teamId AS teamId, user.name AS owner FROM d_b_user AS user
54+
LEFT JOIN d_b_team_membership AS member ON (user.id = member.userId)
55+
WHERE member.teamId IN (${teamIds.map(id => `'${id}'`).join(", ")})
56+
AND member.deleted = 0
57+
AND member.role = 'owner'
58+
`)) as { teamId: string, owner: string }[];
59+
60+
const result: (Project & { teamOwners?: string[] })[] = [];
61+
for (const project of projects) {
62+
result.push({...project, teamOwners: teamIdsAndOwners.filter(i => i.teamId === project.teamId).map(i => i.owner)});
63+
}
64+
4565
return result;
4666
}
4767

components/gitpod-protocol/src/gitpod-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ export interface ProviderRepository {
271271
installationId?: number;
272272
installationUpdatedAt?: string;
273273

274-
inUse?: boolean;
274+
inUse?: { userName: string };
275275
}
276276

277277
export interface ClientHeaderFields {

components/server/ee/src/workspace/gitpod-server-impl.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,8 +1436,25 @@ export class GitpodServerEEImpl extends GitpodServerImpl {
14361436
}
14371437
const projects = await this.projectsService.getProjectsByCloneUrls(repositories.map(r => r.cloneUrl));
14381438

1439-
const cloneUrlsInUse = new Set(projects.map(p => p.cloneUrl));
1440-
repositories.forEach(r => { r.inUse = cloneUrlsInUse.has(r.cloneUrl) });
1439+
const cloneUrlToProject = new Map(projects.map(p => [p.cloneUrl, p]));
1440+
1441+
for (const repo of repositories) {
1442+
const p = cloneUrlToProject.get(repo.cloneUrl);
1443+
if (p) {
1444+
if (p.userId) {
1445+
const owner = await this.userDB.findUserById(p.userId);
1446+
if (owner) {
1447+
repo.inUse = {
1448+
userName: owner?.name || owner?.fullName || 'somebody'
1449+
}
1450+
}
1451+
} else if (p.teamOwners && p.teamOwners[0]) {
1452+
repo.inUse = {
1453+
userName: p.teamOwners[0] || 'somebody'
1454+
}
1455+
}
1456+
}
1457+
}
14411458

14421459
return repositories;
14431460
}

components/server/src/projects/projects-service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export class ProjectsService {
3737
return this.projectDB.findUserProjects(userId);
3838
}
3939

40-
async getProjectsByCloneUrls(cloneUrls: string[]): Promise<Project[]> {
40+
async getProjectsByCloneUrls(cloneUrls: string[]): Promise<(Project & { teamOwners?: string[] })[]> {
4141
return this.projectDB.findProjectsByCloneUrls(cloneUrls);
4242
}
4343

0 commit comments

Comments
 (0)