Skip to content

Commit 3d222b1

Browse files
authored
Project Member Active/Inactive handling (#1702)
2 parents e5e0d2b + 78bf571 commit 3d222b1

13 files changed

+201
-162
lines changed

src/common/hacky-inspect-dates.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ function makeAllPropsLazy(obj: any) {
3131
get(): any {
3232
return props[key];
3333
},
34+
set(v: any) {
35+
props[key] = v;
36+
},
3437
// somehow properties are getting lost if they cannot be enumerated
3538
enumerable: true,
3639
});

src/components/ProjectMemberCard/ProjectMember.graphql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,11 @@ fragment ProjectMemberCard on ProjectMember {
1818
value
1919
canRead
2020
}
21+
active
22+
inactiveAt {
23+
value
24+
canRead
25+
canEdit
26+
}
27+
canDelete
2128
}

src/components/ProjectMemberCard/ProjectMemberCard.tsx

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { makeStyles } from 'tss-react/mui';
1010
import { RoleLabels } from '~/api/schema.graphql';
1111
import { labelsFrom } from '~/common';
1212
import { Avatar } from '../Avatar';
13-
import { FormattedDateTime } from '../Formatters';
13+
import { FormattedDate, FormattedDateTime } from '../Formatters';
14+
import { Redacted } from '../Redacted';
15+
import { Link } from '../Routing';
1416
import { ProjectMemberCardFragment } from './ProjectMember.graphql';
1517

