広場投稿追加画面の刷新 (#399) #413
@@ -128,7 +128,6 @@ class PostsController < ApplicationController
|
||||
provenance: { },
|
||||
tag_sources: { } }],
|
||||
fetch_metadata: true).first
|
||||
return render_validation_error fields: preview[:validation_errors] if preview[:validation_errors].present?
|
||||
|
||||
render json: {
|
||||
url: preview[:url],
|
||||
@@ -141,6 +140,7 @@ class PostsController < ApplicationController
|
||||
video_ms: preview[:attributes]['video_ms'],
|
||||
field_warnings: preview[:field_warnings],
|
||||
base_warnings: preview[:base_warnings],
|
||||
validation_errors: preview[:validation_errors],
|
||||
existing_post: compact_post(preview[:existing_post_id]) }
|
||||
rescue ArgumentError => e
|
||||
render_bad_request e.message
|
||||
|
||||
@@ -74,6 +74,7 @@ type PreviewResponse = {
|
||||
tags?: string
|
||||
fieldWarnings?: Record<string, string[]>
|
||||
baseWarnings?: string[]
|
||||
validationErrors?: Record<string, string[]>
|
||||
existingPost?: {
|
||||
id: number
|
||||
title: string
|
||||
@@ -249,7 +250,13 @@ const mergePreviewRow = (
|
||||
): PostImportRow => {
|
||||
const fieldWarnings = preview.fieldWarnings ?? { }
|
||||
const baseWarnings = preview.baseWarnings ?? []
|
||||
const validationErrors = preview.validationErrors ?? { }
|
||||
const metadataChanged = currentRow.metadataUrl !== preview.url
|
||||
const hasWarnings =
|
||||
Object.values (fieldWarnings).some (messages => messages.length > 0)
|
||||
|| baseWarnings.length > 0
|
||||
const hasErrors =
|
||||
Object.values (validationErrors).some (messages => messages.length > 0)
|
||||
const nextRow: PostImportRow = {
|
||||
...currentRow,
|
||||
attributes: { ...currentRow.attributes },
|
||||
@@ -260,6 +267,7 @@ const mergePreviewRow = (
|
||||
url: preview.url,
|
||||
fieldWarnings,
|
||||
baseWarnings,
|
||||
validationErrors,
|
||||
existingPostId: preview.existingPost?.id,
|
||||
existingPost: preview.existingPost ?? undefined,
|
||||
skipReason:
|
||||
@@ -274,10 +282,11 @@ const mergePreviewRow = (
|
||||
? buildPreviewResetSnapshot (preview)
|
||||
: currentRow.resetSnapshot,
|
||||
status:
|
||||
Object.keys (fieldWarnings).length > 0
|
||||
|| baseWarnings.length > 0
|
||||
? 'warning'
|
||||
: 'ready' }
|
||||
hasErrors
|
||||
? 'error'
|
||||
: hasWarnings
|
||||
? 'warning'
|
||||
: 'ready' }
|
||||
|
||||
if (currentRow.provenance.title !== 'manual')
|
||||
nextRow.attributes.title = preview.title ?? ''
|
||||
|
||||
@@ -48,6 +48,7 @@ type PreviewResponse = {
|
||||
tags?: string
|
||||
fieldWarnings?: Record<string, string[]>
|
||||
baseWarnings?: string[]
|
||||
validationErrors?: Record<string, string[]>
|
||||
existingPost?: {
|
||||
id: number
|
||||
title: string
|
||||
@@ -75,6 +76,12 @@ const previewRowFromResult = (
|
||||
): PostImportRow => {
|
||||
const fieldWarnings = result.fieldWarnings ?? { }
|
||||
const baseWarnings = result.baseWarnings ?? []
|
||||
const validationErrors = result.validationErrors ?? { }
|
||||
const hasWarnings =
|
||||
Object.values (fieldWarnings).some (messages => messages.length > 0)
|
||||
|| baseWarnings.length > 0
|
||||
const hasErrors =
|
||||
Object.values (validationErrors).some (messages => messages.length > 0)
|
||||
const row: PostImportRow = {
|
||||
sourceRow,
|
||||
url: result.url,
|
||||
@@ -89,7 +96,7 @@ const previewRowFromResult = (
|
||||
parentPostIds: '' },
|
||||
fieldWarnings,
|
||||
baseWarnings,
|
||||
validationErrors: { },
|
||||
validationErrors,
|
||||
provenance: {
|
||||
url: 'manual',
|
||||
title: 'automatic',
|
||||
@@ -104,9 +111,11 @@ const previewRowFromResult = (
|
||||
automatic: result.tags ?? '',
|
||||
manual: '' },
|
||||
status:
|
||||
Object.keys (fieldWarnings).length > 0 || baseWarnings.length > 0
|
||||
? 'warning'
|
||||
: 'ready',
|
||||
hasErrors
|
||||
? 'error'
|
||||
: hasWarnings
|
||||
? 'warning'
|
||||
: 'ready',
|
||||
skipReason: result.existingPost?.id != null ? 'existing' : undefined,
|
||||
existingPostId: result.existingPost?.id,
|
||||
existingPost: result.existingPost ?? undefined,
|
||||
@@ -155,6 +164,36 @@ const fetchPreviewRows = async (
|
||||
message: string
|
||||
url: string }> = []
|
||||
let nextIndex = 0
|
||||
|
||||
const previewIssues = (
|
||||
sourceRow: number,
|
||||
url: string,
|
||||
requestError: unknown,
|
||||
): Array<{ sourceRow: number
|
||||
message: string
|
||||
url: string }> => {
|
||||
if (!(isApiError<{
|
||||
message?: string
|
||||
errors?: Record<string, string[]>
|
||||
baseErrors?: string[]
|
||||
}> (requestError)))
|
||||
{
|
||||
return [{
|
||||
sourceRow,
|
||||
message: '入力を確認してください.',
|
||||
url }]
|
||||
}
|
||||
|
||||
const fieldMessages = Object.values (requestError.response?.data?.errors ?? { }).flat ()
|
||||
const baseMessages = requestError.response?.data?.baseErrors ?? []
|
||||
const messages = [...new Set ([...fieldMessages, ...baseMessages])]
|
||||
return (messages.length > 0 ? messages : [requestError.response?.data?.message ?? '入力を確認してください.'])
|
||||
.map (message => ({
|
||||
sourceRow,
|
||||
message,
|
||||
url }))
|
||||
}
|
||||
|
||||
const worker = async () => {
|
||||
while (nextIndex < rows.length)
|
||||
{
|
||||
@@ -172,21 +211,7 @@ const fetchPreviewRows = async (
|
||||
{
|
||||
if (signal.aborted)
|
||||
return
|
||||
|
||||
const apiMessage =
|
||||
isApiError<{
|
||||
message?: string
|
||||
errors?: Record<string, string[]>
|
||||
baseErrors?: string[]
|
||||
}> (requestError)
|
||||
? (requestError.response?.data?.errors?.url?.[0]
|
||||
?? requestError.response?.data?.message
|
||||
?? requestError.response?.data?.baseErrors?.[0])
|
||||
: undefined
|
||||
issues.push ({
|
||||
sourceRow: row.sourceRow,
|
||||
message: apiMessage ?? '入力を確認してください.',
|
||||
url: row.url })
|
||||
issues.push (...previewIssues (row.sourceRow, row.url, requestError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
新しい課題から参照
ユーザをブロックする