This is an automated email from the ASF dual-hosted git repository.
bbovenzi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 21ca3ce024f UI: Implement navigation on bar click (#50416)
21ca3ce024f is described below
commit 21ca3ce024f27e200be0864644000b77a6374a7c
Author: LI,JHE-CHEN <[email protected]>
AuthorDate: Tue May 13 06:12:00 2025 +0800
UI: Implement navigation on bar click (#50416)
* UI: implement navigation on bar click
* use default tooltip
* fix: remove unnecessary type assertion and add TI overview
click-to-navigate function
* refactor: optimize hover handling in DurationChart
* nit:Use switch statement and extract common path
---
.../airflow/ui/src/components/DurationChart.tsx | 31 +++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
index 6a4e86ff1bd..a10af96f417 100644
--- a/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
+++ b/airflow-core/src/airflow/ui/src/components/DurationChart.tsx
@@ -31,6 +31,7 @@ import type { PartialEventContext } from
"chartjs-plugin-annotation";
import annotationPlugin from "chartjs-plugin-annotation";
import dayjs from "dayjs";
import { Bar } from "react-chartjs-2";
+import { useNavigate } from "react-router-dom";
import type { TaskInstanceResponse, DAGRunResponse } from
"openapi/requests/types.gen";
import { system } from "src/theme";
@@ -64,6 +65,8 @@ export const DurationChart = ({
readonly entries: Array<RunResponse> | undefined;
readonly kind: "Dag Run" | "Task Instance";
}) => {
+ const navigate = useNavigate();
+
if (!entries) {
return undefined;
}
@@ -141,6 +144,33 @@ export const DurationChart = ({
}}
datasetIdKey="id"
options={{
+ onClick: (_event, elements) => {
+ const [element] = elements;
+
+ if (!element) {
+ return;
+ }
+
+ const entry = entries[element.index];
+ const baseUrl = `/dags/${entry?.dag_id}/runs/${entry?.dag_run_id}`;
+
+ switch (kind) {
+ case "Dag Run": {
+ navigate(baseUrl);
+ break;
+ }
+ case "Task Instance": {
+ const taskInstance = entry as TaskInstanceResponse;
+
+ navigate(`${baseUrl}/tasks/${taskInstance.task_id}`);
+ break;
+ }
+ default:
+ }
+ },
+ onHover: (_event, elements, chart) => {
+ chart.canvas.style.cursor = elements.length > 0 ? "pointer" :
"default";
+ },
plugins: {
annotation: {
annotations: {
@@ -158,7 +188,6 @@ export const DurationChart = ({
},
title: { align: "end", display: true, text: "Run After" },
},
-
y: {
title: { align: "end", display: true, text: "Duration (seconds)"
},
},