feat: POC of useQuery -> mutation and query (#2512)
This commit is contained in:
parent
d03a7fd5a3
commit
9af47895f9
16 changed files with 349 additions and 108 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
|
|
||||||
68
src/frontend/package-lock.json
generated
68
src/frontend/package-lock.json
generated
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 />
|
||||||
|
|
|
||||||
14
src/frontend/src/controllers/API/helpers/constants.ts
Normal file
14
src/frontend/src/controllers/API/helpers/constants.ts
Normal 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;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./use-post-add-api-key";
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./use-get-transactions";
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -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 };
|
||||||
|
}
|
||||||
|
|
@ -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">
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
|
|
@ -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>;
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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: {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue