fix: detail panel not opening after task selection

Open detail window synchronously to avoid popup blocking, persist selected task, and show API errors on the detail page.
This commit is contained in:
EENE Dashboard
2026-06-05 22:21:10 +09:00
parent 49fe4ca4a9
commit d53f82b044
2 changed files with 81 additions and 12 deletions

View File

@@ -1,7 +1,8 @@
import { useState, useEffect, useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiClient, getApiErrorMessage } from '../lib/apiClient';
import { onDualMonitorEvent } from '../lib/dualMonitor';
import { onDualMonitorEvent, getPersistedTaskId } from '../lib/dualMonitor';
import { ContextMenu } from '../components/common/ContextMenu';
import { FeedbackModal, type FeedbackFormData } from '../components/detail/FeedbackModal';
import { ResultPreview } from '../components/detail/ResultPreview';
@@ -701,7 +702,14 @@ function DetailView({ task }: { task: TaskWithRelations }) {
}
export default function DetailPage() {
const [taskId, setTaskId] = useState<string | null>(null);
const { taskId: routeTaskId } = useParams<{ taskId?: string }>();
const [taskId, setTaskId] = useState<string | null>(
() => routeTaskId ?? getPersistedTaskId(),
);
useEffect(() => {
if (routeTaskId) setTaskId(routeTaskId);
}, [routeTaskId]);
useEffect(() => {
const unsub = onDualMonitorEvent((evt) => {
@@ -711,7 +719,7 @@ export default function DetailPage() {
return unsub;
}, []);
const { data: task, isLoading } = useQuery({
const { data: task, isLoading, isError, error } = useQuery({
queryKey: ['task', taskId],
queryFn: async () => {
const { data } = await apiClient.get<TaskWithRelations>(`/tasks/${taskId}`);
@@ -719,6 +727,7 @@ export default function DetailPage() {
},
enabled: !!taskId,
staleTime: 10_000,
retry: 2,
});
return (
@@ -728,6 +737,11 @@ export default function DetailPage() {
<div className="flex min-h-0 flex-1 flex-col overflow-hidden">
{isLoading ? (
<div className="flex h-full items-center justify-center text-xl text-slate-400"> ...</div>
) : isError ? (
<div className="flex h-full flex-col items-center justify-center gap-3 text-center">
<p className="text-xl font-bold text-red-500"> .</p>
<p className="text-base text-slate-500">{getApiErrorMessage(error, '서버 연결을 확인해 주세요.')}</p>
</div>
) : !task ? (
<WaitingScreen />
) : (