#171 #171 #171 #171 #171 #171 #171 Co-authored-by: miteruzo <miteruzo@naver.com> Reviewed-on: #345
This commit was merged in pull request #345.
This commit is contained in:
@@ -3,11 +3,12 @@ import { useEffect, useState } from 'react'
|
||||
import PostFormTagsArea from '@/components/PostFormTagsArea'
|
||||
import PostOriginalCreatedTimeField from '@/components/PostOriginalCreatedTimeField'
|
||||
import Label from '@/components/common/Label'
|
||||
import { useDialogue } from '@/components/dialogues/DialogueProvider'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
import { apiPut } from '@/lib/api'
|
||||
import { updatePost } from '@/lib/posts'
|
||||
|
||||
import type { FC } from 'react'
|
||||
import type { FC, FormEvent } from 'react'
|
||||
|
||||
import type { Post, Tag } from '@/types'
|
||||
|
||||
@@ -32,6 +33,7 @@ type Props = { post: Post
|
||||
|
||||
|
||||
export default (({ post, onSave }: Props) => {
|
||||
const [disabled, setDisabled] = useState (false)
|
||||
const [originalCreatedBefore, setOriginalCreatedBefore] =
|
||||
useState<string | null> (post.originalCreatedBefore)
|
||||
const [originalCreatedFrom, setOriginalCreatedFrom] =
|
||||
@@ -41,16 +43,14 @@ export default (({ post, onSave }: Props) => {
|
||||
const [tags, setTags] = useState<string> ('')
|
||||
const [title, setTitle] = useState (post.title)
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const dialogue = useDialogue ()
|
||||
|
||||
const update = async (...args: Parameters<typeof updatePost>) => {
|
||||
try
|
||||
{
|
||||
const data = await apiPut<Post> (
|
||||
`/posts/${ post.id }`,
|
||||
{ title, tags, parent_post_ids: parentPostIds,
|
||||
original_created_from: originalCreatedFrom,
|
||||
original_created_before: originalCreatedBefore },
|
||||
{ headers: { 'Content-Type': 'multipart/form-data' } })
|
||||
const data = await updatePost (...args)
|
||||
onSave ({ ...post,
|
||||
versionNo: data.versionNo,
|
||||
title: data.title,
|
||||
tags: data.tags,
|
||||
parentPosts: data.parentPosts,
|
||||
@@ -60,9 +60,58 @@ export default (({ post, onSave }: Props) => {
|
||||
originalCreatedBefore: data.originalCreatedBefore } as Post)
|
||||
toast ({ description: '更新しました.' })
|
||||
}
|
||||
catch
|
||||
catch (e)
|
||||
{
|
||||
toast ({ description: '更新はできなかったよ……' })
|
||||
const response = (e as any)?.response
|
||||
|
||||
if (response?.status !== 409)
|
||||
{
|
||||
toast ({ description: '更新はできなかったよ……' })
|
||||
return
|
||||
}
|
||||
|
||||
const action = await dialogue.choice ({
|
||||
title: '競合が発生しました.',
|
||||
description: (
|
||||
<div>
|
||||
<p>ほかの耕作員が先に更新してゐます.</p>
|
||||
<p>現在の変更をどう扱ひますか?</p>
|
||||
</div>),
|
||||
choices: [...(response?.data?.mergeable ? [{ value: 'merge', label: '差分をマージ' }] : []),
|
||||
{ value: 'overwrite', label: '強制上書き', variant: 'danger' }] })
|
||||
|
||||
if (action === 'merge')
|
||||
{
|
||||
// TODO: 差分 UI
|
||||
await update ({ id: post.id, title, tags, parentPostIds,
|
||||
originalCreatedFrom, originalCreatedBefore },
|
||||
{ baseVersionNo: post.versionNo, merge: true })
|
||||
return
|
||||
}
|
||||
|
||||
if (action === 'overwrite')
|
||||
{
|
||||
await update ({ id: post.id, title, tags, parentPostIds,
|
||||
originalCreatedFrom, originalCreatedBefore },
|
||||
{ baseVersionNo: post.versionNo, force: true })
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async (e: FormEvent) => {
|
||||
e.preventDefault ()
|
||||
|
||||
setDisabled (true)
|
||||
try
|
||||
{
|
||||
await update ({ id: post.id, title, tags, parentPostIds,
|
||||
originalCreatedFrom, originalCreatedBefore },
|
||||
{ baseVersionNo: post.versionNo })
|
||||
}
|
||||
finally
|
||||
{
|
||||
setDisabled (false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,14 +120,16 @@ export default (({ post, onSave }: Props) => {
|
||||
}, [post])
|
||||
|
||||
return (
|
||||
<div className="max-w-xl pt-2 space-y-4">
|
||||
<form onSubmit={handleSubmit} className="max-w-xl pt-2 space-y-4">
|
||||
{/* タイトル */}
|
||||
<div>
|
||||
<Label>タイトル</Label>
|
||||
<input type="text"
|
||||
className="w-full border rounded p-2"
|
||||
value={title ?? ''}
|
||||
onChange={ev => setTitle (ev.target.value)}/>
|
||||
<input
|
||||
type="text"
|
||||
disabled={disabled}
|
||||
className="w-full border rounded p-2"
|
||||
value={title ?? ''}
|
||||
onChange={ev => setTitle (ev.target.value)}/>
|
||||
</div>
|
||||
|
||||
{/* 親投稿 */}
|
||||
@@ -86,25 +137,31 @@ export default (({ post, onSave }: Props) => {
|
||||
<Label>親投稿</Label>
|
||||
<input
|
||||
type="text"
|
||||
disabled={disabled}
|
||||
value={parentPostIds}
|
||||
onChange={e => setParentPostIds (e.target.value)}
|
||||
className="w-full border p-2 rounded"/>
|
||||
</div>
|
||||
|
||||
{/* タグ */}
|
||||
<PostFormTagsArea tags={tags} setTags={setTags}/>
|
||||
<PostFormTagsArea
|
||||
disabled={disabled}
|
||||
tags={tags}
|
||||
setTags={setTags}/>
|
||||
|
||||
{/* オリジナルの作成日時 */}
|
||||
<PostOriginalCreatedTimeField
|
||||
disabled={disabled}
|
||||
originalCreatedFrom={originalCreatedFrom}
|
||||
setOriginalCreatedFrom={setOriginalCreatedFrom}
|
||||
originalCreatedBefore={originalCreatedBefore}
|
||||
setOriginalCreatedBefore={setOriginalCreatedBefore}/>
|
||||
|
||||
{/* 送信 */}
|
||||
<Button onClick={handleSubmit}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded disabled:bg-gray-400">
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={disabled}>
|
||||
更新
|
||||
</Button>
|
||||
</div>)
|
||||
</form>)
|
||||
}) satisfies FC<Props>
|
||||
|
||||
Reference in New Issue
Block a user