From 86bdde404f121dbdd2b7065f905f55e6f73827e6 Mon Sep 17 00:00:00 2001 From: Olfa Maslah Date: Tue, 2 Jun 2026 15:28:18 -0400 Subject: [PATCH 1/4] active task dialog --- frontend/components/header.tsx | 20 +++++++- frontend/components/task-dialog/header.tsx | 8 ++- .../components/task-dialog/task-dialog.tsx | 50 +++++++++++-------- frontend/components/task-error-content.tsx | 14 ++---- .../components/task-notification-menu.tsx | 14 +++++- frontend/contexts/task-context.tsx | 38 +++++++++++++- 6 files changed, 108 insertions(+), 36 deletions(-) diff --git a/frontend/components/header.tsx b/frontend/components/header.tsx index b22db36d3..a2375a534 100644 --- a/frontend/components/header.tsx +++ b/frontend/components/header.tsx @@ -1,7 +1,9 @@ "use client"; import { Bell } from "lucide-react"; +import { useMemo } from "react"; import { BrandSwitcher } from "@/components/brand-switcher"; +import { IncidentReporterIcon } from "@/components/icons/incident-reporter-icon"; import Logo from "@/components/icons/openrag-logo"; import { UserNav } from "@/components/user-nav"; import { useIsCloudBrand } from "@/contexts/brand-context"; @@ -10,7 +12,7 @@ import { cn } from "@/lib/utils"; export function Header() { const isCloudBrand = useIsCloudBrand(); - const { tasks, toggleMenu } = useTask(); + const { tasks, toggleMenu, openTaskDialog } = useTask(); // Calculate active tasks for the bell icon const activeTasks = tasks.filter( @@ -19,6 +21,10 @@ export function Header() { task.status === "running" || task.status === "processing", ); + const primaryActiveTaskId = useMemo( + () => activeTasks[0]?.task_id ?? null, + [activeTasks], + ); return (
@@ -56,6 +62,18 @@ export function Header() { )} + {primaryActiveTaskId && ( + + )} + {/* Task Notification Bell */} {showRetryActions && selectedCount > 0 ? ( ) : null} + ); diff --git a/frontend/components/task-error-content.tsx b/frontend/components/task-error-content.tsx index c03d9fe44..96271c3f4 100644 --- a/frontend/components/task-error-content.tsx +++ b/frontend/components/task-error-content.tsx @@ -4,14 +4,13 @@ import * as AccordionPrimitive from "@radix-ui/react-accordion"; import { AlertCircle, ChevronDown, Flag, XCircle } from "lucide-react"; import { useMemo, useState } from "react"; import { IncidentReporterIcon } from "@/components/icons/incident-reporter-icon"; -import TaskDialog from "@/components/task-dialog"; import { Accordion, AccordionContent, AccordionItem, } from "@/components/ui/accordion"; import { useIsCloudBrand } from "@/contexts/brand-context"; -import { type Task } from "@/contexts/task-context"; +import { type Task, useTask } from "@/contexts/task-context"; import { formatApiComponent, resolveTaskFileError, @@ -43,10 +42,10 @@ export function TaskErrorContent({ defaultExpanded = false, }: TaskErrorContentProps) { const isCloudBrand = useIsCloudBrand(); + const { openTaskDialog } = useTask(); const [accordionValue, setAccordionValue] = useState( defaultExpanded ? "failed-files" : "", ); - const [isTaskDialogOpen, setIsTaskDialogOpen] = useState(false); const isExpanded = accordionValue === "failed-files"; const failedEntries = useMemo(() => getFailedFileEntries(task), [task]); @@ -90,7 +89,7 @@ export function TaskErrorContent({ type="button" aria-label="Open task details" className="inline-flex shrink-0 items-center justify-center text-muted-foreground hover:text-foreground" - onClick={() => setIsTaskDialogOpen(true)} + onClick={() => openTaskDialog(task.task_id)} > @@ -237,13 +236,6 @@ export function TaskErrorContent({ - - setIsTaskDialogOpen(false)} - /> ); } diff --git a/frontend/components/task-notification-menu.tsx b/frontend/components/task-notification-menu.tsx index f2a2ea4fc..9efa3378f 100644 --- a/frontend/components/task-notification-menu.tsx +++ b/frontend/components/task-notification-menu.tsx @@ -10,6 +10,7 @@ import { XCircle, } from "lucide-react"; import { useEffect, useMemo, useRef, useState } from "react"; +import { IncidentReporterIcon } from "@/components/icons/incident-reporter-icon"; import { TaskCollapsibleSection } from "@/components/task-collapsible-section"; import { TaskErrorContent } from "@/components/task-error-content"; import { TaskPanelHeader } from "@/components/task-panel-header"; @@ -43,6 +44,7 @@ export function TaskNotificationMenu() { selectedTaskTrigger, cancelTask, closeMenu, + openTaskDialog, } = useTask(); const [isPastOpen, setIsPastOpen] = useState(true); const lastHandledSelectionTriggerRef = useRef(0); @@ -361,8 +363,8 @@ export function TaskNotificationMenu() { className="bg-card/50 border-0 shadow-none py-mmd px-4" > -
- +
+ {showTaskIcon && getTaskIcon( task.status, @@ -371,6 +373,14 @@ export function TaskNotificationMenu() { )} Task {task.task_id.substring(0, 8)}... +
Started {formatRelativeTime(task.created_at)} diff --git a/frontend/contexts/task-context.tsx b/frontend/contexts/task-context.tsx index ba904933a..bd7784be2 100644 --- a/frontend/contexts/task-context.tsx +++ b/frontend/contexts/task-context.tsx @@ -20,6 +20,7 @@ import { useGetTasksQuery, } from "@/app/api/queries/useGetTasksQuery"; import type { ListFilesResponse } from "@/app/api/queries/useListFiles"; +import TaskDialog from "@/components/task-dialog"; import { useAuth } from "@/contexts/auth-context"; import { useOnboardingState } from "@/hooks/use-onboarding-state"; import { trackProcessFailure, trackProcessSuccess } from "@/lib/analytics"; @@ -74,6 +75,10 @@ interface TaskContextType { setSelectedTaskId: (taskId: string | null) => void; selectedTaskTrigger: number; selectTask: (taskId: string | null) => void; + isTaskDialogOpen: boolean; + taskDialogTaskId: string | null; + openTaskDialog: (taskId: string) => void; + closeTaskDialog: () => void; // React Query states isLoading: boolean; error: Error | null; @@ -87,7 +92,17 @@ export function TaskProvider({ children }: { children: React.ReactNode }) { const [isRecentTasksExpanded, setIsRecentTasksExpanded] = useState(false); const [selectedTaskId, setSelectedTaskId] = useState(null); const [selectedTaskTrigger, setSelectedTaskTrigger] = useState(0); + const [taskDialogTaskId, setTaskDialogTaskId] = useState(null); + const [isTaskDialogOpen, setIsTaskDialogOpen] = useState(false); const previousTasksRef = useRef([]); + const openTaskDialog = useCallback((taskId: string) => { + setTaskDialogTaskId(taskId); + setIsTaskDialogOpen(true); + }, []); + const closeTaskDialog = useCallback(() => { + setIsTaskDialogOpen(false); + setTaskDialogTaskId(null); + }, []); const selectTask = useCallback((taskId: string | null) => { setSelectedTaskId(taskId); if (taskId) { @@ -636,11 +651,32 @@ export function TaskProvider({ children }: { children: React.ReactNode }) { setSelectedTaskId, selectedTaskTrigger, selectTask, + isTaskDialogOpen, + taskDialogTaskId, + openTaskDialog, + closeTaskDialog, isLoading, error, }; - return {children}; + return ( + + {children} + {taskDialogTaskId ? ( + { + setIsTaskDialogOpen(open); + if (!open) { + setTaskDialogTaskId(null); + } + }} + task_id={taskDialogTaskId} + onClose={closeTaskDialog} + /> + ) : null} + + ); } export function useTask() { From a2b050c355a7b512fe883bbb2ab51254367d05c9 Mon Sep 17 00:00:00 2001 From: Olfa Maslah Date: Tue, 2 Jun 2026 15:39:26 -0400 Subject: [PATCH 2/4] remove condition for the incident report icon --- frontend/components/header.tsx | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/frontend/components/header.tsx b/frontend/components/header.tsx index a2375a534..51458ab4d 100644 --- a/frontend/components/header.tsx +++ b/frontend/components/header.tsx @@ -1,7 +1,6 @@ "use client"; import { Bell } from "lucide-react"; -import { useMemo } from "react"; import { BrandSwitcher } from "@/components/brand-switcher"; import { IncidentReporterIcon } from "@/components/icons/incident-reporter-icon"; import Logo from "@/components/icons/openrag-logo"; @@ -21,10 +20,7 @@ export function Header() { task.status === "running" || task.status === "processing", ); - const primaryActiveTaskId = useMemo( - () => activeTasks[0]?.task_id ?? null, - [activeTasks], - ); + const primaryActiveTaskId = activeTasks[0]?.task_id; return (
@@ -62,17 +58,20 @@ export function Header() { )} - {primaryActiveTaskId && ( - - )} + {/* Task Notification Bell */}
From fea94f9c2f54fcc8ea05736d4124fea95f1b0500 Mon Sep 17 00:00:00 2001 From: Olfa Maslah Date: Tue, 2 Jun 2026 22:50:48 -0400 Subject: [PATCH 4/4] remove incidentreport from the header --- frontend/components/header.tsx | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/frontend/components/header.tsx b/frontend/components/header.tsx index 51458ab4d..b22db36d3 100644 --- a/frontend/components/header.tsx +++ b/frontend/components/header.tsx @@ -2,7 +2,6 @@ import { Bell } from "lucide-react"; import { BrandSwitcher } from "@/components/brand-switcher"; -import { IncidentReporterIcon } from "@/components/icons/incident-reporter-icon"; import Logo from "@/components/icons/openrag-logo"; import { UserNav } from "@/components/user-nav"; import { useIsCloudBrand } from "@/contexts/brand-context"; @@ -11,7 +10,7 @@ import { cn } from "@/lib/utils"; export function Header() { const isCloudBrand = useIsCloudBrand(); - const { tasks, toggleMenu, openTaskDialog } = useTask(); + const { tasks, toggleMenu } = useTask(); // Calculate active tasks for the bell icon const activeTasks = tasks.filter( @@ -20,7 +19,6 @@ export function Header() { task.status === "running" || task.status === "processing", ); - const primaryActiveTaskId = activeTasks[0]?.task_id; return (
@@ -58,21 +56,6 @@ export function Header() { )} - - {/* Task Notification Bell */}