Fix reconnection issues (#624)

* continue showing tasks but display warning if disconnected

* don't kill connection if stream fails

* styles on project error
This commit is contained in:
Louis Knight-Webb
2025-09-04 13:55:44 +01:00
committed by GitHub
parent 2e4eb6d403
commit 6c9d098216
3 changed files with 23 additions and 6 deletions

View File

@@ -4,7 +4,7 @@ import { cva, type VariantProps } from 'class-variance-authority';
import { cn } from '@/lib/utils';
const alertVariants = cva(
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
'relative w-full border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
{
variants: {
variant: {

View File

@@ -100,7 +100,6 @@ export const useJsonPatchStream = <T>(
eventSource.onerror = () => {
setError('Connection failed');
eventSource.close();
eventSourceRef.current = null;
setIsConnected(false);
};

View File

@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState, useMemo } from 'react';
import { useNavigate, useParams, useLocation } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Plus } from 'lucide-react';
import { AlertTriangle, Plus } from 'lucide-react';
import { Loader } from '@/components/ui/loader';
import { projectsApi, tasksApi, attemptsApi } from '@/lib/api';
import { useTaskDialog } from '@/contexts/task-dialog-context';
@@ -31,6 +31,7 @@ import DeleteTaskConfirmationDialog from '@/components/tasks/DeleteTaskConfirmat
import type { TaskWithAttemptStatus, Project, TaskAttempt } from 'shared/types';
import type { DragEndEvent } from '@/components/ui/shadcn-io/kanban';
import { useProjectTasks } from '@/hooks/useProjectTasks';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
type Task = TaskWithAttemptStatus;
@@ -234,10 +235,16 @@ export function ProjectTasks() {
return <Loader message="Loading tasks..." size={32} className="py-8" />;
}
if (error || streamError) {
if (error) {
return (
<div className="text-center py-8 text-destructive">
{error || streamError}
<div className="p-4">
<Alert>
<AlertTitle className="flex items-center gap-2">
<AlertTriangle size="16" />
Error
</AlertTitle>
<AlertDescription>{error}</AlertDescription>
</Alert>
</div>
);
}
@@ -246,6 +253,17 @@ export function ProjectTasks() {
<div
className={`min-h-full ${getMainContainerClasses(isPanelOpen, isFullscreen)}`}
>
{streamError && (
<div>
<Alert>
<AlertTitle className="flex items-center gap-2">
<AlertTriangle size="16" />
Reconnecting
</AlertTitle>
<AlertDescription>{streamError}</AlertDescription>
</Alert>
</div>
)}
{/* Left Column - Kanban Section */}
<div className={getKanbanSectionClasses(isPanelOpen, isFullscreen)}>
{tasks.length === 0 ? (