feat: POC of useQuery -> mutation and query (#2512)

This commit is contained in:
Cristhian Zanforlin Lousa 2024-07-03 19:16:23 -03:00 • committed by GitHub
commit 9af47895f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 349 additions and 108 deletions

View file

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />

View file

@ -31,6 +31,7 @@
"@tabler/icons-react": "^3.6.0", "@tabler/icons-react": "^3.6.0",
"@tailwindcss/forms": "^0.5.7", "@tailwindcss/forms": "^0.5.7",
"@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/line-clamp": "^0.4.4",
"@tanstack/react-query": "^5.49.2",
"@types/axios": "^0.14.0", "@types/axios": "^0.14.0",
"ace-builds": "^1.35.0", "ace-builds": "^1.35.0",
"ag-grid-community": "^31.3.2", "ag-grid-community": "^31.3.2",
@ -78,6 +79,7 @@
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"uuid": "^10.0.0", "uuid": "^10.0.0",
"vite-plugin-svgr": "^4.2.0", "vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^4.3.2",
"web-vitals": "^4.1.1", "web-vitals": "^4.1.1",
"zod": "^3.23.8", "zod": "^3.23.8",
"zustand": "^4.5.2" "zustand": "^4.5.2"
@ -4260,6 +4262,30 @@
"tailwindcss": ">=3.0.0 || insiders" "tailwindcss": ">=3.0.0 || insiders"
} }
}, },
"node_modules/@tanstack/query-core": {
"version": "5.49.1",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.49.1.tgz",
"integrity": "sha512-JnC9ndmD1KKS01Rt/ovRUB1tmwO7zkyXAyIxN9mznuJrcNtOrkmOnQqdJF2ib9oHzc2VxHomnEG7xyfo54Npkw==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/react-query": {
"version": "5.49.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.49.2.tgz",
"integrity": "sha512-6rfwXDK9BvmHISbNFuGd+wY3P44lyW7lWiA9vIFGT/T0P9aHD1VkjTvcM4SDAIbAQ9ygEZZoLt7dlU1o3NjMVA==",
"dependencies": {
"@tanstack/query-core": "5.49.1"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^18.0.0"
}
},
"node_modules/@tanstack/react-virtual": { "node_modules/@tanstack/react-virtual": {
"version": "3.5.0", "version": "3.5.0",
"resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz", "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.5.0.tgz",
@ -7881,6 +7907,11 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/globrex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="
},
"node_modules/got": { "node_modules/got": {
"version": "11.8.6", "version": "11.8.6",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
@ -13946,6 +13977,25 @@
"code-block-writer": "^12.0.0" "code-block-writer": "^12.0.0"
} }
}, },
"node_modules/tsconfck": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.1.tgz",
"integrity": "sha512-00eoI6WY57SvZEVjm13stEVE90VkEdJAFGgpFLTsZbJyW/LwFQ7uQxJHWpZ2hzSWgCPKc9AnBnNP+0X7o3hAmQ==",
"bin": {
"tsconfck": "bin/tsconfck.js"
},
"engines": {
"node": "^18 || >=20"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/tsconfig-paths": { "node_modules/tsconfig-paths": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
@ -14453,6 +14503,24 @@
"vite": "^2.6.0 || 3 || 4 || 5" "vite": "^2.6.0 || 3 || 4 || 5"
} }
}, },
"node_modules/vite-tsconfig-paths": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-4.3.2.tgz",
"integrity": "sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==",
"dependencies": {
"debug": "^4.1.1",
"globrex": "^0.1.2",
"tsconfck": "^3.0.3"
},
"peerDependencies": {
"vite": "*"
},
"peerDependenciesMeta": {
"vite": {
"optional": true
}
}
},
"node_modules/vite/node_modules/fsevents": { "node_modules/vite/node_modules/fsevents": {
"version": "2.3.3", "version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",

View file

@ -26,6 +26,7 @@
"@tabler/icons-react": "^3.6.0", "@tabler/icons-react": "^3.6.0",
"@tailwindcss/forms": "^0.5.7", "@tailwindcss/forms": "^0.5.7",
"@tailwindcss/line-clamp": "^0.4.4", "@tailwindcss/line-clamp": "^0.4.4",
"@tanstack/react-query": "^5.49.2",
"@types/axios": "^0.14.0", "@types/axios": "^0.14.0",
"ace-builds": "^1.35.0", "ace-builds": "^1.35.0",
"ag-grid-community": "^31.3.2", "ag-grid-community": "^31.3.2",
@ -73,6 +74,7 @@
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
"uuid": "^10.0.0", "uuid": "^10.0.0",
"vite-plugin-svgr": "^4.2.0", "vite-plugin-svgr": "^4.2.0",
"vite-tsconfig-paths": "^4.3.2",
"web-vitals": "^4.1.1", "web-vitals": "^4.1.1",
"zod": "^3.23.8", "zod": "^3.23.8",
"zustand": "^4.5.2" "zustand": "^4.5.2"
@ -133,4 +135,4 @@
"ua-parser-js": "^1.0.38", "ua-parser-js": "^1.0.38",
"vite": "^5.3.1" "vite": "^5.3.1"
} }
} }

