このコミットが含まれているのは:
@@ -1,10 +1,10 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { useNavigate, useParams, useSearchParams } from 'react-router-dom'
|
||||
|
||||
import PageTitle from '@/components/common/PageTitle'
|
||||
import MainArea from '@/components/layout/MainArea'
|
||||
import PostImportRowForm, { buildDraft } from '@/components/posts/import/PostImportRowForm'
|
||||
import PostImportRowForm from '@/components/posts/import/PostImportRowForm'
|
||||
import PostImportRowSummary from '@/components/posts/import/PostImportRowSummary'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { toast } from '@/components/ui/use-toast'
|
||||
@@ -43,12 +43,6 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
const [session, setSession] = useState<PostImportSession | null> (null)
|
||||
const [loading, setLoading] = useState (false)
|
||||
const [missing, setMissing] = useState (false)
|
||||
const [savingRow, setSavingRow] = useState<number | null> (null)
|
||||
const [dialogueMessageRow, setDialogueMessageRow] = useState<PostImportRow | null> (null)
|
||||
const [dialogueDraft, setDialogueDraft] = useState<PostImportRowDraft | null> (null)
|
||||
const [dialogueResetRequested, setDialogueResetRequested] = useState (false)
|
||||
const dialogueDraftRef = useRef<PostImportRowDraft | null> (null)
|
||||
const dialogueResetRequestedRef = useRef (false)
|
||||
|
||||
useEffect (() => {
|
||||
if (sessionId == null)
|
||||
@@ -68,14 +62,6 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
toast ({ title: '取込状態を保存できませんでした', description: message }))
|
||||
}, [session, sessionId])
|
||||
|
||||
useEffect (() => {
|
||||
dialogueDraftRef.current = dialogueDraft
|
||||
}, [dialogueDraft])
|
||||
|
||||
useEffect (() => {
|
||||
dialogueResetRequestedRef.current = dialogueResetRequested
|
||||
}, [dialogueResetRequested])
|
||||
|
||||
const rows = session?.rows ?? []
|
||||
const editingSourceRow = Number (searchParams.get ('edit') ?? '')
|
||||
const editingRow =
|
||||
@@ -107,21 +93,6 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
element?.scrollIntoView ({ block: 'center', behavior: 'smooth' })
|
||||
}, [editingRow, session?.repairMode])
|
||||
|
||||
useEffect (() => {
|
||||
if (editingRow == null)
|
||||
{
|
||||
setDialogueMessageRow (null)
|
||||
setDialogueDraft (null)
|
||||
setDialogueResetRequested (false)
|
||||
return
|
||||
}
|
||||
if (dialogueMessageRow?.sourceRow !== editingRow.sourceRow)
|
||||
setDialogueMessageRow (null)
|
||||
setDialogueDraft (current =>
|
||||
current != null ? current : buildDraft (editingRow))
|
||||
setDialogueResetRequested (false)
|
||||
}, [editingRow, dialogueMessageRow])
|
||||
|
||||
const updateSessionRows = (nextRows: PostImportRow[]) =>
|
||||
setSession (current =>
|
||||
current != null ? { ...current, rows: nextRows } : current)
|
||||
@@ -155,11 +126,10 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
const urlChanged = draft.url !== baseRow.url
|
||||
const nextRow = buildNextEditedRow (baseRow, draft, urlChanged)
|
||||
|
||||
setSavingRow (editingRow.sourceRow)
|
||||
const nextRows = session.rows.map (row =>
|
||||
row.sourceRow === editingRow.sourceRow
|
||||
? nextRow
|
||||
: row)
|
||||
row.sourceRow === editingRow.sourceRow
|
||||
? nextRow
|
||||
: row)
|
||||
try
|
||||
{
|
||||
const validated = await apiPost<{ rows: PostImportRow[] }> ('/posts/import/validate', {
|
||||
@@ -176,12 +146,8 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
const validatedRows = initialisePreviewRows (validated.rows)
|
||||
const target = validatedRows.find (row => row.sourceRow === editingRow.sourceRow)
|
||||
if (target != null && Object.keys (target.validationErrors).length > 0)
|
||||
{
|
||||
setDialogueMessageRow (target)
|
||||
return { saved: false, row: target }
|
||||
}
|
||||
return { saved: false, row: target }
|
||||
updateSessionRows (mergeValidatedImportRows (nextRows, validatedRows))
|
||||
setDialogueMessageRow (null)
|
||||
setSearchParams ({ })
|
||||
return { saved: true, row: null }
|
||||
}
|
||||
@@ -192,48 +158,25 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
}
|
||||
finally
|
||||
{
|
||||
setSavingRow (null)
|
||||
}
|
||||
}
|
||||
|
||||
const openEditingDialogue = async (row: PostImportRow) => {
|
||||
let currentRow = row
|
||||
|
||||
while (true)
|
||||
{
|
||||
const initialDraft = buildDraft (currentRow)
|
||||
setDialogueDraft (current => current != null ? current : initialDraft)
|
||||
setDialogueResetRequested (false)
|
||||
|
||||
const action = await dialogue.choice ({
|
||||
title: '投稿を編輯',
|
||||
description: <PostImportRowForm
|
||||
row={currentRow}
|
||||
messageRow={dialogueMessageRow?.sourceRow === currentRow.sourceRow
|
||||
? dialogueMessageRow
|
||||
: null}
|
||||
saving={savingRow === currentRow.sourceRow}
|
||||
onDraftChange={setDialogueDraft}
|
||||
onResetRequestedChange={setDialogueResetRequested}/>,
|
||||
cancelText: '取消',
|
||||
choices: [{ value: 'save', label: '編輯内容を保存' }] as const })
|
||||
|
||||
if (action !== 'save')
|
||||
{
|
||||
setSearchParams ({ })
|
||||
return
|
||||
}
|
||||
|
||||
const draft = dialogueDraftRef.current ?? initialDraft
|
||||
const result = await saveDraft ({
|
||||
draft,
|
||||
resetRequested: dialogueResetRequestedRef.current,
|
||||
resetSnapshot: currentRow.resetSnapshot })
|
||||
if (result.saved)
|
||||
return
|
||||
|
||||
currentRow = result.row ?? currentRow
|
||||
}
|
||||
await dialogue.form ({
|
||||
title: '投稿を編輯',
|
||||
description: `投稿 ${ row.sourceRow } の内容を確認し、必要な項目を編輯してください.`,
|
||||
cancelText: '取消',
|
||||
size: 'large',
|
||||
body: controls => (
|
||||
<PostImportRowForm
|
||||
row={row}
|
||||
controls={controls}
|
||||
onSave={({ draft, resetRequested }) =>
|
||||
saveDraft ({
|
||||
draft,
|
||||
resetRequested,
|
||||
resetSnapshot: row.resetSnapshot })}/>) })
|
||||
setSearchParams ({ })
|
||||
}
|
||||
|
||||
useEffect (() => {
|
||||
@@ -267,7 +210,6 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
if (firstInvalid != null)
|
||||
{
|
||||
setSession ({ ...session, rows: mergedRows })
|
||||
setDialogueMessageRow (firstInvalid)
|
||||
setSearchParams ({ edit: String (firstInvalid.sourceRow) })
|
||||
return
|
||||
}
|
||||
@@ -308,7 +250,6 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
rows: nextRows,
|
||||
repairMode: 'failed' as const }
|
||||
setSession (repairSession)
|
||||
setDialogueMessageRow (firstRecoverable)
|
||||
const saved = savePostImportSession (sessionId, repairSession, message =>
|
||||
toast ({ title: '取込状態を保存できませんでした', description: message }))
|
||||
if (saved)
|
||||
@@ -358,7 +299,7 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
|
||||
<MainArea className="min-h-0">
|
||||
<div className="mx-auto max-w-6xl space-y-4 p-4">
|
||||
<PageTitle>投稿情報の確認・編輯</PageTitle>
|
||||
<PageTitle>投稿情報の確認</PageTitle>
|
||||
|
||||
<div className="space-y-3">
|
||||
{reviewRows.map (row => (
|
||||
@@ -380,7 +321,6 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
skipPlannedCount={counts.skipPlanned}
|
||||
onBack={() => navigate ('/posts/import')}
|
||||
onSubmit={submit}/>
|
||||
|
||||
</>)
|
||||
}
|
||||
|
||||
@@ -415,7 +355,7 @@ const PostImportFooter = (
|
||||
type="button"
|
||||
onClick={onSubmit}
|
||||
disabled={loading || processableCount === 0}>
|
||||
取込を実行
|
||||
取込実行
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
新しい課題から参照
ユーザをブロックする