このコミットが含まれているのは:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { Helmet } from 'react-helmet-async'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
import PageTitle from '@/components/common/PageTitle'
|
||||
import MainArea from '@/components/layout/MainArea'
|
||||
@@ -11,9 +11,8 @@ import { toast } from '@/components/ui/use-toast'
|
||||
import { SITE_TITLE } from '@/config'
|
||||
import { apiPost } from '@/lib/api'
|
||||
import useDialogue from '@/lib/dialogues/useDialogue'
|
||||
import { clearPostImportSession,
|
||||
clearPostImportSourceDraft,
|
||||
loadPostImportSession,
|
||||
import { parsePostNewState, serialisePostNewState } from '@/lib/postNewQueryState'
|
||||
import { clearPostImportSourceDraft,
|
||||
buildNextEditedRow,
|
||||
canEditReviewRow,
|
||||
canRetryResultRow,
|
||||
@@ -31,7 +30,6 @@ import { clearPostImportSession,
|
||||
resultRowMessages,
|
||||
reviewSummaryCounts,
|
||||
retryImportRow,
|
||||
savePostImportSession,
|
||||
validatableImportRows } from '@/lib/postImportSession'
|
||||
import { canEditContent } from '@/lib/users'
|
||||
import Forbidden from '@/pages/Forbidden'
|
||||
@@ -56,6 +54,7 @@ const isRepairRow = (row: PostImportRow): boolean =>
|
||||
const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
const editable = canEditContent (user)
|
||||
const dialogue = useDialogue ()
|
||||
const location = useLocation ()
|
||||
const navigate = useNavigate ()
|
||||
|
||||
const [session, setSession] = useState<PostImportSession | null> (null)
|
||||
@@ -64,17 +63,84 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
const [editingRow, setEditingRow] = useState<PostImportRow | null> (null)
|
||||
const [showExistingRows, setShowExistingRows] = useState (false)
|
||||
const sessionRef = useRef<PostImportSession | null> (null)
|
||||
const persistedSearchRef = useRef<string | null> (null)
|
||||
|
||||
useEffect (() => {
|
||||
const loaded = loadPostImportSession (message =>
|
||||
toast ({ title: '取込状態を復元できませんでした', description: message }))
|
||||
if (loaded == null)
|
||||
if (sessionRef.current != null && persistedSearchRef.current === location.search)
|
||||
return
|
||||
|
||||
const parsed = parsePostNewState (location.search)
|
||||
if (parsed == null)
|
||||
{
|
||||
navigate ('/posts/new', { replace: true })
|
||||
return
|
||||
}
|
||||
const loaded = {
|
||||
version: 2,
|
||||
savedAt: new Date ().toISOString (),
|
||||
source: parsed.source,
|
||||
rows: parsed.rows,
|
||||
repairMode: parsed.repairMode }
|
||||
persistedSearchRef.current = location.search
|
||||
sessionRef.current = loaded
|
||||
setSession (loaded)
|
||||
}, [navigate])
|
||||
|
||||
const hydrate = async () => {
|
||||
if (parsed.shortcut)
|
||||
{
|
||||
try
|
||||
{
|
||||
const preview = await apiPost<{ rows: PostImportRow[] }> ('/posts/import/preview', {
|
||||
source: parsed.source })
|
||||
const rows = initialisePreviewRows (preview.rows)
|
||||
const nextSession = {
|
||||
...loaded,
|
||||
source: parsed.source,
|
||||
rows,
|
||||
repairMode: resultRepairMode (rows) }
|
||||
persistSession (nextSession)
|
||||
}
|
||||
catch
|
||||
{
|
||||
navigate ('/posts/new', { replace: true })
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const requestedRows = validatableImportRows (parsed.rows)
|
||||
if (requestedRows.length === 0)
|
||||
return
|
||||
|
||||
try
|
||||
{
|
||||
const validated = await apiPost<{ rows: PostImportRow[] }> ('/posts/import/validate', {
|
||||
rows: requestedRows.map (row => ({
|
||||
sourceRow: row.sourceRow,
|
||||
url: row.url,
|
||||
attributes: row.attributes,
|
||||
provenance: row.provenance,
|
||||
tagSources: row.tagSources,
|
||||
metadataUrl: row.metadataUrl })),
|
||||
changed_row: 'all' })
|
||||
const validatedRows = initialisePreviewRows (validated.rows)
|
||||
if (!(hasExactSourceRows (requestedRows.map (row => row.sourceRow), validatedRows)))
|
||||
return
|
||||
const latest = sessionRef.current ?? loaded
|
||||
const rows = mergeValidatedImportRows (latest.rows, validatedRows)
|
||||
const nextSession = {
|
||||
...latest,
|
||||
rows,
|
||||
repairMode: resultRepairMode (rows) }
|
||||
sessionRef.current = nextSession
|
||||
setSession (nextSession)
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void hydrate ()
|
||||
}, [location.search, navigate])
|
||||
|
||||
useEffect (() => {
|
||||
sessionRef.current = session
|
||||
@@ -96,15 +162,18 @@ const PostImportReviewPage: FC<Props> = ({ user }) => {
|
||||
const busy = loading || loadingRow != null
|
||||
|
||||
const persistSession = (nextSession: PostImportSession) => {
|
||||
sessionRef.current = nextSession
|
||||
setSession (nextSession)
|
||||
savePostImportSession (nextSession, message =>
|
||||
toast ({ title: '取込状態を保存できませんでした', description: message }))
|
||||
const source = nextSession.rows.map (row => row.url).join ('\n')
|
||||
const persistedSession = {
|
||||
...nextSession,
|
||||
source }
|
||||
const nextPath = serialisePostNewState (persistedSession.rows)
|
||||
persistedSearchRef.current = nextPath.replace ('/posts/new', '')
|
||||
sessionRef.current = persistedSession
|
||||
setSession (persistedSession)
|
||||
navigate (nextPath, { replace: true })
|
||||
}
|
||||
|
||||
const finishImport = () => {
|
||||
clearPostImportSession (message =>
|
||||
toast ({ title: '取込状態を削除できませんでした', description: message }))
|
||||
clearPostImportSourceDraft (message =>
|
||||
toast ({ title: '入力内容を削除できませんでした', description: message }))
|
||||
navigate ('/posts')
|
||||
|
||||
新しい課題から参照
ユーザをブロックする