Skip to content

Commit

Permalink
[UI v2] feat: adds query to join flow runs with parent flow
Browse files Browse the repository at this point in the history
  • Loading branch information
devinvillarosa committed Feb 20, 2025
1 parent d73a001 commit 4a69fe8
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { usePaginateFlowRunswithFlows } from "./use-paginate-flow-runs-with-flows";
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
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 { usePaginateFlowRunswithFlows } from "./use-paginate-flow-runs-with-flows";

describe("usePaginateFlowRunswithFlows", () => {
const mockPaginateFlowRunsAPI = (flowRuns: Array<FlowRun>) => {
server.use(
http.post(buildApiUrl("/flow_runs/paginate"), () => {
return HttpResponse.json({
limit: 10,
page: 1,
pages: 1,
results: flowRuns,
count: flowRuns.length,
});
}),
);
};

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

it("returns maps of the different sources used in an automation", 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];
mockPaginateFlowRunsAPI(mockFlowRuns);
mockFilterFlowsAPI(mockFlows);

// TEST
const { result } = renderHook(
() => usePaginateFlowRunswithFlows({ page: 1, 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?.results).toEqual(EXPECTED);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
type FlowRunsPaginateFilter,
buildPaginateFlowRunsQuery,
} 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 usePaginateFlowRunswithFlows = (
filter: FlowRunsPaginateFilter,
) => {
const { data: paginateFlowRunsData, error: paginateFlowRunsError } = useQuery(
buildPaginateFlowRunsQuery(filter),
);

const flowIds = useMemo(() => {
if (!paginateFlowRunsData) {
return new Set<string>();
}
const flowIds = paginateFlowRunsData.results.map(
(flowRun) => flowRun.flow_id,
);
return new Set<string>(flowIds);
}, [paginateFlowRunsData]);

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

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

if (paginateFlowRunsData && flowMap.size > 0) {
return {
status: "success" as const,
error: null,
data: {
...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,
};
}),
},
};
}

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

return {
status: "pending" as const,
error: null,
data: undefined,
};
};

0 comments on commit 4a69fe8

Please sign in to comment.