画面上でのテストは完了. 移行にす早さが求められるので,準備ができたらマージする. Reviewed-on: #430 Co-authored-by: miteruzo <miteruzo@naver.com>
120 行
4.1 KiB
TypeScript
120 行
4.1 KiB
TypeScript
import { useQuery } from '@tanstack/react-query'
|
|
import { useMemo } from 'react'
|
|
import { Helmet } from 'react-helmet-async'
|
|
import { useSearchParams } from 'react-router-dom'
|
|
|
|
import PrefetchLink from '@/components/PrefetchLink'
|
|
import PageTitle from '@/components/common/PageTitle'
|
|
import Pagination from '@/components/common/Pagination'
|
|
import MainArea from '@/components/layout/MainArea'
|
|
import { SITE_TITLE } from '@/config'
|
|
import { getHelpChanges, helpEditionDate } from '@/lib/help'
|
|
import { helpKeys } from '@/lib/queryKeys'
|
|
import { LIST_LIMIT_OPTIONS } from '@/lib/settings'
|
|
import { dateString } from '@/lib/utils'
|
|
|
|
import type { FC } from 'react'
|
|
|
|
|
|
const HelpChangesPage: FC = () => {
|
|
const [searchParams, setSearchParams] = useSearchParams ()
|
|
const identifier = searchParams.get ('identifier') ?? ''
|
|
const pageValue = searchParams.get ('page') ?? '1'
|
|
const pageNumber = Number (pageValue)
|
|
const requestedPage =
|
|
(/^[1-9]\d*$/.test (pageValue) && Number.isSafeInteger (pageNumber))
|
|
? pageNumber : 1
|
|
const limit = LIST_LIMIT_OPTIONS.find (
|
|
value => String (value) === searchParams.get ('limit')) ?? 20
|
|
const { data: changes = [], isLoading, error } = useQuery ({
|
|
queryKey: helpKeys.changes ('ja'),
|
|
queryFn: () => getHelpChanges ('ja'),
|
|
staleTime: Infinity })
|
|
|
|
const results = useMemo (() => identifier
|
|
? changes.filter (entry => entry.identifier === identifier)
|
|
: changes, [changes, identifier])
|
|
const totalPages = Math.ceil (results.length / limit)
|
|
const page = requestedPage <= Math.max (1, totalPages) ? requestedPage : 1
|
|
const pageResults = results.slice ((page - 1) * limit, page * limit)
|
|
|
|
const handleLimit = (value: string) => {
|
|
const next = new URLSearchParams (searchParams)
|
|
next.set ('limit', value)
|
|
next.set ('page', '1')
|
|
setSearchParams (next)
|
|
}
|
|
|
|
return (
|
|
<MainArea className="min-w-0 max-w-full">
|
|
<Helmet>
|
|
<title>{`ヘルプ改定履歴 | ${ SITE_TITLE }`}</title>
|
|
</Helmet>
|
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
|
<PageTitle>ヘルプ改定履歴</PageTitle>
|
|
<label className="flex items-center gap-2 text-xs text-muted-foreground">
|
|
<span>件数</span>
|
|
<select value={limit} onChange={ev => handleLimit (ev.target.value)}
|
|
className="rounded border border-border bg-background px-2 py-1 text-sm
|
|
text-foreground">
|
|
{LIST_LIMIT_OPTIONS.map (value => (
|
|
<option key={value} value={value}>{value}</option>))}
|
|
</select>
|
|
</label>
|
|
</div>
|
|
|
|
{isLoading
|
|
? <p className="mt-4">読み込み中...</p>
|
|
: (error
|
|
? <p className="mt-4 text-red-600" role="alert">{error.message}</p>
|
|
: (
|
|
<div className="mt-4">
|
|
<div className="min-w-0 max-w-full overflow-x-auto">
|
|
<table className="table-auto w-full min-w-[900px] whitespace-nowrap
|
|
border-collapse">
|
|
<thead className="border-b-2 border-black dark:border-white">
|
|
<tr>
|
|
<th className="p-2 text-left">差分</th>
|
|
<th className="p-2 text-left">タイトル</th>
|
|
<th className="p-2 text-left">有効開始年月日</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{pageResults.map (entry => {
|
|
const path = `/help/${ encodeURIComponent (entry.identifier) }`
|
|
const diffQuery = new URLSearchParams ({
|
|
from: entry.pred ?? '', to: entry.edition })
|
|
const diffTo = `${ path }/diff?${ diffQuery.toString () }`
|
|
const updatedAt = helpEditionDate (entry.edition)
|
|
|
|
return (
|
|
<tr key={`${ entry.identifier }/${ entry.edition }`}
|
|
className="even:bg-gray-100 text-gray-900
|
|
dark:even:bg-gray-700 dark:text-gray-100">
|
|
<td className="p-2">
|
|
{entry.pred != null && (
|
|
<PrefetchLink to={diffTo}>
|
|
差分
|
|
</PrefetchLink>)}
|
|
</td>
|
|
<td className="p-2">
|
|
<PrefetchLink to={`${ path }?edition=${ entry.edition }`}>
|
|
{entry.title}
|
|
</PrefetchLink>
|
|
</td>
|
|
<td className="p-2">
|
|
{updatedAt != null && dateString (updatedAt, 'hour')}
|
|
</td>
|
|
</tr>)
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{totalPages > 0 && <Pagination page={page} totalPages={totalPages}/>}
|
|
</div>))}
|
|
</MainArea>)
|
|
}
|
|
|
|
|
|
export default HelpChangesPage
|