バグ修正(#253) #254
@@ -120,7 +120,7 @@ export default (({ user }: Props) => {
|
|||||||
const fetchPostCount = async () => {
|
const fetchPostCount = async () => {
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const wikiPage = await fetchWikiPage (String (wikiId ?? ''))
|
const wikiPage = await fetchWikiPage (String (wikiId ?? ''), { })
|
||||||
const tag = await fetchTagByName (wikiPage.title)
|
const tag = await fetchTagByName (wikiPage.title)
|
||||||
|
|
||||||
setPostCount (tag.postCount)
|
setPostCount (tag.postCount)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { apiDelete, apiGet, apiPost } from '@/lib/api'
|
import { apiDelete, apiGet, apiPost } from '@/lib/api'
|
||||||
|
|
||||||
import type { Post } from '@/types'
|
import type { Post, PostTagChange } from '@/types'
|
||||||
|
|
||||||
|
|
||||||
export const fetchPosts = async (
|
export const fetchPosts = async (
|
||||||
@@ -13,8 +13,8 @@ export const fetchPosts = async (
|
|||||||
): Promise<{
|
): Promise<{
|
||||||
posts: Post[]
|
posts: Post[]
|
||||||
count: number
|
count: number
|
||||||
nextCursor: string }> => await apiGet ('/posts', {
|
nextCursor: string }> =>
|
||||||
params: {
|
await apiGet ('/posts', { params: {
|
||||||
tags,
|
tags,
|
||||||
match,
|
match,
|
||||||
...(page && { page }),
|
...(page && { page }),
|
||||||
@@ -25,6 +25,17 @@ export const fetchPosts = async (
|
|||||||
export const fetchPost = async (id: string): Promise<Post> => await apiGet (`/posts/${ id }`)
|
export const fetchPost = async (id: string): Promise<Post> => await apiGet (`/posts/${ id }`)
|
||||||
|
|
||||||
|
|
||||||
|
export const fetchPostChanges = async (
|
||||||
|
{ id, page, limit }: {
|
||||||
|
id?: string
|
||||||
|
page: number
|
||||||
|
limit: number },
|
||||||
|
): Promise<{
|
||||||
|
changes: PostTagChange[]
|
||||||
|
count: number }> =>
|
||||||
|
await apiGet ('/posts/changes', { params: { ...(id && { id }), page, limit } })
|
||||||
|
|
||||||
|
|
||||||
export const toggleViewedFlg = async (id: string, viewed: boolean): Promise<void> => {
|
export const toggleViewedFlg = async (id: string, viewed: boolean): Promise<void> => {
|
||||||
await (viewed ? apiPost : apiDelete) (`/posts/${ id }/viewed`)
|
await (viewed ? apiPost : apiDelete) (`/posts/${ id }/viewed`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
import { QueryClient } from '@tanstack/react-query'
|
import { QueryClient } from '@tanstack/react-query'
|
||||||
import { match } from 'path-to-regexp'
|
import { match } from 'path-to-regexp'
|
||||||
|
|
||||||
import { fetchPost, fetchPosts } from '@/lib/posts'
|
import { fetchPost, fetchPosts, fetchPostChanges } from '@/lib/posts'
|
||||||
import { postsKeys } from '@/lib/queryKeys'
|
import { postsKeys, wikiKeys } from '@/lib/queryKeys'
|
||||||
|
import { fetchWikiPages } from '@/lib/wiki'
|
||||||
|
|
||||||
type Prefetcher = (qc: QueryClient, url: URL) => Promise<void>
|
type Prefetcher = (qc: QueryClient, url: URL) => Promise<void>
|
||||||
|
|
||||||
const mPost = match<{ id: string }> ('/posts/:id')
|
const mPost = match<{ id: string }> ('/posts/:id')
|
||||||
|
|
||||||
|
|
||||||
|
const prefetchWikiPagesIndex: Prefetcher = async (qc, url) => {
|
||||||
|
const title = url.searchParams.get ('title') ?? ''
|
||||||
|
await qc.prefetchQuery ({
|
||||||
|
queryKey: wikiKeys.index ({ title }),
|
||||||
|
queryFn: () => fetchWikiPages ({ title }) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const prefetchPostsIndex: Prefetcher = async (qc, url) => {
|
const prefetchPostsIndex: Prefetcher = async (qc, url) => {
|
||||||
const tags = url.searchParams.get ('tags') ?? ''
|
const tags = url.searchParams.get ('tags') ?? ''
|
||||||
const m = url.searchParams.get ('match') === 'any' ? 'any' : 'all'
|
const m = url.searchParams.get ('match') === 'any' ? 'any' : 'all'
|
||||||
@@ -32,11 +41,23 @@ const prefetchPostShow: Prefetcher = async (qc, url) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const routePrefetchers: {
|
const prefetchPostChanges: Prefetcher = async (qc, url) => {
|
||||||
test: (u: URL) => boolean
|
const id = url.searchParams.get ('id')
|
||||||
run: Prefetcher }[] = [
|
const page = Number (url.searchParams.get ('page') || 1)
|
||||||
|
const limit = Number (url.searchParams.get ('limit') || 20)
|
||||||
|
await qc.prefetchQuery ({
|
||||||
|
queryKey: postsKeys.changes ({ ...(id && { id }), page, limit }),
|
||||||
|
queryFn: () => fetchPostChanges ({ ...(id && { id }), page, limit }) })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const routePrefetchers: { test: (u: URL) => boolean; run: Prefetcher }[] = [
|
||||||
{ test: u => u.pathname === '/' || u.pathname === '/posts', run: prefetchPostsIndex },
|
{ test: u => u.pathname === '/' || u.pathname === '/posts', run: prefetchPostsIndex },
|
||||||
{ test: u => Boolean (mPost (u.pathname)), run: prefetchPostShow }]
|
{ test: u => (['/posts/new', '/posts/changes'].includes(u.pathname)
|
||||||
|
&& Boolean (mPost (u.pathname))),
|
||||||
|
run: prefetchPostShow },
|
||||||
|
{ test: u => u.pathname === '/posts/changes', run: prefetchPostChanges },
|
||||||
|
{ test: u => u.pathname === '/wiki', run: prefetchWikiPagesIndex }]
|
||||||
|
|
||||||
|
|
||||||
export const prefetchForURL = async (qc: QueryClient, urlLike: string): Promise<void> => {
|
export const prefetchForURL = async (qc: QueryClient, urlLike: string): Promise<void> => {
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ export const postsKeys = {
|
|||||||
index: (p: { tags: string; match: 'any' | 'all'; page: number; limit: number }) =>
|
index: (p: { tags: string; match: 'any' | 'all'; page: number; limit: number }) =>
|
||||||
['posts', 'index', p] as const,
|
['posts', 'index', p] as const,
|
||||||
show: (id: string) => ['posts', id] as const,
|
show: (id: string) => ['posts', id] as const,
|
||||||
related: (id: string) => ['related', id] as const }
|
related: (id: string) => ['related', id] as const,
|
||||||
|
changes: (p: { id?: string; page: number; limit: number }) =>
|
||||||
|
['posts', 'changes', p] as const }
|
||||||
|
|
||||||
export const wikiKeys = {
|
export const wikiKeys = {
|
||||||
root: ['wiki'] as const,
|
root: ['wiki'] as const,
|
||||||
|
index: (p: { title: string }) => ['wiki', 'index', p] as const,
|
||||||
show: (title: string, p: { version: string }) => ['wiki', title, p] as const }
|
show: (title: string, p: { version: string }) => ['wiki', title, p] as const }
|
||||||
|
|||||||
@@ -3,12 +3,20 @@ import { apiGet } from '@/lib/api'
|
|||||||
import type { WikiPage } from '@/types'
|
import type { WikiPage } from '@/types'
|
||||||
|
|
||||||
|
|
||||||
export const fetchWikiPage = async (id: string): Promise<WikiPage> =>
|
export const fetchWikiPages = async ({ title }: { title: string }) =>
|
||||||
await apiGet (`/wiki/${ id }`)
|
await apiGet ('/wiki', { params: { title } })
|
||||||
|
|
||||||
|
|
||||||
|
export const fetchWikiPage = async (
|
||||||
|
id: string,
|
||||||
|
{ version }: { version?: string },
|
||||||
|
): Promise<WikiPage> =>
|
||||||
|
await apiGet (`/wiki/${ id }`, { params: version ? { version } : { } })
|
||||||
|
|
||||||
|
|
||||||
export const fetchWikiPageByTitle = async (
|
export const fetchWikiPageByTitle = async (
|
||||||
title: string,
|
title: string,
|
||||||
{ version }: { version?: string },
|
{ version }: { version?: string },
|
||||||
): Promise<WikiPage> =>
|
): Promise<WikiPage> =>
|
||||||
await apiGet (`/wiki/title/${ title }`, { params: version ? { version } : { } })
|
await apiGet (`/wiki/title/${ title }`,
|
||||||
|
{ params: version ? { version } : { } })
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import axios from 'axios'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import toCamel from 'camelcase-keys'
|
|
||||||
import { useEffect, useState } from 'react'
|
|
||||||
import { Helmet } from 'react-helmet-async'
|
import { Helmet } from 'react-helmet-async'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -9,17 +7,14 @@ import PrefetchLink from '@/components/PrefetchLink'
|
|||||||
import PageTitle from '@/components/common/PageTitle'
|
import PageTitle from '@/components/common/PageTitle'
|
||||||
import Pagination from '@/components/common/Pagination'
|
import Pagination from '@/components/common/Pagination'
|
||||||
import MainArea from '@/components/layout/MainArea'
|
import MainArea from '@/components/layout/MainArea'
|
||||||
import { API_BASE_URL, SITE_TITLE } from '@/config'
|
import { SITE_TITLE } from '@/config'
|
||||||
|
import { fetchPostChanges } from '@/lib/posts'
|
||||||
|
import { postsKeys } from '@/lib/queryKeys'
|
||||||
|
|
||||||
import type { FC } from 'react'
|
import type { FC } from 'react'
|
||||||
|
|
||||||
import type { PostTagChange } from '@/types'
|
|
||||||
|
|
||||||
|
|
||||||
export default (() => {
|
export default (() => {
|
||||||
const [changes, setChanges] = useState<PostTagChange[]> ([])
|
|
||||||
const [totalPages, setTotalPages] = useState<number> (0)
|
|
||||||
|
|
||||||
const location = useLocation ()
|
const location = useLocation ()
|
||||||
const query = new URLSearchParams (location.search)
|
const query = new URLSearchParams (location.search)
|
||||||
const id = query.get ('id')
|
const id = query.get ('id')
|
||||||
@@ -29,17 +24,11 @@ export default (() => {
|
|||||||
// 投稿列の結合で使用
|
// 投稿列の結合で使用
|
||||||
let rowsCnt: number
|
let rowsCnt: number
|
||||||
|
|
||||||
useEffect (() => {
|
const { data, isLoading: loading } = useQuery ({
|
||||||
void (async () => {
|
queryKey: postsKeys.changes ({ ...(id && { id }), page, limit }),
|
||||||
const res = await axios.get (`${ API_BASE_URL }/posts/changes`,
|
queryFn: () => fetchPostChanges ({ ...(id && { id }), page, limit }) })
|
||||||
{ params: { ...(id && { id }), page, limit } })
|
const changes = data?.changes ?? []
|
||||||
const data = toCamel (res.data as any, { deep: true }) as {
|
const totalPages = data ? Math.ceil (data.count / limit) : 0
|
||||||
changes: PostTagChange[]
|
|
||||||
count: number }
|
|
||||||
setChanges (data.changes)
|
|
||||||
setTotalPages (Math.ceil (data.count / limit))
|
|
||||||
}) ()
|
|
||||||
}, [id, page, limit])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MainArea>
|
<MainArea>
|
||||||
@@ -52,6 +41,8 @@ export default (() => {
|
|||||||
{id && <>: 投稿 {<PrefetchLink to={`/posts/${ id }`}>#{id}</PrefetchLink>}</>}
|
{id && <>: 投稿 {<PrefetchLink to={`/posts/${ id }`}>#{id}</PrefetchLink>}</>}
|
||||||
</PageTitle>
|
</PageTitle>
|
||||||
|
|
||||||
|
{loading ? 'Loading...' : (
|
||||||
|
<>
|
||||||
<table className="table-auto w-full border-collapse">
|
<table className="table-auto w-full border-collapse">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -85,7 +76,7 @@ export default (() => {
|
|||||||
</td>)}
|
</td>)}
|
||||||
<td>
|
<td>
|
||||||
<TagLink tag={change.tag} withWiki={false} withCount={false}/>
|
<TagLink tag={change.tag} withWiki={false} withCount={false}/>
|
||||||
{`を${ change.changeType === 'add' ? '追加' : '削除' }`}
|
{`を${ change.changeType === 'add' ? '記載' : '消除' }`}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{change.user ? (
|
{change.user ? (
|
||||||
@@ -101,5 +92,6 @@ export default (() => {
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<Pagination page={page} totalPages={totalPages}/>
|
<Pagination page={page} totalPages={totalPages}/>
|
||||||
|
</>)}
|
||||||
</MainArea>)
|
</MainArea>)
|
||||||
}) satisfies FC
|
}) satisfies FC
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export default () => {
|
|||||||
setWikiPage (undefined)
|
setWikiPage (undefined)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const data = await fetchWikiPage (title)
|
const data = await fetchWikiPage (title, { })
|
||||||
navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
|
navigate (`/wiki/${ encodeURIComponent(data.title) }`, { replace: true })
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
Reference in New Issue
Block a user