Skip to content

Commit

Permalink
[UI v2] feat: Adds query to join filtered flow runs with flow API
Browse files Browse the repository at this point in the history
  • Loading branch information
devinvillarosa committed Feb 22, 2025
1 parent fdc2b8a commit 842d850
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useFilterFlowRunswithFlows } from "./use-filter-flow-runs-with-flows";
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { createFakeFlow, createFakeFlowRun } from "@/mocks";

import type { FlowRun } from "@/api/flow-runs";
import type { Flow } from "@/api/flows";

import { QueryClient } from "@tanstack/react-query";
import { renderHook, waitFor } from "@testing-library/react";
import { buildApiUrl, createWrapper, server } from "@tests/utils";
import { http, HttpResponse } from "msw";
import { describe, expect, it } from "vitest";
import { useFilterFlowRunswithFlows } from "./use-filter-flow-runs-with-flows";

describe("useFilterFlowRunswithFlows", () => {
const mockFilterFlowRunsAPI = (flowRuns: Array<FlowRun>) => {
server.use(
http.post(buildApiUrl("/flow_runs/filter"), () => {
return HttpResponse.json(flowRuns);
}),
);
};

const mockFilterFlowsAPI = (flows: Array<Flow>) => {
server.use(
http.post(buildApiUrl("/flows/filter"), () => {
return HttpResponse.json(flows);
}),
);
};

it("returns a list with no results", async () => {
// SETUP
const queryClient = new QueryClient();

mockFilterFlowRunsAPI([]);

// TEST
const { result } = renderHook(
() => useFilterFlowRunswithFlows({ offset: 0, sort: "START_TIME_ASC" }),
{ wrapper: createWrapper({ queryClient }) },
);

await waitFor(() => expect(result.current.status).toEqual("success"));
expect(result.current.data).toHaveLength(0);
});

it("returns a list with joined flows and flow runs", async () => {
// SETUP
const queryClient = new QueryClient();
const MOCK_FLOW_RUN_0 = createFakeFlowRun({
id: "0",
flow_id: "flow-id-0",
});
const MOCK_FLOW_RUN_1 = createFakeFlowRun({
id: "0",
flow_id: "flow-id-0",
});
const MOCK_FLOW_RUN_2 = createFakeFlowRun({
id: "0",
flow_id: "flow-id-1",
});
const MOCK_FLOW_0 = createFakeFlow({ id: "flow-id-0" });
const MOCK_FLOW_1 = createFakeFlow({ id: "flow-id-1" });

const mockFlowRuns = [MOCK_FLOW_RUN_0, MOCK_FLOW_RUN_1, MOCK_FLOW_RUN_2];
const mockFlows = [MOCK_FLOW_0, MOCK_FLOW_1];
mockFilterFlowRunsAPI(mockFlowRuns);
mockFilterFlowsAPI(mockFlows);

// TEST
const { result } = renderHook(
() => useFilterFlowRunswithFlows({ offset: 0, sort: "NAME_ASC" }),
{ wrapper: createWrapper({ queryClient }) },
);

await waitFor(() => expect(result.current.status).toEqual("success"));

// ASSERT
const EXPECTED = [
{
...MOCK_FLOW_RUN_0,
flow: MOCK_FLOW_0,
},
{
...MOCK_FLOW_RUN_1,
flow: MOCK_FLOW_0,
},
{
...MOCK_FLOW_RUN_2,
flow: MOCK_FLOW_1,
},
];

expect(result.current.data).toEqual(EXPECTED);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { FlowRunsFilter, buildFilterFlowRunsQuery } from "@/api/flow-runs";
import { Flow, buildListFlowsQuery } from "@/api/flows";
import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";

/**
*
* @param filter
* @returns a simplified query object that joins a flow run's pagination data with it's parent flow
*/
export const useFilterFlowRunswithFlows = (filter: FlowRunsFilter) => {
const { data: flowRunsData, error: flowRunsError } = useQuery(
buildFilterFlowRunsQuery(filter),
);

const flowIds = useMemo(() => {
if (!flowRunsData) {
return [];
}
return flowRunsData.map((flowRun) => flowRun.flow_id);
}, [flowRunsData]);

const { data: flows, error: flowsError } = useQuery(
buildListFlowsQuery(
{
flows: { id: { any_: flowIds }, operator: "and_" },
offset: 0,
sort: "CREATED_DESC",
},
{ enabled: flowIds.length > 0 },
),
);

const flowMap = useMemo(() => {
if (!flows) {
return new Map<string, Flow>();
}
return new Map(flows.map((flow) => [flow.id, flow]));
}, [flows]);

// If there's no results from the query, return empty
if (flowRunsData && flowRunsData.length === 0) {
return {
status: "success" as const,
error: null,
data: [],
};
}

if (flowRunsData && flowMap.size > 0) {
return {
status: "success" as const,
error: null,
data: flowRunsData.map((flowRun) => {
const flow = flowMap.get(flowRun.flow_id);
return {
...flowRun,
flow,
};
}),
};
}

if (flowRunsError || flowsError) {
return {
status: "error" as const,
error: flowRunsError || flowsError,
data: undefined,
};
}

return {
status: "pending" as const,
error: null,
data: undefined,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@ export const usePaginateFlowRunswithFlows = (
...paginateFlowRunsData,
results: paginateFlowRunsData.results.map((flowRun) => {
const flow = flowMap.get(flowRun.flow_id);
if (!flow) {
throw new Error("Expecting parent flow to be found");
}
return {
...flowRun,
flow,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { Icon } from "@/components/ui/icons";
import { Typography } from "@/components/ui/typography";
import { pluralize } from "@/utils";

import { FlowRunWithFlow } from "@/api/flow-runs";
import { Checkbox } from "@/components/ui/checkbox";
import { CheckedState } from "@radix-ui/react-checkbox";
import { useMemo } from "react";
import { FlowRunRow } from "./types";
import { useDeleteFlowRunsDialog } from "./use-delete-flow-runs-dialog";

// type FlowRunsRowCountProps = {
Expand All @@ -22,7 +22,7 @@ type CountOnlyProps = {
};
type SelectableProps = {
count: number | undefined;
results: Array<FlowRunWithFlow> | undefined;
results: Array<FlowRunRow> | undefined;
setSelectedRows: (rows: Set<string>) => void;
selectedRows: Set<string>;
};
Expand Down
2 changes: 1 addition & 1 deletion ui-v2/src/components/flow-runs/flow-runs-list/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { FlowRun } from "@/api/flow-runs";
import { Flow } from "@/api/flows";

export type FlowRunRow = FlowRun & {
flow: Flow;
flow?: Flow;
deployment?: Deployment;
};

0 comments on commit 842d850

Please sign in to comment.