From 964286176c0b728167daef8e4370bc8ced80fd23 Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Wed, 16 Jul 2025 19:43:07 -0400 Subject: [PATCH 1/2] Add custom tooltip back to grid view --- .../ui/src/layouts/Details/Grid/GridTI.tsx | 99 ++++++++++++++++--- .../Details/Grid/TaskInstancesColumn.tsx | 2 +- 2 files changed, 84 insertions(+), 17 deletions(-) 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 9e25de4c29efe..44ba926701c6b 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 @@ -16,22 +16,24 @@ * specific language governing permissions and limitations * under the License. */ -import { Badge, Flex } from "@chakra-ui/react"; +import { Badge, chakra, Flex } from "@chakra-ui/react"; import type { MouseEvent } from "react"; -import React from "react"; +import React, { useRef } from "react"; +import { useTranslation } from "react-i18next"; import { Link, useParams } from "react-router-dom"; -import type { TaskInstanceState } from "openapi/requests/types.gen"; +import type { LightGridTaskInstanceSummary } from "openapi/requests/types.gen"; import { StateIcon } from "src/components/StateIcon"; +import Time from "src/components/Time"; type Props = { readonly dagId: string; + readonly instance: LightGridTaskInstanceSummary; readonly isGroup?: boolean; readonly isMapped?: boolean | null; readonly label: string; readonly runId: string; readonly search: string; - readonly state?: TaskInstanceState | null; readonly taskId: string; }; @@ -51,8 +53,44 @@ const onMouseLeave = (event: MouseEvent) => { }); }; -const Instance = ({ dagId, isGroup, isMapped, runId, search, state, taskId }: Props) => { +const Instance = ({ dagId, instance, isGroup, isMapped, runId, search, taskId }: Props) => { const { groupId: selectedGroupId, taskId: selectedTaskId } = useParams(); + const { t: translate } = useTranslation(); + const debounceTimeoutRef = useRef(undefined); + const tooltipRef = useRef(undefined); + + const onBadgeMouseEnter = (event: MouseEvent) => { + // Clear any existing timeout + if (debounceTimeoutRef.current) { + clearTimeout(debounceTimeoutRef.current); + } + + // Store reference to the tooltip element + const tooltip = event.currentTarget.querySelector("#tooltip") as HTMLElement; + + tooltipRef.current = tooltip; + + // Set a new timeout to show the tooltip after 200ms + debounceTimeoutRef.current = setTimeout(() => { + if (tooltipRef.current) { + tooltipRef.current.style.visibility = "visible"; + } + }, 200); + }; + + const onBadgeMouseLeave = () => { + // Clear any existing timeout + if (debounceTimeoutRef.current) { + clearTimeout(debounceTimeoutRef.current); + debounceTimeoutRef.current = undefined; + } + + // Hide the tooltip immediately + if (tooltipRef.current) { + tooltipRef.current.style.visibility = "hidden"; + tooltipRef.current = undefined; + } + }; return ( - {state === undefined ? undefined : ( - - )} + + + {translate("taskId")}: {taskId} +
+ {translate("state")}: {instance.state} + {instance.min_start_date !== null && ( + <> +
+ {translate("startDate")}:
diff --git a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskInstancesColumn.tsx b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskInstancesColumn.tsx index ad864fe1f2acd..e4efa0128c1ac 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskInstancesColumn.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Details/Grid/TaskInstancesColumn.tsx @@ -47,13 +47,13 @@ export const TaskInstancesColumn = ({ nodes, runId, taskInstances }: Props) => { return ( ); From 8117cd794894f1a2cac00711632c471d3f0bb477 Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Wed, 16 Jul 2025 19:44:50 -0400 Subject: [PATCH 2/2] Remove opacity --- airflow-core/src/airflow/ui/src/layouts/Details/Grid/GridTI.tsx | 1 - 1 file changed, 1 deletion(-) 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 44ba926701c6b..0fabe1cf89a90 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 @@ -121,7 +121,6 @@ const Instance = ({ dagId, instance, isGroup, isMapped, runId, search, taskId }: minH={0} onMouseEnter={onBadgeMouseEnter} onMouseLeave={onBadgeMouseLeave} - opacity={instance.state === "success" ? 0.6 : 1} p={0} position="relative" variant="solid"