このコミットが含まれているのは:
2026-07-16 18:33:45 +09:00
コミット ef95b20a7e
9個のファイルの変更145行の追加24行の削除
+7
ファイルの表示
@@ -92,6 +92,13 @@ const PostImportRowSummary: FC<Props> = ({ row, onEdit }) => {
<div className="flex flex-wrap gap-2">
{displayStatus != null && <PostImportStatusBadge value={displayStatus}/>}
</div>
<div className="text-xs text-neutral-500 dark:text-neutral-400">
{String (row.attributes.tags ?? '') || 'タグなし'}
</div>
<div className="text-xs text-neutral-500 dark:text-neutral-400">
{summaryDate (row)}
{row.attributes.duration ? ` / ${ row.attributes.duration }` : ''}
</div>
{warning && (
<div className="text-xs text-amber-700 dark:text-amber-200">
{warning}
+18
ファイルの表示
@@ -5,6 +5,8 @@ import { creatableImportRows,
mergeImportResults,
mergeValidatedImportRows,
processableImportRows,
resultRepairMode,
resultRowMessages,
resultSummaryCounts,
retryImportRow,
reviewSummaryCounts } from '@/lib/postImportSession'
@@ -131,6 +133,22 @@ describe ('post import row state', () => {
importErrors: undefined })
})
it ('deduplicates messages and keeps repair mode only for repairable rows', () => {
const repairable = buildPostImportRow ({
sourceRow: 1,
importStatus: 'pending',
validationErrors: { title: ['invalid'], base: ['duplicate'] },
importErrors: { base: ['duplicate'], url: ['network'] } })
const complete = buildPostImportRow ({
sourceRow: 2,
importStatus: 'created',
createdPostId: 2 })
expect (resultRowMessages (repairable)).toEqual (['invalid', 'duplicate', 'network'])
expect (resultRepairMode ([repairable, complete])).toBe ('failed')
expect (resultRepairMode ([complete])).toBe ('all')
})
it ('copies reset snapshot values instead of sharing mutable records', () => {
const row = buildPostImportRow ({ fieldWarnings: { title: ['warning'] } })
const initialised = initialisePreviewRows ([row])[0]
+17
ファイルの表示
@@ -7,6 +7,9 @@ const hasSkipReason = (row: PostImportRow): boolean =>
const hasValidationErrors = (row: PostImportRow): boolean =>
Object.keys (row.validationErrors ?? { }).length > 0
const isRepairableImportStatus = (row: PostImportRow): boolean =>
row.importStatus === 'failed' || row.importStatus === 'pending'
const buildResetSnapshot = (row: PostImportRow) => ({
url: row.url,
attributes: { ...row.attributes },
@@ -67,6 +70,20 @@ export const resultSummaryCounts = (rows: PostImportRow[]) =>
{ created: 0, skipped: 0, failed: 0 })
export const resultRepairMode = (
rows: PostImportRow[],
): 'all' | 'failed' =>
rows.some (row => hasValidationErrors (row) || isRepairableImportStatus (row))
? 'failed'
: 'all'
export const resultRowMessages = (row: PostImportRow): string[] =>
[...new Set ([
...Object.values (row.validationErrors ?? { }).flat (),
...Object.values (row.importErrors ?? { }).flat ()])]
export const mergeValidatedImportRows = (
current: PostImportRow[],
validated: PostImportRow[],
+10 -8
ファイルの表示
@@ -20,6 +20,8 @@ import { clearPostImportSourceDraft,
loadPostImportSession,
mergeImportResults,
mergeValidatedImportRows,
resultRepairMode,
resultRowMessages,
resultSummaryCounts,
retryImportRow,
savePostImportSession } from '@/lib/postImportSession'
@@ -34,9 +36,6 @@ import type { User } from '@/types'
type Props = { user: User | null }
const rowMessages = (row: PostImportRow): string[] =>
Object.values (row.importErrors ?? { }).flat ()
const buildNextEditedRow = (
editingRow: PostImportRow,
draft: PostImportRowDraft,
@@ -293,7 +292,7 @@ const PostImportResultPage: FC<Props> = ({ user }) => {
const resultSession = {
...nextSession,
rows: nextRows,
repairMode: recoverableTarget == null ? 'all' as const : 'failed' as const }
repairMode: resultRepairMode (nextRows) }
sessionRef.current = resultSession
setSession (resultSession)
if (recoverableTarget != null
@@ -367,10 +366,13 @@ const PostImportResultPage: FC<Props> = ({ user }) => {
<div className="space-y-3">
{session.rows.map (row => {
const displayStatus = displayPostImportStatus (row)
const canEdit = row.importStatus === 'failed'
const canRetry =
const hasValidationErrors = Object.keys (row.validationErrors).length > 0
const canEdit =
row.importStatus === 'failed'
&& Object.keys (row.validationErrors).length === 0
|| (row.importStatus === 'pending' && hasValidationErrors)
const canRetry =
(row.importStatus === 'failed' || row.importStatus === 'pending')
&& !(hasValidationErrors)
return (
<div
key={row.sourceRow}
@@ -388,7 +390,7 @@ const PostImportResultPage: FC<Props> = ({ user }) => {
<div className="text-xs text-neutral-500 dark:text-neutral-400">
{row.url}
</div>
<FieldError messages={rowMessages (row)}/>
<FieldError messages={resultRowMessages (row)}/>
</div>
<div className="flex flex-col gap-2 sm:flex-row">