@@ -4,17 +4,26 @@ import { FormattedMessage } from 'react-intl';
44import { Table } from 'react-bootstrap' ;
55import { lruMemoize } from 'reselect' ;
66
7+ import PaginationButtons from '../PaginationButtons' ;
78import { UserUIDataContext } from '../../../helpers/contexts.js' ;
89import { CloseIcon , SortedIcon } from '../../icons' ;
910import withRouter , { withRouterProps } from '../../../helpers/withRouter.js' ;
1011import { storageGetItem , storageSetItem } from '../../../helpers/localStorage.js' ;
1112
1213const localStorageKeyPrefix = 'SortableTable' ;
1314
15+ const _sortData = lruMemoize ( ( data , column , ascendant ) =>
16+ column === null || column . comparator === null
17+ ? data
18+ : ascendant
19+ ? data . sort ( column . comparator )
20+ : data . sort ( column . comparator ) . reverse ( )
21+ ) ;
22+
1423class SortableTable extends Component {
1524 constructor ( props ) {
1625 super ( props ) ;
17- this . state = { sortColumn : props . defaultOrder || null , ascendant : true } ;
26+ this . state = { sortColumn : props . defaultOrder || null , ascendant : true , page : 0 } ;
1827 }
1928
2029 setSortColumnFromLocalStorage = ( ) => {
@@ -34,6 +43,9 @@ class SortableTable extends Component {
3443 componentDidUpdate ( prevProps ) {
3544 if ( prevProps . id !== this . props . id ) {
3645 this . setSortColumnFromLocalStorage ( ) ;
46+ this . setState ( { page : 0 } ) ;
47+ } else if ( prevProps . data . length !== this . props . data . length || prevProps . maxAmount !== this . props . maxAmount ) {
48+ this . setState ( { page : 0 } ) ;
3749 }
3850 }
3951
@@ -87,15 +99,16 @@ class SortableTable extends Component {
8799 this . setState ( { sortColumn, ascendant } ) ;
88100 } ;
89101
102+ selectPage = page => {
103+ this . setState ( { page : page - 1 } ) ;
104+ } ;
105+
90106 // Helper function that actually sorts the data according to internal state
91- sortData = lruMemoize ( ( data , colId , ascendant ) => {
107+ sortData = lruMemoize ( ( data , colId , ascendant , offset , amount ) => {
92108 const { columns } = this . props ;
93109 const column = columns && columns . find ( ( { id } ) => id === colId ) ;
94- return column === null || column . comparator === null
95- ? data
96- : ascendant
97- ? data . sort ( column . comparator )
98- : data . sort ( column . comparator ) . reverse ( ) ;
110+ const allData = _sortData ( data , column , ascendant ) ;
111+ return allData . slice ( offset , offset + amount ) ;
99112 } ) ;
100113
101114 getHeaderSuffixRow = ( ) => {
@@ -125,9 +138,12 @@ class SortableTable extends Component {
125138 openLinkGenerator = null ,
126139 staticContext /* avoid capturing static context in the rest of ...props */ ,
127140 navigate /* avoid capturing injected function by ...props */ ,
141+ maxAmount = null ,
128142 ...props
129143 } = this . props ;
130- const { sortColumn, ascendant } = this . state ;
144+ const { sortColumn, ascendant, page } = this . state ;
145+ const offset = maxAmount ? page * maxAmount : 0 ;
146+ const amount = maxAmount || data . length ;
131147
132148 return (
133149 < UserUIDataContext . Consumer >
@@ -164,7 +180,7 @@ class SortableTable extends Component {
164180 ) }
165181 < tbody >
166182 { data . length > 0 ? (
167- this . sortData ( data , sortColumn , ascendant ) . map ( ( row , idx ) =>
183+ this . sortData ( data , sortColumn , ascendant , offset , amount ) . map ( ( row , idx ) =>
168184 rowRenderer ( row , idx , columns , openOnDoubleclick ? openLinkGenerator : null )
169185 )
170186 ) : (
@@ -180,6 +196,31 @@ class SortableTable extends Component {
180196 </ tr >
181197 ) }
182198 </ tbody >
199+ { maxAmount && maxAmount < data . length && (
200+ < tfoot >
201+ < tr >
202+ < td colSpan = { columns . length } className = "pt-3 px-4" >
203+ < small className = "float-end text-muted" >
204+ < FormattedMessage
205+ id = "app.sortableTable.showingEntries"
206+ defaultMessage = "showing entries {from} – {to} of {total}"
207+ values = { { from : offset + 1 , to : Math . min ( offset + maxAmount , data . length ) , total : data . length } }
208+ />
209+ </ small >
210+ < PaginationButtons
211+ prev
212+ next
213+ maxButtons = { 10 }
214+ boundaryLinks
215+ items = { Math . ceil ( data . length / maxAmount ) }
216+ activePage = { this . state . page + 1 }
217+ size = "small"
218+ onSelect = { this . selectPage }
219+ />
220+ </ td >
221+ </ tr >
222+ </ tfoot >
223+ ) }
183224 </ Table >
184225 ) }
185226 </ UserUIDataContext . Consumer >
@@ -197,6 +238,7 @@ SortableTable.propTypes = {
197238 openLinkGenerator : PropTypes . func ,
198239 staticContext : PropTypes . any ,
199240 navigate : withRouterProps . navigate ,
241+ maxAmount : PropTypes . number ,
200242} ;
201243
202244export default withRouter ( SortableTable ) ;
0 commit comments