mirror of
https://github.com/StanGirard/quivr.git
synced 2024-12-24 20:03:41 +03:00
Frontent/test/explore/1 (#552)
* refactor(MultipleBrain): separate providing and data fetching * refactor(MultipleBrain): update useBrainApi * feat(MultipleBrains): remove unnecessary data fetchings * test(useBrainApi): update unit tests
This commit is contained in:
parent
0dec4f6bdd
commit
3ba2c92b50
27
frontend/app/App.tsx
Normal file
27
frontend/app/App.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
"use client";
|
||||
|
||||
import { PropsWithChildren, useEffect } from "react";
|
||||
|
||||
import Footer from "@/lib/components/Footer";
|
||||
import { NavBar } from "@/lib/components/NavBar";
|
||||
import { TrackingWrapper } from "@/lib/components/TrackingWrapper";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
|
||||
// This wrapper is used to make effect calls at a high level in app rendering.
|
||||
export const App = ({ children }: PropsWithChildren): JSX.Element => {
|
||||
const { fetchAllBrains, fetchAndSetActiveBrain } = useBrainContext();
|
||||
|
||||
useEffect(() => {
|
||||
void fetchAllBrains();
|
||||
void fetchAndSetActiveBrain();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<TrackingWrapper />
|
||||
<NavBar />
|
||||
<div className="flex-1">{children}</div>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
};
|
@ -2,7 +2,6 @@ import { UUID } from "crypto";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { useBrainApi } from "@/lib/api/brain/useBrainApi";
|
||||
import { getBrainFromLocalStorage } from "@/lib/context/BrainProvider/helpers/brainLocalStorage";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||
import { useAxios } from "@/lib/hooks";
|
||||
@ -14,25 +13,12 @@ export const useExplore = () => {
|
||||
const [isPending, setIsPending] = useState(true);
|
||||
const { session } = useSupabase();
|
||||
const { axiosInstance } = useAxios();
|
||||
const { setActiveBrain, setDefaultBrain, currentBrainId } = useBrainContext();
|
||||
const { currentBrainId } = useBrainContext();
|
||||
const { getBrainDocuments } = useBrainApi();
|
||||
const fetchAndSetActiveBrain = async () => {
|
||||
const storedBrain = getBrainFromLocalStorage();
|
||||
if (storedBrain) {
|
||||
setActiveBrain({ ...storedBrain });
|
||||
|
||||
return storedBrain;
|
||||
} else {
|
||||
const defaultBrain = await setDefaultBrain();
|
||||
|
||||
return defaultBrain;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchDocuments = async (brainId: UUID | null) => {
|
||||
setIsPending(true);
|
||||
await fetchAndSetActiveBrain();
|
||||
try {
|
||||
if (brainId === null) {
|
||||
throw new Error("Brain id not found");
|
||||
|
@ -3,13 +3,12 @@ import { Analytics } from "@vercel/analytics/react";
|
||||
import { Inter } from "next/font/google";
|
||||
import { cookies, headers } from "next/headers";
|
||||
|
||||
import Footer from "@/lib/components/Footer";
|
||||
import { NavBar } from "@/lib/components/NavBar";
|
||||
import { TrackingWrapper } from "@/lib/components/TrackingWrapper";
|
||||
import { ToastProvider } from "@/lib/components/ui/Toast";
|
||||
import { BrainConfigProvider } from "@/lib/context/BrainConfigProvider";
|
||||
import { BrainProvider } from "@/lib/context/BrainProvider";
|
||||
import { SupabaseProvider } from "@/lib/context/SupabaseProvider";
|
||||
|
||||
import { App } from "./App";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
@ -43,10 +42,9 @@ const RootLayout = async ({
|
||||
<SupabaseProvider session={session}>
|
||||
<BrainConfigProvider>
|
||||
<BrainProvider>
|
||||
<TrackingWrapper />
|
||||
<NavBar />
|
||||
<div className="flex-1">{children}</div>
|
||||
<Footer />
|
||||
<App>
|
||||
<div className="flex-1">{children}</div>
|
||||
</App>
|
||||
</BrainProvider>
|
||||
</BrainConfigProvider>
|
||||
</SupabaseProvider>
|
||||
|
@ -1,39 +1,15 @@
|
||||
/* eslint-disable */
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import { Divider } from "@/lib/components/ui/Divider";
|
||||
import PageHeading from "@/lib/components/ui/PageHeading";
|
||||
import { getBrainFromLocalStorage } from "@/lib/context/BrainProvider/helpers/brainLocalStorage";
|
||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||
|
||||
|
||||
import { Crawler } from "./components/Crawler";
|
||||
import { FileUploader } from "./components/FileUploader";
|
||||
|
||||
const UploadPage = (): JSX.Element => {
|
||||
const { setActiveBrain, setDefaultBrain } = useBrainContext();
|
||||
|
||||
const fetchAndSetActiveBrain = async () => {
|
||||
const storedBrain = getBrainFromLocalStorage();
|
||||
if (storedBrain) {
|
||||
setActiveBrain({ ...storedBrain });
|
||||
return storedBrain;
|
||||
} else {
|
||||
const defaultBrain = await setDefaultBrain();
|
||||
return defaultBrain;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBrains = async () => {
|
||||
await fetchAndSetActiveBrain();
|
||||
};
|
||||
fetchBrains();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<main className="pt-10">
|
||||
<PageHeading
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { renderHook } from "@testing-library/react";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
@ -9,17 +10,28 @@ const axiosGetMock = vi.fn(() => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const axiosPostMock = vi.fn(() => ({
|
||||
data: {
|
||||
id: "123",
|
||||
name: "Test Brain",
|
||||
},
|
||||
}));
|
||||
|
||||
const axiosDeleteMock = vi.fn(() => ({}));
|
||||
|
||||
vi.mock("@/lib/hooks", () => ({
|
||||
useAxios: vi.fn(() => ({
|
||||
axiosInstance: {
|
||||
get: axiosGetMock,
|
||||
post: axiosPostMock,
|
||||
delete: axiosDeleteMock,
|
||||
},
|
||||
})),
|
||||
}));
|
||||
|
||||
describe("useBrainApi", () => {
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should call getBrainDocuments with the correct parameters", async () => {
|
||||
@ -34,4 +46,67 @@ describe("useBrainApi", () => {
|
||||
expect(axiosGetMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosGetMock).toHaveBeenCalledWith(`/explore/?brain_id=${brainId}`);
|
||||
});
|
||||
|
||||
it("should call createBrain with the correct parameters", async () => {
|
||||
const {
|
||||
result: {
|
||||
current: { createBrain },
|
||||
},
|
||||
} = renderHook(() => useBrainApi());
|
||||
const name = "Test Brain";
|
||||
await createBrain(name);
|
||||
|
||||
expect(axiosPostMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosPostMock).toHaveBeenCalledWith("/brains/", { name });
|
||||
});
|
||||
|
||||
it("should call deleteBrain with the correct parameters", async () => {
|
||||
const {
|
||||
result: {
|
||||
current: { deleteBrain },
|
||||
},
|
||||
} = renderHook(() => useBrainApi());
|
||||
const id = "123";
|
||||
await deleteBrain(id);
|
||||
|
||||
expect(axiosDeleteMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosDeleteMock).toHaveBeenCalledWith(`/brains/${id}/`);
|
||||
});
|
||||
|
||||
it("should call getDefaultBrain with the correct parameters", async () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getDefaultBrain },
|
||||
},
|
||||
} = renderHook(() => useBrainApi());
|
||||
await getDefaultBrain();
|
||||
|
||||
expect(axiosGetMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosGetMock).toHaveBeenCalledWith("/brains/default/");
|
||||
});
|
||||
|
||||
it("should call getBrains with the correct parameters", async () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getBrains },
|
||||
},
|
||||
} = renderHook(() => useBrainApi());
|
||||
await getBrains();
|
||||
|
||||
expect(axiosGetMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosGetMock).toHaveBeenCalledWith("/brains/");
|
||||
});
|
||||
|
||||
it("should call getBrain with the correct parameters", async () => {
|
||||
const {
|
||||
result: {
|
||||
current: { getBrain },
|
||||
},
|
||||
} = renderHook(() => useBrainApi());
|
||||
const id = "123";
|
||||
await getBrain(id);
|
||||
|
||||
expect(axiosGetMock).toHaveBeenCalledTimes(1);
|
||||
expect(axiosGetMock).toHaveBeenCalledWith(`/brains/${id}/`);
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { AxiosInstance } from "axios";
|
||||
|
||||
import { Brain } from "@/lib/context/BrainProvider/types";
|
||||
import { Document } from "@/lib/types/Document";
|
||||
|
||||
export const getBrainDocuments = async (
|
||||
@ -12,3 +13,49 @@ export const getBrainDocuments = async (
|
||||
|
||||
return response.data.documents;
|
||||
};
|
||||
|
||||
export const createBrain = async (
|
||||
name: string,
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Brain> => {
|
||||
const createdBrain = (await axiosInstance.post<Brain>(`/brains/`, { name }))
|
||||
.data;
|
||||
|
||||
return createdBrain;
|
||||
};
|
||||
|
||||
export const getBrain = async (
|
||||
brainId: string,
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Brain | undefined> => {
|
||||
const brain = (
|
||||
await axiosInstance.get<Brain | undefined>(`/brains/${brainId}/`)
|
||||
).data;
|
||||
|
||||
return brain;
|
||||
};
|
||||
|
||||
export const deleteBrain = async (
|
||||
brainId: string,
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<void> => {
|
||||
await axiosInstance.delete(`/brains/${brainId}/`);
|
||||
};
|
||||
|
||||
export const getDefaultBrain = async (
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Brain | undefined> => {
|
||||
const defaultBrain = (await axiosInstance.get<Brain>(`/brains/default/`))
|
||||
.data;
|
||||
|
||||
return { id: defaultBrain.id, name: defaultBrain.name };
|
||||
};
|
||||
|
||||
export const getBrains = async (
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Brain[]> => {
|
||||
const brains = (await axiosInstance.get<{ brains: Brain[] }>(`/brains/`))
|
||||
.data;
|
||||
|
||||
return brains.brains;
|
||||
};
|
||||
|
@ -1,6 +1,13 @@
|
||||
import { useAxios } from "@/lib/hooks";
|
||||
|
||||
import { getBrainDocuments } from "./brain";
|
||||
import {
|
||||
createBrain,
|
||||
deleteBrain,
|
||||
getBrain,
|
||||
getBrainDocuments,
|
||||
getBrains,
|
||||
getDefaultBrain,
|
||||
} from "./brain";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const useBrainApi = () => {
|
||||
@ -9,5 +16,10 @@ export const useBrainApi = () => {
|
||||
return {
|
||||
getBrainDocuments: async (brainId: string) =>
|
||||
getBrainDocuments(brainId, axiosInstance),
|
||||
createBrain: async (name: string) => createBrain(name, axiosInstance),
|
||||
deleteBrain: async (id: string) => deleteBrain(id, axiosInstance),
|
||||
getDefaultBrain: async () => getDefaultBrain(axiosInstance),
|
||||
getBrains: async () => getBrains(axiosInstance),
|
||||
getBrain: async (id: string) => getBrain(id, axiosInstance),
|
||||
};
|
||||
};
|
||||
|
@ -1,76 +0,0 @@
|
||||
import { AxiosInstance } from "axios";
|
||||
import { UUID } from "crypto";
|
||||
|
||||
import { Brain } from "../context/BrainProvider/types";
|
||||
|
||||
export const createBrainFromBackend = async (
|
||||
axiosInstance: AxiosInstance,
|
||||
name: string
|
||||
): Promise<Brain | undefined> => {
|
||||
try {
|
||||
const createdBrain = (await axiosInstance.post<Brain>(`/brains/`, { name }))
|
||||
.data;
|
||||
|
||||
return createdBrain;
|
||||
} catch (error) {
|
||||
console.error(`Error creating brain ${name}`, error);
|
||||
}
|
||||
};
|
||||
|
||||
export const getUserDefaultBrainFromBackend = async (
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Brain | undefined> => {
|
||||
try {
|
||||
const defaultBrain = (await axiosInstance.get<Brain>(`/brains/default/`))
|
||||
.data;
|
||||
|
||||
return { id: defaultBrain.id, name: defaultBrain.name };
|
||||
} catch (error) {
|
||||
console.error(`Error getting user's default brain`, error);
|
||||
}
|
||||
};
|
||||
|
||||
export const getBrainFromBE = async (
|
||||
axiosInstance: AxiosInstance,
|
||||
brainId: UUID
|
||||
): Promise<Brain | undefined> => {
|
||||
try {
|
||||
const brain = (await axiosInstance.get<Brain>(`/brains/${brainId}/`)).data;
|
||||
|
||||
return brain;
|
||||
} catch (error) {
|
||||
console.error(`Error getting brain ${brainId}`, error);
|
||||
|
||||
throw new Error(`Error getting brain ${brainId}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const deleteBrainFromBE = async (
|
||||
axiosInstance: AxiosInstance,
|
||||
brainId: UUID
|
||||
): Promise<void> => {
|
||||
try {
|
||||
(await axiosInstance.delete(`/brains/${brainId}/`)).data;
|
||||
} catch (error) {
|
||||
console.error(`Error deleting brain ${brainId}`, error);
|
||||
|
||||
throw new Error(`Error deleting brain ${brainId}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const getAllUserBrainsFromBE = async (
|
||||
axiosInstance: AxiosInstance
|
||||
): Promise<Brain[] | undefined> => {
|
||||
try {
|
||||
const brains = (await axiosInstance.get<{ brains: Brain[] }>(`/brains/`))
|
||||
.data;
|
||||
|
||||
console.log("BRAINS", brains);
|
||||
|
||||
return brains.brains;
|
||||
} catch (error) {
|
||||
console.error(`Error getting brain for current user}`, error);
|
||||
|
||||
throw new Error(`Error getting brain for current user`);
|
||||
}
|
||||
};
|
@ -1 +0,0 @@
|
||||
export * from "./brains";
|
@ -2,7 +2,7 @@
|
||||
|
||||
import { createContext } from "react";
|
||||
|
||||
import { useBrainState } from "./hooks/useBrainState";
|
||||
import { useBrainProvider } from "./hooks/useBrainProvider";
|
||||
import { BrainContextType } from "./types";
|
||||
|
||||
export const BrainContext = createContext<BrainContextType | undefined>(
|
||||
@ -14,9 +14,11 @@ export const BrainProvider = ({
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}): JSX.Element => {
|
||||
const brainState = useBrainState();
|
||||
const brainProviderUtils = useBrainProvider();
|
||||
|
||||
return (
|
||||
<BrainContext.Provider value={brainState}>{children}</BrainContext.Provider>
|
||||
<BrainContext.Provider value={brainProviderUtils}>
|
||||
{children}
|
||||
</BrainContext.Provider>
|
||||
);
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { useContext } from "react";
|
||||
|
||||
import { BrainStateProps } from "./useBrainState";
|
||||
import { BrainContext } from "../brain-provider";
|
||||
import { BrainContextType } from "../types";
|
||||
|
||||
export const useBrainContext = (): BrainStateProps => {
|
||||
export const useBrainContext = (): BrainContextType => {
|
||||
const context = useContext(BrainContext);
|
||||
|
||||
if (context === undefined) {
|
||||
|
108
frontend/lib/context/BrainProvider/hooks/useBrainProvider.ts
Normal file
108
frontend/lib/context/BrainProvider/hooks/useBrainProvider.ts
Normal file
@ -0,0 +1,108 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { UUID } from "crypto";
|
||||
import { useCallback, useState } from "react";
|
||||
|
||||
import { useBrainApi } from "@/lib/api/brain/useBrainApi";
|
||||
import { useToast } from "@/lib/hooks";
|
||||
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
||||
|
||||
import {
|
||||
getBrainFromLocalStorage,
|
||||
saveBrainInLocalStorage,
|
||||
} from "../helpers/brainLocalStorage";
|
||||
import { Brain } from "../types";
|
||||
|
||||
// CAUTION: This hook should be use in BrainProvider only. You may be need `useBrainContext` instead.
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const useBrainProvider = () => {
|
||||
const { publish } = useToast();
|
||||
const { track } = useEventTracking();
|
||||
const { createBrain, deleteBrain, getBrains, getDefaultBrain } =
|
||||
useBrainApi();
|
||||
|
||||
const [allBrains, setAllBrains] = useState<Brain[]>([]);
|
||||
const [currentBrainId, setCurrentBrainId] = useState<null | UUID>(null);
|
||||
const [isFetchingBrains, setIsFetchingBrains] = useState(false);
|
||||
|
||||
const currentBrain = allBrains.find((brain) => brain.id === currentBrainId);
|
||||
|
||||
const createBrainHandler = async (
|
||||
name: string
|
||||
): Promise<UUID | undefined> => {
|
||||
const createdBrain = await createBrain(name);
|
||||
try {
|
||||
setAllBrains((prevBrains) => [...prevBrains, createdBrain]);
|
||||
saveBrainInLocalStorage(createdBrain);
|
||||
void track("BRAIN_CREATED");
|
||||
|
||||
return createdBrain.id;
|
||||
} catch {
|
||||
publish({
|
||||
variant: "danger",
|
||||
text: "Error occured while creating a brain",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const deleteBrainHandler = async (id: UUID) => {
|
||||
await deleteBrain(id);
|
||||
setAllBrains((prevBrains) => prevBrains.filter((brain) => brain.id !== id));
|
||||
void track("DELETE_BRAIN");
|
||||
};
|
||||
|
||||
const fetchAllBrains = useCallback(async () => {
|
||||
setIsFetchingBrains(true);
|
||||
try {
|
||||
const brains = await getBrains();
|
||||
setAllBrains(brains);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
setIsFetchingBrains(false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const setActiveBrain = useCallback(
|
||||
({ id, name }: { id: UUID; name: string }) => {
|
||||
const newActiveBrain = { id, name };
|
||||
saveBrainInLocalStorage(newActiveBrain);
|
||||
setCurrentBrainId(id);
|
||||
void track("CHANGE_BRAIN");
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const setDefaultBrain = useCallback(async () => {
|
||||
const defaultBrain = await getDefaultBrain();
|
||||
if (defaultBrain !== undefined) {
|
||||
saveBrainInLocalStorage(defaultBrain);
|
||||
setActiveBrain({ ...defaultBrain });
|
||||
} else {
|
||||
console.warn("No brains found");
|
||||
}
|
||||
}, [setActiveBrain]);
|
||||
|
||||
const fetchAndSetActiveBrain = useCallback(async () => {
|
||||
const storedBrain = getBrainFromLocalStorage();
|
||||
if (storedBrain?.id !== undefined) {
|
||||
setActiveBrain({ ...storedBrain });
|
||||
} else {
|
||||
await setDefaultBrain();
|
||||
}
|
||||
}, [setDefaultBrain, setActiveBrain]);
|
||||
|
||||
return {
|
||||
currentBrain,
|
||||
currentBrainId,
|
||||
allBrains,
|
||||
createBrain: createBrainHandler,
|
||||
deleteBrain: deleteBrainHandler,
|
||||
setActiveBrain,
|
||||
fetchAllBrains,
|
||||
setDefaultBrain,
|
||||
fetchAndSetActiveBrain,
|
||||
isFetchingBrains,
|
||||
setIsFetchingBrains,
|
||||
};
|
||||
};
|
@ -1,148 +0,0 @@
|
||||
/* eslint-disable max-lines */
|
||||
import { UUID } from "crypto";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import {
|
||||
createBrainFromBackend,
|
||||
deleteBrainFromBE,
|
||||
getAllUserBrainsFromBE,
|
||||
getBrainFromBE,
|
||||
getUserDefaultBrainFromBackend,
|
||||
} from "@/lib/api";
|
||||
import { useAxios, useToast } from "@/lib/hooks";
|
||||
import { useEventTracking } from "@/services/analytics/useEventTracking";
|
||||
|
||||
import {
|
||||
getBrainFromLocalStorage,
|
||||
saveBrainInLocalStorage,
|
||||
} from "../helpers/brainLocalStorage";
|
||||
import { Brain } from "../types";
|
||||
|
||||
export interface BrainStateProps {
|
||||
currentBrain: Brain | undefined;
|
||||
currentBrainId: UUID | null;
|
||||
allBrains: Brain[];
|
||||
createBrain: (name: string) => Promise<UUID | undefined>;
|
||||
deleteBrain: (id: UUID) => Promise<void>;
|
||||
setActiveBrain: ({ id, name }: { id: UUID; name: string }) => void;
|
||||
getBrainWithId: (brainId: UUID) => Promise<Brain>;
|
||||
fetchAllBrains: () => Promise<void>;
|
||||
setDefaultBrain: () => Promise<void>;
|
||||
}
|
||||
|
||||
export const useBrainState = (): BrainStateProps => {
|
||||
const { publish } = useToast();
|
||||
|
||||
const [allBrains, setAllBrains] = useState<Brain[]>([]);
|
||||
const [currentBrainId, setCurrentBrainId] = useState<null | UUID>(null);
|
||||
const { axiosInstance } = useAxios();
|
||||
|
||||
const { track } = useEventTracking();
|
||||
|
||||
const currentBrain = allBrains.find((brain) => brain.id === currentBrainId);
|
||||
|
||||
// options: Record<string, string | unknown>;
|
||||
|
||||
const createBrain = async (name: string): Promise<UUID | undefined> => {
|
||||
const createdBrain = await createBrainFromBackend(axiosInstance, name);
|
||||
if (createdBrain !== undefined) {
|
||||
setAllBrains((prevBrains) => [...prevBrains, createdBrain]);
|
||||
saveBrainInLocalStorage(createdBrain);
|
||||
void track("BRAIN_CREATED");
|
||||
|
||||
return createdBrain.id;
|
||||
} else {
|
||||
publish({
|
||||
variant: "danger",
|
||||
text: "Error occured while creating a brain",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const deleteBrain = async (id: UUID) => {
|
||||
await deleteBrainFromBE(axiosInstance, id);
|
||||
setAllBrains((prevBrains) => prevBrains.filter((brain) => brain.id !== id));
|
||||
void track("DELETE_BRAIN");
|
||||
};
|
||||
|
||||
const getBrainWithId = async (brainId: UUID): Promise<Brain> => {
|
||||
const brain =
|
||||
allBrains.find(({ id }) => id === brainId) ??
|
||||
(await getBrainFromBE(axiosInstance, brainId));
|
||||
|
||||
if (brain === undefined) {
|
||||
throw new Error(`Error finding brain ${brainId}`);
|
||||
}
|
||||
|
||||
return brain;
|
||||
};
|
||||
|
||||
const fetchAllBrains = useCallback(async () => {
|
||||
try {
|
||||
console.log("Fetching all brains for a user");
|
||||
const brains = await getAllUserBrainsFromBE(axiosInstance);
|
||||
console.log(brains);
|
||||
setAllBrains(brains ?? []);
|
||||
console.log("Fetched all brains for user");
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}, [axiosInstance]);
|
||||
|
||||
const setActiveBrain = useCallback(
|
||||
({ id, name }: { id: UUID; name: string }) => {
|
||||
const newActiveBrain = { id, name };
|
||||
saveBrainInLocalStorage(newActiveBrain);
|
||||
setCurrentBrainId(id);
|
||||
console.log("Setting active brain", newActiveBrain);
|
||||
void track("CHANGE_BRAIN");
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const setDefaultBrain = useCallback(async () => {
|
||||
console.log("Setting default brain");
|
||||
const defaultBrain = await getUserDefaultBrainFromBackend(axiosInstance);
|
||||
console.log("defaultBrain", defaultBrain);
|
||||
if (defaultBrain) {
|
||||
saveBrainInLocalStorage(defaultBrain);
|
||||
setActiveBrain({ ...defaultBrain });
|
||||
} else {
|
||||
console.warn("No brains found");
|
||||
}
|
||||
}, [axiosInstance, setActiveBrain]);
|
||||
|
||||
const fetchAndSetActiveBrain = useCallback(async () => {
|
||||
console.log(
|
||||
"Fetching and setting active brain use effect in useBrainState"
|
||||
);
|
||||
const storedBrain = getBrainFromLocalStorage();
|
||||
if (storedBrain?.id !== undefined) {
|
||||
console.log("Setting active brain from local storage");
|
||||
console.log("storedBrain", storedBrain);
|
||||
setActiveBrain({ ...storedBrain });
|
||||
} else {
|
||||
console.log("Setting default brain for first time");
|
||||
await setDefaultBrain();
|
||||
}
|
||||
}, [setDefaultBrain, setActiveBrain]);
|
||||
|
||||
useEffect(() => {
|
||||
void fetchAllBrains();
|
||||
|
||||
console.log("brainId", currentBrainId);
|
||||
void fetchAndSetActiveBrain();
|
||||
}, [fetchAllBrains, fetchAndSetActiveBrain, currentBrainId]);
|
||||
|
||||
return {
|
||||
currentBrain,
|
||||
currentBrainId,
|
||||
allBrains,
|
||||
createBrain,
|
||||
deleteBrain,
|
||||
setActiveBrain,
|
||||
getBrainWithId,
|
||||
fetchAllBrains,
|
||||
setDefaultBrain,
|
||||
};
|
||||
};
|
@ -2,7 +2,7 @@ import { UUID } from "crypto";
|
||||
|
||||
import { Document } from "@/lib/types/Document";
|
||||
|
||||
import { useBrainState } from "./hooks/useBrainState";
|
||||
import { useBrainProvider } from "./hooks/useBrainProvider";
|
||||
|
||||
export type Brain = {
|
||||
id: UUID;
|
||||
@ -14,4 +14,4 @@ export type Brain = {
|
||||
temperature?: string;
|
||||
};
|
||||
|
||||
export type BrainContextType = ReturnType<typeof useBrainState>;
|
||||
export type BrainContextType = ReturnType<typeof useBrainProvider>;
|
||||
|
Loading…
Reference in New Issue
Block a user