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 d5812660b1e34e9d67dfec97822f1d9ba853564d
Author: Brent Bovenzi <[email protected]>
AuthorDate: Thu May 1 11:32:21 2025 -0400

    Restore hover+selection crosshairs to grid view (#50050)
    
    (cherry picked from commit 359447665af41b43913f8cf7a22d9b9b353a7cf9)
---
 .../airflow/ui/src/layouts/Details/Grid/Grid.tsx   |   2 +-
 .../airflow/ui/src/layouts/Details/Grid/GridTI.tsx | 105 +++++++++++----------
 .../ui/src/layouts/Details/Grid/TaskNames.tsx      |  22 ++++-
 3 files changed, 76 insertions(+), 53 deletions(-)

diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/Grid.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/Grid.tsx
index ba4ecad0b01..75fe7209dc8 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/Grid.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/Grid.tsx
@@ -72,7 +72,7 @@ export const Grid = ({ limit }: Props) => {
 
   return (
     <Flex justifyContent="flex-start" position="relative" pt={50} width="100%">
-      <Box flexGrow={1} minWidth={7} mr={3} position="relative" top="100px">
+      <Box flexGrow={1} minWidth={7} position="relative" top="100px">
         <TaskNames nodes={flatNodes} />
       </Box>
       <Box position="relative">
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
index 85a8342d8ac..08a17ea9e75 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx
@@ -19,7 +19,7 @@
 import { Badge, Flex } from "@chakra-ui/react";
 import type { MouseEvent } from "react";
 import React from "react";
-import { Link } from "react-router-dom";
+import { Link, useParams } from "react-router-dom";
 
 import type { TaskInstanceState } from "openapi/requests/types.gen";
 import { StateIcon } from "src/components/StateIcon";
@@ -36,7 +36,7 @@ type Props = {
 };
 
 const onMouseEnter = (event: MouseEvent<HTMLDivElement>) => {
-  const tasks = 
document.querySelectorAll<HTMLDivElement>(`#name-${event.currentTarget.id}`);
+  const tasks = 
document.querySelectorAll<HTMLDivElement>(`#${event.currentTarget.id}`);
 
   tasks.forEach((task) => {
     task.style.backgroundColor = "var(--chakra-colors-blue-subtle)";
@@ -44,56 +44,32 @@ const onMouseEnter = (event: MouseEvent<HTMLDivElement>) => 
{
 };
 
 const onMouseLeave = (event: MouseEvent<HTMLDivElement>) => {
-  const tasks = 
document.querySelectorAll<HTMLDivElement>(`#name-${event.currentTarget.id}`);
+  const tasks = 
document.querySelectorAll<HTMLDivElement>(`#${event.currentTarget.id}`);
 
   tasks.forEach((task) => {
     task.style.backgroundColor = "";
   });
 };
 
-const Instance = ({ dagId, isGroup, isMapped, runId, search, state, taskId }: 
Props) => (
-  <Flex
-    alignItems="center"
-    height="20px"
-    id={taskId.replaceAll(".", "-")}
-    justifyContent="center"
-    key={taskId}
-    onMouseEnter={onMouseEnter}
-    onMouseLeave={onMouseLeave}
-    px="2px"
-    py={0}
-    transition="background-color 0.2s"
-    zIndex={1}
-  >
-    {isGroup ? (
-      <Badge
-        borderRadius={4}
-        colorPalette={state === null ? "none" : state}
-        height="14px"
-        minH={0}
-        opacity={state === "success" ? 0.6 : 1}
-        p={0}
-        variant="solid"
-        width="14px"
-      >
-        {state === undefined ? undefined : (
-          <StateIcon
-            size={10}
-            state={state}
-            style={{
-              marginLeft: "2px",
-            }}
-          />
-        )}
-      </Badge>
-    ) : (
-      <Link
-        replace
-        to={{
-          pathname: `/dags/${dagId}/runs/${runId}/tasks/${taskId}${isMapped ? 
"/mapped" : ""}`,
-          search,
-        }}
-      >
+const Instance = ({ dagId, isGroup, isMapped, runId, search, state, taskId }: 
Props) => {
+  const { taskId: selectedTaskId } = useParams();
+
+  return (
+    <Flex
+      alignItems="center"
+      bg={selectedTaskId === taskId ? "blue.muted" : undefined}
+      height="20px"
+      id={taskId.replaceAll(".", "-")}
+      justifyContent="center"
+      key={taskId}
+      onMouseEnter={onMouseEnter}
+      onMouseLeave={onMouseLeave}
+      px="2px"
+      py={0}
+      transition="background-color 0.2s"
+      zIndex={1}
+    >
+      {isGroup ? (
         <Badge
           borderRadius={4}
           colorPalette={state === null ? "none" : state}
@@ -114,9 +90,38 @@ const Instance = ({ dagId, isGroup, isMapped, runId, 
search, state, taskId }: Pr
             />
           )}
         </Badge>
-      </Link>
-    )}
-  </Flex>
-);
+      ) : (
+        <Link
+          replace
+          to={{
+            pathname: `/dags/${dagId}/runs/${runId}/tasks/${taskId}${isMapped 
? "/mapped" : ""}`,
+            search,
+          }}
+        >
+          <Badge
+            borderRadius={4}
+            colorPalette={state === null ? "none" : state}
+            height="14px"
+            minH={0}
+            opacity={state === "success" ? 0.6 : 1}
+            p={0}
+            variant="solid"
+            width="14px"
+          >
+            {state === undefined ? undefined : (
+              <StateIcon
+                size={10}
+                state={state}
+                style={{
+                  marginLeft: "2px",
+                }}
+              />
+            )}
+          </Badge>
+        </Link>
+      )}
+    </Flex>
+  );
+};
 
 export const GridTI = React.memo(Instance);
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskNames.tsx 
b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskNames.tsx
index 4fe7420c8a9..60105579223 100644
--- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskNames.tsx
+++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskNames.tsx
@@ -17,6 +17,7 @@
  * under the License.
  */
 import { Box, chakra, Flex, Link } from "@chakra-ui/react";
+import type { MouseEvent } from "react";
 import { FiChevronUp } from "react-icons/fi";
 import { Link as RouterLink, useParams, useSearchParams } from 
"react-router-dom";
 
@@ -30,6 +31,22 @@ type Props = {
   nodes: Array<GridTask>;
 };
 
+const onMouseEnter = (event: MouseEvent<HTMLDivElement>) => {
+  const tasks = 
document.querySelectorAll<HTMLDivElement>(`#${event.currentTarget.id}`);
+
+  tasks.forEach((task) => {
+    task.style.backgroundColor = "var(--chakra-colors-blue-subtle)";
+  });
+};
+
+const onMouseLeave = (event: MouseEvent<HTMLDivElement>) => {
+  const tasks = 
document.querySelectorAll<HTMLDivElement>(`#${event.currentTarget.id}`);
+
+  tasks.forEach((task) => {
+    task.style.backgroundColor = "";
+  });
+};
+
 export const TaskNames = ({ nodes }: Props) => {
   const { toggleGroupId } = useOpenGroups();
   const { dagId = "", taskId } = useParams();
@@ -37,13 +54,14 @@ export const TaskNames = ({ nodes }: Props) => {
 
   return nodes.map((node) => (
     <Box
-      _hover={{ bg: "blue.subtle" }}
       bg={node.id === taskId ? "blue.muted" : undefined}
       borderBottomWidth={1}
       borderColor={node.isGroup ? "border.emphasized" : "border.muted"}
-      id={`name-${node.id.replaceAll(".", "-")}`}
+      id={node.id.replaceAll(".", "-")}
       key={node.id}
       maxHeight="20px"
+      onMouseEnter={onMouseEnter}
+      onMouseLeave={onMouseLeave}
       transition="background-color 0.2s"
     >
       {node.isGroup ? (

Reply via email to