Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9827293
Popup is getting automatically closed when there is a DAG running
0lai0 Oct 30, 2025
f624ebf
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Oct 30, 2025
db98718
Merge branch 'apache:main' into airflow-57341-PopupClose
0lai0 Oct 31, 2025
16d7353
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Oct 31, 2025
c775b96
Merge branch 'apache:main' into airflow-57341-PopupClose
0lai0 Nov 1, 2025
154271e
data refresh affects only the table rows, not the dialog boxes.
0lai0 Nov 1, 2025
fd4a0d2
Merge branch 'apache:main' into airflow-57341-PopupClose
0lai0 Nov 1, 2025
8ba8bd2
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 3, 2025
04633e5
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 3, 2025
d753b3c
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 7, 2025
92ef7e3
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 8, 2025
763eaac
use useMemo to memorize columns
0lai0 Nov 8, 2025
cd67f8c
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 9, 2025
70999fe
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 13, 2025
6b4de8e
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 14, 2025
748484c
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 14, 2025
92d4b53
modify hope the dialog state will not be lost due to auto-refresh.
0lai0 Nov 14, 2025
45c06a3
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 15, 2025
dbe82fb
Merge branch 'main' into airflow-57341-PopupClose
0lai0 Nov 15, 2025
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 @@ -18,6 +18,7 @@
*/
import { Box, Editable, Text, VStack } from "@chakra-ui/react";
import type { ChangeEvent } from "react";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";

