22// SPDX-License-Identifier: Apache-2.0
33
44import * as Redux from 'redux'
5- import { Container , Table , TableBody , TableCell , TableHead , TableRow } from '@material-ui/core'
5+ import { Container , Table , TableBody , TableCell , TableHead , TableRow , Theme , Tooltip } from '@material-ui/core'
6+ import { ChevronLeftRounded , ChevronRightRounded } from '@material-ui/icons'
7+ import IconButton from '@material-ui/core/IconButton'
68import { Dataset } from '../../types/api'
79import { IState } from '../../store/reducers'
810import { MqScreenLoad } from '../../components/core/screen-load/MqScreenLoad'
@@ -20,7 +22,13 @@ import React from 'react'
2022import createStyles from '@material-ui/core/styles/createStyles'
2123import withStyles , { WithStyles } from '@material-ui/core/styles/withStyles'
2224
23- const styles = ( ) => createStyles ( { } )
25+ const PAGE_SIZE = 20
26+
27+ const styles = ( theme : Theme ) => createStyles ( {
28+ ml2 : {
29+ marginLeft : theme . spacing ( 2 )
30+ }
31+ } )
2432
2533interface StateProps {
2634 datasets : Dataset [ ]
@@ -34,31 +42,91 @@ interface DispatchProps {
3442 resetDatasets : typeof resetDatasets
3543}
3644
45+ interface DatasetsState {
46+ datasets : Dataset [ ]
47+ page : number
48+ pageIsLast : boolean
49+ }
50+
3751type DatasetsProps = WithStyles < typeof styles > & StateProps & DispatchProps
3852
39- class Datasets extends React . Component < DatasetsProps > {
53+ class Datasets extends React . Component < DatasetsProps , DatasetsState > {
54+
55+ constructor ( props : DatasetsProps ) {
56+ super ( props )
57+ this . state = {
58+ datasets : [ ] ,
59+ page : 1 ,
60+ pageIsLast : false
61+ }
62+ }
63+
4064 componentDidMount ( ) {
4165 if ( this . props . selectedNamespace ) {
42- this . props . fetchDatasets ( this . props . selectedNamespace )
66+ this . props . fetchDatasets ( this . props . selectedNamespace , PAGE_SIZE )
4367 }
4468 }
4569
4670 componentDidUpdate ( prevProps : Readonly < DatasetsProps > ) {
71+ const { datasets : datasetsState , page } = this . state
72+ const { datasets : datasetsProps } = this . props
73+
4774 if (
4875 prevProps . selectedNamespace !== this . props . selectedNamespace &&
4976 this . props . selectedNamespace
5077 ) {
51- this . props . fetchDatasets ( this . props . selectedNamespace )
78+ this . props . fetchDatasets ( this . props . selectedNamespace , PAGE_SIZE )
79+ }
80+
81+ if ( datasetsProps !== datasetsState ) {
82+ this . setState ( {
83+ datasets : datasetsProps ,
84+ pageIsLast : datasetsProps . length < page * PAGE_SIZE
85+ } )
5286 }
5387 }
5488
5589 componentWillUnmount ( ) {
5690 this . props . resetDatasets ( )
5791 }
5892
93+ getDatasets ( ) {
94+ const { datasets, page } = this . state
95+ return datasets . slice ( ( page - 1 ) * PAGE_SIZE , PAGE_SIZE + ( page - 1 ) * PAGE_SIZE )
96+ }
97+
98+ pageNavigation ( ) {
99+ const { datasets, page, pageIsLast } = this . state
100+ const titlePos = datasets . length < PAGE_SIZE && page === 1
101+ ? `1 - ${ datasets . length } `
102+ : datasets . length > PAGE_SIZE && page === 1
103+ ? `1 - ${ PAGE_SIZE } `
104+ : datasets . length && page > 1 && pageIsLast === false
105+ ? `${ PAGE_SIZE * page - PAGE_SIZE + 1 } - ${ PAGE_SIZE * page } `
106+ : datasets . length && page > 1 && pageIsLast
107+ ? `${ PAGE_SIZE * page - PAGE_SIZE + 1 } - ${ datasets . length } `
108+ : `${ datasets . length } `
109+ return `${ page } (${ titlePos } )`
110+ }
111+
112+ handleClickPage ( direction : 'prev' | 'next' ) {
113+ const { page } = this . state
114+ const directionPage = direction === 'next' ? page + 1 : page - 1
115+
116+ if ( this . props . selectedNamespace ) {
117+ this . props . fetchDatasets (
118+ this . props . selectedNamespace ,
119+ PAGE_SIZE * directionPage
120+ )
121+ }
122+ this . setState ( { page : directionPage } )
123+ }
124+
59125 render ( ) {
60- const { datasets, isDatasetsLoading, isDatasetsInit } = this . props
126+ const { isDatasetsLoading, isDatasetsInit, classes } = this . props
127+ const { datasets, page, pageIsLast } = this . state
61128 const i18next = require ( 'i18next' )
129+
62130 return (
63131 < Container maxWidth = { 'lg' } disableGutters >
64132 < MqScreenLoad loading = { isDatasetsLoading || ! isDatasetsInit } >
@@ -68,11 +136,35 @@ class Datasets extends React.Component<DatasetsProps> {
68136 < MqEmpty title = { i18next . t ( 'datasets_route.empty_title' ) } >
69137 < MqText subdued > { i18next . t ( 'datasets_route.empty_body' ) } </ MqText >
70138 </ MqEmpty >
71- </ Box >
139+ </ Box >
72140 ) : (
73141 < >
74- < Box p = { 2 } >
75- < MqText heading > { i18next . t ( 'datasets_route.heading' ) } </ MqText >
142+ < Box p = { 2 } display = { 'flex' } justifyContent = { 'space-between' } >
143+ < Box >
144+ < MqText heading > { i18next . t ( 'datasets_route.heading' ) } </ MqText >
145+ Page: { this . pageNavigation ( ) }
146+ </ Box >
147+ < Box >
148+ < Tooltip title = { i18next . t ( 'events_route.previous_page' ) } >
149+ < IconButton
150+ className = { classes . ml2 }
151+ color = 'primary'
152+ disabled = { page === 1 }
153+ onClick = { ( ) => this . handleClickPage ( 'prev' ) }
154+ >
155+ < ChevronLeftRounded />
156+ </ IconButton >
157+ </ Tooltip >
158+ < Tooltip title = { i18next . t ( 'events_route.next_page' ) } >
159+ < IconButton
160+ color = 'primary'
161+ disabled = { pageIsLast }
162+ onClick = { ( ) => this . handleClickPage ( 'next' ) }
163+ >
164+ < ChevronRightRounded />
165+ </ IconButton >
166+ </ Tooltip >
167+ </ Box >
76168 </ Box >
77169 < Table size = 'small' >
78170 < TableHead >
@@ -95,7 +187,7 @@ class Datasets extends React.Component<DatasetsProps> {
95187 </ TableRow >
96188 </ TableHead >
97189 < TableBody >
98- { datasets
190+ { this . getDatasets ( )
99191 . filter ( dataset => ! dataset . deleted )
100192 . map ( dataset => {
101193 return (
@@ -137,6 +229,27 @@ class Datasets extends React.Component<DatasetsProps> {
137229 </ Table >
138230 </ >
139231 ) }
232+ < Box display = { 'flex' } justifyContent = { 'flex-end' } mb = { 2 } >
233+ < Tooltip title = { i18next . t ( 'events_route.previous_page' ) } >
234+ < IconButton
235+ className = { classes . ml2 }
236+ color = 'primary'
237+ disabled = { page === 1 }
238+ onClick = { ( ) => this . handleClickPage ( 'prev' ) }
239+ >
240+ < ChevronLeftRounded />
241+ </ IconButton >
242+ </ Tooltip >
243+ < Tooltip title = { i18next . t ( 'events_route.next_page' ) } >
244+ < IconButton
245+ color = 'primary'
246+ disabled = { pageIsLast }
247+ onClick = { ( ) => this . handleClickPage ( 'next' ) }
248+ >
249+ < ChevronRightRounded />
250+ </ IconButton >
251+ </ Tooltip >
252+ </ Box >
140253 </ >
141254 </ MqScreenLoad >
142255 </ Container >
@@ -160,4 +273,4 @@ const mapDispatchToProps = (dispatch: Redux.Dispatch) =>
160273 dispatch
161274 )
162275
163- export default connect ( mapStateToProps , mapDispatchToProps ) ( withStyles ( styles ) ( Datasets ) )
276+ export default connect ( mapStateToProps , mapDispatchToProps ) ( withStyles ( styles ) ( Datasets ) )
0 commit comments