@@ -2,8 +2,10 @@ import Box from "@material-ui/core/Box"
2
2
import { makeStyles } from "@material-ui/core/styles"
3
3
import TableCell from "@material-ui/core/TableCell"
4
4
import TableRow from "@material-ui/core/TableRow"
5
+ import { ChooseOne , Cond } from "components/Conditionals/ChooseOne"
5
6
import { LastUsed } from "components/LastUsed/LastUsed"
6
7
import { FC } from "react"
8
+ import { useTranslation } from "react-i18next"
7
9
import * as TypesGen from "../../api/typesGenerated"
8
10
import { combineClasses } from "../../util/combineClasses"
9
11
import { AvatarData } from "../AvatarData/AvatarData"
@@ -12,15 +14,6 @@ import { RoleSelect } from "../RoleSelect/RoleSelect"
12
14
import { TableLoader } from "../TableLoader/TableLoader"
13
15
import { TableRowMenu } from "../TableRowMenu/TableRowMenu"
14
16
15
- export const Language = {
16
- emptyMessage : "No users found" ,
17
- suspendMenuItem : "Suspend" ,
18
- deleteMenuItem : "Delete" ,
19
- listWorkspacesMenuItem : "View workspaces" ,
20
- activateMenuItem : "Activate" ,
21
- resetPasswordMenuItem : "Reset password" ,
22
- }
23
-
24
17
interface UsersTableBodyProps {
25
18
users ?: TypesGen . User [ ]
26
19
roles ?: TypesGen . AssignableRoles [ ]
@@ -36,6 +29,7 @@ interface UsersTableBodyProps {
36
29
user : TypesGen . User ,
37
30
roles : TypesGen . Role [ "name" ] [ ] ,
38
31
) => void
32
+ isNonInitialPage : boolean
39
33
}
40
34
41
35
export const UsersTableBody : FC <
@@ -52,121 +46,144 @@ export const UsersTableBody: FC<
52
46
isUpdatingUserRoles,
53
47
canEditUsers,
54
48
isLoading,
49
+ isNonInitialPage,
55
50
} ) => {
56
51
const styles = useStyles ( )
57
-
58
- if ( isLoading ) {
59
- return < TableLoader />
60
- }
61
-
62
- if ( ! users || users . length === 0 ) {
63
- return (
64
- < TableRow >
65
- < TableCell colSpan = { 999 } >
66
- < Box p = { 4 } >
67
- < EmptyState message = { Language . emptyMessage } />
68
- </ Box >
69
- </ TableCell >
70
- </ TableRow >
71
- )
72
- }
52
+ const { t } = useTranslation ( "usersPage" )
73
53
74
54
return (
75
- < >
76
- { users . map ( ( user ) => {
77
- // When the user has no role we want to show they are a Member
78
- const fallbackRole : TypesGen . Role = {
79
- name : "member" ,
80
- display_name : "Member" ,
81
- }
82
- const userRoles = user . roles . length === 0 ? [ fallbackRole ] : user . roles
55
+ < ChooseOne >
56
+ < Cond condition = { Boolean ( isLoading ) } >
57
+ < TableLoader />
58
+ </ Cond >
59
+ < Cond condition = { ! users || users . length === 0 } >
60
+ < ChooseOne >
61
+ < Cond condition = { isNonInitialPage } >
62
+ < TableRow >
63
+ < TableCell colSpan = { 999 } >
64
+ < Box p = { 4 } >
65
+ < EmptyState message = { t ( "emptyPageMessage" ) } />
66
+ </ Box >
67
+ </ TableCell >
68
+ </ TableRow >
69
+ </ Cond >
70
+ < Cond >
71
+ < TableRow >
72
+ < TableCell colSpan = { 999 } >
73
+ < Box p = { 4 } >
74
+ < EmptyState message = { t ( "emptyMessage" ) } />
75
+ </ Box >
76
+ </ TableCell >
77
+ </ TableRow >
78
+ </ Cond >
79
+ </ ChooseOne >
80
+ </ Cond >
81
+ < Cond >
82
+ < >
83
+ { users &&
84
+ users . map ( ( user ) => {
85
+ // When the user has no role we want to show they are a Member
86
+ const fallbackRole : TypesGen . Role = {
87
+ name : "member" ,
88
+ display_name : "Member" ,
89
+ }
90
+ const userRoles =
91
+ user . roles . length === 0 ? [ fallbackRole ] : user . roles
83
92
84
- return (
85
- < TableRow key = { user . id } >
86
- < TableCell >
87
- < AvatarData
88
- title = { user . username }
89
- subtitle = { user . email }
90
- highlightTitle
91
- avatar = {
92
- user . avatar_url ? (
93
- < img
94
- className = { styles . avatar }
95
- alt = { `${ user . username } 's Avatar` }
96
- src = { user . avatar_url }
93
+ return (
94
+ < TableRow key = { user . id } >
95
+ < TableCell >
96
+ < AvatarData
97
+ title = { user . username }
98
+ subtitle = { user . email }
99
+ highlightTitle
100
+ avatar = {
101
+ user . avatar_url ? (
102
+ < img
103
+ className = { styles . avatar }
104
+ alt = { `${ user . username } 's Avatar` }
105
+ src = { user . avatar_url }
106
+ />
107
+ ) : null
108
+ }
97
109
/>
98
- ) : null
99
- }
100
- />
101
- </ TableCell >
102
- < TableCell
103
- className = { combineClasses ( [
104
- styles . status ,
105
- user . status === "suspended" ? styles . suspended : undefined ,
106
- ] ) }
107
- >
108
- { user . status }
109
- </ TableCell >
110
- < TableCell >
111
- < LastUsed lastUsedAt = { user . last_seen_at } />
112
- </ TableCell >
113
- < TableCell >
114
- { canEditUsers ? (
115
- < RoleSelect
116
- roles = { roles ?? [ ] }
117
- selectedRoles = { userRoles }
118
- loading = { isUpdatingUserRoles }
119
- onChange = { ( roles ) => {
120
- // Remove the fallback role because it is only for the UI
121
- roles = roles . filter ( ( role ) => role !== fallbackRole . name )
122
- onUpdateUserRoles ( user , roles )
123
- } }
124
- />
125
- ) : (
126
- < > { userRoles . map ( ( role ) => role . display_name ) . join ( ", " ) } </ >
127
- ) }
128
- </ TableCell >
129
- { canEditUsers && (
130
- < TableCell >
131
- < TableRowMenu
132
- data = { user }
133
- menuItems = {
134
- // Return either suspend or activate depending on status
135
- ( user . status === "active"
136
- ? [
137
- {
138
- label : Language . suspendMenuItem ,
139
- onClick : onSuspendUser ,
140
- } ,
141
- ]
142
- : [
143
- {
144
- label : Language . activateMenuItem ,
145
- onClick : onActivateUser ,
146
- } ,
147
- ]
148
- ) . concat (
149
- {
150
- label : Language . deleteMenuItem ,
151
- onClick : onDeleteUser ,
152
- } ,
153
- {
154
- label : Language . listWorkspacesMenuItem ,
155
- onClick : onListWorkspaces ,
156
- } ,
157
- {
158
- label : Language . resetPasswordMenuItem ,
159
- onClick : onResetUserPassword ,
160
- } ,
161
- )
162
- }
163
- />
164
- </ TableCell >
165
- ) }
166
- </ TableRow >
167
- )
168
- } ) }
169
- </ >
110
+ </ TableCell >
111
+ < TableCell
112
+ className = { combineClasses ( [
113
+ styles . status ,
114
+ user . status === "suspended"
115
+ ? styles . suspended
116
+ : undefined ,
117
+ ] ) }
118
+ >
119
+ { user . status }
120
+ </ TableCell >
121
+ < TableCell >
122
+ < LastUsed lastUsedAt = { user . last_seen_at } />
123
+ </ TableCell >
124
+ < TableCell >
125
+ { canEditUsers ? (
126
+ < RoleSelect
127
+ roles = { roles ?? [ ] }
128
+ selectedRoles = { userRoles }
129
+ loading = { isUpdatingUserRoles }
130
+ onChange = { ( roles ) => {
131
+ // Remove the fallback role because it is only for the UI
132
+ roles = roles . filter (
133
+ ( role ) => role !== fallbackRole . name ,
134
+ )
135
+ onUpdateUserRoles ( user , roles )
136
+ } }
137
+ />
138
+ ) : (
139
+ < >
140
+ { userRoles . map ( ( role ) => role . display_name ) . join ( ", " ) }
141
+ </ >
142
+ ) }
143
+ </ TableCell >
144
+ { canEditUsers && (
145
+ < TableCell >
146
+ < TableRowMenu
147
+ data = { user }
148
+ menuItems = {
149
+ // Return either suspend or activate depending on status
150
+ ( user . status === "active"
151
+ ? [
152
+ {
153
+ label : t ( "suspendMenuItem" ) ,
154
+ onClick : onSuspendUser ,
155
+ } ,
156
+ ]
157
+ : [
158
+ {
159
+ label : t ( "activateMenuItem" ) ,
160
+ onClick : onActivateUser ,
161
+ } ,
162
+ ]
163
+ ) . concat (
164
+ {
165
+ label : t ( "deleteMenuItem" ) ,
166
+ onClick : onDeleteUser ,
167
+ } ,
168
+ {
169
+ label : t ( "listWorkspacesMenuItem" ) ,
170
+ onClick : onListWorkspaces ,
171
+ } ,
172
+ {
173
+ label : t ( "resetPasswordMenuItem" ) ,
174
+ onClick : onResetUserPassword ,
175
+ } ,
176
+ )
177
+ }
178
+ />
179
+ </ TableCell >
180
+ ) }
181
+ </ TableRow >
182
+ )
183
+ } ) }
184
+ </ >
185
+ </ Cond >
186
+ </ ChooseOne >
170
187
)
171
188
}
172
189
0 commit comments