diff --git a/src/components/landing/pages/history/history-card/history-card-list.tsx b/src/components/landing/pages/history/history-card/history-card-list.tsx index 23bf7465c..03ca11c58 100644 --- a/src/components/landing/pages/history/history-card/history-card-list.tsx +++ b/src/components/landing/pages/history/history-card/history-card-list.tsx @@ -1,18 +1,23 @@ -import React, {Fragment} from 'react' +import React from 'react' import {HistoryEntriesProps} from "../history-content/history-content"; import {HistoryCard} from "./history-card"; +import {Pager} from '../../../../pagination/pager'; +import {Row} from 'react-bootstrap'; + +export const HistoryCardList: React.FC = ({entries, onPinClick, pageIndex, onLastPageIndexChange}) => { -export const HistoryCardList: React.FC = ({entries, onPinClick}) => { return ( - - { - entries.map((entry) => ( - )) - } - - ) + + + { + entries.map((entry) => ( + )) + } + + + ); } diff --git a/src/components/landing/pages/history/history-content/history-content.tsx b/src/components/landing/pages/history/history-content/history-content.tsx index bd1493c44..24bbf4617 100644 --- a/src/components/landing/pages/history/history-content/history-content.tsx +++ b/src/components/landing/pages/history/history-content/history-content.tsx @@ -1,10 +1,11 @@ -import React from "react"; +import React, {Fragment, useState} from "react"; import {HistoryEntry, pinClick} from "../history"; import {HistoryTable} from "../history-table/history-table"; -import {Alert} from "react-bootstrap"; +import {Alert, Row} from "react-bootstrap"; import {Trans} from "react-i18next"; import {HistoryCardList} from "../history-card/history-card-list"; import {ViewStateEnum} from "../history-toolbar/history-toolbar"; +import {PagerPagination} from "../../../../pagination/pager-pagination"; export interface HistoryContentProps { viewState: ViewStateEnum @@ -20,23 +21,43 @@ export interface HistoryEntryProps { export interface HistoryEntriesProps { entries: HistoryEntry[] onPinClick: pinClick + pageIndex: number + onLastPageIndexChange: (lastPageIndex: number) => void } + export const HistoryContent: React.FC = ({viewState, entries, onPinClick}) => { + const [pageIndex, setPageIndex] = useState(0); + const [lastPageIndex, setLastPageIndex] = useState(0); if (entries.length === 0) { return ( - - - + + + + + ); } - switch (viewState) { - default: - case ViewStateEnum.card: - return - case ViewStateEnum.table: - return ; + const mapViewStateToComponent = (viewState: ViewStateEnum) => { + switch (viewState) { + default: + case ViewStateEnum.card: + return + case ViewStateEnum.table: + return + } } + + return ( + + {mapViewStateToComponent(viewState)} + + + + ); } \ No newline at end of file diff --git a/src/components/landing/pages/history/history-table/history-table.tsx b/src/components/landing/pages/history/history-table/history-table.tsx index 6eb2d63f1..abc041a36 100644 --- a/src/components/landing/pages/history/history-table/history-table.tsx +++ b/src/components/landing/pages/history/history-table/history-table.tsx @@ -3,8 +3,9 @@ import {Table} from "react-bootstrap" import {HistoryTableRow} from "./history-table-row"; import {HistoryEntriesProps} from "../history-content/history-content"; import {Trans} from "react-i18next"; +import {Pager} from "../../../../pagination/pager"; -const HistoryTable: React.FC = ({entries, onPinClick}) => { +export const HistoryTable: React.FC = ({entries, onPinClick, pageIndex, onLastPageIndexChange}) => { return ( @@ -16,17 +17,17 @@ const HistoryTable: React.FC = ({entries, onPinClick}) => { - { - entries.map((entry) => - ) - } + + { + entries.map((entry) => + ) + } +
) } - -export {HistoryTable} diff --git a/src/components/landing/pages/history/history.tsx b/src/components/landing/pages/history/history.tsx index aa8eacf69..1158b5277 100644 --- a/src/components/landing/pages/history/history.tsx +++ b/src/components/landing/pages/history/history.tsx @@ -57,11 +57,9 @@ export const History: React.FC = () => { -
-
) } \ No newline at end of file diff --git a/src/components/pagination/pager-item.tsx b/src/components/pagination/pager-item.tsx new file mode 100644 index 000000000..40f579668 --- /dev/null +++ b/src/components/pagination/pager-item.tsx @@ -0,0 +1,17 @@ +import React from "react"; + +export interface PageItemProps { + onClick: (index: number) => void + index: number +} + + +export const PagerItem: React.FC = ({index, onClick}) => { + return ( +
  • + onClick(index)}> + {index + 1} + +
  • + ); +} \ No newline at end of file diff --git a/src/components/pagination/pager-pagination.tsx b/src/components/pagination/pager-pagination.tsx new file mode 100644 index 000000000..72accb68f --- /dev/null +++ b/src/components/pagination/pager-pagination.tsx @@ -0,0 +1,82 @@ +import React, {Fragment, useEffect, useState} from "react"; +import {Pagination} from "react-bootstrap"; +import {PagerItem} from "./pager-item"; + +export interface PaginationProps { + numberOfPageButtonsToShowAfterAndBeforeCurrent: number + onPageChange: (pageIndex: number) => void + lastPageIndex: number +} + +export const PagerPagination: React.FC = ({numberOfPageButtonsToShowAfterAndBeforeCurrent, onPageChange, lastPageIndex}) => { + if (numberOfPageButtonsToShowAfterAndBeforeCurrent % 2 !== 0) { + throw new Error("number of pages to show must be even!") + } + + const [pageIndex, setPageIndex] = useState(0); + const correctedPageIndex = Math.min(pageIndex, lastPageIndex); + const wantedUpperPageIndex = correctedPageIndex + numberOfPageButtonsToShowAfterAndBeforeCurrent; + const wantedLowerPageIndex = correctedPageIndex - numberOfPageButtonsToShowAfterAndBeforeCurrent; + + useEffect(() => { + onPageChange(pageIndex) + }, [onPageChange, pageIndex]) + + const correctedLowerPageIndex = + Math.min( + Math.max( + Math.min( + wantedLowerPageIndex, + wantedLowerPageIndex + lastPageIndex - wantedUpperPageIndex + ), + 0 + ), + lastPageIndex + ); + + const correctedUpperPageIndex = + Math.max( + Math.min( + Math.max( + wantedUpperPageIndex, + wantedUpperPageIndex - wantedLowerPageIndex + ), + lastPageIndex + ), + 0 + ); + + const paginationItemsBefore = Array.from(new Array(correctedPageIndex - correctedLowerPageIndex)).map((k, index) => { + const itemIndex = correctedLowerPageIndex + index; + return + }); + + const paginationItemsAfter = Array.from(new Array(correctedUpperPageIndex - correctedPageIndex)).map((k, index) => { + const itemIndex = correctedPageIndex + index + 1; + return + }); + + return ( + + { + correctedLowerPageIndex > 0 ? + + + + + : null + } + {paginationItemsBefore} + {correctedPageIndex + 1} + {paginationItemsAfter} + { + correctedUpperPageIndex < lastPageIndex ? + + + + + : null + } + + ); +} \ No newline at end of file diff --git a/src/components/pagination/pager.tsx b/src/components/pagination/pager.tsx new file mode 100644 index 000000000..983b8230f --- /dev/null +++ b/src/components/pagination/pager.tsx @@ -0,0 +1,24 @@ +import React, {Fragment, useEffect} from "react"; + +export interface PagerPageProps { + pageIndex: number + numberOfElementsPerPage: number + onLastPageIndexChange: (lastPageIndex: number) => void +} + +export const Pager: React.FC = ({children, numberOfElementsPerPage, pageIndex, onLastPageIndexChange}) => { + + useEffect(() => { + const lastPageIndex = Math.ceil(React.Children.count(children) / numberOfElementsPerPage) - 1; + onLastPageIndexChange(lastPageIndex) + }, [children, numberOfElementsPerPage, onLastPageIndexChange]) + + return + { + React.Children.toArray(children).filter((value, index) => { + const pageOfElement = Math.floor((index) / numberOfElementsPerPage); + return (pageOfElement === pageIndex); + }) + } + +} \ No newline at end of file