View file

@ -1,12 +1,10 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { ErrorBoundary } from "react-error-boundary"; import { ErrorBoundary } from "react-error-boundary";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import "reactflow/dist/style.css"; import "reactflow/dist/style.css";
import "./App.css"; import "./App.css";
import AlertDisplayArea from "./alerts/displayArea"; import AlertDisplayArea from "./alerts/displayArea";
import ErrorAlert from "./alerts/error";
import NoticeAlert from "./alerts/notice";
import SuccessAlert from "./alerts/success";
import CrashErrorComponent from "./components/crashErrorComponent"; import CrashErrorComponent from "./components/crashErrorComponent";
import FetchErrorComponent from "./components/fetchErrorComponent"; import FetchErrorComponent from "./components/fetchErrorComponent";
import LoadingComponent from "./components/loadingComponent"; import LoadingComponent from "./components/loadingComponent";
@ -24,9 +22,10 @@ import useAlertStore from "./stores/alertStore";
import { useDarkStore } from "./stores/darkStore"; import { useDarkStore } from "./stores/darkStore";
import useFlowsManagerStore from "./stores/flowsManagerStore"; import useFlowsManagerStore from "./stores/flowsManagerStore";
import { useFolderStore } from "./stores/foldersStore"; import { useFolderStore } from "./stores/foldersStore";
import { useGlobalVariablesStore } from "./stores/globalVariablesStore/globalVariables";
import { useStoreStore } from "./stores/storeStore";
export default function App() { export default function App() {
const queryClient = new QueryClient();
useTrackLastVisitedPath(); useTrackLastVisitedPath();
const [fetchError, setFetchError] = useState(false); const [fetchError, setFetchError] = useState(false);
@ -35,13 +34,8 @@ export default function App() {
const { isAuthenticated, login, setUserData, setAutoLogin, getUser } = const { isAuthenticated, login, setUserData, setAutoLogin, getUser } =
useContext(AuthContext); useContext(AuthContext);
const setLoading = useAlertStore((state) => state.setLoading); const setLoading = useAlertStore((state) => state.setLoading);
const fetchApiData = useStoreStore((state) => state.fetchApiData);
const refreshVersion = useDarkStore((state) => state.refreshVersion); const refreshVersion = useDarkStore((state) => state.refreshVersion);
const refreshStars = useDarkStore((state) => state.refreshStars); const refreshStars = useDarkStore((state) => state.refreshStars);
const setGlobalVariables = useGlobalVariablesStore(
(state) => state.setGlobalVariables,
);
const checkHasStore = useStoreStore((state) => state.checkHasStore);
const navigate = useNavigate(); const navigate = useNavigate();
const dark = useDarkStore((state) => state.dark); const dark = useDarkStore((state) => state.dark);
@ -160,36 +154,38 @@ export default function App() {
return ( return (
//need parent component with width and height //need parent component with width and height
<div className="flex h-full flex-col"> <div className="flex h-full flex-col">
<ErrorBoundary <QueryClientProvider client={queryClient}>
onReset={() => { <ErrorBoundary
// any reset function onReset={() => {
}} // any reset function
FallbackComponent={CrashErrorComponent} }}
> FallbackComponent={CrashErrorComponent}
<> >
{ <>
<FetchErrorComponent {
description={FETCH_ERROR_DESCRIPION} <FetchErrorComponent
message={FETCH_ERROR_MESSAGE} description={FETCH_ERROR_DESCRIPION}
openModal={fetchError} message={FETCH_ERROR_MESSAGE}
setRetry={() => { openModal={fetchError}
checkApplicationHealth(); setRetry={() => {
}} checkApplicationHealth();
isLoadingHealth={isLoadingHealth} }}
></FetchErrorComponent> isLoadingHealth={isLoadingHealth}
} ></FetchErrorComponent>
}
<Case condition={isLoadingApplication}> <Case condition={isLoadingApplication}>
<div className="loading-page-panel"> <div className="loading-page-panel">
<LoadingComponent remSize={50} /> <LoadingComponent remSize={50} />
</div> </div>
</Case> </Case>
<Case condition={!isLoadingApplication}> <Case condition={!isLoadingApplication}>
<Router /> <Router />
</Case> </Case>
</> </>
</ErrorBoundary> </ErrorBoundary>
</QueryClientProvider>
<div></div> <div></div>
<div className="app-div"> <div className="app-div">
<AlertDisplayArea /> <AlertDisplayArea />

View file

@ -0,0 +1,14 @@
import { BASE_URL_API } from "../../../constants/constants";
export const URLs = {
TRANSACTIONS: `monitor/transactions`,
API_KEY: `api_key`,
} as const;
export function getURL(key: keyof typeof URLs, params: any = {}) {
let url = URLs[key];
Object.keys(params).forEach((key) => (url += `/${params[key]}`));
return `${BASE_URL_API}${url.toString()}`;
}
export type URLsType = typeof URLs;

View file

@ -0,0 +1 @@
export * from "./use-post-add-api-key";

View file

@ -0,0 +1,45 @@
import { useMutationFunctionType } from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
interface IPostAddApiKey {
key: string;
}
// add types for error handling and success
export const usePostAddApiKey: useMutationFunctionType<IPostAddApiKey> = ({
callbackSuccess,
callbackError,
}) => {
const { mutate } = UseRequestProcessor();
const postAddApiKeyFn = async (payload: IPostAddApiKey): Promise<any> => {
return await api.post<any>(`${getURL("API_KEY")}/store`, {
api_key: payload.key,
});
};
const mutation: UseMutationResult<any, any, IPostAddApiKey> = mutate(
["usePostAddApiKey"],
async (payload: IPostAddApiKey) => {
const res = await postAddApiKeyFn(payload);
return res.data;
},
{
onError: (err) => {
if (callbackError) {
callbackError(err);
}
},
onSuccess: (data) => {
if (callbackSuccess) {
callbackSuccess(data);
}
},
},
);
return mutation;
};

View file

@ -0,0 +1 @@
export * from "./use-get-transactions";

View file

@ -0,0 +1,67 @@
import { keepPreviousData } from "@tanstack/react-query";
import { ColDef, ColGroupDef } from "ag-grid-community";
import { useQueryFunctionType } from "../../../../types/api";
import { extractColumnsFromRows } from "../../../../utils/utils";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
interface TransactionsQueryParams {
id: string;
params?: Record<string, unknown>;
}
interface TransactionsResponse {
rows: Array<object>;
columns: Array<ColDef | ColGroupDef>;
}
export const useGetTransactionsQuery: useQueryFunctionType<
TransactionsQueryParams,
TransactionsResponse
> = ({ id, params }, onFetch) => {
const { query } = UseRequestProcessor();
const responseFn = (data: any) => {
if (!onFetch) return data;
if (typeof onFetch === "function") return onFetch(data);
switch (onFetch) {
case "TableUnion": {
const columns = extractColumnsFromRows(data.data, "union");
return { rows: data.data, columns };
}
case "TableIntersection": {
const columns = extractColumnsFromRows(data.data, "intersection");
return { rows: data.data, columns };
}
default:
return data;
}
};
const getTransactionsFn = async (id: string, params = {}) => {
const config = {};
config["params"] = { flow_id: id };
if (params) {
config["params"] = { ...config["params"], ...params };
}
return await api.get<TransactionsResponse>(
`${getURL("TRANSACTIONS")}`,
config,
);
};
const queryResult = query(
["useGetTransactionsQuery"],
async () => {
const rows = await getTransactionsFn(id, params);
return responseFn(rows);
},
{
placeholderData: keepPreviousData,
},
);
return queryResult;
};

View file

@ -0,0 +1,28 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { MutationFunctionType, QueryFunctionType } from "../../../types/api";
export function UseRequestProcessor(): {
query: QueryFunctionType;
mutate: MutationFunctionType;
} {
const queryClient = useQueryClient();
function query(queryKey, queryFn, options = {}) {
return useQuery({
queryKey,
queryFn,
...options,
});
}
function mutate(mutationKey, mutationFn, options = {}) {
return useMutation({
mutationKey,
mutationFn,
onSettled: () => queryClient.invalidateQueries(mutationKey),
...options,
});
}
return { query, mutate };
}

View file

@ -1,8 +1,8 @@
import { useGetTransactionsQuery } from "@/controllers/API/queries/transactions";
import { ColDef, ColGroupDef } from "ag-grid-community"; import { ColDef, ColGroupDef } from "ag-grid-community";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import TableComponent from "../../components/tableComponent"; import TableComponent from "../../components/tableComponent";
import { getTransactionTable } from "../../controllers/API";
import useFlowsManagerStore from "../../stores/flowsManagerStore"; import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { FlowSettingsPropsType } from "../../types/components"; import { FlowSettingsPropsType } from "../../types/components";
import BaseModal from "../baseModal"; import BaseModal from "../baseModal";
@ -16,13 +16,21 @@ export default function FlowLogsModal({
const [columns, setColumns] = useState<Array<ColDef | ColGroupDef>>([]); const [columns, setColumns] = useState<Array<ColDef | ColGroupDef>>([]);
const [rows, setRows] = useState<any>([]); const [rows, setRows] = useState<any>([]);
const { data, isLoading, refetch } = useGetTransactionsQuery(
{
id: currentFlowId,
},
"TableUnion",
);
useEffect(() => { useEffect(() => {
getTransactionTable(currentFlowId, "union").then((data) => { if (data) {
const { columns, rows } = data; const { columns, rows } = data;
setColumns(columns.map((col) => ({ ...col, editable: true }))); setColumns(columns.map((col) => ({ ...col, editable: true })));
setRows(rows); setRows(rows);
}); }
}, [open]); if (open) refetch();
}, [data, open, isLoading]);
return ( return (
<BaseModal open={open} setOpen={setOpen} size="large"> <BaseModal open={open} setOpen={setOpen} size="large">

View file

@ -1,4 +1,5 @@
import { useContext, useState } from "react"; import { usePostAddApiKey } from "@/controllers/API/queries/api-keys";
import { useContext, useEffect, useState } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { CONTROL_PATCH_USER_STATE } from "../../../../constants/constants"; import { CONTROL_PATCH_USER_STATE } from "../../../../constants/constants";
import { AuthContext } from "../../../../contexts/authContext"; import { AuthContext } from "../../../../contexts/authContext";
@ -11,7 +12,6 @@ import {
} from "../../../../types/components"; } from "../../../../types/components";
import usePatchPassword from "../hooks/use-patch-password"; import usePatchPassword from "../hooks/use-patch-password";
import usePatchProfilePicture from "../hooks/use-patch-profile-picture"; import usePatchProfilePicture from "../hooks/use-patch-profile-picture";
import useSaveKey from "../hooks/use-save-key";
import useScrollToElement from "../hooks/use-scroll-to-element"; import useScrollToElement from "../hooks/use-scroll-to-element";
import GeneralPageHeaderComponent from "./components/GeneralPageHeader"; import GeneralPageHeaderComponent from "./components/GeneralPageHeader";
import PasswordFormComponent from "./components/PasswordForm"; import PasswordFormComponent from "./components/PasswordForm";
@ -19,7 +19,7 @@ import ProfilePictureFormComponent from "./components/ProfilePictureForm";
import useGetProfilePictures from "./components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures"; import useGetProfilePictures from "./components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-get-profile-pictures";
import StoreApiKeyFormComponent from "./components/StoreApiKeyForm"; import StoreApiKeyFormComponent from "./components/StoreApiKeyForm";
export default function GeneralPage() { export const GeneralPage = () => {
const setCurrentFlowId = useFlowsManagerStore( const setCurrentFlowId = useFlowsManagerStore(
(state) => state.setCurrentFlowId, (state) => state.setCurrentFlowId,
); );
@ -36,14 +36,15 @@ export default function GeneralPage() {
const setErrorData = useAlertStore((state) => state.setErrorData); const setErrorData = useAlertStore((state) => state.setErrorData);
const { userData, setUserData } = useContext(AuthContext); const { userData, setUserData } = useContext(AuthContext);
const hasStore = useStoreStore((state) => state.hasStore); const hasStore = useStoreStore((state) => state.hasStore);
const validApiKey = useStoreStore((state) => state.validApiKey); const validApiKey = useStoreStore((state) => state.validApiKey);
const hasApiKey = useStoreStore((state) => state.hasApiKey); const hasApiKey = useStoreStore((state) => state.hasApiKey);
const setHasApiKey = useStoreStore((state) => state.updateHasApiKey);
const loadingApiKey = useStoreStore((state) => state.loadingApiKey); const loadingApiKey = useStoreStore((state) => state.loadingApiKey);
const { password, cnfPassword, profilePicture, apikey } = inputState;
const { storeApiKey } = useContext(AuthContext);
const setHasApiKey = useStoreStore((state) => state.updateHasApiKey);
const setValidApiKey = useStoreStore((state) => state.updateValidApiKey); const setValidApiKey = useStoreStore((state) => state.updateValidApiKey);
const setLoadingApiKey = useStoreStore((state) => state.updateLoadingApiKey); const setLoadingApiKey = useStoreStore((state) => state.updateLoadingApiKey);
const { password, cnfPassword, profilePicture, apikey } = inputState;
const { handlePatchPassword } = usePatchPassword( const { handlePatchPassword } = usePatchPassword(
userData, userData,
@ -62,13 +63,31 @@ export default function GeneralPage() {
useScrollToElement(scrollId, setCurrentFlowId); useScrollToElement(scrollId, setCurrentFlowId);
const { handleSaveKey } = useSaveKey( const { mutate } = usePostAddApiKey({
setSuccessData, callbackSuccess: () => {
setErrorData, setSuccessData({ title: "API key saved successfully" });
setHasApiKey, setHasApiKey(true);
setValidApiKey, setValidApiKey(true);
setLoadingApiKey, setLoadingApiKey(false);
); handleInput({ target: { name: "apikey", value: "" } });
},
callbackError: (error) => {
setErrorData({
title: "API key save error",
list: [(error as any)?.response?.data?.detail],
});
setHasApiKey(false);
setValidApiKey(false);
setLoadingApiKey(false);
},
});
const handleSaveKey = (apikey: string) => {
if (apikey) {
mutate({ key: apikey });
storeApiKey(apikey);
}
};
function handleInput({ function handleInput({
target: { name, value }, target: { name, value },
@ -110,4 +129,6 @@ export default function GeneralPage() {
</div> </div>
</div> </div>
); );
} };
export default GeneralPage;

View file

@ -1,48 +0,0 @@
import { useContext } from "react";
import {
API_ERROR_ALERT,
API_SUCCESS_ALERT,
} from "../../../../constants/alerts_constants";
import { AuthContext } from "../../../../contexts/authContext";
import { addApiKeyStore } from "../../../../controllers/API";
const useSaveKey = (
setSuccessData: (data: { title: string }) => void,
setErrorData: (data: { title: string; list: string[] }) => void,
setHasApiKey: (hasApiKey: boolean) => void,
setValidApiKey: (validApiKey: boolean) => void,
setLoadingApiKey: (loadingApiKey: boolean) => void,
) => {
const { storeApiKey } = useContext(AuthContext);
const handleSaveKey = (apikey, handleInput) => {
if (apikey) {
setLoadingApiKey(true);
addApiKeyStore(apikey).then(
() => {
setSuccessData({ title: API_SUCCESS_ALERT });
storeApiKey(apikey);
setHasApiKey(true);
setValidApiKey(true);
setLoadingApiKey(false);
handleInput({ target: { name: "apikey", value: "" } });
},
(error) => {
setErrorData({
title: API_ERROR_ALERT,
list: [error.response.data.detail],
});
setHasApiKey(false);
setValidApiKey(false);
setLoadingApiKey(false);
},
);
}
};
return {
handleSaveKey,
};
};
export default useSaveKey;

View file

@ -1,3 +1,10 @@
import {
MutationFunction,
UndefinedInitialDataOptions,
UseMutationOptions,
UseMutationResult,
UseQueryResult,
} from "@tanstack/react-query";
import { Edge, Node, Viewport } from "reactflow"; import { Edge, Node, Viewport } from "reactflow";
import { ChatInputType, ChatOutputType } from "../chat"; import { ChatInputType, ChatOutputType } from "../chat";
import { FlowType } from "../flow"; import { FlowType } from "../flow";
@ -225,3 +232,28 @@ export type ResponseErrorTypeAPI = {
export type ResponseErrorDetailAPI = { export type ResponseErrorDetailAPI = {
response: { data: { detail: string } }; response: { data: { detail: string } };
}; };
export type useQueryFunctionType<T, R> = (
props: T,
onFetch?: ((data: R) => void) | string,
) => UseQueryResult<R>;
export type QueryFunctionType = (
queryKey: UndefinedInitialDataOptions["queryKey"],
queryFn: UndefinedInitialDataOptions["queryFn"],
options?: Omit<UndefinedInitialDataOptions, "queryKey" | "queryFn">,
) => UseQueryResult<any>;
export type MutationFunctionType = (
mutationKey: UseMutationOptions["mutationKey"],
mutationFn: MutationFunction<any, any>,
options?: Omit<UseMutationOptions<any, any>, "mutationFn" | "mutationKey">,
) => UseMutationResult<any, any, any, any>;
export type useMutationFunctionType<Variables, Data = any, Error = any> = ({
callbackError,
callbackSuccess,
}: {
callbackSuccess: (data: Data) => void;
callbackError: (err: Error) => void;
}) => UseMutationResult<Data, Error, Variables>;

View file

@ -15,7 +15,12 @@
"isolatedModules": true, "isolatedModules": true,
"noEmit": true, "noEmit": true,
"jsx": "react-jsx", "jsx": "react-jsx",
"noImplicitAny": false "noImplicitAny": false,
"paths": {
"@/*": ["*"],
"@queries/*": ["controllers/API/queries/*"]
},
"baseUrl": "src"
}, },
"include": [ "include": [
"src", "src",

View file

@ -3,6 +3,7 @@ import dotenv from "dotenv";
import path from "path"; import path from "path";
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import svgr from "vite-plugin-svgr"; import svgr from "vite-plugin-svgr";
import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig(({ mode }) => { export default defineConfig(({ mode }) => {
dotenv.config({ path: path.resolve(__dirname, "../../.env") }); dotenv.config({ path: path.resolve(__dirname, "../../.env") });
@ -32,7 +33,7 @@ export default defineConfig(({ mode }) => {
define: { define: {
"process.env.BACKEND_URL": JSON.stringify(process.env.BACKEND_URL), "process.env.BACKEND_URL": JSON.stringify(process.env.BACKEND_URL),
}, },
plugins: [react(), svgr()], plugins: [react(), svgr(), tsconfigPaths()],
server: { server: {
port: port, port: port,
proxy: { proxy: {