Skip to content

Commit

Permalink
Add latest dag run info to dags list and dag details (apache#43489)
Browse files Browse the repository at this point in the history
* Add latest dag run info to dags list and dag details

* Add tooltip offset
  • Loading branch information
bbovenzi authored Oct 30, 2024
1 parent c0be402 commit 6641d78
Show file tree
Hide file tree
Showing 13 changed files with 372 additions and 92 deletions.
7 changes: 0 additions & 7 deletions airflow/ui/src/layouts/Nav/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import { Box, Flex, Icon, VStack } from "@chakra-ui/react";
import { motion } from "framer-motion";
import {
FiBarChart2,
FiCornerUpLeft,
FiDatabase,
FiGlobe,
Expand Down Expand Up @@ -70,12 +69,6 @@ export const Nav = () => (
title="Assets"
to="assets"
/>
<NavButton
icon={<FiBarChart2 size="1.75rem" />}
isDisabled
title="Dag Runs"
to="dag_runs"
/>
<NavButton
icon={<FiGlobe size="1.75rem" />}
isDisabled
Expand Down
23 changes: 19 additions & 4 deletions airflow/ui/src/pages/DagsList/Dag/Dag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ import {
import { FiChevronsLeft } from "react-icons/fi";
import { Link as RouterLink, useParams } from "react-router-dom";

import { useDagServiceGetDagDetails } from "openapi/queries";
import {
useDagServiceGetDagDetails,
useDagsServiceRecentDagRuns,
} from "openapi/queries";
import { ErrorAlert } from "src/components/ErrorAlert";

import { Header } from "./Header";
Expand All @@ -45,6 +48,17 @@ export const Dag = () => {
dagId: dagId ?? "",
});

// TODO: replace with with a list dag runs by dag id request
const {
data: runsData,
error: runsError,
isLoading: isLoadingRuns,
} = useDagsServiceRecentDagRuns({ dagIdPattern: dagId ?? "" });

const runs =
runsData?.dags.find((dagWithRuns) => dagWithRuns.dag_id === dagId)
?.latest_dag_runs ?? [];

return (
<Box>
<Button
Expand All @@ -56,18 +70,19 @@ export const Dag = () => {
>
Back to all dags
</Button>
<Header dag={dag} dagId={dagId} />
<ErrorAlert error={error} />
<Header dag={dag} dagId={dagId} latestRun={runs[0]} />
<ErrorAlert error={error ?? runsError} />
<Progress
isIndeterminate
size="xs"
visibility={isLoading ? "visible" : "hidden"}
visibility={isLoading || isLoadingRuns ? "visible" : "hidden"}
/>
<Tabs>
<TabList>
<Tab>Overview</Tab>
<Tab>Runs</Tab>
<Tab>Tasks</Tab>
<Tab>Events</Tab>
</TabList>

<TabPanels>
Expand Down
7 changes: 6 additions & 1 deletion airflow/ui/src/pages/DagsList/Dag/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,22 @@ import {
} from "@chakra-ui/react";
import { FiCalendar, FiPlay } from "react-icons/fi";

import type { DAGResponse } from "openapi/requests/types.gen";
import type { DAGResponse, DAGRunResponse } 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";
import { LatestRun } from "../LatestRun";

export const Header = ({
dag,
dagId,
latestRun,
}: {
readonly dag?: DAGResponse;
readonly dagId?: string;
readonly latestRun?: DAGRunResponse;
}) => {
const grayBg = useColorModeValue("gray.100", "gray.900");
const grayBorder = useColorModeValue("gray.200", "gray.700");
Expand Down Expand Up @@ -74,6 +77,8 @@ export const Header = ({
<Heading color="gray.500" fontSize="xs">
Last Run
</Heading>
<LatestRun latestRun={latestRun} />
<LatestRun />
</VStack>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Expand Down
10 changes: 7 additions & 3 deletions airflow/ui/src/pages/DagsList/DagCard.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
*/
import { render, screen } from "@testing-library/react";
import type {
DAGResponse,
DagTagPydantic,
DAGWithLatestDagRunsResponse,
} from "openapi-gen/requests/types.gen";
import { afterEach, describe, it, vi, expect } from "vitest";

Expand All @@ -44,6 +44,7 @@ const mockDag = {
last_expired: null,
last_parsed_time: "2024-08-22T13:50:10.372238+00:00",
last_pickled: null,
latest_dag_runs: [],
max_active_runs: 16,
max_active_tasks: 16,
max_consecutive_failed_dag_runs: 0,
Expand All @@ -56,7 +57,7 @@ const mockDag = {
tags: [],
timetable_description: "",
timetable_summary: "",
} satisfies DAGResponse;
} satisfies DAGWithLatestDagRunsResponse;

afterEach(() => {
vi.restoreAllMocks();
Expand All @@ -77,7 +78,10 @@ describe("DagCard", () => {
{ dag_id: "id", name: "tag4" },
] satisfies Array<DagTagPydantic>;

const expandedMockDag = { ...mockDag, tags } satisfies DAGResponse;
const expandedMockDag = {
...mockDag,
tags,
} satisfies DAGWithLatestDagRunsResponse;

render(<DagCard dag={expandedMockDag} />, { wrapper: Wrapper });
expect(screen.getByTestId("dag-tag")).toBeInTheDocument();
Expand Down
34 changes: 15 additions & 19 deletions airflow/ui/src/pages/DagsList/DagCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,23 @@ import {
HStack,
Heading,
SimpleGrid,
Text,
Tooltip,
VStack,
Link,
} from "@chakra-ui/react";
import { FiCalendar } from "react-icons/fi";
import { Link as RouterLink } from "react-router-dom";

import type { DAGResponse } from "openapi/requests/types.gen";
import type { DAGWithLatestDagRunsResponse } from "openapi/requests/types.gen";
import Time from "src/components/Time";
import { TogglePause } from "src/components/TogglePause";

import { DagTags } from "./DagTags";
import { LatestRun } from "./LatestRun";
import { RecentRuns } from "./RecentRuns";
import { Schedule } from "./Schedule";

type Props = {
readonly dag: DAGResponse;
readonly dag: DAGWithLatestDagRunsResponse;
};

export const DagCard = ({ dag }: Props) => (
Expand Down Expand Up @@ -73,30 +74,25 @@ export const DagCard = ({ dag }: Props) => (
</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
Schedule
</Heading>
<Schedule dag={dag} />
</VStack>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Latest Run
</Heading>
<LatestRun latestRun={dag.latest_dag_runs[0]} />
</VStack>
<VStack align="flex-start" spacing={1}>
<Heading color="gray.500" fontSize="xs">
Next Run
</Heading>
<Text fontSize="sm">
<Time datetime={dag.next_dagrun} />
</Text>
{Boolean(dag.timetable_summary) ? (
<Tooltip hasArrow label={dag.timetable_description}>
<Text fontSize="sm">
{" "}
<FiCalendar style={{ display: "inline" }} />{" "}
{dag.timetable_summary}
</Text>
</Tooltip>
) : undefined}
<Time datetime={dag.next_dagrun} />
</VStack>
<div />
<RecentRuns latestRuns={dag.latest_dag_runs} />
</SimpleGrid>
</Box>
);
5 changes: 3 additions & 2 deletions airflow/ui/src/pages/DagsList/DagTags.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ import type { DagTagPydantic } from "openapi/requests/types.gen";
const MAX_TAGS = 3;

type Props = {
readonly hideIcon?: boolean;
readonly tags: Array<DagTagPydantic>;
};

export const DagTags = ({ tags }: Props) =>
export const DagTags = ({ hideIcon = false, tags }: Props) =>
tags.length ? (
<Flex alignItems="center" ml={2}>
<FiTag data-testid="dag-tag" />
{hideIcon ? undefined : <FiTag data-testid="dag-tag" />}
<Text ml={1}>
{tags
.slice(0, MAX_TAGS)
Expand Down
2 changes: 1 addition & 1 deletion airflow/ui/src/pages/DagsList/DagsFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export const DagsFilters = () => {
onClick={handleStateChange}
value="success"
>
Successful
Success
</QuickFilterButton>
</HStack>
<Select
Expand Down
Loading

0 comments on commit 6641d78

Please sign in to comment.