refactor: add useQuery management on globalVariables CRUD (#3121)

*  (App.tsx): Add useGetGlobalVariables hook to fetch global variables data
🔧 (addNewVariableButton.tsx): Replace registerGlobalVariable function with usePostGlobalVariables hook for adding new global variables
🔧 (inputGlobalComponent/index.tsx): Replace deleteGlobalVariable function with useDeleteGlobalVariables hook for deleting global variables
🔧 (authContext.tsx): Remove unused getGlobalVariables function and setGlobalVariables state from authContext
🔧 (constants.ts): Add VARIABLES constant for global variables endpoint
🔧 (index.ts): Remove getGlobalVariables, registerGlobalVariable, and deleteGlobalVariable functions from API index
 (variables/index.ts): Add use-delete-global-variables hook for deleting global variables
🔧 (use-delete-global-variables.ts): Implement useDeleteGlobalVariables hook for deleting global variables

 (use-get-global-variables.ts): Add functionality to fetch and set global variables from API
 (use-patch-global-variables.ts): Add functionality to update global variables via API patch request
 (use-post-global-variables.ts): Add functionality to create new global variables via API post request
📝 (index.tsx): Import useGetGlobalVariables hook to fetch global variables on login page
📝 (index.tsx): Call mutateGetGlobalVariables function to fetch global variables on successful login
📝 (index.tsx): Import useDeleteGlobalVariables hook to delete global variables on global variables page
📝 (index.tsx): Call mutateDeleteGlobalVariable function to delete selected global variables
📝 (index.tsx): Handle success and error cases for deleting global variables

* Removed console.log

---------

Co-authored-by: Lucas Oliveira <62335616+lucaseduoli@users.noreply.github.com>
This commit is contained in:
Cristhian Zanforlin Lousa 2024-07-31 16:49:54 -03:00 committed by GitHub
commit 61c921e1ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 236 additions and 94 deletions

View file

@ -16,6 +16,7 @@ import {
import { AuthContext } from "./contexts/authContext";
import { autoLogin } from "./controllers/API";
import { useGetHealthQuery } from "./controllers/API/queries/health";
import { useGetGlobalVariables } from "./controllers/API/queries/variables";
import { useGetVersionQuery } from "./controllers/API/queries/version";
import { setupAxiosDefaults } from "./controllers/API/utils";
import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path";
@ -42,6 +43,8 @@ export default function App() {
const isLoadingFolders = useFolderStore((state) => state.isLoadingFolders);
const { mutate: mutateGetGlobalVariables } = useGetGlobalVariables();
const {
data: healthData,
isFetching: fetchingHealth,
@ -66,6 +69,7 @@ export default function App() {
if (user && user["access_token"]) {
user["refresh_token"] = "auto";
login(user["access_token"], "auto");
mutateGetGlobalVariables();
setUserData(user);
setAutoLogin(true);
fetchAllData();
@ -99,6 +103,7 @@ export default function App() {
*/
return () => abortController.abort();
}, []);
const fetchAllData = async () => {
setTimeout(async () => {
await Promise.all([refreshStars(), fetchData()]);

View file

@ -1,5 +1,5 @@
import { usePostGlobalVariables } from "@/controllers/API/queries/variables";
import { useState } from "react";
import { registerGlobalVariable } from "../../controllers/API";
import BaseModal from "../../modals/baseModal";
import useAlertStore from "../../stores/alertStore";
import { useGlobalVariablesStore } from "../../stores/globalVariablesStore/globalVariables";
@ -28,6 +28,7 @@ export default function AddNewVariableButton({
const [open, setOpen] = useState(false);
const setErrorData = useAlertStore((state) => state.setErrorData);
const componentFields = useTypesStore((state) => state.ComponentFields);
const unavaliableFields = new Set(
Object.keys(
useGlobalVariablesStore((state) => state.unavaliableFields) ?? {},
@ -46,6 +47,9 @@ export default function AddNewVariableButton({
(state) => state.addGlobalVariable,
);
const { mutate: mutateAddGlobalVariable } = usePostGlobalVariables();
const setSuccessData = useAlertStore((state) => state.setSuccessData);
function handleSaveVariable() {
let data: {
name: string;
@ -58,8 +62,9 @@ export default function AddNewVariableButton({
value,
default_fields: fields,
};
registerGlobalVariable(data)
.then((res) => {
mutateAddGlobalVariable(data, {
onSuccess: (res) => {
const { name, id, type } = res.data;
addGlobalVariable(name, id, type, fields);
setKey("");
@ -67,8 +72,12 @@ export default function AddNewVariableButton({
setType("");
setFields([]);
setOpen(false);
})
.catch((error) => {
setSuccessData({
title: `Variable ${name} created successfully`,
});
},
onError: (error) => {
let responseError = error as ResponseErrorDetailAPI;
setErrorData({
title: "Error creating variable",
@ -77,8 +86,10 @@ export default function AddNewVariableButton({
"An unexpected error occurred while adding a new variable. Please try again.",
],
});
});
},
});
}
return (
<BaseModal
open={open}

View file

@ -1,6 +1,5 @@
import { useDeleteGlobalVariables } from "@/controllers/API/queries/variables";
import { useEffect } from "react";
import { Controller } from "react-hook-form";
import { deleteGlobalVariable } from "../../controllers/API";
import DeleteConfirmationModal from "../../modals/deleteConfirmationModal";
import useAlertStore from "../../stores/alertStore";
import { useGlobalVariablesStore } from "../../stores/globalVariablesStore/globalVariables";
@ -28,6 +27,8 @@ export default function InputGlobalComponent({
);
const setErrorData = useAlertStore((state) => state.setErrorData);
const { mutate: mutateDeleteGlobalVariable } = useDeleteGlobalVariables();
useEffect(() => {
if (data && globalVariablesEntries)
if (data.load_from_db && !globalVariablesEntries.includes(data.value)) {
@ -38,19 +39,23 @@ export default function InputGlobalComponent({
async function handleDelete(key: string) {
const id = getVariableId(key);
if (id !== undefined) {
await deleteGlobalVariable(id)
.then(() => {
removeGlobalVariable(key);
if (data?.value === key && data?.load_from_db) {
onChange("", false);
}
})
.catch(() => {
setErrorData({
title: "Error deleting variable",
list: [cn("ID not found for variable: ", key)],
});
});
mutateDeleteGlobalVariable(
{ id },
{
onSuccess: () => {
removeGlobalVariable(key);
if (data?.value === key && data?.load_from_db) {
onChange("", false);
}
},
onError: () => {
setErrorData({
title: "Error deleting variable",
list: [cn("ID not found for variable: ", key)],
});
},
},
);
} else {
setErrorData({
title: "Error deleting variable",

View file

@ -8,14 +8,9 @@ import useFlowsManagerStore from "@/stores/flowsManagerStore";
import { createContext, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import Cookies from "universal-cookie";
import {
getGlobalVariables,
getLoggedUser,
requestLogout,
} from "../controllers/API";
import { getLoggedUser, requestLogout } from "../controllers/API";
import useAlertStore from "../stores/alertStore";
import { useFolderStore } from "../stores/foldersStore";
import { useGlobalVariablesStore } from "../stores/globalVariablesStore/globalVariables";
import { useStoreStore } from "../stores/storeStore";
import { Users } from "../types/api";
import { AuthContextType } from "../types/contexts/auth";
@ -48,9 +43,7 @@ export function AuthProvider({ children }): React.ReactElement {
);
const getFoldersApi = useFolderStore((state) => state.getFoldersApi);
const setGlobalVariables = useGlobalVariablesStore(
(state) => state.setGlobalVariables,
);
const checkHasStore = useStoreStore((state) => state.checkHasStore);
const fetchApiData = useStoreStore((state) => state.fetchApiData);
const setAllFlows = useFlowsManagerStore((state) => state.setAllFlows);
@ -77,8 +70,7 @@ export function AuthProvider({ children }): React.ReactElement {
const isSuperUser = user!.is_superuser;
useAuthStore.getState().setIsAdmin(isSuperUser);
getFoldersApi(true, true);
const res = await getGlobalVariables();
setGlobalVariables(res);
checkHasStore();
fetchApiData();
})

View file

@ -17,6 +17,7 @@ export const URLs = {
CUSTOM_COMPONENT: `custom_component`,
FLOWS: `flows`,
FOLDERS: `folders`,
VARIABLES: `variables`,
} as const;
export function getURL(key: keyof typeof URLs, params: any = {}) {

View file

@ -818,53 +818,6 @@ export async function requestLogout() {
}
}
export async function getGlobalVariables(): Promise<{
[key: string]: { id: string; type: string; default_fields: string[] };
}> {
const globalVariables = {};
(await api.get(`${BASE_URL_API}variables/`))?.data?.forEach((element) => {
globalVariables[element.name] = {
id: element.id,
type: element.type,
default_fields: element.default_fields,
};
});
return globalVariables;
}
export async function registerGlobalVariable({
name,
value,
type,
default_fields = [],
}: {
name: string;
value: string;
type?: string;
default_fields?: string[];
}): Promise<AxiosResponse<{ name: string; id: string; type: string }>> {
try {
const response = await api.post(`${BASE_URL_API}variables/`, {
name,
value,
type,
default_fields: default_fields,
});
return response;
} catch (error) {
throw error;
}
}
export async function deleteGlobalVariable(id: string) {
try {
const response = await api.delete(`${BASE_URL_API}variables/${id}`);
return response;
} catch (error) {
throw error;
}
}
export async function updateGlobalVariable(
name: string,
value: string,

View file

@ -0,0 +1,4 @@
export * from "./use-delete-global-variables";
export * from "./use-get-global-variables";
export * from "./use-patch-global-variables";
export * from "./use-post-global-variables";

View file

@ -0,0 +1,31 @@
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 DeleteGlobalVariablesParams {
id: string | undefined;
}
export const useDeleteGlobalVariables: useMutationFunctionType<
undefined,
DeleteGlobalVariablesParams
> = (options?) => {
const { mutate } = UseRequestProcessor();
const deleteGlobalVariables = async ({
id,
}: DeleteGlobalVariablesParams): Promise<any> => {
const res = await api.delete(`${getURL("VARIABLES")}/${id}`);
return res.data;
};
const mutation: UseMutationResult<
DeleteGlobalVariablesParams,
any,
DeleteGlobalVariablesParams
> = mutate(["useDeleteGlobalVariables"], deleteGlobalVariables, options);
return mutation;
};

View file

@ -0,0 +1,54 @@
import { useGlobalVariablesStore } from "@/stores/globalVariablesStore/globalVariables";
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";
type GlobalVariable = {
id: string;
type: string;
default_fields: string[];
name: string;
};
export const useGetGlobalVariables: useMutationFunctionType<undefined, void> = (
options?,
) => {
const { mutate } = UseRequestProcessor();
const setGlobalVariables = useGlobalVariablesStore(
(state) => state.setGlobalVariables,
);
const getGlobalVariables = async (): Promise<[GlobalVariable]> => {
const res = await api.get(`${getURL("VARIABLES")}/`);
return res.data;
};
const getGlobalVariablesFn = async (): Promise<{
[key: string]: GlobalVariable;
}> => {
const data = await getGlobalVariables();
const globalVariables = {};
data?.forEach((element) => {
globalVariables[element.name] = {
id: element.id,
type: element.type,
default_fields: element.default_fields,
};
});
setGlobalVariables(globalVariables);
return globalVariables;
};
const mutation: UseMutationResult<any, any, any> = mutate(
["useGetGlobalVariables"],
getGlobalVariablesFn,
options,
);
return mutation;
};

View file

@ -0,0 +1,38 @@
import { changeUser, 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 PatchGlobalVariablesParams {
name: string;
value: string;
id: string;
}
export const usePatchGlobalVariables: useMutationFunctionType<
undefined,
PatchGlobalVariablesParams
> = (options?) => {
const { mutate } = UseRequestProcessor();
async function patchGlobalVariables({
name,
value,
id,
}: PatchGlobalVariablesParams): Promise<any> {
const res = await api.patch(`${getURL("VARIABLES")}/${id}`, {
name,
value,
});
return res.data;
}
const mutation: UseMutationResult<
PatchGlobalVariablesParams,
any,
PatchGlobalVariablesParams
> = mutate(["usePatchGlobalVariables"], patchGlobalVariables, options);
return mutation;
};

View file

@ -0,0 +1,40 @@
import { useMutationFunctionType } from "@/types/api";
import { UseMutationResult } from "@tanstack/react-query";
import { AxiosResponse } from "axios";
import { api } from "../../api";
import { getURL } from "../../helpers/constants";
import { UseRequestProcessor } from "../../services/request-processor";
interface PostGlobalVariablesParams {
name: string;
value: string;
type?: string;
default_fields?: string[];
}
export const usePostGlobalVariables: useMutationFunctionType<
undefined,
PostGlobalVariablesParams
> = (options?) => {
const { mutate } = UseRequestProcessor();
const postGlobalVariablesFunction = async ({
name,
value,
type,
default_fields = [],
}): Promise<AxiosResponse<{ name: string; id: string; type: string }>> => {
const res = await api.post(`${getURL("VARIABLES")}`, {
name,
value,
type,
default_fields: default_fields,
});
return res;
};
const mutation: UseMutationResult<any, any, PostGlobalVariablesParams> =
mutate(["usePostGlobalVariables"], postGlobalVariablesFunction, options);
return mutation;
};

View file

@ -1,3 +1,4 @@
import { useGetGlobalVariables } from "@/controllers/API/queries/variables";
import { useContext, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Button } from "../../../components/ui/button";
@ -21,6 +22,8 @@ export default function LoginAdminPage() {
const { login } = useContext(AuthContext);
const setLoading = useAlertStore((state) => state.setLoading);
const { mutate: mutateGetGlobalVariables } = useGetGlobalVariables();
const { password, username } = inputState;
const setErrorData = useAlertStore((state) => state.setErrorData);
function handleInput({
@ -41,6 +44,8 @@ export default function LoginAdminPage() {
setLoading(true);
login(user.access_token, "login");
mutateGetGlobalVariables();
navigate("/admin/");
})
.catch((error) => {

View file

@ -1,6 +1,7 @@
import IconComponent from "../../../../components/genericIconComponent";
import { Button } from "../../../../components/ui/button";
import { useDeleteGlobalVariables } from "@/controllers/API/queries/variables";
import { ColDef, ColGroupDef, SelectionChangedEvent } from "ag-grid-community";
import { useEffect, useState } from "react";
import AddNewVariableButton from "../../../../components/addNewVariableButtonComponent/addNewVariableButton";
@ -8,7 +9,6 @@ import Dropdown from "../../../../components/dropdownComponent";
import ForwardedIconComponent from "../../../../components/genericIconComponent";
import TableComponent from "../../../../components/tableComponent";
import { Badge } from "../../../../components/ui/badge";
import { deleteGlobalVariable } from "../../../../controllers/API";
import useAlertStore from "../../../../stores/alertStore";
import { useGlobalVariablesStore } from "../../../../stores/globalVariablesStore/globalVariables";
@ -108,23 +108,26 @@ export default function GlobalVariablesPage() {
const [selectedRows, setSelectedRows] = useState<string[]>([]);
const { mutate: mutateDeleteGlobalVariable } = useDeleteGlobalVariables();
async function removeVariables() {
const deleteGlobalVariablesPromise = selectedRows.map(async (row) => {
selectedRows.map(async (row) => {
const id = getVariableId(row);
const deleteGlobalVariables = deleteGlobalVariable(id!);
await deleteGlobalVariables;
mutateDeleteGlobalVariable(
{ id },
{
onSuccess: () => {
removeGlobalVariable(row);
},
onError: () => {
setErrorData({
title: `Error deleting variable`,
list: [`ID not found for variable: ${row}`],
});
},
},
);
});
Promise.all(deleteGlobalVariablesPromise)
.then(() => {
selectedRows.forEach((row) => {
removeGlobalVariable(row);
});
})
.catch(() => {
setErrorData({
title: `Error deleting global variables.`,
});
});
}
return (