diff --git a/.eslintrc.js b/.eslintrc.js index 21684c6..acfee81 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -38,7 +38,7 @@ module.exports = { 'no-confusing-arrow': 0, 'no-console': 0, 'no-unused-vars': 'off', - '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-unused-vars': 'warn', 'no-use-before-define': 0, 'prefer-template': 2, 'prefer-destructuring': 0, @@ -100,6 +100,7 @@ module.exports = { '@typescript-eslint/no-unused-expressions': 0, '@typescript-eslint/naming-convention': 0, '@typescript-eslint/brace-style': 0, + 'no-param-reassign': 1, }, parserOptions: { ecmaVersion: 2020, diff --git a/public/images/mevs/Flashbots-dark.svg b/public/images/mevs/flashbots-dark.svg similarity index 100% rename from public/images/mevs/Flashbots-dark.svg rename to public/images/mevs/flashbots-dark.svg diff --git a/public/images/mevs/Flashbots.svg b/public/images/mevs/flashbots.svg similarity index 100% rename from public/images/mevs/Flashbots.svg rename to public/images/mevs/flashbots.svg diff --git a/src/app/components/OperatorsList/OperatorsList.tsx b/src/app/components/OperatorsList/OperatorsList.tsx index e1f26a6..533b1db 100644 --- a/src/app/components/OperatorsList/OperatorsList.tsx +++ b/src/app/components/OperatorsList/OperatorsList.tsx @@ -56,7 +56,7 @@ const OperatorsList = () => { .then((result: any) => { overviewStore.setTotalOperators(result.data.pagination.total); setOperators(result.data.operators); - setPagination(result.data.pagination); + setPagination({ page, ...result.data.pagination }); setLoading(false); }); }; diff --git a/src/app/components/Overview/components/Tables/Validators/Validators.tsx b/src/app/components/Overview/components/Tables/Validators/Validators.tsx index c5c65d9..318881c 100644 --- a/src/app/components/Overview/components/Tables/Validators/Validators.tsx +++ b/src/app/components/Overview/components/Tables/Validators/Validators.tsx @@ -7,7 +7,7 @@ import TableRow from '@material-ui/core/TableRow'; import TableHead from '@material-ui/core/TableHead'; import TableBody from '@material-ui/core/TableBody'; import config from '~app/common/config'; -import ApiParams from '~lib/api/ApiParams'; +import ApiParams, { PageDirection } from '~lib/api/ApiParams'; import SsvNetwork from '~lib/api/SsvNetwork'; import { useStores } from '~app/hooks/useStores'; import { useStyles } from '~app/components/Styles'; @@ -43,7 +43,7 @@ const Validators = (props: Props) => { */ const loadValidators = () => { setLoadingValidators(true); - SsvNetwork.getInstance().fetchValidators(1, ApiParams.PER_PAGE).then((result: any) => { + SsvNetwork.getInstance().fetchValidators({ lastFetchedRecordId: 1, pageDirection: PageDirection.NEXT, perPage: ApiParams.PER_PAGE }).then((result: any) => { overviewStore.setTotalValidators(result.data.pagination.total); if (result.data.validators.length > 0) setValidatorsExist(true); overviewStore.setTotalEth(result.data.pagination.total * 32); diff --git a/src/app/components/ValidatorsList/ValidatorsList.tsx b/src/app/components/ValidatorsList/ValidatorsList.tsx index cb3ab75..fcd91e2 100644 --- a/src/app/components/ValidatorsList/ValidatorsList.tsx +++ b/src/app/components/ValidatorsList/ValidatorsList.tsx @@ -4,7 +4,7 @@ import { Box } from '@material-ui/core'; import Link from '@material-ui/core/Link'; import Typography from '@material-ui/core/Typography'; import config from '~app/common/config'; -import ApiParams from '~lib/api/ApiParams'; +import ApiParams, { PageDirection } from '~lib/api/ApiParams'; import SsvNetwork from '~lib/api/SsvNetwork'; import Layout from '~app/common/components/Layout'; import { useStyles } from '~app/components/Styles'; @@ -29,23 +29,21 @@ const ValidatorsList = () => { const [loading, setLoading] = useState(false); const [validators, setValidators] = useState([]); const [pagination, setPagination] = useState(ApiParams.DEFAULT_PAGINATION); + const [firstAndLastRecordIds, setLastRecordIds]: [number[], any] = useState([]); + const isXsWindowSize = windowSize.size === WINDOW_SIZES.XS; /** * Loading operators by page * @param paginationPage */ const loadValidators = (paginationPage?: number) => { - if (paginationPage) { - ApiParams.saveInStorage('validators', 'page', paginationPage); - } - - const page: number = ApiParams.getInteger('validators', 'page', 1); - const perPage: number = ApiParams.getInteger('validators', 'perPage', ApiParams.PER_PAGE); - + const { page, perPage } = getGlobalPageData(paginationPage); setLoading(true); - SsvNetwork.getInstance().fetchValidators(page, perPage).then((result: any) => { - setValidators(result.data.validators); - setPagination(result.data.pagination); + const directionAndRecord = getDirectionAndRecordId(paginationPage); + SsvNetwork.getInstance().fetchValidators({ perPage, ...directionAndRecord }).then((result: any) => { + setValidators(directionAndRecord.pageDirection === PageDirection.NEXT ? result.data.validators : result.data.validators.reverse()); + setPagination({ ...result.data.pagination, page }); + setLastRecordIds([result.data.pagination.current_first, result.data.pagination.current_last]); setLoading(false); }); }; @@ -81,7 +79,46 @@ const ValidatorsList = () => { ); }), ]; - }); + }); + }; + + const getGlobalPageData = (paginationPage?: number) => { + if (paginationPage) { + ApiParams.saveInStorage('validators', 'page', paginationPage); + } + const page: number = ApiParams.getInteger('validators', 'page', 1); + const perPage: number = ApiParams.getInteger('validators', 'perPage', ApiParams.PER_PAGE); + return { page, perPage }; + }; + + const getDirectionAndRecordId = (paginationPage?: number): { lastFetchedRecordId?: number, pageDirection: PageDirection } => { + const params: any = { + pageDirection: PageDirection.NEXT, + lastFetchedRecordId: 0, + }; + + if (paginationPage === undefined) { + return params; + } + // last page + if (paginationPage === pagination.pages) { + params.pageDirection = PageDirection.PREV; + delete params.lastFetchedRecordId; + } + // first page + else if (paginationPage === 1) { + params.lastFetchedRecordId = 1; + } + // previous page + else if (paginationPage < pagination.page) { + params.pageDirection = PageDirection.PREV; + params.lastFetchedRecordId = firstAndLastRecordIds[0]; + } + // next page + else { + params.lastFetchedRecordId = firstAndLastRecordIds[1]; + } + return params; }; const getCustomOwnTableRows = () => { diff --git a/src/lib/api/ApiParams.ts b/src/lib/api/ApiParams.ts index 85adc32..3d6df8e 100644 --- a/src/lib/api/ApiParams.ts +++ b/src/lib/api/ApiParams.ts @@ -1,3 +1,8 @@ +export enum PageDirection { + NEXT = 'next', + PREV = 'prev', +} + class ApiParams { static PER_PAGE: number = 10; static DEFAULT_PAGINATION = { diff --git a/src/lib/api/SsvNetwork.ts b/src/lib/api/SsvNetwork.ts index 15de1f7..ab5de7c 100644 --- a/src/lib/api/SsvNetwork.ts +++ b/src/lib/api/SsvNetwork.ts @@ -1,5 +1,5 @@ import config from '~app/common/config'; -import ApiParams from '~lib/api/ApiParams'; +import ApiParams, { PageDirection } from '~lib/api/ApiParams'; import ApiRequest from '~lib/utils/ApiRequest'; export enum IncentivizedType { @@ -22,11 +22,14 @@ class SsvNetwork { return SsvNetwork.instance; } - async fetchValidators(page: number = 1, perPage: number = ApiParams.PER_PAGE) { + async fetchValidators({ lastFetchedRecordId, pageDirection, perPage = ApiParams.PER_PAGE }: { lastFetchedRecordId?: number, pageDirection: PageDirection, perPage?: number }) { let params: any = { - page, + pageDirection, perPage, }; + if (lastFetchedRecordId) { + params.lastId = lastFetchedRecordId; + } params = new URLSearchParams(params); const url = `${this.baseUrl}/validators/?${params.toString()}`; return new ApiRequest({