From ef727d084f77e073c72a739b87d89fd37f2ebf7d Mon Sep 17 00:00:00 2001
From: Aigamo <51428094+ycanardeau@users.noreply.github.com>
Date: Tue, 6 Jul 2021 21:06:52 +1000
Subject: [PATCH] Create ServerSidePaging
---
.../Partials/Knockout/ServerSidePaging.tsx | 58 +++++++++++++
.../Scripts/Stores/ServerSidePagingStore.ts | 86 +++++++++++++++++++
2 files changed, 144 insertions(+)
create mode 100644 VocaDbWeb/Scripts/Components/Shared/Partials/Knockout/ServerSidePaging.tsx
create mode 100644 VocaDbWeb/Scripts/Stores/ServerSidePagingStore.ts
diff --git a/VocaDbWeb/Scripts/Components/Shared/Partials/Knockout/ServerSidePaging.tsx b/VocaDbWeb/Scripts/Components/Shared/Partials/Knockout/ServerSidePaging.tsx
new file mode 100644
index 0000000000..1061b2214b
--- /dev/null
+++ b/VocaDbWeb/Scripts/Components/Shared/Partials/Knockout/ServerSidePaging.tsx
@@ -0,0 +1,58 @@
+import Pagination from '@Bootstrap/Pagination';
+import ServerSidePagingStore from '@Stores/ServerSidePagingStore';
+import { observer } from 'mobx-react-lite';
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+
+interface ServerSidePagingProps {
+ store: ServerSidePagingStore;
+}
+
+const ServerSidePaging = observer(
+ ({ store }: ServerSidePagingProps): React.ReactElement => {
+ const { t } = useTranslation(['VocaDb.Web.Resources.Other']);
+
+ return (
+
+
+ «« {t('VocaDb.Web.Resources.Other:PagedList.First')}
+
+
+ « {t('VocaDb.Web.Resources.Other:PagedList.Previous')}
+
+
+ {store.showMoreBegin && }
+
+ {store.pages.map((page) => (
+ store.setPage(page)}
+ key={page}
+ >
+ {page}
+
+ ))}
+
+ {store.showMoreEnd && }
+
+
+ {t('VocaDb.Web.Resources.Other:PagedList.Next')} »
+
+
+ {t('VocaDb.Web.Resources.Other:PagedList.Last')} »»
+
+
+ );
+ },
+);
+
+export default ServerSidePaging;
diff --git a/VocaDbWeb/Scripts/Stores/ServerSidePagingStore.ts b/VocaDbWeb/Scripts/Stores/ServerSidePagingStore.ts
new file mode 100644
index 0000000000..e9569268fc
--- /dev/null
+++ b/VocaDbWeb/Scripts/Stores/ServerSidePagingStore.ts
@@ -0,0 +1,86 @@
+import _ from 'lodash';
+import { action, computed, makeObservable, observable } from 'mobx';
+
+export default class ServerSidePagingStore {
+ @observable public page = 1;
+ @action public setPage = (value: number): void => {
+ this.page = value;
+ };
+
+ @observable public totalItems = 0;
+ @action public setTotalItems = (value: number): void => {
+ this.totalItems = value;
+ };
+
+ @observable public pageSize = 10;
+ @action public setPageSize = (value: number): void => {
+ this.pageSize = value;
+ };
+
+ public constructor(pageSize: number = 10) {
+ makeObservable(this);
+
+ this.pageSize = pageSize;
+ }
+
+ @computed public get firstItem(): number {
+ return (this.page - 1) * this.pageSize;
+ }
+
+ @computed public get totalPages(): number {
+ return Math.ceil(this.totalItems / this.pageSize);
+ }
+
+ @computed public get hasMultiplePages(): boolean {
+ return this.totalPages > 1;
+ }
+
+ @computed public get isFirstPage(): boolean {
+ return this.page <= 1;
+ }
+
+ @computed public get isLastPage(): boolean {
+ return this.page >= this.totalPages;
+ }
+
+ @computed public get pages(): number[] {
+ const start = Math.max(this.page - 4, 1);
+ const end = Math.min(this.page + 4, this.totalPages);
+
+ return _.range(start, end + 1);
+ }
+
+ @computed public get showMoreBegin(): boolean {
+ return this.page > 5;
+ }
+
+ @computed public get showMoreEnd(): boolean {
+ return this.page < this.totalPages - 4;
+ }
+
+ public getPagingProperties = (
+ clearResults: boolean = false,
+ ): { start: number; maxEntries: number; getTotalCount: boolean } => {
+ return {
+ start: this.firstItem,
+ maxEntries: this.pageSize,
+ getTotalCount: clearResults || this.totalItems === 0,
+ };
+ };
+
+ @action public goToFirstPage = (): void => {
+ this.page = 1;
+ };
+
+ @action public goToLastPage = (): void => {
+ this.page = this.totalPages;
+ };
+
+ @action public nextPage = (): void => {
+ if (!this.isLastPage) this.page = this.page + 1;
+ };
+
+ @action public previousPage = (): void => {
+ if (!this.isFirstPage) this.page = this.page - 1;
+ };
+}