このコミットが含まれているのは:
@@ -39,15 +39,12 @@ const PostImportSourcePage: FC<Props> = ({ user }) => {
|
||||
|
||||
const [source, setSource] = useState (draft.source)
|
||||
const [loading, setLoading] = useState (false)
|
||||
const [error, setError] = useState<string | null> (null)
|
||||
const [touched, setTouched] = useState (false)
|
||||
const [sourceIssues, setSourceIssues] = useState<ReturnType<typeof validateImportSource>> ([])
|
||||
const [sourceError, setSourceError] = useState<string | null> (null)
|
||||
const saveTimer = useRef<number | null> (null)
|
||||
|
||||
const lineCount = countImportSourceLines (source)
|
||||
const issues = useMemo (() => validateImportSource (source), [source])
|
||||
const messages = [
|
||||
...(((touched) && lineCount === 0) ? ['URL を入力してください.'] : []),
|
||||
...(error ? [error] : [])]
|
||||
const messages = sourceError ? [sourceError] : []
|
||||
|
||||
useEffect (() => {
|
||||
cleanupExpiredPostImportSessions (message =>
|
||||
@@ -68,12 +65,24 @@ const PostImportSourcePage: FC<Props> = ({ user }) => {
|
||||
}, [source])
|
||||
|
||||
const preview = async () => {
|
||||
setTouched (true)
|
||||
if (lineCount === 0 || issues.length > 0)
|
||||
return
|
||||
if (lineCount === 0)
|
||||
{
|
||||
setSourceIssues ([])
|
||||
setSourceError ('URL を入力してください.')
|
||||
return
|
||||
}
|
||||
|
||||
const issues = validateImportSource (source)
|
||||
if (issues.length > 0)
|
||||
{
|
||||
setSourceIssues (issues)
|
||||
setSourceError (null)
|
||||
return
|
||||
}
|
||||
|
||||
setLoading (true)
|
||||
setError (null)
|
||||
setSourceIssues ([])
|
||||
setSourceError (null)
|
||||
try
|
||||
{
|
||||
const data = await apiPost<{ rows: PostImportRow[] }> ('/posts/import/preview', {
|
||||
@@ -95,7 +104,7 @@ const PostImportSourcePage: FC<Props> = ({ user }) => {
|
||||
? requestError.response?.data?.message
|
||||
?? requestError.response?.data?.baseErrors?.[0]
|
||||
: undefined
|
||||
setError (message ?? '入力を確認してください.')
|
||||
setSourceError (message ?? '入力を確認してください.')
|
||||
toast ({
|
||||
title: '投稿情報の取得に失敗しました',
|
||||
description: message ?? '入力を確認してください.' })
|
||||
@@ -126,11 +135,10 @@ const PostImportSourcePage: FC<Props> = ({ user }) => {
|
||||
value={source}
|
||||
rows={14}
|
||||
className={inputClass (
|
||||
messages.length > 0 || issues.length > 0,
|
||||
messages.length > 0 || sourceIssues.length > 0,
|
||||
'font-mono text-sm',
|
||||
)}
|
||||
onBlur={() => {
|
||||
setTouched (true)
|
||||
savePostImportSourceDraft (source, message =>
|
||||
toast ({
|
||||
title: '入力内容を保存できませんでした',
|
||||
@@ -138,12 +146,13 @@ const PostImportSourcePage: FC<Props> = ({ user }) => {
|
||||
}}
|
||||
onChange={ev => {
|
||||
setSource (ev.target.value)
|
||||
setError (null)
|
||||
setSourceError (null)
|
||||
setSourceIssues ([])
|
||||
}}/>)}
|
||||
</FormField>
|
||||
<FieldError messages={messages}/>
|
||||
<div className="space-y-2">
|
||||
{issues.map (issue => (
|
||||
{sourceIssues.map (issue => (
|
||||
<div
|
||||
key={`${ issue.sourceRow }-${ issue.message }-${ issue.url }`}
|
||||
className="rounded-md border border-red-300 bg-red-50 p-3 text-sm
|
||||
@@ -163,8 +172,8 @@ const PostImportSourcePage: FC<Props> = ({ user }) => {
|
||||
<Button
|
||||
type="button"
|
||||
onClick={preview}
|
||||
disabled={loading || lineCount === 0 || issues.length > 0}>
|
||||
投稿情報を取得
|
||||
disabled={loading}>
|
||||
次へ
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
新しい課題から参照
ユーザをブロックする