diff --git a/src/frontend/src/controllers/API/helpers/constants.ts b/src/frontend/src/controllers/API/helpers/constants.ts index 26a6b696d035..0bdba73f80e3 100644 --- a/src/frontend/src/controllers/API/helpers/constants.ts +++ b/src/frontend/src/controllers/API/helpers/constants.ts @@ -20,6 +20,7 @@ export const URLs = { VARIABLES: `variables`, VALIDATE: `validate`, CONFIG: `config`, + STARTER_PROJECTS: `starter-projects`, } as const; export function getURL(key: keyof typeof URLs, params: any = {}) { diff --git a/src/frontend/src/controllers/API/queries/starter-projects/index.ts b/src/frontend/src/controllers/API/queries/starter-projects/index.ts new file mode 100644 index 000000000000..ad878f5e41f2 --- /dev/null +++ b/src/frontend/src/controllers/API/queries/starter-projects/index.ts @@ -0,0 +1 @@ +export * from "./use-get-starter-projects"; diff --git a/src/frontend/src/controllers/API/queries/starter-projects/use-get-starter-projects.ts b/src/frontend/src/controllers/API/queries/starter-projects/use-get-starter-projects.ts new file mode 100644 index 000000000000..4e2b27911db0 --- /dev/null +++ b/src/frontend/src/controllers/API/queries/starter-projects/use-get-starter-projects.ts @@ -0,0 +1,44 @@ +import { useDarkStore } from "@/stores/darkStore"; +import { useQueryFunctionType } from "@/types/api"; +import { api } from "../../api"; +import { getURL } from "../../helpers/constants"; +import { UseRequestProcessor } from "../../services/request-processor"; + +export interface IStarterProjectsDataArray { + name: string; + last_used_at: string | null; + total_uses: number; + is_active: boolean; + id: string; + api_key: string; + user_id: string; + created_at: string; +} + +interface IApiQueryResponse { + total_count: number; + user_id: string; + api_keys: Array; +} + +export const useGetStarterProjectsQuery: useQueryFunctionType< + undefined, + IApiQueryResponse +> = (_, options) => { + const { query } = UseRequestProcessor(); + + const getStarterProjectsFn = async () => { + return await api.get(`${getURL("STARTER_PROJECTS")}/`); + }; + + const responseFn = async () => { + const { data } = await getStarterProjectsFn(); + return data; + }; + + const queryResult = query(["useGetStarterProjectsQuery"], responseFn, { + ...options, + }); + + return queryResult; +}; diff --git a/src/frontend/src/pages/AppWrapperPage/index.tsx b/src/frontend/src/pages/AppWrapperPage/index.tsx index 154a82733d5e..595ccbd198ae 100644 --- a/src/frontend/src/pages/AppWrapperPage/index.tsx +++ b/src/frontend/src/pages/AppWrapperPage/index.tsx @@ -49,8 +49,6 @@ export function AppWrapperPage() { const [retryCount, setRetryCount] = useState(0); - console.log(healthCheckMaxRetries); - useEffect(() => { const isServerBusy = (error as AxiosError)?.response?.status === 503 || diff --git a/src/frontend/tests/end-to-end/starter-projects.spec.ts b/src/frontend/tests/end-to-end/starter-projects.spec.ts new file mode 100644 index 000000000000..12c116082989 --- /dev/null +++ b/src/frontend/tests/end-to-end/starter-projects.spec.ts @@ -0,0 +1,91 @@ +const { test, expect } = require("@playwright/test"); + +test("vector store from starter projects should have its connections and nodes on the flow", async ({ + page, + request, +}) => { + const response = await request.get("/api/v1/starter-projects"); + expect(response.status()).toBe(200); + const responseBody = await response.json(); + + const astraStarterProject = responseBody.find((project) => { + if (project.data.nodes) { + return project.data.nodes.some((node) => node.id.includes("Astra")); + } + }); + + await page.route("**/api/v1/flows/", async (route) => { + if (route.request().method() === "GET") { + try { + const response = await route.fetch(); + const flowsData = await response.json(); + + const modifiedFlows = flowsData.map((flow) => { + if (flow.name === "Vector Store RAG" && flow.user_id === null) { + return { + ...flow, + data: astraStarterProject?.data, + }; + } + return flow; + }); + + const modifiedResponse = JSON.stringify(modifiedFlows); + + route.fulfill({ + status: response.status(), + headers: response.headers(), + body: modifiedResponse, + }); + } catch (error) { + console.error("Error in route handler:", error); + } + } else { + // If not a GET request, continue without modifying + await route.continue(); + } + }); + + await page.goto("/"); + + await page.waitForSelector('[data-testid="mainpage_title"]', { + timeout: 30000, + }); + + await page.waitForSelector('[id="new-project-btn"]', { + timeout: 30000, + }); + + let modalCount = 0; + try { + const modalTitleElement = await page?.getByTestId("modal-title"); + if (modalTitleElement) { + modalCount = await modalTitleElement.count(); + } + } catch (error) { + modalCount = 0; + } + + while (modalCount === 0) { + await page.getByText("New Project", { exact: true }).click(); + await page.waitForTimeout(3000); + modalCount = await page.getByTestId("modal-title")?.count(); + } + + await page.getByRole("heading", { name: "Vector Store RAG" }).click(); + await page.waitForSelector('[title="fit view"]', { + timeout: 100000, + }); + + await page.getByTitle("fit view").click(); + await page.getByTitle("zoom out").click(); + + const edges = await page.locator(".react-flow__edge-interaction").count(); + const nodes = await page.getByTestId("div-generic-node").count(); + + const edgesFromServer = astraStarterProject?.data.edges.length; + const nodesFromServer = astraStarterProject?.data.nodes.length; + + expect(edges).toBe(edgesFromServer); + expect(nodes).toBe(nodesFromServer); +});