From 5fc4c0372fb854a356c14ef1ad8858a3276ca50e Mon Sep 17 00:00:00 2001 From: Brent Bovenzi Date: Thu, 24 Oct 2024 15:05:44 -0400 Subject: [PATCH] use get dag details to build header for Dag Page --- airflow/ui/src/pages/DagsList/Dag/Dag.tsx | 69 ++++++++- airflow/ui/src/pages/DagsList/Dag/Header.tsx | 120 +++++++++++++++ .../ui/src/pages/DagsList/DagCard.test.tsx | 2 +- airflow/ui/src/pages/DagsList/DagCard.tsx | 140 ++++++++---------- airflow/ui/src/pages/DagsList/DagTags.tsx | 55 +++++++ airflow/ui/src/pages/DagsList/DagsFilters.tsx | 88 +++++------ 6 files changed, 345 insertions(+), 129 deletions(-) create mode 100644 airflow/ui/src/pages/DagsList/Dag/Header.tsx create mode 100644 airflow/ui/src/pages/DagsList/DagTags.tsx diff --git a/airflow/ui/src/pages/DagsList/Dag/Dag.tsx b/airflow/ui/src/pages/DagsList/Dag/Dag.tsx index 79290803e70e4..52f8934e899cc 100644 --- a/airflow/ui/src/pages/DagsList/Dag/Dag.tsx +++ b/airflow/ui/src/pages/DagsList/Dag/Dag.tsx @@ -16,11 +16,72 @@ * specific language governing permissions and limitations * under the License. */ -import { Box } from "@chakra-ui/react"; -import { useParams } from "react-router-dom"; +import { + Box, + Button, + Progress, + Tab, + TabList, + TabPanel, + TabPanels, + Tabs, +} from "@chakra-ui/react"; +import { FiChevronsLeft } from "react-icons/fi"; +import { Link as RouterLink, useParams } from "react-router-dom"; + +import { useDagServiceGetDagDetails } from "openapi/queries"; +import { ErrorAlert } from "src/components/ErrorAlert"; + +import { Header } from "./Header"; export const Dag = () => { - const params = useParams(); + const { dagId } = useParams(); + + const { + data: dag, + error, + isLoading, + } = useDagServiceGetDagDetails({ + dagId: dagId ?? "", + }); + + return ( + + +
+ + + + + Overview + Runs + Tasks + - return {params.dagId}; + + +

one!

+
+ +

two!

+
+ +

three!

+
+
+
+ + ); }; diff --git a/airflow/ui/src/pages/DagsList/Dag/Header.tsx b/airflow/ui/src/pages/DagsList/Dag/Header.tsx new file mode 100644 index 0000000000000..25d674e144130 --- /dev/null +++ b/airflow/ui/src/pages/DagsList/Dag/Header.tsx @@ -0,0 +1,120 @@ +/*! + * 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, + Button, + Flex, + Heading, + HStack, + SimpleGrid, + Text, + Tooltip, + useColorModeValue, + VStack, +} from "@chakra-ui/react"; +import { FiCalendar, FiPlay } from "react-icons/fi"; + +import type { DAGResponse } from "openapi/requests/types.gen"; +import { DagIcon } from "src/assets/DagIcon"; +import Time from "src/components/Time"; +import { TogglePause } from "src/components/TogglePause"; + +import { DagTags } from "../DagTags"; + +export const Header = ({ + dag, + dagId, +}: { + readonly dag?: DAGResponse; + readonly dagId?: string; +}) => { + const grayBg = useColorModeValue("gray.100", "gray.900"); + const grayBorder = useColorModeValue("gray.200", "gray.700"); + + return ( + + + + + + {dag?.dag_display_name ?? dagId} + {dag !== undefined && ( + + )} + + + + + + + + + Last Run + + + + + Next Run + + {Boolean(dag?.next_dagrun) ? ( + + + ) : undefined} + + + + Schedule + + {Boolean(dag?.timetable_summary) ? ( + + + {" "} + {dag?.timetable_summary} + + + ) : undefined} + +
+ + + + Owner: {dag?.owners.join(", ")} + + + + ); +}; diff --git a/airflow/ui/src/pages/DagsList/DagCard.test.tsx b/airflow/ui/src/pages/DagsList/DagCard.test.tsx index 3ae6e4fceeac9..b039d7c90b467 100644 --- a/airflow/ui/src/pages/DagsList/DagCard.test.tsx +++ b/airflow/ui/src/pages/DagsList/DagCard.test.tsx @@ -82,6 +82,6 @@ describe("DagCard", () => { render(, { wrapper: Wrapper }); expect(screen.getByTestId("dag-tag")).toBeInTheDocument(); - expect(screen.getByText("+1 more")).toBeInTheDocument(); + expect(screen.getByText(", +1 more")).toBeInTheDocument(); }); }); diff --git a/airflow/ui/src/pages/DagsList/DagCard.tsx b/airflow/ui/src/pages/DagsList/DagCard.tsx index c222ac678979f..41f24493c5f2d 100644 --- a/airflow/ui/src/pages/DagsList/DagCard.tsx +++ b/airflow/ui/src/pages/DagsList/DagCard.tsx @@ -17,7 +17,6 @@ * under the License. */ import { - Badge, Box, Flex, HStack, @@ -27,94 +26,85 @@ import { Tooltip, VStack, Link, + useColorModeValue, } from "@chakra-ui/react"; -import { FiCalendar, FiTag } from "react-icons/fi"; +import { FiCalendar } from "react-icons/fi"; import { Link as RouterLink } from "react-router-dom"; import type { DAGResponse } from "openapi/requests/types.gen"; -import Time from "src/components/Time"; import { TogglePause } from "src/components/TogglePause"; +import { DagTags } from "./DagTags"; + type Props = { readonly dag: DAGResponse; }; -const MAX_TAGS = 3; +export const DagCard = ({ dag }: Props) => { + const cardBorder = useColorModeValue("gray.100", "gray.700"); -export const DagCard = ({ dag }: Props) => ( - - - - - - {dag.dag_display_name} - - - {dag.tags.length ? ( - - - {dag.tags.slice(0, MAX_TAGS).map((tag) => ( - {tag.name} - ))} - {dag.tags.length > MAX_TAGS && ( - - {dag.tags.slice(MAX_TAGS).map((tag) => ( - {tag.name} - ))} - - } - > - +{dag.tags.length - MAX_TAGS} more - - )} - - ) : undefined} - - - - -
- - - Next Run - - {Boolean(dag.next_dagrun) ? ( - - - ) : undefined} - {Boolean(dag.timetable_summary) ? ( - + + + + + {dag.dag_display_name} + + + + + + + + + +
+ + + Last Run + + + + + Next Run + + {Boolean(dag.next_dagrun) ? ( {" "} {" "} {dag.timetable_summary} - - ) : undefined} - -
-
- - -); + ) : undefined} + {Boolean(dag.timetable_summary) ? ( + + + {" "} + {" "} + {dag.timetable_summary} + + + ) : undefined} + +
+ + + ); +}; diff --git a/airflow/ui/src/pages/DagsList/DagTags.tsx b/airflow/ui/src/pages/DagsList/DagTags.tsx new file mode 100644 index 0000000000000..2a3cb3f76befb --- /dev/null +++ b/airflow/ui/src/pages/DagsList/DagTags.tsx @@ -0,0 +1,55 @@ +/*! + * 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 { Flex, Text, Tooltip, VStack } from "@chakra-ui/react"; +import { FiTag } from "react-icons/fi"; + +import type { DagTagPydantic } from "openapi/requests/types.gen"; + +const MAX_TAGS = 3; + +type Props = { + readonly tags: Array; +}; + +export const DagTags = ({ tags }: Props) => + tags.length ? ( + + + + {tags + .slice(0, MAX_TAGS) + .map(({ name }) => name) + .join(", ")} + + {tags.length > MAX_TAGS && ( + + {tags.slice(MAX_TAGS).map((tag) => ( + {tag.name} + ))} + + } + > + , +{tags.length - MAX_TAGS} more + + )} + + ) : undefined; diff --git a/airflow/ui/src/pages/DagsList/DagsFilters.tsx b/airflow/ui/src/pages/DagsList/DagsFilters.tsx index 0b2ff79fb0e0c..376b9220d23a3 100644 --- a/airflow/ui/src/pages/DagsList/DagsFilters.tsx +++ b/airflow/ui/src/pages/DagsList/DagsFilters.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { HStack, Select, Text, Box } from "@chakra-ui/react"; +import { HStack, Select } from "@chakra-ui/react"; import { Select as ReactSelect } from "chakra-react-select"; import type { MultiValue } from "chakra-react-select"; import { useCallback } from "react"; @@ -106,55 +106,45 @@ export const DagsFilters = () => { return ( - - - State: - - - - All - - - Failed - - - Running - - - Successful - - - - - - Active: - - - + All + + + Failed + + + Running + + + Successful + + +