This is an automated email from the ASF dual-hosted git repository.

kaxilnaik pushed a commit to branch v3-0-test
in repository https://gitbox.apache.org/repos/asf/airflow.git

commit 44bb1010372eaabb39a87a232d97531888b82f09
Author: Dominic Leung <[email protected]>
AuthorDate: Sat May 3 05:31:37 2025 +0800

    Added focus view on grid and graph on second click (#50125)
    
    (cherry picked from commit e28d460d9fbfe8fc9679ed4bcce5b84872925ec2)
---
 .../ui/src/layouts/Details/DetailsLayout.tsx       | 12 ++++++--
 .../ui/src/layouts/Details/PanelButtons.tsx        | 35 ++++++++++++++++++++--
 2 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx
index 69d32034fc4..bae001db6f3 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/DetailsLayout.tsx
@@ -18,6 +18,7 @@
  */
 import { Box, HStack, Flex, useDisclosure } from "@chakra-ui/react";
 import { useReactFlow } from "@xyflow/react";
+import { useRef } from "react";
 import type { PropsWithChildren, ReactNode } from "react";
 import { LuFileWarning } from "react-icons/lu";
 import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
@@ -53,6 +54,7 @@ export const DetailsLayout = ({ children, error, isLoading, 
tabs }: Props) => {
 
   const { data: dag } = useDagServiceGetDag({ dagId });
   const [defaultDagView] = useLocalStorage<"graph" | 
"grid">("default_dag_view", "grid");
+  const panelGroupRef = useRef(null);
   const [dagView, setDagView] = useLocalStorage<"graph" | 
"grid">(`dag_view-${dagId}`, defaultDagView);
   const [limit, setLimit] = useLocalStorage<number>(`dag_runs_limit-${dagId}`, 
10);
 
@@ -75,10 +77,16 @@ export const DetailsLayout = ({ children, error, isLoading, 
tabs }: Props) => {
       <Toaster />
       <BackfillBanner dagId={dagId} />
       <Box flex={1} minH={0}>
-        <PanelGroup autoSaveId={dagId} direction="horizontal">
+        <PanelGroup autoSaveId={dagId} direction="horizontal" 
ref={panelGroupRef}>
           <Panel defaultSize={dagView === "graph" ? 70 : 20} minSize={6}>
             <Box height="100%" overflowY="auto" position="relative" pr={2}>
-              <PanelButtons dagView={dagView} limit={limit} 
setDagView={setDagView} setLimit={setLimit} />
+              <PanelButtons
+                dagView={dagView}
+                limit={limit}
+                panelGroupRef={panelGroupRef}
+                setDagView={setDagView}
+                setLimit={setLimit}
+              />
               {dagView === "graph" ? <Graph /> : <Grid limit={limit} />}
             </Box>
           </Panel>
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/PanelButtons.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/PanelButtons.tsx
index 384eaa407c2..4d18f87d921 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/PanelButtons.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/PanelButtons.tsx
@@ -26,6 +26,7 @@ import {
   Portal,
   Select,
 } from "@chakra-ui/react";
+import { useReactFlow } from "@xyflow/react";
 import { FiChevronDown, FiGrid } from "react-icons/fi";
 import { MdOutlineAccountTree } from "react-icons/md";
 import { useParams } from "react-router-dom";
@@ -41,6 +42,7 @@ import { ToggleGroups } from "./ToggleGroups";
 type Props = {
   readonly dagView: string;
   readonly limit: number;
+  readonly panelGroupRef: React.RefObject<{ setLayout?: (layout: 
Array<number>) => void } & HTMLDivElement>;
   readonly setDagView: (x: "graph" | "grid") => void;
   readonly setLimit: React.Dispatch<React.SetStateAction<number>>;
 };
@@ -68,8 +70,9 @@ const deps = ["all", "immediate", "tasks"];
 
 type Dependency = (typeof deps)[number];
 
-export const PanelButtons = ({ dagView, limit, setDagView, setLimit }: Props) 
=> {
+export const PanelButtons = ({ dagView, limit, panelGroupRef, setDagView, 
setLimit }: Props) => {
   const { dagId = "" } = useParams();
+  const { fitView } = useReactFlow();
   const [dependencies, setDependencies, removeDependencies] = 
useLocalStorage<Dependency>(
     `dependencies-${dagId}`,
     "tasks",
@@ -97,13 +100,34 @@ export const PanelButtons = ({ dagView, limit, setDagView, 
setLimit }: Props) =>
     }
   };
 
+  const handleFocus = (view: string) => {
+    if (panelGroupRef.current) {
+      const panelGroup = panelGroupRef.current;
+
+      if (typeof panelGroup.setLayout === "function") {
+        const newLayout = view === "graph" ? [70, 30] : [30, 70];
+
+        panelGroup.setLayout(newLayout);
+        // Used setTimeout to ensure DOM has been updated
+        setTimeout(() => {
+          void fitView();
+        }, 1);
+      }
+    }
+  };
+
   return (
     <Flex justifyContent="space-between" position="absolute" top={1} 
width="100%" zIndex={1}>
       <ButtonGroup attached size="sm" variant="outline">
         <IconButton
           aria-label="Show Grid"
           colorPalette="blue"
-          onClick={() => setDagView("grid")}
+          onClick={() => {
+            setDagView("grid");
+            if (dagView === "grid") {
+              handleFocus("grid");
+            }
+          }}
           title="Show Grid"
           variant={dagView === "grid" ? "solid" : "outline"}
         >
@@ -112,7 +136,12 @@ export const PanelButtons = ({ dagView, limit, setDagView, 
setLimit }: Props) =>
         <IconButton
           aria-label="Show Graph"
           colorPalette="blue"
-          onClick={() => setDagView("graph")}
+          onClick={() => {
+            setDagView("graph");
+            if (dagView === "graph") {
+              handleFocus("graph");
+            }
+          }}
           title="Show Graph"
           variant={dagView === "graph" ? "solid" : "outline"}
         >

Reply via email to