このコミットが含まれているのは:
2026-07-15 19:57:09 +09:00
コミット 6e5aa1e30f
16個のファイルの変更299行の追加345行の削除
+28 -21
ファイルの表示
@@ -8,7 +8,7 @@ import PageTitle from '@/components/common/PageTitle'
import PrefetchLink from '@/components/PrefetchLink'
import MainArea from '@/components/layout/MainArea'
import PostImportStatusBadge from '@/components/posts/import/PostImportStatusBadge'
import { effectivePostImportStatus } from '@/components/posts/import/postImportRowStatus'
import { displayPostImportStatus } from '@/components/posts/import/postImportRowStatus'
import { importPanelToneClass } from '@/components/posts/import/postImportTone'
import PostImportSummaryChip from '@/components/posts/import/PostImportSummaryChip'
import { Button } from '@/components/ui/button'
@@ -35,9 +35,8 @@ import type { User } from '@/types'
type Props = { user: User | null }
const rowMessages = (row: PostImportRow): string[] => [
...Object.values (row.validationErrors ?? { }).flat (),
...Object.values (row.importErrors ?? { }).flat ()]
const rowMessages = (row: PostImportRow): string[] =>
Object.values (row.importErrors ?? { }).flat ()
const PostImportResultPage: FC<Props> = ({ user }) => {
@@ -94,15 +93,22 @@ const PostImportResultPage: FC<Props> = ({ user }) => {
const validatedRows = mergeValidatedImportRows (
pendingRows,
initialisePreviewRows (validated.rows))
setSession (current =>
current
? { ...current, rows: validatedRows }
: current)
const nextSession = {
...session,
rows: validatedRows,
repairMode: 'failed' as const }
setSession (nextSession)
const target = validatedRows.find (_1 => _1.sourceRow === sourceRow)
if (target == null)
return
if (Object.keys (target.validationErrors ?? { }).length > 0)
return
{
const saved = savePostImportSession (sessionId, nextSession, message =>
toast ({ title: '取込状態を保存できませんでした', description: message }))
if (saved)
navigate (`/posts/import/${ sessionId }/review?edit=${ sourceRow }`)
return
}
const result = await apiPost<{
created: number
@@ -174,36 +180,37 @@ const PostImportResultPage: FC<Props> = ({ user }) => {
<div className="rounded-lg border bg-white p-4 dark:border-neutral-700
dark:bg-neutral-900">
<div className="flex flex-wrap gap-2">
<PostImportSummaryChip label="登録成功" value={counts.created} badge="created"/>
<PostImportSummaryChip label="登録成功" value={counts.created}/>
<PostImportSummaryChip label="スキップ" value={counts.skipped} badge="skipped"/>
<PostImportSummaryChip label="失敗" value={counts.failed} badge="failed"/>
<PostImportSummaryChip label="要修正" value={counts.invalid} badge="error"/>
<PostImportSummaryChip label="失敗" value={counts.failed}/>
</div>
</div>
<div className="space-y-3">
{session.rows.map (row => {
const displayStatus = effectivePostImportStatus (row)
const canEdit =
Object.keys (row.validationErrors).length > 0
|| row.importStatus === 'failed'
const displayStatus = displayPostImportStatus (row)
const canEdit = row.importStatus === 'failed'
const canRetry =
row.importStatus === 'created'
? false
: row.importStatus === 'failed'
row.importStatus === 'failed'
&& Object.keys (row.validationErrors).length === 0
const panelStatus =
row.importStatus === 'created'
? 'created'
: (row.importStatus === 'failed'
? 'failed'
: displayStatus ?? 'ready')
return (
<div
key={row.sourceRow}
className={[
'rounded-lg border p-4',
...importPanelToneClass (displayStatus)].join (' ')}>
...importPanelToneClass (panelStatus)].join (' ')}>
<div className="flex flex-col gap-3 md:flex-row md:items-start
md:justify-between">
<div className="space-y-2">
<div className="flex flex-wrap items-center gap-2">
<span className="text-sm font-medium"> {row.sourceRow}</span>
<PostImportStatusBadge value={displayStatus}/>
{displayStatus != null && <PostImportStatusBadge value={displayStatus}/>}
</div>
<div className="text-sm text-neutral-700 dark:text-neutral-200">
{String (row.attributes.title ?? '') || row.url}