-
Notifications
You must be signed in to change notification settings - Fork 245
/
UserList.tsx
99 lines (92 loc) · 2.61 KB
/
UserList.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import React, { Suspense, useState } from 'react'
import { gql, useQuery } from 'urql'
import { UserAvatar } from '../util/avatars'
import UserPhoneNumberFilterContainer from './UserPhoneNumberFilterContainer'
import UserCreateDialog from './UserCreateDialog'
import { useSessionInfo } from '../util/RequireConfig'
import ListPageControls from '../lists/ListPageControls'
import Search from '../util/Search'
import FlatList from '../lists/FlatList'
import { UserConnection } from '../../schema'
import { useURLParam } from '../actions'
import { FavoriteIcon } from '../util/SetFavoriteButton'
const query = gql`
query usersQuery($input: UserSearchOptions) {
users(input: $input) {
nodes {
id
name
email
isFavorite
}
pageInfo {
hasNextPage
endCursor
}
}
}
`
const context = { suspense: false }
function UserList(): JSX.Element {
const { isAdmin } = useSessionInfo()
const [create, setCreate] = useState(false)
const [search] = useURLParam<string>('search', '')
const [cursor, setCursor] = useState('')
const inputVars = {
favoritesFirst: true,
search,
CMValue: '',
after: cursor,
}
if (search.startsWith('phone=')) {
inputVars.CMValue = search.replace(/^phone=/, '')
inputVars.search = ''
}
const [q] = useQuery<{ users: UserConnection }>({
query,
variables: { input: inputVars },
context,
})
const nextCursor = q.data?.users.pageInfo.hasNextPage
? q.data?.users.pageInfo.endCursor
: ''
// cache the next page
useQuery({
query,
variables: { input: { ...inputVars, after: nextCursor } },
context,
pause: !nextCursor,
})
return (
<React.Fragment>
<Suspense>
{create && <UserCreateDialog onClose={() => setCreate(false)} />}
</Suspense>
<ListPageControls
createLabel='User'
nextCursor={nextCursor}
onCursorChange={setCursor}
loading={q.fetching}
onCreateClick={isAdmin ? () => setCreate(true) : undefined}
slots={{
search: <Search endAdornment={<UserPhoneNumberFilterContainer />} />,
list: (
<FlatList
emptyMessage='No results'
items={
q.data?.users.nodes.map((u) => ({
title: u.name,
subText: u.email,
url: u.id,
secondaryAction: u.isFavorite ? <FavoriteIcon /> : undefined,
icon: <UserAvatar userID={u.id} />,
})) || []
}
/>
),
}}
/>
</React.Fragment>
)
}
export default UserList