Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const toTooltipSummary = (

return {
child_states: null,
max_end_date: dayjs(segment.x[1]).toISOString(),
max_end_date: segment.end_when ?? dayjs(segment.x[1]).toISOString(),
min_start_date: segment.start_when ?? dayjs(segment.x[0]).toISOString(),
state: segment.state ?? null,
task_display_name: segment.y,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/
import dayjs from "dayjs";
import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";

import type { LightGridTaskInstanceSummary } from "openapi/requests/types.gen";
import type { GridTask } from "src/layouts/Details/Grid/utils";
Expand Down Expand Up @@ -237,6 +237,70 @@ describe("transformGanttData", () => {
expect(result[2]?.state).toBe("success");
});

it("carries the task's actual start and end on every segment of the try", () => {
const result = transformGanttData({
allTries: [
{
end_date: "2024-03-14T10:05:00+00:00",
is_mapped: false,
queued_dttm: "2024-03-14T09:59:00+00:00",
scheduled_dttm: "2024-03-14T09:58:00+00:00",
start_date: "2024-03-14T10:00:00+00:00",
state: "success",
task_display_name: "task_1",
task_id: "task_1",
try_number: 1,
},
],
flatNodes: [{ depth: 0, id: "task_1", is_mapped: false, label: "task_1" }],
gridSummaries: [],
});

expect(result).toHaveLength(3);
// The scheduled, queued, and execution bars all report the task's real start_date/end_date
// (the raw API strings) so the tooltip is consistent no matter which segment is hovered
// (regression from #68174).
for (const segment of result) {
expect(segment.start_when).toBe("2024-03-14T10:00:00+00:00");
expect(segment.end_when).toBe("2024-03-14T10:05:00+00:00");
}
});

it("uses the current time as end_when on every segment while the task is still running", () => {
const now = new Date("2024-03-14T10:30:00.000Z");

vi.useFakeTimers();
vi.setSystemTime(now);

try {
const result = transformGanttData({
allTries: [
{
end_date: null,
is_mapped: false,
queued_dttm: "2024-03-14T09:59:00+00:00",
scheduled_dttm: null,
start_date: "2024-03-14T10:00:00+00:00",
state: "running",
task_display_name: "task_1",
task_id: "task_1",
try_number: 1,
},
],
flatNodes: [{ depth: 0, id: "task_1", is_mapped: false, label: "task_1" }],
gridSummaries: [],
});

// Queued + execution bars, both reporting the same "now" end so the tooltip is consistent.
expect(result.length).toBeGreaterThan(0);
for (const segment of result) {
expect(segment.end_when).toBe(now.toISOString());
}
} finally {
vi.useRealTimers();
}
Comment thread
Aaryan123456679 marked this conversation as resolved.
});

it("produces 2 segments when only queued_dttm is present", () => {
const result = transformGanttData({
allTries: [
Expand Down
14 changes: 13 additions & 1 deletion airflow-core/src/airflow/ui/src/layouts/Details/Gantt/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { renderDuration } from "src/utils/datetimeUtils";
import { buildTaskInstanceUrl } from "src/utils/links";

export type GanttDataItem = {
/** Effective task end (end_date, or "now" while running) — consistent across all segments of the same try. */
end_when?: string | null;
isGroup?: boolean | null;
isMapped?: boolean | null;
/** Source try times for tooltips (matches TaskInstance `*_when` fields). */
Expand Down Expand Up @@ -135,11 +137,21 @@ export const transformGanttData = ({
const queuedMs = queuedDttm === null ? undefined : dayjs(queuedDttm).valueOf();
const scheduledMs = scheduledDttm === null ? undefined : dayjs(scheduledDttm).valueOf();

// Include scheduled/queued/start times in tooltip data whenever the timestamps exist.
// Effective task end for tooltips: the real end_date, or "now" while a started task
// is still running. Mirrors startDate/start_when so end_when stays on the same scale —
// both are skipped together for a not-yet-started task and fall back to the bar's own
// bounds.
const effectiveEndDate =
endDate ?? (hasTaskRunning && startDate !== null ? new Date().toISOString() : null);

// Carry scheduled/queued/start/end times on every segment of a try so the tooltip
// reports the task's actual start and end on the scheduled and queued bars too, not
// just the execution bar's own bounds.
const tryWhenForTooltip = {
...(scheduledMs === undefined ? {} : { scheduled_when: scheduledDttm }),
...(queuedMs === undefined ? {} : { queued_when: queuedDttm }),
...(startDate === null ? {} : { start_when: startDate }),
...(effectiveEndDate === null ? {} : { end_when: effectiveEndDate }),
};

let endMs: number;
Expand Down
Loading