Răsfoiți Sursa

fix(dashboard): keep job queue dropdown open during auto refresh (#4059)

Co-authored-by: Michael Bromley <michael@michaelbromley.co.uk>
starry-osean 4 săptămâni în urmă
părinte
comite
6eb2d52ce1

+ 9 - 2
packages/dashboard/src/app/routes/_authenticated/_system/components/payload-dialog.tsx

@@ -14,11 +14,18 @@ type PayloadDialogProps = {
     trigger: React.ReactNode;
     title?: string | React.ReactNode;
     description?: string | React.ReactNode;
+    onOpenChange?: (open: boolean) => void;
 };
 
-export function PayloadDialog({ payload, trigger, title, description }: Readonly<PayloadDialogProps>) {
+export function PayloadDialog({
+    payload,
+    trigger,
+    title,
+    description,
+    onOpenChange,
+}: Readonly<PayloadDialogProps>) {
     return (
-        <Dialog>
+        <Dialog onOpenChange={open => onOpenChange?.(open)}>
             <DialogTrigger asChild>{trigger}</DialogTrigger>
             <DialogContent>
                 <DialogHeader>

+ 11 - 2
packages/dashboard/src/app/routes/_authenticated/_system/job-queue.tsx

@@ -78,12 +78,17 @@ function JobQueuePage() {
     const refreshRef = useRef<() => void>(() => {});
     const { t } = useLingui();
     const [refreshInterval, setRefreshInterval] = useState(10000);
+    const isActionMenuOpenRef = useRef(false);
 
     useEffect(() => {
         if (refreshInterval === 0) return;
 
         const interval = setInterval(() => {
-            refreshRef.current();
+            // Pause auto-refresh while the row action dropdown is open
+            // to avoid closing it mid-interaction
+            if (!isActionMenuOpenRef.current) {
+                refreshRef.current();
+            }
         }, refreshInterval);
 
         return () => clearInterval(interval);
@@ -111,6 +116,7 @@ function JobQueuePage() {
                         <PayloadDialog
                             payload={row.original.data}
                             title={<Trans>View job data</Trans>}
+                            onOpenChange={open => (isActionMenuOpenRef.current = open)}
                             description={<Trans>The data that has been passed to the job</Trans>}
                             trigger={
                                 <Button size="sm" variant="secondary">
@@ -129,6 +135,7 @@ function JobQueuePage() {
                             <PayloadDialog
                                 payload={row.original.result}
                                 title={<Trans>View job result</Trans>}
+                                onOpenChange={open => (isActionMenuOpenRef.current = open)}
                                 description={<Trans>The result of the job</Trans>}
                                 trigger={
                                     <Button size="sm" variant="secondary">
@@ -168,7 +175,9 @@ function JobQueuePage() {
                                 {row.original.state}
                                 {row.original.state === 'RUNNING' ? (
                                     <div className="flex items-center gap-2">
-                                        <DropdownMenu>
+                                        <DropdownMenu
+                                            onOpenChange={open => (isActionMenuOpenRef.current = open)}
+                                        >
                                             <DropdownMenuTrigger asChild>
                                                 <Button variant="ghost" size="sm" className="h-6 w-6 p-0">
                                                     <MoreVertical className="h-4 w-4" />