import type { DAGRunResponse, TaskInstanceCollectionResponse } from "openapi/requests/types.gen";
Expand All @@ -39,6 +40,8 @@ const ActionAccordion = ({ affectedTasks, note, setNote }: Props) => {
const showTaskSection = affectedTasks !== undefined;
const { t: translate } = useTranslation();

const columns = useMemo(() => getColumns(translate), [translate]);

return (
<Accordion.Root
collapsible
Expand All @@ -58,7 +61,7 @@ const ActionAccordion = ({ affectedTasks, note, setNote }: Props) => {
<Accordion.ItemContent>
<Box maxH="400px" overflowY="scroll">
<DataTable
columns={getColumns(translate)}
columns={columns}
data={affectedTasks.task_instances}
displayMode="table"
modelName={translate("common:taskInstance_other")}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,34 @@ import ClearTaskInstanceDialog from "./ClearTaskInstanceDialog";
type Props = {
readonly groupTaskInstance?: LightGridTaskInstanceSummary;
readonly isHotkeyEnabled?: boolean;
// Optional: allow parent to handle opening a stable, page-level dialog
readonly onOpen?: (ti: LightGridTaskInstanceSummary | TaskInstanceResponse) => void;
readonly taskInstance?: TaskInstanceResponse;
readonly withText?: boolean;
};

const ClearTaskInstanceButton = ({
groupTaskInstance,
isHotkeyEnabled = false,
onOpen,
taskInstance,
withText = true,
}: Props) => {
const { onClose, onOpen, open } = useDisclosure();
const { onClose, onOpen: onOpenInternal, open } = useDisclosure();
const { t: translate } = useTranslation();
const isGroup = groupTaskInstance && !taskInstance;
const useInternalDialog = !Boolean(onOpen);

const selectedInstance = taskInstance ?? groupTaskInstance;

useHotkeys(
"shift+c",
() => {
onOpen();
if (onOpen && selectedInstance) {
onOpen(selectedInstance);
} else {
onOpenInternal();
}
},
{ enabled: isHotkeyEnabled },
);
Expand All @@ -66,18 +76,18 @@ const ClearTaskInstanceButton = ({
type: translate("taskInstance_one"),
})}
icon={<CgRedo />}
onClick={onOpen}
onClick={() => (onOpen && selectedInstance ? onOpen(selectedInstance) : onOpenInternal())}
text={translate("dags:runAndTaskActions.clear.button", {
type: translate(isGroup ? "taskGroup" : "taskInstance_one"),
})}
withText={withText}
/>

{open && isGroup ? (
{useInternalDialog && open && isGroup ? (
<ClearGroupTaskInstanceDialog onClose={onClose} open={open} taskInstance={groupTaskInstance} />
) : undefined}

{open && !isGroup && taskInstance ? (
{useInternalDialog && open && !isGroup && taskInstance ? (
<ClearTaskInstanceDialog onClose={onClose} open={open} taskInstance={taskInstance} />
) : undefined}
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
import { Box, Heading, Link, VStack } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useSearchParams, Link as RouterLink } from "react-router-dom";

Expand Down Expand Up @@ -111,6 +112,8 @@ export const AssetsList = () => {
orderBy,
});

const columns = useMemo(() => createColumns(translate), [translate]);

const handleSearchChange = (value: string) => {
setTableURLState({
pagination: { ...pagination, pageIndex: 0 },
Expand Down Expand Up @@ -140,7 +143,7 @@ export const AssetsList = () => {
</VStack>
<Box overflow="auto">
<DataTable
columns={createColumns(translate)}
columns={columns}
data={data?.assets ?? []}
errorMessage={<ErrorAlert error={error} />}
initialState={tableURLState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
import { Box, Heading, Text } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";

Expand Down Expand Up @@ -117,14 +118,16 @@ export const Backfills = () => {
offset: pagination.pageIndex * pagination.pageSize,
});

const columns = useMemo(() => getColumns(translate), [translate]);

return (
<Box>
<ErrorAlert error={error} />
<Heading my={1} size="md">
{translate("backfill", { count: data ? data.total_entries : 0 })}
</Heading>
<DataTable
columns={getColumns(translate)}
columns={columns}
data={data ? data.backfills : []}
isFetching={isFetching}
isLoading={isLoading}
Expand Down
5 changes: 4 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/DagRuns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import { Flex, HStack, Link, Text } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useParams, useSearchParams } from "react-router-dom";

Expand Down Expand Up @@ -237,11 +238,13 @@ export const DagRuns = () => {
},
);

const columns = useMemo(() => runColumns(translate, dagId), [translate, dagId]);

return (
<>
<DagRunsFilters dagId={dagId} />
<DataTable
columns={runColumns(translate, dagId)}
columns={columns}
data={data?.dag_runs ?? []}
errorMessage={<ErrorAlert error={error} />}
initialState={tableURLState}
Expand Down
8 changes: 7 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/Events/Events.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import { Code, Flex, Heading, useDisclosure, VStack } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import dayjs from "dayjs";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { useParams, useSearchParams } from "react-router-dom";

Expand Down Expand Up @@ -207,6 +208,11 @@ export const Events = () => {
undefined,
);

const columns = useMemo(
() => eventsColumn({ dagId, open, runId, taskId }, translate),
[dagId, open, runId, taskId, translate],
);

return (
<VStack alignItems="stretch">
{dagId === undefined && runId === undefined && taskId === undefined ? (
Expand All @@ -224,7 +230,7 @@ export const Events = () => {

<ErrorAlert error={error} />
<DataTable
columns={eventsColumn({ dagId, open, runId, taskId }, translate)}
columns={columns}
data={data?.event_logs ?? []}
displayMode="table"
initialState={tableURLState}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import { Heading, Link, VStack } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
import { useCallback } from "react";
import { useCallback, useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useParams, useSearchParams } from "react-router-dom";

Expand Down Expand Up @@ -240,6 +240,17 @@ export const HITLTaskInstances = () => {
setSearchParams(searchParams);
}, [pagination, searchParams, setSearchParams, setTableURLState, sorting]);

const columns = useMemo(
() =>
taskInstanceColumns({
dagId,
runId,
taskId,
translate,
}),
[dagId, runId, taskId, translate],
);

return (
<VStack align="start">
{!Boolean(dagId) && !Boolean(runId) && !Boolean(taskId) ? (
Expand All @@ -249,12 +260,7 @@ export const HITLTaskInstances = () => {
) : undefined}
<HITLFilters onResponseChange={handleResponseChange} />
<DataTable
columns={taskInstanceColumns({
dagId,
runId,
taskId,
translate,
})}
columns={columns}
data={data?.hitl_details ?? []}
errorMessage={<ErrorAlert error={error} />}
initialState={tableURLState}
Expand Down
12 changes: 12 additions & 0 deletions airflow-core/src/airflow/ui/src/pages/TaskInstance/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { MdOutlineTask } from "react-icons/md";

import type { TaskInstanceResponse } from "openapi/requests/types.gen";
import { ClearTaskInstanceButton } from "src/components/Clear";
import ClearTaskInstanceDialog from "src/components/Clear/TaskInstance/ClearTaskInstanceDialog";
import { DagVersion } from "src/components/DagVersion";
import EditableMarkdownButton from "src/components/EditableMarkdownButton";
import { HeaderCard } from "src/components/HeaderCard";
Expand Down Expand Up @@ -93,6 +94,9 @@ export const Header = ({
setNote(taskInstance.note ?? "");
};

// Stable dialog state at header/page level
const [clearOpen, setClearOpen] = useState(false);

return (
<Box ref={containerRef}>
<HeaderCard
Expand All @@ -111,6 +115,7 @@ export const Header = ({
/>
<ClearTaskInstanceButton
isHotkeyEnabled
onOpen={() => setClearOpen(true)}
taskInstance={taskInstance}
withText={containerWidth > 700}
/>
Expand All @@ -127,6 +132,13 @@ export const Header = ({
stats={stats}
title={`${taskInstance.task_display_name}${taskInstance.map_index > -1 ? ` [${taskInstance.rendered_map_index ?? taskInstance.map_index}]` : ""}`}
/>
{clearOpen ? (
<ClearTaskInstanceDialog
onClose={() => setClearOpen(false)}
open={clearOpen}
taskInstance={taskInstance}
/>
) : undefined}
</Box>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import { Flex, Link } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import type { TFunction } from "i18next";
import { useState } from "react";
import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useParams, useSearchParams } from "react-router-dom";

Expand Down Expand Up @@ -264,19 +264,25 @@ export const TaskInstances = () => {
},
);

const columns = useMemo(
() =>
taskInstanceColumns({
dagId,
runId,
taskId: Boolean(groupId) ? undefined : taskId,
translate,
}),
[dagId, runId, groupId, taskId, translate],
);

return (
<>
<TaskInstancesFilter
setTaskDisplayNamePattern={setTaskDisplayNamePattern}
taskDisplayNamePattern={taskDisplayNamePattern}
/>
<DataTable
columns={taskInstanceColumns({
dagId,
runId,
taskId: Boolean(groupId) ? undefined : taskId,
translate,
})}
columns={columns}
data={data?.task_instances ?? []}
errorMessage={<ErrorAlert error={error} />}
initialState={tableURLState}
Expand Down
5 changes: 4 additions & 1 deletion airflow-core/src/airflow/ui/src/pages/XCom/XCom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
import { Box, Heading, Link, Flex, useDisclosure } from "@chakra-ui/react";
import type { ColumnDef } from "@tanstack/react-table";
import { useMemo } from "react";
import { useTranslation } from "react-i18next";
import { Link as RouterLink, useParams, useSearchParams } from "react-router-dom";

Expand Down Expand Up @@ -161,6 +162,8 @@ export const XCom = () => {

const { data, error, isFetching, isLoading } = useXcomServiceGetXcomEntries(apiParams, undefined);

const memoizedColumns = useMemo(() => columns(translate, open), [translate, open]);

return (
<Box>
{dagId === "~" && runId === "~" && taskId === "~" ? (
Expand All @@ -179,7 +182,7 @@ export const XCom = () => {

<ErrorAlert error={error} />
<DataTable
columns={columns(translate, open)}
columns={memoizedColumns}
data={data ? data.xcom_entries : []}
displayMode="table"
initialState={tableURLState}
Expand Down