Skip to content

Commit

Permalink
use get dag details to build header for Dag Page
Browse files Browse the repository at this point in the history
  • Loading branch information
bbovenzi committed Oct 25, 2024
1 parent d075176 commit 11992fd
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 83 deletions.
69 changes: 65 additions & 4 deletions airflow/ui/src/pages/DagsList/Dag/Dag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<Box>
<Button
as={RouterLink}
color="blue.400"
leftIcon={<FiChevronsLeft />}
to="/dags"
variant="link"
>
Back to all dags
</Button>
<Header dag={dag} dagId={dagId} />
<ErrorAlert error={error} />
<Progress
isIndeterminate
size="xs"
visibility={isLoading ? "visible" : "hidden"}
/>
<Tabs>
<TabList>
<Tab>Overview</Tab>
<Tab>Runs</Tab>
<Tab>Tasks</Tab>
</TabList>

return <Box>{params.dagId}</Box>;
<TabPanels>
<TabPanel>
<p>one!</p>
</TabPanel>
<TabPanel>
<p>two!</p>
</TabPanel>
<TabPanel>
<p>three!</p>
</TabPanel>
</TabPanels>
</Tabs>
</Box>
);
};
120 changes: 120 additions & 0 deletions airflow/ui/src/pages/DagsList/Dag/Header.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Box
borderColor={grayBorder}
borderRadius={8}
borderWidth={1}
overflow="hidden"
>
<Box p={2}>
<Flex alignItems="center" justifyContent="space-between">
<HStack alignItems="center" spacing={2}>
<DagIcon height={8} width={8} />
<Heading size="lg">{dag?.dag_display_name ?? dagId}</Heading>
{dag !== undefined && (
<TogglePause dagId={dag.dag_id} isPaused={dag.is_paused} />
)}
</HStack>
<Flex>
<Button colorScheme="blue" isDisabled leftIcon={<FiPlay />}>
Trigger
</Button>
</Flex>
</Flex>
<SimpleGrid columns={4} height={8} my={4} spacing={4}>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Last Run
</Heading>
</VStack>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Next Run
</Heading>
{Boolean(dag?.next_dagrun) ? (
<Text fontSize="sm">
<Time datetime={dag?.next_dagrun} />
</Text>
) : undefined}
</VStack>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Schedule
</Heading>
{Boolean(dag?.timetable_summary) ? (
<Tooltip hasArrow label={dag?.timetable_description}>
<Text fontSize="sm">
<FiCalendar style={{ display: "inline" }} />{" "}
{dag?.timetable_summary}
</Text>
</Tooltip>
) : undefined}
</VStack>
<div />
</SimpleGrid>
</Box>
<Flex
alignItems="center"
bg={grayBg}
borderTopColor={grayBorder}
borderTopWidth={1}
color="gray.400"
fontSize="sm"
justifyContent="space-between"
px={2}
py={1}
>
<Text>Owner: {dag?.owners.join(", ")}</Text>
<DagTags tags={dag?.tags ?? []} />
</Flex>
</Box>
);
};
2 changes: 1 addition & 1 deletion airflow/ui/src/pages/DagsList/DagCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,6 @@ describe("DagCard", () => {

render(<DagCard dag={expandedMockDag} />, { wrapper: Wrapper });
expect(screen.getByTestId("dag-tag")).toBeInTheDocument();
expect(screen.getByText("+1 more")).toBeInTheDocument();
expect(screen.getByText(", +1 more")).toBeInTheDocument();
});
});
38 changes: 9 additions & 29 deletions airflow/ui/src/pages/DagsList/DagCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* under the License.
*/
import {
Badge,
Box,
Flex,
HStack,
Expand All @@ -29,22 +28,21 @@ import {
VStack,
Link,
} 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");
const tooltipBg = useColorModeValue("gray.200", "gray.700");

return (
<Box
Expand Down Expand Up @@ -72,36 +70,19 @@ export const DagCard = ({ dag }: Props) => {
{dag.dag_display_name}
</Link>
</Tooltip>
{dag.tags.length ? (
<HStack spacing={1}>
<FiTag data-testid="dag-tag" />
{dag.tags.slice(0, MAX_TAGS).map((tag) => (
<Badge key={tag.name}>{tag.name}</Badge>
))}
{dag.tags.length > MAX_TAGS && (
<Tooltip
bg={tooltipBg}
hasArrow
label={
<VStack p={1} spacing={1}>
{dag.tags.slice(MAX_TAGS).map((tag) => (
<Badge key={tag.name}>{tag.name}</Badge>
))}
</VStack>
}
>
<Badge>+{dag.tags.length - MAX_TAGS} more</Badge>
</Tooltip>
)}
</HStack>
) : undefined}
<DagTags tags={dag.tags} />
</HStack>
<HStack>
<TogglePause dagId={dag.dag_id} isPaused={dag.is_paused} />
</HStack>
</Flex>
<SimpleGrid columns={4} height={20} px={3} py={2} spacing={4}>
<div />
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Last Run
</Heading>
</VStack>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Next Run
Expand All @@ -122,7 +103,6 @@ export const DagCard = ({ dag }: Props) => {
) : undefined}
</VStack>
<div />
<div />
</SimpleGrid>
</Box>
);
Expand Down
55 changes: 55 additions & 0 deletions airflow/ui/src/pages/DagsList/DagTags.tsx
Original file line number Diff line number Diff line change
@@ -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<DagTagPydantic>;
};

export const DagTags = ({ tags }: Props) =>
tags.length ? (
<Flex alignItems="center" ml={2}>
<FiTag data-testid="dag-tag" />
<Text ml={1}>
{tags
.slice(0, MAX_TAGS)
.map(({ name }) => name)
.join(", ")}
</Text>
{tags.length > MAX_TAGS && (
<Tooltip
hasArrow
label={
<VStack p={1} spacing={1}>
{tags.slice(MAX_TAGS).map((tag) => (
<Text key={tag.name}>{tag.name}</Text>
))}
</VStack>
}
>
<Text>, +{tags.length - MAX_TAGS} more</Text>
</Tooltip>
)}
</Flex>
) : undefined;
Loading

0 comments on commit 11992fd

Please sign in to comment.