Skip to content

Commit

Permalink
[UI v2] feat: Start flow runs data table UX
Browse files Browse the repository at this point in the history
  • Loading branch information
devinvillarosa committed Feb 18, 2025
1 parent b31bfa3 commit 308ca66
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 0 deletions.
3 changes: 3 additions & 0 deletions ui-v2/src/api/flow-runs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import { components } from "../prefect";
import { getQueryService } from "../service";

export type FlowRun = components["schemas"]["FlowRun"];
export type FlowRunWithFlow = FlowRun & {
flow: Flow;
};
export type FlowRunWithDeploymentAndFlow = FlowRun & {
deployment: Deployment;
flow: Flow;
Expand Down
20 changes: 20 additions & 0 deletions ui-v2/src/components/flow-runs/data-table/data-table.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";

import { createFakeFlowRunWithDeploymentAndFlow } from "@/mocks/create-fake-flow-run";
import { routerDecorator } from "@/storybook/utils";
import { FlowRunsDataTable } from "./data-table";

const MOCK_DATA = Array.from(
{ length: 5 },
createFakeFlowRunWithDeploymentAndFlow,
);

const meta: Meta<typeof FlowRunsDataTable> = {
title: "Components/FlowRuns/DataTable/FlowRunsDataTable",
decorators: [routerDecorator],
args: { flowRuns: MOCK_DATA },
component: FlowRunsDataTable,
};
export default meta;

export const story: StoryObj = { name: "FlowRunsDataTable" };
92 changes: 92 additions & 0 deletions ui-v2/src/components/flow-runs/data-table/data-table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type { Deployment } from "@/api/deployments";
import {
type FlowRunWithDeploymentAndFlow,
type FlowRunWithFlow,
} from "@/api/flow-runs";
import { DataTable } from "@/components/ui/data-table";
import { StateBadge } from "@/components/ui/state-badge";
import { TagBadgeGroup } from "@/components/ui/tag-badge-group";
import {
createColumnHelper,
getCoreRowModel,
getPaginationRowModel,
useReactTable,
} from "@tanstack/react-table";
import { useMemo } from "react";

import { DeploymentCell } from "./deployment-cell";
import { NameCell } from "./name-cell";

const columnHelper = createColumnHelper<
FlowRunWithDeploymentAndFlow | FlowRunWithFlow
>();

const createColumns = ({
showDeployment,
}: {
showDeployment: boolean;
}) => {
const ret = [
columnHelper.display({
id: "name",
header: "Name",
cell: ({ row }) => <NameCell flowRun={row.original} />,
}),
columnHelper.accessor("state", {
id: "state",
header: "State",
cell: (props) => {
const state = props.getValue();
if (!state) {
return null;
}
return <StateBadge type={state.type} name={state.name} />;
},
}),
columnHelper.accessor("tags", {
id: "tags",
header: "Tags",
cell: (props) => (
<TagBadgeGroup tags={props.getValue()} maxTagsDisplayed={4} />
),
}),
];
if (showDeployment) {
ret.push(
columnHelper.accessor("deployment", {
id: "deployment",
header: "Deployment",
cell: (props) => {
const deployment = props.getValue() as Deployment;
return <DeploymentCell deployment={deployment} />;
},
}),
);
}
return ret;
};

type FlowRunsDataTableProps = {
flowRuns: Array<FlowRunWithDeploymentAndFlow | FlowRunWithFlow>;
};
export const FlowRunsDataTable = ({ flowRuns }: FlowRunsDataTableProps) => {
const showDeployment = useMemo(
() => flowRuns.some((flowRun) => "deployment" in flowRun),
[flowRuns],
);

const table = useReactTable({
data: flowRuns,
columns: createColumns({
showDeployment,
}),
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(), // TODO: use server-side pagination
});

return (
<div className="flex flex-col gap-4">
<DataTable table={table} />
</div>
);
};
20 changes: 20 additions & 0 deletions ui-v2/src/components/flow-runs/data-table/deployment-cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Deployment } from "@/api/deployments";

import { Icon } from "@/components/ui/icons";
import { Typography } from "@/components/ui/typography";

import { Link } from "@tanstack/react-router";

type DeploymentCellProps = { deployment: Deployment };
export const DeploymentCell = ({ deployment }: DeploymentCellProps) => {
return (
<Link
className="flex items-center gap-1 min-w-40"
to="/deployments/deployment/$id"
params={{ id: deployment.id }}
>
<Icon id="Rocket" className="h-4 w-4" />
<Typography variant="bodySmall">{deployment.name}</Typography>
</Link>
);
};
42 changes: 42 additions & 0 deletions ui-v2/src/components/flow-runs/data-table/name-cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import {
type FlowRunWithDeploymentAndFlow,
type FlowRunWithFlow,
} from "@/api/flow-runs";
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb";

type NameCellProps = {
flowRun: FlowRunWithDeploymentAndFlow | FlowRunWithFlow;
};

export const NameCell = ({ flowRun }: NameCellProps) => {
return (
<div className="flex items-center min-w-40">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink
to="/flows/flow/$id"
params={{ id: flowRun.flow_id }}
>
{flowRun.flow.name}
</BreadcrumbLink>
</BreadcrumbItem>

<BreadcrumbSeparator>/</BreadcrumbSeparator>

<BreadcrumbItem className="font-bold text-black">
<BreadcrumbLink to="/runs/flow-run/$id" params={{ id: flowRun.id }}>
{flowRun.name}
</BreadcrumbLink>
</BreadcrumbItem>
</BreadcrumbList>
</Breadcrumb>
</div>
);
};

0 comments on commit 308ca66

Please sign in to comment.