1+ import React , { Component } from 'react' ;
2+ import { getList , getManyReference , isIdExists , setManyReference } from '../utils/api' ;
3+ import Checkbox from '@material-ui/core/Checkbox' ;
4+
5+
6+ import classNames from 'classnames' ;
7+ import PropTypes from 'prop-types' ;
8+ import { withStyles } from '@material-ui/core/styles' ;
9+ import Table from '@material-ui/core/Table' ;
10+ import TableBody from '@material-ui/core/TableBody' ;
11+ import TableCell from '@material-ui/core/TableCell' ;
12+ import TableHead from '@material-ui/core/TableHead' ;
13+ import TablePagination from '@material-ui/core/TablePagination' ;
14+ import TableRow from '@material-ui/core/TableRow' ;
15+ import TableSortLabel from '@material-ui/core/TableSortLabel' ;
16+ import Toolbar from '@material-ui/core/Toolbar' ;
17+ import Typography from '@material-ui/core/Typography' ;
18+ import Paper from '@material-ui/core/Paper' ;
19+ import IconButton from '@material-ui/core/IconButton' ;
20+ import Tooltip from '@material-ui/core/Tooltip' ;
21+ import CheckCircleIcon from '@material-ui/icons/CheckCircle' ;
22+ import FilterListIcon from '@material-ui/icons/FilterList' ;
23+ import { lighten } from '@material-ui/core/styles/colorManipulator' ;
24+
25+
26+ function getSorting ( order , orderBy ) {
27+ return order === 'desc' ?
28+ ( a , b ) => ( b [ orderBy ] < a [ orderBy ] ? - 1 : 1 ) :
29+ ( a , b ) => ( a [ orderBy ] < b [ orderBy ] ? - 1 : 1 ) ;
30+ }
31+
32+
33+ const columnData = [
34+ { id : 'Id' , numeric : false , disablePadding : false , label : 'Id' } ,
35+ { id : 'Exam Name' , numeric : false , disablePadding : false , label : 'Exam Name' } ,
36+ { id : 'Date' , numeric : false , disablePadding : false , label : 'Date' } ,
37+ ] ;
38+
39+ class EnhancedTableHead extends React . Component {
40+ createSortHandler = property => event => {
41+ this . props . onRequestSort ( event , property ) ;
42+ } ;
43+
44+ render ( ) {
45+ const { onSelectAllClick, order, orderBy, numSelected, rowCount } = this . props ;
46+
47+ return (
48+ < TableHead >
49+ < TableRow >
50+ < TableCell padding = "checkbox" >
51+ < Checkbox
52+ indeterminate = { numSelected > 0 && numSelected < rowCount }
53+ checked = { numSelected === rowCount }
54+ onChange = { onSelectAllClick }
55+ />
56+ </ TableCell >
57+ { columnData . map ( column => {
58+ return (
59+ < TableCell
60+ key = { column . id }
61+ numeric = { column . numeric }
62+ padding = { column . disablePadding ? 'none' : 'default' }
63+ sortDirection = { orderBy === column . id ? order : false }
64+ >
65+ < Tooltip
66+ title = "Sort"
67+ placement = { column . numeric ? 'bottom-end' : 'bottom-start' }
68+ enterDelay = { 300 }
69+ >
70+ < TableSortLabel
71+ active = { orderBy === column . id }
72+ direction = { order }
73+ onClick = { this . createSortHandler ( column . id ) }
74+ >
75+ { column . label }
76+ </ TableSortLabel >
77+ </ Tooltip >
78+ </ TableCell >
79+ ) ;
80+ } , this ) }
81+ </ TableRow >
82+ </ TableHead >
83+ ) ;
84+ }
85+ }
86+
87+ EnhancedTableHead . propTypes = {
88+ numSelected : PropTypes . number . isRequired ,
89+ onRequestSort : PropTypes . func . isRequired ,
90+ onSelectAllClick : PropTypes . func . isRequired ,
91+ order : PropTypes . string . isRequired ,
92+ orderBy : PropTypes . string . isRequired ,
93+ rowCount : PropTypes . number . isRequired ,
94+ } ;
95+
96+
97+ const toolbarStyles = theme => ( {
98+ root : {
99+ paddingRight : theme . spacing . unit ,
100+ } ,
101+ highlight :
102+ theme . palette . type === 'light'
103+ ? {
104+ color : theme . palette . secondary . main ,
105+ backgroundColor : lighten ( theme . palette . secondary . light , 0.85 ) ,
106+ }
107+ : {
108+ color : theme . palette . text . primary ,
109+ backgroundColor : theme . palette . secondary . dark ,
110+ } ,
111+ spacer : {
112+ flex : '1 1 100%' ,
113+ } ,
114+ actions : {
115+ color : theme . palette . text . secondary ,
116+ } ,
117+ title : {
118+ flex : '0 0 auto' ,
119+ } ,
120+ } ) ;
121+
122+ let EnhancedTableToolbar = props => {
123+ const { numSelected, classes } = props ;
124+
125+ return (
126+ < Toolbar
127+ className = { classNames ( classes . root , {
128+ [ classes . highlight ] : numSelected > 0 ,
129+ } ) }
130+ >
131+ < div className = { classes . title } >
132+ { numSelected > 0 ? (
133+ < Typography color = "inherit" variant = "subheading" >
134+ { numSelected } selected
135+ </ Typography >
136+ ) : (
137+ < Typography variant = "title" id = "tableTitle" >
138+ All
139+ </ Typography >
140+ ) }
141+ </ div >
142+ < div className = { classes . spacer } />
143+ < div className = { classes . actions } >
144+ { numSelected > 0 ? (
145+ < Tooltip title = "CheckCircle" >
146+ < IconButton aria-label = "CheckCircle" >
147+ < CheckCircleIcon />
148+ </ IconButton >
149+ </ Tooltip >
150+ ) : (
151+ < Tooltip title = "Filter list" >
152+ < IconButton aria-label = "Filter list" >
153+ < FilterListIcon />
154+ </ IconButton >
155+ </ Tooltip >
156+ ) }
157+ </ div >
158+ </ Toolbar >
159+ ) ;
160+ } ;
161+
162+ EnhancedTableToolbar . propTypes = {
163+ classes : PropTypes . object . isRequired ,
164+ numSelected : PropTypes . number . isRequired ,
165+ } ;
166+
167+ EnhancedTableToolbar = withStyles ( toolbarStyles ) ( EnhancedTableToolbar ) ;
168+
169+ const styles = theme => ( {
170+ root : {
171+ width : '100%' ,
172+ marginTop : theme . spacing . unit * 3 ,
173+ } ,
174+ table : {
175+ minWidth : 1020 ,
176+ } ,
177+ tableWrapper : {
178+ overflowX : 'auto' ,
179+ } ,
180+ } ) ;
181+
182+
183+ class ExamsManager extends Component {
184+ constructor ( props ) {
185+ super ( props ) ;
186+ this . course = props . source ;
187+ this . state = {
188+ // all exams
189+ exams : [ ] ,
190+ //default order
191+ order : 'asc' ,
192+ //key for order
193+ orderBy : 'id' ,
194+ //page number
195+ page : 0 ,
196+ //rows number per page
197+ rowsPerPage : 5 ,
198+ // exams that already choose this course
199+ selected : [ ] ,
200+ } ;
201+ }
202+
203+ componentDidMount ( ) {
204+ getList ( "exams" )
205+ . then ( exams => this . setState ( { exams : exams } ) ) ;
206+ // get exam that already choose this course
207+ getManyReference ( "courses" , "exams" , this . course )
208+ . then ( selected => this . setState ( { selected : selected [ 0 ] } ) ) ;
209+ }
210+
211+
212+ handleRequestSort = ( event , property ) => {
213+ const orderBy = property ;
214+ let order = 'desc' ;
215+
216+ if ( this . state . orderBy === property && this . state . order === 'desc' ) {
217+ order = 'asc' ;
218+ }
219+
220+ this . setState ( { order, orderBy } ) ;
221+ } ;
222+
223+ handleSelectAllClick = ( event , checked ) => {
224+ if ( checked ) {
225+ let selected = this . state . selected ;
226+ for ( var i = 0 ; i < this . state . exams . length ; ++ i ) {
227+ let index = isIdExists ( this . state . selected , this . state . exams [ i ] . id ) ;
228+ if ( index === - 1 ) {
229+ selected . push ( this . state . exams [ i ] ) ;
230+ }
231+ }
232+ this . setState ( { selected : selected } , this . submit ) ;
233+ return ;
234+ }
235+ this . setState ( { selected : [ ] } , this . submit ) ;
236+ } ;
237+
238+ handleChangePage = ( event , page ) => {
239+ this . setState ( { page : page } ) ;
240+ } ;
241+
242+ handleChangeRowsPerPage = event => {
243+ this . setState ( { rowsPerPage : event . target . value } ) ;
244+ } ;
245+
246+ render ( ) {
247+ const classes = this . props ;
248+ const { exams, order, orderBy, page, rowsPerPage, selected } = this . state ;
249+ console . log ( exams ) ;
250+ const emptyRows = rowsPerPage - Math . min ( rowsPerPage , exams . length - page * rowsPerPage ) ;
251+ return (
252+ < Paper className = { classes . root } >
253+ < EnhancedTableToolbar numSelected = { selected . length } />
254+ < div className = { classes . tableWrapper } >
255+ < Table className = { classes . table } aria-labelledby = "tableTitle" >
256+ < EnhancedTableHead
257+ numSelected = { selected . length }
258+ order = { order }
259+ orderBy = { orderBy }
260+ onSelectAllClick = { this . handleSelectAllClick }
261+ onRequestSort = { this . handleRequestSort }
262+ rowCount = { exams . length }
263+ />
264+ < TableBody >
265+ { exams
266+ . sort ( getSorting ( order , orderBy ) )
267+ . slice ( page * rowsPerPage , page * rowsPerPage + rowsPerPage )
268+ . map ( exam => {
269+ const isSelected = isIdExists ( exams , exam . id ) !== - 1 ? true : false ;
270+ return (
271+ < TableRow
272+ hover
273+ role = "checkbox"
274+ aria-checked = { isSelected }
275+ tabIndex = { - 1 }
276+ key = { exam . id }
277+ selected = { isSelected }
278+ >
279+ < TableCell padding = "checkbox" >
280+ < Checkbox
281+ onChange = {
282+ ( ) => {
283+ let index = isIdExists ( selected , exam . id ) ;
284+ if ( index === - 1 ) {
285+ selected . push ( exam ) ;
286+ this . setState ( { selected : selected } , this . submit ) ;
287+ }
288+ else if ( index !== - 1 ) {
289+ selected . splice ( index , 1 ) ;
290+ this . setState ( { selected : selected } , this . submit ) ;
291+ }
292+ }
293+ }
294+ checked = { isIdExists ( this . state . selected , exam . id ) !== - 1 ? true : false }
295+ />
296+ </ TableCell >
297+ < TableCell numeric = { false } > { exam . id } </ TableCell >
298+ < TableCell numeric = { false } > { exam . examName } </ TableCell >
299+ < TableCell numeric = { false } > { exam . date } </ TableCell >
300+ </ TableRow >
301+ ) ;
302+ } ) }
303+ { emptyRows > 0 && (
304+ < TableRow style = { { height : 49 * emptyRows } } >
305+ < TableCell colSpan = { 6 } />
306+ </ TableRow >
307+ ) }
308+ </ TableBody >
309+ </ Table >
310+ </ div >
311+ < TablePagination
312+ component = "div"
313+ count = { exams . length }
314+ rowsPerPage = { rowsPerPage }
315+ page = { page }
316+ backIconButtonProps = { {
317+ 'aria-label' : 'Previous Page' ,
318+ } }
319+ nextIconButtonProps = { {
320+ 'aria-label' : 'Next Page' ,
321+ } }
322+ onChangePage = { this . handleChangePage }
323+ onChangeRowsPerPage = { this . handleChangeRowsPerPage }
324+ />
325+ </ Paper >
326+ ) ;
327+ }
328+
329+ submit ( ) {
330+ setManyReference ( "exams" , this . course , this . state . selected ) ;
331+ }
332+ }
333+
334+ ExamsManager . propTypes = {
335+ classes : PropTypes . object . isRequired ,
336+ } ;
337+
338+
339+ export default withStyles ( styles ) ( ExamsManager ) ;
0 commit comments