1618
const useStyles = makeStyles()(({ spacing }) => ({
@@ -60,13 +62,7 @@ export const ProjectMemberCard = ({
6062
{projectMember?.user.value?.avatarLetters}
6163
</Avatar>
6264
<div className={classes.memberInfo}>
63-
<Typography>
64-
{!projectMember ? (
65-
<Skeleton variant="text" width="40%" />
66-
) : (
67-
projectMember.user.value?.fullName
68-
)}
69-
</Typography>
65+
<UserRef projectMember={projectMember} />
7066
<Typography variant="body2" color="primary">
7167
{!projectMember ? (
7268
<Skeleton variant="text" width="33%" />
@@ -90,13 +86,45 @@ export const ProjectMemberCard = ({
9086
<Typography variant="subtitle2" color="textSecondary">
9187
{!projectMember ? (
9288
<Skeleton variant="text" width="23ch" />
89+
) : projectMember.active === false ? (
90+
projectMember.inactiveAt.value ? (
91+
<>
92+
Membership ended on{' '}
93+
<FormattedDate date={projectMember.inactiveAt.value} />
94+
</>
95+
) : null
9396
) : (
9497
<>
95-
Member Since <FormattedDateTime date={projectMember.createdAt} />
98+
Membership started at{' '}
99+
<FormattedDateTime date={projectMember.createdAt} />
96100
</>
97101
)}
98102
</Typography>
99103
</CardActions>
100104
</Card>
101105
);
102106
};
107+
108+
const UserRef = ({
109+
projectMember,
110+
}: Pick<ProjectMemberCardProps, 'projectMember'>) => {
111+
if (!projectMember) {
112+
return (
113+
<Typography>
114+
<Skeleton width="40%" />
115+
</Typography>
116+
);
117+
}
118+
if (!projectMember.user.value) {
119+
return <Redacted info="You cannot view this person" width="100%" />;
120+
}
121+
return (
122+
<Link
123+
color="inherit"
124+
to={`/users/${projectMember.user.value.id}`}
125+
underline="hover"
126+
>
127+
{projectMember.user.value.fullName}
128+
</Link>
129+
);
130+
};

src/components/ProjectMembersSummary/ProjectMemberItem.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
fragment ProjectMemberItem on ProjectMember {
22
id
3+
active
34
user {
45
canRead
56
canEdit
Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
fragment ProjectMemberList on SecuredProjectMemberList {
2-
items {
3-
...ProjectMemberItem
1+
fragment projectMembersSummary on Project {
2+
id
3+
activeMembers: team(input: { filter: { active: true } }) {
4+
total
5+
}
6+
team {
7+
items {
8+
...ProjectMemberItem
9+
}
10+
...Pagination
411
}
5-
...Pagination
612
}

src/components/ProjectMembersSummary/ProjectMembersSummary.stories.tsx

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/components/ProjectMembersSummary/ProjectMembersSummary.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { Group } from '@mui/icons-material';
22
import { MemberListSummary, MemberSummaryItem } from '../MemberListSummary';
3-
import { ProjectMemberListFragment } from './ProjectMembersSummary.graphql';
3+
import { ProjectMembersSummaryFragment as Project } from './ProjectMembersSummary.graphql';
44

55
export interface ProjectMembersSummaryProps {
6-
members?: ProjectMemberListFragment;
6+
project?: Project;
77
}
88

99
export const ProjectMembersSummary = ({
10-
members,
10+
project,
1111
}: ProjectMembersSummaryProps) => {
12-
const summarizedMembers = members?.items
13-
.filter(({ user }) => user.canRead && user.value)
12+
const summarizedMembers = project?.team.items
13+
.filter(({ active, user }) => active && user.canRead && user.value)
1414
.map(({ user }) => user.value!)
1515
.map(
1616
(user): MemberSummaryItem => ({
@@ -22,7 +22,7 @@ export const ProjectMembersSummary = ({
2222

2323
return (
2424
<MemberListSummary
25-
total={members?.total}
25+
total={project?.activeMembers.total}
2626
title="Team Members"
2727
members={summarizedMembers}
2828
to="members"

src/components/form/DateField.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,12 @@ export type DateFieldProps = Except<
3232
> &
3333
Pick<
3434
TextFieldProps,
35-
'label' | 'disabled' | 'helperText' | 'placeholder' | 'fullWidth'
35+
| 'variant'
36+
| 'label'
37+
| 'disabled'
38+
| 'helperText'
39+
| 'placeholder'
40+
| 'fullWidth'
3641
> & {
3742
name: string;
3843
defaultValue?: CalendarDateOrISO | null;
@@ -49,6 +54,7 @@ export const DateField = ({
4954
errorMessages,
5055
disableFormatHelperText,
5156
placeholder,
57+
variant,
5258
...props
5359
}: DateFieldProps) => {
5460
const i10nCtx = useLocalization();
@@ -154,6 +160,7 @@ export const DateField = ({
154160
renderInput={(params) => (
155161
<TextField
156162
autoComplete="off"
163+
variant={variant}
157164
{...params}
158165
onFocus={() => {
159166
if (!open.current) {

src/scenes/Projects/Members/List/ProjectMembersList.tsx

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Add } from '@mui/icons-material';
2-
import { Breadcrumbs, Tooltip, Typography } from '@mui/material';
2+
import { Breadcrumbs, Stack, Tooltip, Typography } from '@mui/material';
3+
import { partition } from 'lodash';
34
import { Helmet } from 'react-helmet-async';
45
import { makeStyles } from 'tss-react/mui';
56
import { Breadcrumb } from '../../../../components/Breadcrumb';
@@ -10,7 +11,7 @@ import { ProjectBreadcrumb } from '../../../../components/ProjectBreadcrumb';
1011
import { ProjectMemberCard } from '../../../../components/ProjectMemberCard';
1112
import { useProjectId } from '../../useProjectId';
1213
import { CreateProjectMember } from '../Create/CreateProjectMember';
13-
import { UpdateProjectMember, UpdateProjectMemberFormParams } from '../Update';
14+
import { UpdateProjectMember, UpdateProjectMemberProps } from '../Update';
1415
import { ProjectMembersDocument } from './ProjectMembers.graphql';
1516

1617
const useStyles = makeStyles()(({ spacing, breakpoints }) => ({
@@ -40,14 +41,15 @@ export const ProjectMembersList = () => {
4041
},
4142
});
4243

43-
const [createProjectMemberDialogState, openCreateProjectMemberDialog] =
44-
useDialog();
44+
const [createMemberState, createMember] = useDialog();
4545

46-
const [
47-
updateProjectMemberDialogState,
48-
openUpdateProjectMemberDialog,
49-
projectMemberProps,
50-
] = useDialog<UpdateProjectMemberFormParams>();
46+
const [editMemberState, editMember, editingMember] =
47+
useDialog<UpdateProjectMemberProps['member']>();
48+
49+
const [active, historic] = partition(
50+
data?.project.team.items,
51+
(member) => member.active !== false
52+
);
5153

5254
return (
5355
<div className={classes.root}>
@@ -68,17 +70,14 @@ export const ProjectMembersList = () => {
6870
color="error"
6971
aria-label="Add Team Member"
7072
loading={!list.data}
71-
onClick={openCreateProjectMemberDialog}
73+
onClick={createMember}
7274
>
7375
<Add />
7476
</Fab>
7577
</Tooltip>
7678
)}
7779
{data && (
78-
<CreateProjectMember
79-
{...createProjectMemberDialogState}
80-
project={data.project}
81-
/>
80+
<CreateProjectMember {...createMemberState} project={data.project} />
8281
)}
8382
</div>
8483
{list.data?.canRead === false ? (
@@ -88,27 +87,41 @@ export const ProjectMembersList = () => {
8887
) : (
8988
<List
9089
{...list}
90+
data={list.data ? { ...list.data, items: active } : undefined}
9191
spacing={3}
9292
renderItem={(member) => (
9393
<ProjectMemberCard
9494
projectMember={member}
95-
onEdit={() =>
96-
openUpdateProjectMemberDialog({
97-
project: data!.project,
98-
projectMemberId: member.id,
99-
userId: member.user.value?.id || '',
100-
userRoles: member.roles.value,
101-
})
102-
}
95+
onEdit={() => editMember(member)}
10396
/>
10497
)}
10598
renderSkeleton={<ProjectMemberCard />}
10699
/>
107100
)}
108-
{projectMemberProps && (
101+
{historic.length > 0 && (
102+
<>
103+
<Typography variant="h3" sx={{ my: 2 }}>
104+
Historic
105+
</Typography>
106+
<Stack
107+
// to match the list above
108+
sx={{ gap: 3, pr: 2 }}
109+
>
110+
{historic.map((member) => (
111+
<ProjectMemberCard
112+
key={member.id}
113+
projectMember={member}
114+
onEdit={() => editMember(member)}
115+
/>
116+
))}
117+
</Stack>
118+
</>
119+
)}
120+
{editingMember && (
109121
<UpdateProjectMember
110-
{...updateProjectMemberDialogState}
111-
{...projectMemberProps}
122+
{...editMemberState}
123+
member={editingMember}
124+
project={data!.project}
112125
/>
113126
)}
114127
</div>

src/scenes/Projects/Members/Update/UpdateProjectMember.graphql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ query GetUserRoles($userId: ID!) {
1010
user(id: $userId) {
1111
id
1212
roles {
13-
canRead
14-
value
13+
availableForProjects
1514
}
1615
}
1716
}

0 commit comments

Comments
 (0)