AI: address review on PR #477
このコミットが含まれているのは:
+56
-12
@@ -1,6 +1,6 @@
|
||||
import { isAxiosError } from 'axios'
|
||||
|
||||
import { apiGet } from '@/lib/api'
|
||||
import { apiGet, apiPost, apiPut } from '@/lib/api'
|
||||
import { switchLocalePath } from '@/lib/locales'
|
||||
import { fetchTag, fetchTagByName } from '@/lib/tags'
|
||||
|
||||
@@ -24,19 +24,54 @@ export const fetchWikiChanges = (
|
||||
|
||||
|
||||
export const fetchWikiPages = async (
|
||||
{ title, resourceType }: { title?: string, resourceType?: WikiPage['resourceType'] },
|
||||
{ title, resourceType = 'tag_description' }: {
|
||||
title?: string, resourceType?: WikiPage['resourceType'] },
|
||||
locale: LocaleCode = 'ja',
|
||||
): Promise<WikiPage[]> =>
|
||||
await apiGet ('/wiki', { locale, params: { title, resource_type: resourceType } })
|
||||
): Promise<WikiPage[]> => apiGet (
|
||||
resourceType === 'tag_group' ? '/tag_groups' : '/tags/descriptions',
|
||||
{ locale, params: { title, document: '1' } })
|
||||
|
||||
|
||||
export const fetchWikiPage = async (
|
||||
id: string,
|
||||
{ version }: { version?: string },
|
||||
id: string,
|
||||
{ version }: { version?: string },
|
||||
locale: LocaleCode = 'ja',
|
||||
): Promise<WikiPage> =>
|
||||
await apiGet (`/wiki/${ encodeURIComponent (id) }`, {
|
||||
locale, params: version ? { version } : { } })
|
||||
): Promise<WikiPage> => {
|
||||
if (version != null)
|
||||
return apiGet (`/wiki/${encodeURIComponent (id)}`, { locale, params: { version } })
|
||||
try
|
||||
{
|
||||
return await apiGet (`/tags/descriptions/${encodeURIComponent (id)}`,
|
||||
{ locale, params: { document: '1' } })
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
if (!isAxiosError (error) || error.response?.status !== 404)
|
||||
throw error
|
||||
return apiGet (`/tag_groups/${encodeURIComponent (id)}`,
|
||||
{ locale, params: { document: '1' } })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export const saveTagDocument = async (
|
||||
{ title, body, page }: { title: string, body: string, page?: WikiPage },
|
||||
locale: LocaleCode,
|
||||
): Promise<WikiPage> => {
|
||||
const groupName = /^(?:タググループ:|tag_group:)(.*)$/i.exec (title.trim ())?.[1]
|
||||
const options = { locale, params: { document: '1' } }
|
||||
if (page?.resourceType === 'tag_group' || (page == null && groupName != null))
|
||||
{
|
||||
const attributes = { name: groupName ?? title.trim (), body }
|
||||
return page == null
|
||||
? apiPost ('/tag_groups', attributes, options)
|
||||
: apiPut (`/tag_groups/${encodeURIComponent (String (page.id))}`, attributes, options)
|
||||
}
|
||||
if (page == null)
|
||||
return apiPost ('/tags/descriptions', { title, body }, options)
|
||||
return apiPut (`/tags/${encodeURIComponent (String (page.tagId))}/description`,
|
||||
{ title, body }, options)
|
||||
}
|
||||
|
||||
|
||||
export const fetchWikiPageByTitle = async (
|
||||
@@ -46,7 +81,14 @@ export const fetchWikiPageByTitle = async (
|
||||
): Promise<WikiPage | null> => {
|
||||
try
|
||||
{
|
||||
return await apiGet (`/wiki/title/${ encodeURIComponent (title) }`, { locale, params: { version } })
|
||||
if (version != null)
|
||||
return await apiGet (`/wiki/title/${encodeURIComponent (title)}`,
|
||||
{ locale, params: { version } })
|
||||
const groupName = /^(?:タググループ:|tag_group:)(.*)$/i.exec (title.trim ())?.[1]
|
||||
const path = groupName == null
|
||||
? `/tags/name/${encodeURIComponent (title)}/description`
|
||||
: `/tag_groups/name/${encodeURIComponent (groupName)}`
|
||||
return await apiGet (path, { locale, params: { document: '1' } })
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
@@ -72,7 +114,7 @@ export const fetchWikiPageByReference = async (
|
||||
{
|
||||
if (!isAxiosError (error) || error.response?.status !== 404)
|
||||
throw error
|
||||
const tag = await fetchWikiTag ({ wikiId: reference }, locale)
|
||||
const tag = await fetchTagByName (reference, locale)
|
||||
return tag == null ? null : fetchWikiPageByTitle (tag.name, params, locale)
|
||||
}
|
||||
}
|
||||
@@ -86,7 +128,9 @@ export const fetchWikiTag = async (
|
||||
return fetchTagByName (reference.name, locale)
|
||||
try
|
||||
{
|
||||
return await apiGet (`/wiki/${encodeURIComponent (reference.wikiId)}/tag`, { locale })
|
||||
const page = await fetchWikiPage (reference.wikiId, { }, locale)
|
||||
return (page.resourceType === 'tag_description' && page.tagId != null)
|
||||
? fetchTag (String (page.tagId), locale) : null
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
|
||||
@@ -11,8 +11,8 @@ import FormField from '@/components/common/FormField'
|
||||
import MainArea from '@/components/layout/MainArea'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import PageHead from '@/components/common/PageHead'
|
||||
import { apiGet, apiPut } from '@/lib/api'
|
||||
import { wikiKeys } from '@/lib/queryKeys'
|
||||
import { fetchWikiPage, saveTagDocument } from '@/lib/wiki'
|
||||
import { tagsKeys, wikiKeys } from '@/lib/queryKeys'
|
||||
import { canEditContent } from '@/lib/users'
|
||||
import { inputClass } from '@/lib/utils'
|
||||
import { useValidationErrors } from '@/lib/useValidationErrors'
|
||||
@@ -33,7 +33,7 @@ const FIXED_WIKI_EDITOR_VIEW = { menu: true, md: true, html: true } as const
|
||||
|
||||
type Props = { user: User | null }
|
||||
|
||||
type WikiFormField = 'title' | 'body'
|
||||
type WikiFormField = 'title' | 'name' | 'body'
|
||||
|
||||
|
||||
const WikiEditPage: FC<Props> = ({ user }) => {
|
||||
@@ -50,7 +50,7 @@ const WikiEditPage: FC<Props> = ({ user }) => {
|
||||
const source = `${locale}:${id}`
|
||||
const { data: wiki, isPending: loading } = useQuery ({
|
||||
queryKey: wikiKeys.show (id ?? '', { }, locale),
|
||||
queryFn: () => apiGet<WikiPage> (`/wiki/${ encodeURIComponent (id ?? '') }`, { locale }),
|
||||
queryFn: () => fetchWikiPage (id ?? '', { }, locale),
|
||||
enabled: editable })
|
||||
const [body, setBody] = useState (wiki?.body ?? '')
|
||||
const [loadedSource, setLoadedSource] = useState (wiki == null ? '' : source)
|
||||
@@ -60,22 +60,19 @@ const WikiEditPage: FC<Props> = ({ user }) => {
|
||||
useValidationErrors<WikiFormField> ()
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (pending || !editable)
|
||||
if (pending || !editable || wiki == null)
|
||||
return
|
||||
clearValidationErrors ()
|
||||
|
||||
const formData = new FormData ()
|
||||
formData.append ('title', title)
|
||||
formData.append ('body', body)
|
||||
|
||||
try
|
||||
{
|
||||
await apiPut (`/wiki/${ id }`, formData,
|
||||
{ locale, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
await saveTagDocument ({ title, body, page: wiki }, locale)
|
||||
qc.setQueryData (wikiKeys.show (title, { }, locale),
|
||||
(prev: WikiPage | undefined) =>
|
||||
prev == null ? prev : { ...prev, title, body })
|
||||
qc.invalidateQueries ({ queryKey: wikiKeys.root })
|
||||
await Promise.all ([
|
||||
qc.invalidateQueries ({ queryKey: wikiKeys.root }),
|
||||
qc.invalidateQueries ({ queryKey: tagsKeys.root })])
|
||||
toast ({ title: label ('shared:messages.postSuccess') })
|
||||
navigate (`/wiki/${ encodeURIComponent (title) }`)
|
||||
}
|
||||
@@ -110,7 +107,7 @@ const WikiEditPage: FC<Props> = ({ user }) => {
|
||||
|
||||
{/* タイトル */}
|
||||
{/* TODO: タグ補完 */}
|
||||
<FormField label={label ('shared:labels.title')} messages={fieldErrors.title}>
|
||||
<FormField label={label ('shared:labels.title')} messages={fieldErrors.title ?? fieldErrors.name}>
|
||||
{({ describedBy, invalid }) => (
|
||||
<input type="text"
|
||||
value={title}
|
||||
|
||||
@@ -12,7 +12,7 @@ import FormField from '@/components/common/FormField'
|
||||
import MainArea from '@/components/layout/MainArea'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import PageHead from '@/components/common/PageHead'
|
||||
import { apiPost } from '@/lib/api'
|
||||
import { saveTagDocument } from '@/lib/wiki'
|
||||
import { tagsKeys, wikiKeys } from '@/lib/queryKeys'
|
||||
import { canEditContent } from '@/lib/users'
|
||||
import { inputClass } from '@/lib/utils'
|
||||
@@ -21,7 +21,7 @@ import Forbidden from '@/pages/Forbidden'
|
||||
|
||||
import type { FC } from 'react'
|
||||
|
||||
import type { User, WikiPage } from '@/types'
|
||||
import type { User } from '@/types'
|
||||
|
||||
const mdParser = new MarkdownIt
|
||||
const FIXED_WIKI_EDITOR_VIEW = { menu: true, md: true, html: true } as const
|
||||
@@ -32,7 +32,7 @@ const FIXED_WIKI_EDITOR_VIEW = { menu: true, md: true, html: true } as const
|
||||
|
||||
type Props = { user: User | null }
|
||||
|
||||
type WikiFormField = 'title' | 'body'
|
||||
type WikiFormField = 'title' | 'name' | 'body'
|
||||
|
||||
|
||||
const WikiNewPage: FC<Props> = ({ user }) => {
|
||||
@@ -55,14 +55,9 @@ const WikiNewPage: FC<Props> = ({ user }) => {
|
||||
const handleSubmit = async () => {
|
||||
clearValidationErrors ()
|
||||
|
||||
const formData = new FormData
|
||||
formData.append ('title', title)
|
||||
formData.append ('body', body)
|
||||
|
||||
try
|
||||
{
|
||||
const data = await apiPost<WikiPage> ('/wiki', formData,
|
||||
{ locale, headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
const data = await saveTagDocument ({ title, body }, locale)
|
||||
await qc.cancelQueries ({ queryKey: wikiKeys.root })
|
||||
qc.setQueryData (wikiKeys.show (data.title, { }, locale), data)
|
||||
await Promise.all ([
|
||||
@@ -91,7 +86,7 @@ const WikiNewPage: FC<Props> = ({ user }) => {
|
||||
|
||||
{/* タイトル */}
|
||||
{/* TODO: タグ補完 */}
|
||||
<FormField label={label ('shared:labels.title')} messages={fieldErrors.title}>
|
||||
<FormField label={label ('shared:labels.title')} messages={fieldErrors.title ?? fieldErrors.name}>
|
||||
{({ describedBy, invalid }) => (
|
||||
<input type="text"
|
||||
value={title}
|
||||
|
||||
新しいイシューから参照
ユーザーをブロックする