From 7789d285c3c16910aff3041c7fa86f0412ab29e6 Mon Sep 17 00:00:00 2001 From: iilj Date: Thu, 31 Dec 2020 15:34:21 +0900 Subject: [PATCH] Store SortName and SortParam as query string --- src/pages/ListPage/ListTable.tsx | 67 +++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/pages/ListPage/ListTable.tsx b/src/pages/ListPage/ListTable.tsx index b78f292..03e7014 100644 --- a/src/pages/ListPage/ListTable.tsx +++ b/src/pages/ListPage/ListTable.tsx @@ -1,4 +1,8 @@ -import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table'; +import { + BootstrapTable, + SortOrder, + TableHeaderColumn, +} from 'react-bootstrap-table'; import React, { useState } from 'react'; import { Button } from 'reactstrap'; import dataFormat from 'dateformat'; @@ -23,6 +27,7 @@ import { } from '../../interfaces/MergedProblem'; import { ProblemDetailModal } from '../../components/ProblemDetailModal'; import { useNavigate } from 'react-router'; +import { useSearchParams } from 'react-router-dom'; export type FilterState = 'All' | 'Only Trying' | 'Only AC'; @@ -38,6 +43,32 @@ interface Props { problemLinkColorMode: ProblemLinkColorMode; } +const SORT_NAMES = [ + 'Date', + 'Title', + 'Level', + 'Contest', + 'SolveDate', + 'FirstSolveDate', + 'Tags', + 'Difficulty', + 'FastestRankingProblem', + 'ShortestRankingProblem', + 'PureShortestRankingProblem', + 'ProblemType', + 'No', + 'ProblemId', +] as const; +type SortName = typeof SORT_NAMES[number]; +const sanitizeColumnName = (sortName: string | null): SortName => { + if (SORT_NAMES.includes(sortName as SortName)) return sortName as SortName; + else return 'Date'; +}; +const sanitizeSortOrder = (sortOrder: string | null): SortOrder => { + if (sortOrder == 'asc' || sortOrder == 'desc') return sortOrder; + else return 'desc'; +}; + export const ListTable: React.FC = (props) => { const { rankingMergedProblems, @@ -59,6 +90,8 @@ export const ListTable: React.FC = (props) => { rankingMergedProblem: undefined, }); + const [searchParams, setSearchParams] = useSearchParams(); + const columns = [ { header: 'Date', @@ -335,7 +368,8 @@ export const ListTable: React.FC = (props) => { }} options={{ paginationPosition: 'top', - sizePerPage: 20, + page: Number(searchParams.get('page') ?? 1), + sizePerPage: Number(searchParams.get('sizePerPage') ?? 20), sizePerPageList: [ { text: '20', @@ -358,11 +392,40 @@ export const ListTable: React.FC = (props) => { value: rankingMergedProblems.length, }, ], + onSizePerPageList: function _onSizePerPageList(sizePerPage: number) { + searchParams.set('page', `1`); + searchParams.set('sizePerPage', `${sizePerPage}`); + setSearchParams(searchParams); + }, + onPageChange: function _onPageChange( + page: number, + sizePerPage: number + ) { + searchParams.set('page', `${page}`); + searchParams.set('sizePerPage', `${sizePerPage}`); + setSearchParams(searchParams); + }, paginationPanel: function _paginationPanel( paginationPanelProps: ListPaginationPanelProps ) { return ; }, + defaultSortName: sanitizeColumnName(searchParams.get('sortName')), + defaultSortOrder: sanitizeSortOrder(searchParams.get('sortOrder')), + onSortChange: function _onSortChange( + sortName: string | number | symbol, + sortOrder: SortOrder + ) { + searchParams.set('sortName', sortName as string); + searchParams.set('sortOrder', sortOrder); + setSearchParams(searchParams); + }, + defaultSearch: searchParams.get('search') ?? '', + onSearchChange: function _onSearchChange(searchText: string) { + searchParams.set('page', `1`); + searchParams.set('search', searchText); + setSearchParams(searchParams, { replace: true }); + }, }} > {columns.map((c) => (