This is an automated email from the ASF dual-hosted git repository.
pierrejeambrun 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 90ee763947 Present affected task instances as table (#30633)
90ee763947 is described below
commit 90ee7639478bc8534164c4bbb05a1ccfb04272dd
Author: Pierre Jeambrun <[email protected]>
AuthorDate: Fri Apr 14 21:27:40 2023 +0200
Present affected task instances as table (#30633)
---
airflow/www/static/js/api/useClearTaskDryRun.ts | 15 ++++++----
airflow/www/static/js/api/useMarkTaskDryRun.ts | 6 ++--
.../taskInstance/taskActions/ActionModal.tsx | 32 +++++++++++++++++-----
airflow/www/static/js/types/index.ts | 17 +++++++-----
airflow/www/views.py | 19 +++++++++----
5 files changed, 62 insertions(+), 27 deletions(-)
diff --git a/airflow/www/static/js/api/useClearTaskDryRun.ts
b/airflow/www/static/js/api/useClearTaskDryRun.ts
index cea46723f4..7f068a001f 100644
--- a/airflow/www/static/js/api/useClearTaskDryRun.ts
+++ b/airflow/www/static/js/api/useClearTaskDryRun.ts
@@ -19,6 +19,7 @@
import axios, { AxiosResponse } from "axios";
import { useQuery } from "react-query";
+import type { MinimalTaskInstance } from "src/types";
import URLSearchParamsWrapper from "src/utils/URLSearchParamWrapper";
import { getMetaValue } from "../utils";
@@ -91,11 +92,15 @@ const useClearTaskDryRun = ({
params.append("map_index", mi.toString());
});
- return axios.post<AxiosResponse, string[]>(clearUrl, params.toString(), {
- headers: {
- "Content-Type": "application/x-www-form-urlencoded",
- },
- });
+ return axios.post<AxiosResponse, MinimalTaskInstance[]>(
+ clearUrl,
+ params.toString(),
+ {
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ }
+ );
}
);
diff --git a/airflow/www/static/js/api/useMarkTaskDryRun.ts
b/airflow/www/static/js/api/useMarkTaskDryRun.ts
index 8e872ed8ea..31bc278644 100644
--- a/airflow/www/static/js/api/useMarkTaskDryRun.ts
+++ b/airflow/www/static/js/api/useMarkTaskDryRun.ts
@@ -19,7 +19,7 @@
import axios, { AxiosResponse } from "axios";
import { useQuery } from "react-query";
-import type { TaskState } from "src/types";
+import type { TaskState, MinimalTaskInstance } from "src/types";
import URLSearchParamsWrapper from "src/utils/URLSearchParamWrapper";
import { getMetaValue } from "../utils";
@@ -74,7 +74,9 @@ const useMarkTaskDryRun = ({
mapIndexes.forEach((mi: number) => {
params.append("map_index", mi.toString());
});
- return axios.get<AxiosResponse, string[]>(confirmUrl, { params });
+ return axios.get<AxiosResponse, MinimalTaskInstance[]>(confirmUrl, {
+ params,
+ });
}
);
diff --git
a/airflow/www/static/js/dag/details/taskInstance/taskActions/ActionModal.tsx
b/airflow/www/static/js/dag/details/taskInstance/taskActions/ActionModal.tsx
index ef89681150..57128bacd1 100644
--- a/airflow/www/static/js/dag/details/taskInstance/taskActions/ActionModal.tsx
+++ b/airflow/www/static/js/dag/details/taskInstance/taskActions/ActionModal.tsx
@@ -35,18 +35,40 @@ import {
AccordionPanel,
AccordionItem,
AccordionIcon,
- Code,
} from "@chakra-ui/react";
import { useContainerRef } from "src/context/containerRef";
+import { Table } from "src/components/Table";
+import type { MinimalTaskInstance } from "src/types";
interface Props extends ModalProps {
- affectedTasks?: string[];
+ affectedTasks?: MinimalTaskInstance[];
header: ReactNode | string;
subheader?: ReactNode | string;
submitButton: ReactNode;
}
+const columns = [
+ {
+ Header: "Task name",
+ accessor: "taskId",
+ },
+ {
+ Header: "Map Index",
+ accessor: "mapIndex",
+ },
+ {
+ Header: "Run Id",
+ accessor: "runId",
+ },
+];
+
+const AffectedTasksTable = ({
+ affectedTasks,
+}: {
+ affectedTasks: MinimalTaskInstance[];
+}) => <Table data={affectedTasks} columns={columns} />;
+
const ActionModal = ({
isOpen,
onClose,
@@ -87,11 +109,7 @@ const ActionModal = ({
</AccordionButton>
<AccordionPanel>
<Box maxHeight="400px" overflowY="auto">
- {(affectedTasks || []).map((ti) => (
- <Code width="100%" key={ti} fontSize="lg">
- {ti}
- </Code>
- ))}
+ <AffectedTasksTable affectedTasks={affectedTasks} />
</Box>
</AccordionPanel>
</AccordionItem>
diff --git a/airflow/www/static/js/types/index.ts
b/airflow/www/static/js/types/index.ts
index 94e0e60526..8f4eb7d450 100644
--- a/airflow/www/static/js/types/index.ts
+++ b/airflow/www/static/js/types/index.ts
@@ -130,16 +130,19 @@ interface DatasetListItem extends API.Dataset {
totalUpdates: number;
}
+type MinimalTaskInstance = Pick<TaskInstance, "taskId" | "mapIndex" | "runId">;
+
export type {
+ API,
+ MinimalTaskInstance,
Dag,
DagRun,
- RunState,
- TaskState,
- TaskInstance,
- Task,
- DepNode,
+ DatasetListItem,
DepEdge,
- API,
+ DepNode,
RunOrdering,
- DatasetListItem,
+ RunState,
+ Task,
+ TaskInstance,
+ TaskState,
};
diff --git a/airflow/www/views.py b/airflow/www/views.py
index cabc8e9e1a..a0e9ce33d2 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -1050,7 +1050,6 @@ class Airflow(AirflowBaseView):
)
if conf.getboolean("webserver",
"SHOW_RECENT_STATS_FOR_COMPLETED_RUNS", fallback=True):
-
last_dag_run = (
session.query(DagRun.dag_id,
sqla.func.max(DagRun.execution_date).label("execution_date"))
.join(DagModel, DagModel.dag_id == DagRun.dag_id)
@@ -2122,7 +2121,12 @@ class Airflow(AirflowBaseView):
if not details:
return redirect_or_json(origin, "No task instances to clear",
status="error", status_code=404)
elif request.headers.get("Accept") == "application/json":
- return htmlsafe_json_dumps(details, separators=(",", ":"))
+ if confirmed:
+ return htmlsafe_json_dumps(details, separators=(",", ":"))
+ return htmlsafe_json_dumps(
+ [{"task_id": ti.task_id, "map_index": ti.map_index, "run_id":
ti.run_id} for ti in tis],
+ separators=(",", ":"),
+ )
return self.render_template(
"airflow/confirm.html",
endpoint=None,
@@ -2528,8 +2532,13 @@ class Airflow(AirflowBaseView):
)
if request.headers.get("Accept") == "application/json":
- details = [str(t) for t in to_be_altered]
- return htmlsafe_json_dumps(details, separators=(",", ":"))
+ return htmlsafe_json_dumps(
+ [
+ {"task_id": ti.task_id, "map_index": ti.map_index,
"run_id": ti.run_id}
+ for ti in to_be_altered
+ ],
+ separators=(",", ":"),
+ )
details = "\n".join(str(t) for t in to_be_altered)
@@ -4475,7 +4484,6 @@ class ConnectionModelView(AirflowModelView):
"warning",
)
else:
-
dup_conn = Connection(
new_conn_id,
selected_conn.conn_type,
@@ -5683,7 +5691,6 @@ class DagDependenciesView(AirflowBaseView):
)
def _calculate_graph(self):
-
nodes_dict: dict[str, Any] = {}
edge_tuples: set[dict[str, str]] = set()