@@ -57,6 +57,8 @@ export interface AppState {
5757 isAdminNextcloud : boolean ;
5858 checkAppsInstalled : boolean ;
5959 currentPage : number ;
60+ loading : boolean ;
61+ totalFolders : number ;
6062}
6163
6264export class App extends Component < unknown , AppState > implements OC . Plugin < OC . Search . Core > {
@@ -80,6 +82,8 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
8082 isAdminNextcloud : false ,
8183 checkAppsInstalled : false ,
8284 currentPage : 0 ,
85+ loading : false ,
86+ totalFolders : 0 ,
8387 }
8488
8589 componentDidMount ( ) {
@@ -93,6 +97,9 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
9397 this . api . listCircles ( ) . then ( ( circles ) => {
9498 this . setState ( { circles } )
9599 } )
100+ this . api . countFolders ( ) . then ( ( totalFolders ) => {
101+ this . setState ( { totalFolders } )
102+ } )
96103
97104 this . setState ( { isAdminNextcloud : loadState ( 'groupfolders' , 'isAdminNextcloud' ) } )
98105 this . setState ( { checkAppsInstalled : loadState ( 'groupfolders' , 'checkAppsInstalled' ) } )
@@ -203,13 +210,25 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
203210 }
204211
205212 async goToPage ( page : number ) {
213+ if ( this . state . loading ) return
214+
206215 const loadedPage = Math . floor ( this . state . folders . length / pageSize )
207216 if ( loadedPage <= page ) {
208- const folders = await this . api . listFolders ( this . state . folders . length , ( page + 1 ) * pageSize - this . state . folders . length + 1 , this . state . sort )
209- this . setState ( {
210- folders : [ ...this . state . folders , ...folders ] ,
211- currentPage : page ,
212- } )
217+ this . setState ( { loading : true } )
218+ try {
219+ const folders = await this . api . listFolders (
220+ this . state . folders . length , ( page + 1 ) * pageSize - this . state . folders . length + 1 ,
221+ this . state . sort ,
222+ this . state . sortOrder === 1 ? 'asc' : 'desc' ,
223+ )
224+ this . setState ( {
225+ folders : [ ...this . state . folders , ...folders ] ,
226+ currentPage : page ,
227+ } )
228+ } finally {
229+ this . setState ( { loading : false } )
230+ }
231+
213232 } else {
214233 this . setState ( {
215234 currentPage : page ,
@@ -266,6 +285,7 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
266285
267286 render ( ) {
268287 const isCirclesEnabled = loadState ( 'groupfolders' , 'isCirclesEnabled' , false )
288+ const lastPage = Math . max ( 0 , Math . ceil ( this . state . totalFolders / pageSize ) - 1 )
269289 const groupHeader = isCirclesEnabled
270290 ? t ( 'groupfolders' , 'Group or team' )
271291 : t ( 'groupfolders' , 'Group' )
@@ -274,6 +294,8 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
274294 ? t ( 'groupfolders' , 'Sort by number of groups or teams that have access to this folder' )
275295 : t ( 'groupfolders' , 'Sort by number of groups that have access to this folder' )
276296
297+ console . log ( 'totalFolders:' , this . state . totalFolders , 'lastPage:' , lastPage , 'currentPage:' , this . state . currentPage )
298+
277299 const rows
278300 = this . state . folders
279301 . filter ( folder => {
@@ -416,13 +438,14 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
416438 </ tr >
417439 </ FlipMove >
418440 </ table >
419- < nav className = "groupfolders-pagination" aria-label = { t ( 'groupfolders' , 'Pagination of team folders' ) } >
441+ < nav className = "groupfolders-pagination" style = { { display : 'flex' , alignItems : 'center' } } aria-label = { t ( 'groupfolders' , 'Pagination of team folders' ) } >
442+ < div style = { { flex : 1 } } />
420443 < ul className = "groupfolders-pagination__list" >
421444 < li >
422445 < button
423446 aria-label = { t ( 'groupfolders' , 'Previous' ) }
424447 className = "groupfolders-pagination__button"
425- disabled = { this . state . currentPage === 0 }
448+ disabled = { this . state . currentPage === 0 || this . state . loading }
426449 title = { t ( 'groupfolders' , 'Previous' ) }
427450 onClick = { ( ) => this . goToPage ( this . state . currentPage - 1 ) } > ⮜</ button >
428451 </ li >
@@ -441,34 +464,53 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
441464 < li > < button aria-current = "page" aria-disabled className = "primary" > { this . state . currentPage + 1 } </ button > </ li >
442465 {
443466 // show the next page if it exists (we know at least that the next exists or not)
444- ( this . state . currentPage + 1 ) < ( this . state . folders . length / pageSize )
467+ ( this . state . currentPage + 1 ) <= lastPage
445468 && < li >
446469 < button onClick = { ( ) => this . goToPage ( this . state . currentPage + 1 ) } > { this . state . currentPage + 2 } </ button >
447470 </ li >
448471 }
449472 {
450473 // If we know more than two next pages exist we show the ellipsis for the intermediate pages
451- ( this . state . currentPage + 3 ) < ( this . state . folders . length / pageSize )
474+ ( this . state . currentPage + 3 ) <= lastPage
452475 && < li >
453476 < button disabled > …</ button >
454477 </ li >
455478 }
456479 {
457480 // If more than one next page exist we show the last page as a button
458- ( this . state . currentPage + 2 ) < ( this . state . folders . length / pageSize )
481+ ( this . state . currentPage + 2 ) <= lastPage
459482 && < li >
460- < button onClick = { ( ) => this . goToPage ( Math . floor ( this . state . folders . length / pageSize ) ) } > { Math . floor ( this . state . folders . length / pageSize ) + 1 } </ button >
483+ < button onClick = { ( ) => this . goToPage ( lastPage ) } > { lastPage + 1 } </ button >
461484 </ li >
462485 }
463486 < li >
464487 < button
465488 aria-label = { t ( 'groupfolders' , 'Next' ) }
466489 className = "groupfolders-pagination__button"
467- disabled = { this . state . currentPage >= Math . floor ( this . state . folders . length / pageSize ) }
490+ disabled = { this . state . currentPage >= lastPage || this . state . loading }
468491 title = { t ( 'groupfolders' , 'Next' ) }
469492 onClick = { ( ) => this . goToPage ( this . state . currentPage + 1 ) } > ⮞</ button >
470493 </ li >
471494 </ ul >
495+ { lastPage > 4 && (
496+ < div className = "groupfolders-pagination__goto-page" >
497+ < label style = { { whiteSpace : 'nowrap' } } >
498+ { t ( 'groupfolders' , 'Page:' ) }
499+ </ label >
500+ < input
501+ type = "number"
502+ min = { 1 }
503+ max = { lastPage + 1 }
504+ style = { { width : 70 , textAlign : 'center' } }
505+ value = { this . state . currentPage + 1 }
506+ onChange = { ( e ) => {
507+ const page = Math . min ( parseInt ( e . target . value ) - 1 , lastPage )
508+ if ( page >= 0 ) this . goToPage ( page )
509+ } }
510+ />
511+ < span style = { { whiteSpace : 'nowrap' } } > / { lastPage + 1 } </ span >
512+ </ div >
513+ ) }
472514 </ nav >
473515 </ div >
474516 }
0 commit comments