Skip to content

Commit bd0ca26

Browse files
authored
Merge pull request #1586 from argos-ci/hide-pending-github-members-by-default
feat: hide pending GitHub members by default
2 parents 5ed04e9 + a626eb1 commit bd0ca26

File tree

9 files changed

+125
-31
lines changed

9 files changed

+125
-31
lines changed

Diff for: apps/backend/src/graphql/__generated__/resolver-types.ts

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: apps/backend/src/graphql/__generated__/schema.gql

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: apps/backend/src/graphql/definitions/Team.ts

+27-4
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,11 @@ export const typeDefs = gql`
7676
levels: [TeamUserLevel!]
7777
sso: Boolean
7878
): TeamMemberConnection!
79-
githubMembers(after: Int = 0, first: Int = 30): TeamGithubMemberConnection
79+
githubMembers(
80+
after: Int = 0
81+
first: Int = 30
82+
isTeamMember: Boolean
83+
): TeamGithubMemberConnection
8084
inviteLink: String
8185
ssoGithubAccount: GithubAccount
8286
defaultUserLevel: TeamDefaultUserLevel!
@@ -317,12 +321,31 @@ export const resolvers: IResolvers = {
317321
return null;
318322
}
319323

320-
const result = await GithubAccountMember.query()
321-
.withGraphJoined("githubMember")
322-
.where("githubAccountId", team.ssoGithubAccountId)
324+
const query = GithubAccountMember.query()
325+
.where(
326+
"github_account_members.githubAccountId",
327+
team.ssoGithubAccountId,
328+
)
323329
.orderBy("githubMember.login", "asc")
324330
.range(after, after + first - 1);
325331

332+
if (args.isTeamMember) {
333+
query
334+
.withGraphJoined("githubMember.account")
335+
.where(
336+
"github_account_members.githubAccountId",
337+
team.ssoGithubAccountId,
338+
)
339+
.whereIn(
340+
"githubMember:account.userId",
341+
TeamUser.query().select("userId").where("teamId", team.id),
342+
);
343+
} else {
344+
query.withGraphJoined("githubMember");
345+
}
346+
347+
const result = await query;
348+
326349
return paginateResult({ result, first, after });
327350
},
328351
inviteLink: async (account, _args, ctx) => {

Diff for: apps/frontend/src/containers/Project/Contributors/AddProjectContributor.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ export function ProjectContributorsAdd(props: {
215215
<DialogTrigger>
216216
<Button variant="secondary">Add contributor</Button>
217217
<Modal>
218-
<Dialog size="medium">
218+
<Dialog size="medium" scrollable={false}>
219219
<DialogBody>
220220
<DialogTitle>Add contributor</DialogTitle>
221221
<DialogText>

Diff for: apps/frontend/src/containers/Team/Members.tsx

+56-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { memo, useState } from "react";
1+
import { memo, useId, useState } from "react";
22
import { Reference, useMutation } from "@apollo/client";
33
import { invariant } from "@argos/util/invariant";
44
import { MarkGithubIcon } from "@primer/octicons-react";
@@ -38,6 +38,7 @@ import {
3838
import { Modal } from "@/ui/Modal";
3939
import { Popover } from "@/ui/Popover";
4040
import { Select, SelectButton } from "@/ui/Select";
41+
import { Switch } from "@/ui/Switch";
4142
import { Tooltip } from "@/ui/Tooltip";
4243

4344
import { AccountAvatar } from "../AccountAvatar";
@@ -72,10 +73,15 @@ const TeamMembersQuery = graphql(`
7273
`);
7374

7475
const TeamGithubMembersQuery = graphql(`
75-
query TeamMembers_githubMembers($id: ID!, $first: Int!, $after: Int!) {
76+
query TeamMembers_githubMembers(
77+
$id: ID!
78+
$first: Int!
79+
$after: Int!
80+
$isTeamMember: Boolean
81+
) {
7682
team: teamById(id: $id) {
7783
id
78-
githubMembers(first: $first, after: $after) {
84+
githubMembers(first: $first, after: $after, isTeamMember: $isTeamMember) {
7985
edges {
8086
id
8187
githubAccount {
@@ -518,7 +524,7 @@ const _TeamGithubMembersListGithubAccountFragment = graphql(`
518524
}
519525
`);
520526

521-
function TeamGithubMembersList(props: {
527+
interface TeamGithubMembersListProps {
522528
teamId: string;
523529
teamName: string;
524530
amOwner: boolean;
@@ -527,14 +533,44 @@ function TeamGithubMembersList(props: {
527533
typeof _TeamGithubMembersListGithubAccountFragment
528534
>;
529535
hasFineGrainedAccessControl: boolean;
530-
}) {
536+
}
537+
538+
function TeamGithubMembersList(props: TeamGithubMembersListProps) {
531539
const { githubAccount } = props;
540+
const [showPendingMembers, setShowPendingMembers] = useState(false);
541+
return (
542+
<div className="my-4">
543+
<div className="flex items-center gap-2">
544+
<ListTitle className="flex-1">
545+
<MarkGithubIcon className="mr-1.5 inline-block size-4" />
546+
GitHub members synced from{" "}
547+
<GithubAccountLink githubAccount={githubAccount} />
548+
</ListTitle>
549+
<ShowPendingSwitch
550+
isSelected={showPendingMembers}
551+
onChange={setShowPendingMembers}
552+
/>
553+
</div>
554+
<TeamGithubMembersFetchList
555+
{...props}
556+
showPendingMembers={showPendingMembers}
557+
/>
558+
</div>
559+
);
560+
}
561+
562+
interface TeamGithubMembersFetchListProps extends TeamGithubMembersListProps {
563+
showPendingMembers: boolean;
564+
}
565+
566+
function TeamGithubMembersFetchList(props: TeamGithubMembersFetchListProps) {
532567
const authPayload = useAssertAuthTokenPayload();
533568
const { data, fetchMore } = useSafeQuery(TeamGithubMembersQuery, {
534569
variables: {
535570
id: props.teamId,
536571
after: 0,
537572
first: NB_MEMBERS_PER_PAGE,
573+
isTeamMember: !props.showPendingMembers,
538574
},
539575
});
540576
if (!data) {
@@ -546,12 +582,7 @@ function TeamGithubMembersList(props: {
546582
}
547583
const members = data.team.githubMembers.edges;
548584
return (
549-
<div className="my-4">
550-
<ListTitle>
551-
<MarkGithubIcon className="mr-1.5 inline-block size-4" />
552-
GitHub members synced from{" "}
553-
<GithubAccountLink githubAccount={githubAccount} />
554-
</ListTitle>
585+
<>
555586
<List>
556587
{members.map((member) => {
557588
const teamMember = member.teamMember ?? null;
@@ -649,6 +680,20 @@ function TeamGithubMembersList(props: {
649680
</Button>
650681
</div>
651682
)}
683+
</>
684+
);
685+
}
686+
687+
function ShowPendingSwitch(props: {
688+
isSelected: boolean;
689+
onChange: (isSelected: boolean) => void;
690+
}) {
691+
const { onChange, isSelected } = props;
692+
const id = useId();
693+
return (
694+
<div className="mb-2 flex select-none items-center gap-1.5 text-sm font-medium">
695+
<label htmlFor={id}>Show pending members</label>
696+
<Switch id={id} size="sm" onChange={onChange} isSelected={isSelected} />
652697
</div>
653698
);
654699
}

Diff for: apps/frontend/src/gql/gql.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ type Documents = {
9090
"\n fragment TeamGitHubSSO_Team on Team {\n id\n plan {\n id\n displayName\n usageBased\n githubSsoIncluded\n }\n subscriptionStatus\n ssoGithubAccount {\n id\n ...GithubAccountLink_GithubAccount\n }\n }\n": typeof types.TeamGitHubSso_TeamFragmentDoc,
9191
"\n mutation ConfigureGitHubSSO_disableGitHubSSOOnTeam($teamAccountId: ID!) {\n disableGitHubSSOOnTeam(input: { teamAccountId: $teamAccountId }) {\n ...TeamGitHubSSO_Team\n }\n }\n": typeof types.ConfigureGitHubSso_DisableGitHubSsoOnTeamDocument,
9292
"\n query TeamMembers_teamMembers($id: ID!, $first: Int!, $after: Int!) {\n team: teamById(id: $id) {\n id\n members(first: $first, after: $after, sso: false) {\n edges {\n id\n level\n user {\n id\n ...UserListRow_user\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n pageInfo {\n hasNextPage\n totalCount\n }\n }\n }\n }\n": typeof types.TeamMembers_TeamMembersDocument,
93-
"\n query TeamMembers_githubMembers($id: ID!, $first: Int!, $after: Int!) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n": typeof types.TeamMembers_GithubMembersDocument,
93+
"\n query TeamMembers_githubMembers(\n $id: ID!\n $first: Int!\n $after: Int!\n $isTeamMember: Boolean\n ) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after, isTeamMember: $isTeamMember) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n": typeof types.TeamMembers_GithubMembersDocument,
9494
"\n fragment TeamMembers_Team on Team {\n id\n name\n slug\n inviteLink\n permissions\n ssoGithubAccount {\n id\n ...TeamGithubMembersList_GithubAccount\n }\n plan {\n id\n fineGrainedAccessControlIncluded\n }\n me {\n id\n level\n }\n }\n": typeof types.TeamMembers_TeamFragmentDoc,
9595
"\n mutation TeamMembers_leaveTeam($teamAccountId: ID!) {\n leaveTeam(input: { teamAccountId: $teamAccountId })\n }\n": typeof types.TeamMembers_LeaveTeamDocument,
9696
"\n mutation TeamMembers_removeUserFromTeam(\n $teamAccountId: ID!\n $userAccountId: ID!\n ) {\n removeUserFromTeam(\n input: { teamAccountId: $teamAccountId, userAccountId: $userAccountId }\n ) {\n teamMemberId\n }\n }\n": typeof types.TeamMembers_RemoveUserFromTeamDocument,
@@ -224,7 +224,7 @@ const documents: Documents = {
224224
"\n fragment TeamGitHubSSO_Team on Team {\n id\n plan {\n id\n displayName\n usageBased\n githubSsoIncluded\n }\n subscriptionStatus\n ssoGithubAccount {\n id\n ...GithubAccountLink_GithubAccount\n }\n }\n": types.TeamGitHubSso_TeamFragmentDoc,
225225
"\n mutation ConfigureGitHubSSO_disableGitHubSSOOnTeam($teamAccountId: ID!) {\n disableGitHubSSOOnTeam(input: { teamAccountId: $teamAccountId }) {\n ...TeamGitHubSSO_Team\n }\n }\n": types.ConfigureGitHubSso_DisableGitHubSsoOnTeamDocument,
226226
"\n query TeamMembers_teamMembers($id: ID!, $first: Int!, $after: Int!) {\n team: teamById(id: $id) {\n id\n members(first: $first, after: $after, sso: false) {\n edges {\n id\n level\n user {\n id\n ...UserListRow_user\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n pageInfo {\n hasNextPage\n totalCount\n }\n }\n }\n }\n": types.TeamMembers_TeamMembersDocument,
227-
"\n query TeamMembers_githubMembers($id: ID!, $first: Int!, $after: Int!) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n": types.TeamMembers_GithubMembersDocument,
227+
"\n query TeamMembers_githubMembers(\n $id: ID!\n $first: Int!\n $after: Int!\n $isTeamMember: Boolean\n ) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after, isTeamMember: $isTeamMember) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n": types.TeamMembers_GithubMembersDocument,
228228
"\n fragment TeamMembers_Team on Team {\n id\n name\n slug\n inviteLink\n permissions\n ssoGithubAccount {\n id\n ...TeamGithubMembersList_GithubAccount\n }\n plan {\n id\n fineGrainedAccessControlIncluded\n }\n me {\n id\n level\n }\n }\n": types.TeamMembers_TeamFragmentDoc,
229229
"\n mutation TeamMembers_leaveTeam($teamAccountId: ID!) {\n leaveTeam(input: { teamAccountId: $teamAccountId })\n }\n": types.TeamMembers_LeaveTeamDocument,
230230
"\n mutation TeamMembers_removeUserFromTeam(\n $teamAccountId: ID!\n $userAccountId: ID!\n ) {\n removeUserFromTeam(\n input: { teamAccountId: $teamAccountId, userAccountId: $userAccountId }\n ) {\n teamMemberId\n }\n }\n": types.TeamMembers_RemoveUserFromTeamDocument,
@@ -603,7 +603,7 @@ export function graphql(source: "\n query TeamMembers_teamMembers($id: ID!, $fi
603603
/**
604604
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
605605
*/
606-
export function graphql(source: "\n query TeamMembers_githubMembers($id: ID!, $first: Int!, $after: Int!) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n"): (typeof documents)["\n query TeamMembers_githubMembers($id: ID!, $first: Int!, $after: Int!) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n"];
606+
export function graphql(source: "\n query TeamMembers_githubMembers(\n $id: ID!\n $first: Int!\n $after: Int!\n $isTeamMember: Boolean\n ) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after, isTeamMember: $isTeamMember) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n"): (typeof documents)["\n query TeamMembers_githubMembers(\n $id: ID!\n $first: Int!\n $after: Int!\n $isTeamMember: Boolean\n ) {\n team: teamById(id: $id) {\n id\n githubMembers(first: $first, after: $after, isTeamMember: $isTeamMember) {\n edges {\n id\n githubAccount {\n id\n login\n avatar {\n ...AccountAvatarFragment\n }\n }\n teamMember {\n id\n level\n user {\n id\n name\n slug\n avatar {\n ...AccountAvatarFragment\n }\n ...RemoveFromTeamDialog_User\n }\n ...LevelSelect_TeamMember\n }\n }\n pageInfo {\n hasNextPage\n }\n }\n }\n }\n"];
607607
/**
608608
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
609609
*/

0 commit comments

Comments
 (0)