Skip to content

Commit 065c3ac

Browse files
committed
Create User Projects grid with gql
1 parent 1627b84 commit 065c3ac

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

src/api/schema/typePolicies/typePolicies.base.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ export const typePolicies: TypePolicies = {
8585
engagements: {},
8686
},
8787
},
88+
User: {
89+
fields: {
90+
projects: {}, // no page merging (infinite scroll)
91+
},
92+
},
8893
Query: {
8994
fields: {
9095
projects: {},
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { TabPanelContent } from '~/components/Tabs';
2+
import { UserProjectsPanel } from './UserProjectPanel/UserProjectsPanel';
3+
4+
export const UserDetailProjects = () => {
5+
return (
6+
<TabPanelContent>
7+
<UserProjectsPanel />
8+
</TabPanelContent>
9+
);
10+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
query UserProjects($userId: ID!, $input: ProjectListInput) {
2+
user(id: $userId) {
3+
id
4+
projects(input: $input) {
5+
canRead
6+
hasMore
7+
total
8+
items {
9+
...userProjectDataGridRow
10+
}
11+
}
12+
}
13+
}
14+
15+
fragment userProjectDataGridRow on Project {
16+
membership(user: $userId) {
17+
id
18+
roles {
19+
value
20+
}
21+
}
22+
...projectDataGridRow
23+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {
2+
DataGridPro as DataGrid,
3+
DataGridProProps as DataGridProps,
4+
GridColDef,
5+
} from '@mui/x-data-grid-pro';
6+
import { merge } from 'lodash';
7+
import { useMemo } from 'react';
8+
import { useParams } from 'react-router-dom';
9+
import { RoleLabels, RoleList } from '~/api/schema.graphql';
10+
import { unmatchedIndexThrow } from '~/common';
11+
import {
12+
DefaultDataGridStyles,
13+
flexLayout,
14+
multiEnumColumn,
15+
noFooter,
16+
noHeaderFilterButtons,
17+
useDataGridSource,
18+
} from '~/components/Grid';
19+
import {
20+
ProjectColumns,
21+
ProjectInitialState,
22+
ProjectToolbar,
23+
} from '~/components/ProjectDataGrid';
24+
import {
25+
UserProjectDataGridRowFragment as UserProject,
26+
UserProjectsDocument,
27+
} from './UserProjectList.graphql';
28+
29+
export const UserProjectsPanel = () => {
30+
const { userId = '' } = useParams();
31+
32+
const [dataGridProps] = useDataGridSource({
33+
query: UserProjectsDocument,
34+
variables: { userId },
35+
listAt: 'user.projects',
36+
initialInput: {
37+
sort: 'name',
38+
},
39+
});
40+
41+
const slots = useMemo(
42+
() =>
43+
merge({}, DefaultDataGridStyles.slots, dataGridProps.slots, {
44+
toolbar: ProjectToolbar,
45+
} satisfies DataGridProps['slots']),
46+
[dataGridProps.slots]
47+
);
48+
49+
const slotProps = useMemo(
50+
() => merge({}, DefaultDataGridStyles.slotProps, dataGridProps.slotProps),
51+
[dataGridProps.slotProps]
52+
);
53+
54+
return (
55+
<DataGrid<UserProject>
56+
{...DefaultDataGridStyles}
57+
{...dataGridProps}
58+
slots={slots}
59+
slotProps={slotProps}
60+
columns={UserProjectColumns}
61+
initialState={ProjectInitialState}
62+
headerFilters
63+
hideFooter
64+
sx={[flexLayout, noHeaderFilterButtons, noFooter]}
65+
/>
66+
);
67+
};
68+
69+
const UserProjectRoleColumn: GridColDef<UserProject> = {
70+
field: 'user.membership',
71+
headerName: 'Role',
72+
width: 300,
73+
...multiEnumColumn(RoleList, RoleLabels),
74+
valueGetter: (_, { membership }) => membership.roles.value,
75+
};
76+
77+
const indexAfterName =
78+
unmatchedIndexThrow(ProjectColumns.findIndex((c) => c.field === 'name')) + 1;
79+
80+
const UserProjectColumns = (ProjectColumns as Array<GridColDef<UserProject>>)
81+
// Add roles' column after name
82+
.toSpliced(indexAfterName, 0, UserProjectRoleColumn);

0 commit comments

Comments
 (0)