1- import { useState , useCallback , useMemo } from 'react' ;
1+ import { useState , useMemo } from 'react' ;
22import { useParams } from 'react-router-dom' ;
33import { useIntl } from '@openedx/frontend-base' ;
4- import { Button , DataTable } from '@openedx/paragon' ;
4+ import { Button , DataTable , FormControl , Icon } from '@openedx/paragon' ;
55import messages from '../messages' ;
6- import { useTeamMembers } from '../data/apiHook' ;
6+ import { useRoles , useTeamMembers } from '../data/apiHook' ;
7+ import UsernameFilter from '@src/components/UsernameFilter' ;
8+ import { FilterList } from '@openedx/paragon/icons' ;
9+ import { DataTableFetchDataProps } from '@src/types' ;
10+ import { Role } from '../types' ;
711
812const TEAM_MEMBERS_PAGE_SIZE = 25 ;
913
14+ const RoleFilter = ( { column : { filterValue, setFilter } } : { column : { filterValue : string , setFilter : ( value : string ) => void } } ) => {
15+ const intl = useIntl ( ) ;
16+ const { courseId = '' } = useParams < { courseId : string } > ( ) ;
17+ const { data } = useRoles ( courseId ) ;
18+
19+ const handleSelectChange = ( e : React . ChangeEvent < HTMLSelectElement > ) => {
20+ setFilter ( e . target . value ) ;
21+ } ;
22+
23+ const roles = useMemo ( ( ) => {
24+ return [ { value : '' , label : intl . formatMessage ( messages . allRoles ) } , ...( data ?. results || [ ] ) . map ( ( role : Role ) => ( { value : role . role , label : role . displayName } ) ) ] ;
25+ } , [ data , intl ] ) ;
26+
27+ return (
28+ < FormControl
29+ as = "select"
30+ className = "mb-0"
31+ disabled = { ! data }
32+ name = "role"
33+ size = "md"
34+ value = { filterValue }
35+ onChange = { handleSelectChange }
36+ leadingElement = { < Icon src = { FilterList } /> }
37+ >
38+ { roles . map ( role => (
39+ < option key = { role . value } value = { role . value } >
40+ { role . label }
41+ </ option >
42+ ) ) }
43+ </ FormControl >
44+ ) ;
45+ } ;
46+
1047const MembersContent = ( ) => {
1148 const intl = useIntl ( ) ;
1249 const { courseId = '' } = useParams < { courseId : string } > ( ) ;
1350 const [ filters , setFilters ] = useState ( { page : 0 , emailOrUsername : '' , role : '' } ) ;
1451 const { data : { results : teamMembers = [ ] , numPages = 1 , count = 0 } = { } , isLoading = false } = useTeamMembers ( courseId , { ...filters , pageSize : TEAM_MEMBERS_PAGE_SIZE } ) ;
1552
1653 const tableColumns = useMemo ( ( ) => [
17- { accessor : 'username' , Header : intl . formatMessage ( messages . username ) } ,
18- { accessor : 'email' , Header : intl . formatMessage ( messages . email ) } ,
19- { accessor : 'role' , Header : intl . formatMessage ( messages . role ) } ,
54+ { accessor : 'username' , Header : intl . formatMessage ( messages . username ) , Filter : UsernameFilter } ,
55+ { accessor : 'email' , Header : intl . formatMessage ( messages . email ) , disableFilters : true } ,
56+ { accessor : 'role' , Header : intl . formatMessage ( messages . role ) , Filter : RoleFilter } ,
2057 ] , [ intl ] ) ;
2158
2259 const additionalColumns = useMemo ( ( ) => [ {
@@ -29,17 +66,27 @@ const MembersContent = () => {
2966 )
3067 } ] , [ intl ] ) ;
3168
32- const handleFetchData = useCallback ( ( { pageIndex, filters : tableFilters } : { pageIndex : number , filters : { id : string , value : string } [ ] } ) => {
33- // Filters will be handled in a future iteration, for now we will just update pagination
34- console . log ( pageIndex , tableFilters ) ;
35- if ( pageIndex !== filters . page ) {
36- setFilters ( prevFilters => ( {
69+ const handleFetchData = ( data : DataTableFetchDataProps ) => {
70+ const usernameFilter = data . filters ?. find ( ( f ) => f . id === 'username' ) ;
71+ const newEmailOrUsername = usernameFilter ? usernameFilter . value : '' ;
72+ const rolesFilter = data . filters ?. find ( ( f ) => f . id === 'role' ) ;
73+ const newRole = rolesFilter ? rolesFilter . value : '' ;
74+ const filtersChanged = ( newEmailOrUsername !== filters . emailOrUsername ) || ( newRole !== filters . role ) ;
75+
76+ if ( filtersChanged ) {
77+ setFilters ( ( prevFilters ) => ( {
3778 ...prevFilters ,
38- page : pageIndex ,
79+ emailOrUsername : newEmailOrUsername ,
80+ role : newRole ,
81+ page : 0 ,
3982 } ) ) ;
83+ return ;
84+ }
85+
86+ if ( data . pageIndex !== filters . page ) {
87+ setFilters ( ( prevFilters ) => ( { ...prevFilters , page : data . pageIndex } ) ) ;
4088 }
41- // eslint-disable-next-line react-hooks/exhaustive-deps
42- } , [ ] ) ;
89+ } ;
4390
4491 const tableState = useMemo ( ( ) => ( {
4592 pageIndex : filters . page ,
@@ -53,11 +100,13 @@ const MembersContent = () => {
53100 data = { teamMembers }
54101 fetchData = { handleFetchData }
55102 state = { tableState }
103+ isFilterable
56104 isLoading = { isLoading }
57105 isPaginated
58106 itemCount = { count }
59107 manualFilters
60108 manualPagination
109+ numBreakoutFilters = { 2 }
61110 pageSize = { TEAM_MEMBERS_PAGE_SIZE }
62111 pageCount = { numPages }
63112 RowStatusComponent = { ( ) => null }
0 commit comments