diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/TaskCard.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/TaskCard.tsx
deleted file mode 100644
index 83f1635cbc355..0000000000000
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/TaskCard.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-/*!
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { Heading, VStack, Box, SimpleGrid, Text, Link } from "@chakra-ui/react";
-import { useTranslation } from "react-i18next";
-import { Link as RouterLink } from "react-router-dom";
-
-import { useTaskInstanceServiceGetTaskInstances } from "openapi/queries/queries.ts";
-import type { TaskResponse } from "openapi/requests/types.gen";
-import { StateBadge } from "src/components/StateBadge";
-import TaskInstanceTooltip from "src/components/TaskInstanceTooltip";
-import Time from "src/components/Time";
-import { isStatePending, useAutoRefresh } from "src/utils";
-import { getTaskInstanceLink } from "src/utils/links";
-
-import { TaskRecentRuns } from "./TaskRecentRuns.tsx";
-
-type Props = {
- readonly dagId: string;
- readonly task: TaskResponse;
-};
-
-export const TaskCard = ({ dagId, task }: Props) => {
- const { t: translate } = useTranslation();
- const refetchInterval = useAutoRefresh({ dagId });
-
- const { data } = useTaskInstanceServiceGetTaskInstances(
- {
- dagId,
- dagRunId: "~",
- limit: 14,
- orderBy: ["-run_after"],
- taskId: task.task_id ?? "",
- },
- undefined,
- {
- enabled: Boolean(dagId) && Boolean(task.task_id),
- refetchInterval: (query) =>
- query.state.data?.task_instances.some((ti) => isStatePending(ti.state)) ? refetchInterval : false,
- },
- );
-
- return (
-
-
-
- {task.task_display_name ?? task.task_id}
- {task.is_mapped ? "[]" : undefined}
-
-
-
-
-
- {translate("task.operator")}
-
- {task.operator_name}
-
-
-
- {translate("task.triggerRule")}
-
- {task.trigger_rule}
-
-
-
- {translate("task.lastInstance")}
-
- {data?.task_instances[0] ? (
-
-
-
-
-
-
-
-
- ) : undefined}
-
- {/* TODO: Handled mapped tasks to not plot each map index as a task instance */}
- {!task.is_mapped && }
-
-
- );
-};
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/TaskRecentRuns.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/TaskRecentRuns.tsx
deleted file mode 100644
index 8dd9e70ad8df3..0000000000000
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/TaskRecentRuns.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-/*!
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { Box, Flex } from "@chakra-ui/react";
-import dayjs from "dayjs";
-import duration from "dayjs/plugin/duration";
-import { Link } from "react-router-dom";
-
-import type { TaskInstanceResponse } from "openapi/requests/types.gen";
-import TaskInstanceTooltip from "src/components/TaskInstanceTooltip";
-import { getTaskInstanceLink } from "src/utils/links";
-
-dayjs.extend(duration);
-
-const BAR_HEIGHT = 60;
-
-export const TaskRecentRuns = ({
- taskInstances,
-}: {
- readonly taskInstances: Array;
-}) => {
- if (!taskInstances.length) {
- return undefined;
- }
-
- const taskInstancesWithDuration = taskInstances.map((taskInstance) => ({
- ...taskInstance,
- duration:
- dayjs.duration(dayjs(taskInstance.end_date ?? dayjs()).diff(taskInstance.start_date)).asSeconds() || 0,
- }));
-
- const max = Math.max.apply(
- undefined,
- taskInstancesWithDuration.map((taskInstance) => taskInstance.duration),
- );
-
- return (
-
- {taskInstancesWithDuration.map((taskInstance) => (
-
-
-
-
-
-
-
- ))}
-
- );
-};
diff --git a/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/Tasks.tsx b/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/Tasks.tsx
index c74723ce775c6..154e0394a2cb6 100644
--- a/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/Tasks.tsx
+++ b/airflow-core/src/airflow/ui/src/pages/Dag/Tasks/Tasks.tsx
@@ -16,25 +16,63 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { Skeleton, Box } from "@chakra-ui/react";
+import { Box, Link } from "@chakra-ui/react";
+import type { ColumnDef } from "@tanstack/react-table";
+import type { TFunction } from "i18next";
+import { useTranslation } from "react-i18next";
import { useParams, useSearchParams } from "react-router-dom";
+import { Link as RouterLink } from "react-router-dom";
import { useTaskServiceGetTasks } from "openapi/queries";
import type { TaskResponse } from "openapi/requests/types.gen";
import { DataTable } from "src/components/DataTable";
-import type { CardDef } from "src/components/DataTable/types";
import { ErrorAlert } from "src/components/ErrorAlert";
+import { TruncatedText } from "src/components/TruncatedText";
import { SearchParamsKeys } from "src/constants/searchParams.ts";
import { TaskFilters } from "src/pages/Dag/Tasks/TaskFilters/TaskFilters.tsx";
-import { TaskCard } from "./TaskCard";
+type TaskRow = { row: { original: TaskResponse } };
-const cardDef = (dagId: string): CardDef => ({
- card: ({ row }) => ,
- meta: {
- customSkeleton: ,
+const createColumns = ({
+ dagId,
+ translate,
+}: {
+ dagId: string;
+ translate: TFunction;
+}): Array> => [
+ {
+ accessorKey: "task_display_name",
+ cell: ({ row: { original } }: TaskRow) => (
+
+
+
+
+
+ ),
+ enableSorting: false,
+ header: translate("common:taskId"),
},
-});
+ {
+ accessorKey: "trigger_rule",
+ enableSorting: false,
+ header: translate("common:task.triggerRule"),
+ },
+ {
+ accessorKey: "operator_name",
+ enableSorting: false,
+ header: translate("common:task.operator"),
+ },
+ {
+ accessorKey: "retries",
+ enableSorting: false,
+ header: translate("tasks:retries"),
+ },
+ {
+ accessorKey: "is_mapped",
+ enableSorting: false,
+ header: translate("tasks:mapped"),
+ },
+];
export const Tasks = () => {
const { dagId = "" } = useParams();
@@ -46,6 +84,10 @@ export const Tasks = () => {
const selectedMapped = searchParams.get(MAPPED) ?? undefined;
const namePattern = searchParams.get(NAME_PATTERN) ?? undefined;
+ const { t: translate } = useTranslation(["tasks", "common"]);
+
+ const columns = createColumns({ dagId, translate });
+
const {
data,
error: tasksError,
@@ -92,8 +134,7 @@ export const Tasks = () => {
> => [
{
accessorKey: "task_instance_state",
- cell: ({ row: { original } }: TaskInstanceRow) => (
+ cell: ({ row: { original } }: HITLRow) => (
{getHITLState(translate, original)}
),
header: translate("requiredActionState"),
},
{
accessorKey: "subject",
- cell: ({ row: { original } }: TaskInstanceRow) => (
+ cell: ({ row: { original } }: HITLRow) => (
@@ -90,9 +90,7 @@ const taskInstanceColumns = ({
: [
{
accessorKey: "run_after",
- cell: ({ row: { original } }: TaskInstanceRow) => (
-
- ),
+ cell: ({ row: { original } }: HITLRow) => ,
header: translate("common:dagRun.runAfter"),
},
]),
@@ -101,9 +99,6 @@ const taskInstanceColumns = ({
: [
{
accessorKey: "task_display_name",
- cell: ({ row: { original } }: TaskInstanceRow) => (
-
- ),
enableSorting: false,
header: translate("common:taskId"),
},