Skip to content

Commit adcda70

Browse files
committed
feat: add pagination to the frontend
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent f457cbc commit adcda70

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

src/settings/Api.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,13 @@ export class Api {
1515
return generateUrl(`apps/groupfolders/${endpoint}`)
1616
}
1717

18-
async listFolders(): Promise<Folder[]> {
19-
const response = await axios.get<OCSResponse<Folder[]>>(this.getUrl('folders'))
18+
async listFolders(offset = 0, limit = 50): Promise<Folder[]> {
19+
const response = await axios.get<OCSResponse<Folder[]>>(this.getUrl('folders'), {
20+
params: {
21+
offset,
22+
limit,
23+
},
24+
})
2025
return Object.keys(response.data.ocs.data).map(id => response.data.ocs.data[id])
2126
}
2227

src/settings/App.scss

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,17 @@
178178
}
179179
}
180180
}
181-
}
181+
}
182+
183+
.groupfolders-pagination__list {
184+
display: flex;
185+
gap: var(--default-grid-baseline);
186+
justify-content: center;
187+
}
188+
189+
.groupfolders-pagination__button {
190+
height: var(--default-clickable-area);
191+
}
182192

183193
}
184194

src/settings/App.tsx

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ export interface AppState {
4646
sortOrder: number;
4747
isAdminNextcloud: boolean;
4848
checkAppsInstalled: boolean;
49+
currentPage: number;
4950
}
5051

5152
export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Search.Core> {
@@ -67,10 +68,12 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
6768
sortOrder: 1,
6869
isAdminNextcloud: false,
6970
checkAppsInstalled: false,
71+
currentPage: 0,
7072
}
7173

7274
componentDidMount() {
73-
this.api.listFolders().then((folders) => {
75+
// list first 51 folders so we know if there are more pages
76+
this.api.listFolders(0, 51).then((folders) => {
7477
this.setState({ folders })
7578
})
7679
this.api.listGroups().then((groups) => {
@@ -170,6 +173,21 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
170173
this.api.setACL(folder.id, acl)
171174
}
172175

176+
async goToPage(page: number) {
177+
const loadedPage = Math.floor(this.state.folders.length / 50)
178+
if (loadedPage <= page) {
179+
const folders = await this.api.listFolders(this.state.folders.length, (page + 1) * 50 - this.state.folders.length + 1)
180+
this.setState({
181+
folders: [...this.state.folders, ...folders],
182+
currentPage: page,
183+
})
184+
} else {
185+
this.setState({
186+
currentPage: page,
187+
})
188+
}
189+
}
190+
173191
onSortClick = (sort: SortKey) => {
174192
if (this.state.sort === sort) {
175193
this.setState({ sortOrder: -this.state.sortOrder })
@@ -233,11 +251,12 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
233251
if (this.state.filter === '') {
234252
return true
235253
}
236-
return folder.mount_point.toLowerCase().indexOf(this.state.filter.toLowerCase()) !== -1
254+
return folder.mount_point.toLowerCase().includes(this.state.filter.toLowerCase())
237255
}),
238256
identifiers,
239257
direction,
240258
)
259+
.slice(this.state.currentPage * 50, this.state.currentPage * 50 + 50)
241260
.map(folder => {
242261
const id = folder.id
243262
return <tr key={id}>
@@ -361,6 +380,60 @@ export class App extends Component<unknown, AppState> implements OC.Plugin<OC.Se
361380
</tr>
362381
</FlipMove>
363382
</table>
383+
<nav className="groupfolders-pagination" aria-label={t('groupfolders', 'Pagination of team folders')}>
384+
<ul className="groupfolders-pagination__list">
385+
<li>
386+
<button
387+
aria-label={t('groupfolders', 'Previous')}
388+
className="groupfolders-pagination__button"
389+
disabled={this.state.currentPage === 0}
390+
title={t('groupfolders', 'Previous')}
391+
onClick={() => this.goToPage(this.state.currentPage - 1)}></button>
392+
</li>
393+
{
394+
// show the "1" button if we are not on the first page
395+
this.state.currentPage > 0 && <li><button onClick={() => this.goToPage(0)}>1</button></li>
396+
}
397+
{
398+
// show the ellipsis button if there are more than 2 pages before the current
399+
this.state.currentPage > 2 && <li><button disabled>&#8230;</button></li>}
400+
{
401+
// show the page right before the current - if there is such a page
402+
this.state.currentPage > 1 && <li><button onClick={() => this.goToPage(this.state.currentPage - 1)}>{this.state.currentPage}</button></li>
403+
}
404+
{ /* the current page as a button */}
405+
<li><button aria-current="page" aria-disabled className="primary">{this.state.currentPage + 1}</button></li>
406+
{
407+
// show the next page if it exists (we know at least that the next exists or not)
408+
(this.state.currentPage + 1) < (this.state.folders.length / 50)
409+
&& <li>
410+
<button onClick={() => this.goToPage(this.state.currentPage + 1)}>{this.state.currentPage + 2}</button>
411+
</li>
412+
}
413+
{
414+
// If we know more than two next pages exist we show the ellipsis for the intermediate pages
415+
(this.state.currentPage + 3) < (this.state.folders.length / 50)
416+
&& <li>
417+
<button disabled>&#8230;</button>
418+
</li>
419+
}
420+
{
421+
// If more than one next page exist we show the last page as a button
422+
(this.state.currentPage + 2) < (this.state.folders.length / 50)
423+
&& <li>
424+
<button onClick={() => this.goToPage(Math.floor(this.state.folders.length / 50))}>{Math.floor(this.state.folders.length / 50) + 1}</button>
425+
</li>
426+
}
427+
<li>
428+
<button
429+
aria-label={t('groupfolders', 'Next')}
430+
className="groupfolders-pagination__button"
431+
disabled={this.state.currentPage >= Math.floor(this.state.folders.length / 50)}
432+
title={t('groupfolders', 'Next')}
433+
onClick={() => this.goToPage(this.state.currentPage + 1)}></button>
434+
</li>
435+
</ul>
436+
</nav>
364437
</div>
365438
}
366439

0 commit comments

Comments
 (0)