fix(authContext.tsx): update useEffect dependencies to include setUserData, setLoading, autoLogin, and setIsAdmin to prevent unnecessary re-renders and ensure proper functionality

feat(authContext.tsx): add support for autoLogin and userData in the TypesProvider component to retrieve and save custom components based on user data

fix(typesContext.tsx): update useEffect dependencies to include autoLogin and userData to ensure proper functionality and prevent unnecessary re-renders

fix(typesContext.tsx): handle error when fetching types and log the error for debugging purposes

feat(typesContext.tsx): add saveComponent function to save custom components to localStorage and update the data state with the new component

fix(nodeToolbarComponent/index.tsx): import typesContext from typesContext file to use the saveComponent function

feat(nodeToolbarComponent/index.tsx): call saveComponent function from typesContext to save the current node data as a custom component

feat(utils.ts): add IncrementObjectKey function to increment the key of an object if it already exists, to avoid overwriting existing keys in localStorage
This commit is contained in:
anovazzi1 2023-09-25 22:04:50 -03:00
commit be69a216de
4 changed files with 57 additions and 24 deletions

View file

@ -71,7 +71,7 @@ export function AuthProvider({ children }): React.ReactElement {
setLoading(false);
}
});
}, []);
}, [setUserData, setLoading, autoLogin, setIsAdmin]);
function getAuthentication() {
const storedRefreshToken = cookies.get("refresh_token");

View file

@ -1,3 +1,4 @@
import _ from "lodash";
import {
createContext,
ReactNode,
@ -11,7 +12,7 @@ import { APIKindType } from "../types/api";
import { localStorageUserType } from "../types/entities";
import { NodeDataType } from "../types/flow";
import { typesContextType } from "../types/typesContext";
import { checkLocalStorageKey } from "../utils/utils";
import { checkLocalStorageKey, IncrementObjectKey } from "../utils/utils";
import { alertContext } from "./alertContext";
import { AuthContext } from "./authContext";
@ -44,7 +45,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
const [data, setData] = useState({});
const [fetchError, setFetchError] = useState(false);
const { setLoading } = useContext(alertContext);
const { getAuthentication } = useContext(AuthContext);
const { getAuthentication, autoLogin, userData } = useContext(AuthContext);
const [getFilterEdge, setFilterEdge] = useState([]);
useEffect(() => {
@ -52,7 +53,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
if (getAuthentication() === true) {
getTypes();
}
}, [getAuthentication()]);
}, [getAuthentication(), autoLogin, userData]);
async function getTypes(): Promise<void> {
// We will keep a flag to handle the case where the component is unmounted before the API call resolves.
@ -62,11 +63,23 @@ export function TypesProvider({ children }: { children: ReactNode }) {
// Make sure to only update the state if the component is still mounted.
if (isMounted && result?.status === 200) {
setLoading(false);
setData(result.data);
let { data } = _.cloneDeep(result);
const savedComponents = autoLogin
? localStorage.getItem("auto")
: localStorage.getItem(userData?.id!);
if (savedComponents !== null) {
const { components }: localStorageUserType = JSON.parse(
savedComponents!
);
Object.keys(components).forEach((key) => {
data["custom_components"][key] = components[key].node!;
});
}
setData(data);
setTemplates(
Object.keys(result.data).reduce((acc, curr) => {
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
acc[c] = result.data[curr][c];
Object.keys(data).reduce((acc, curr) => {
Object.keys(data[curr]).forEach((c: keyof APIKindType) => {
acc[c] = data[curr][c];
});
return acc;
}, {})
@ -74,13 +87,13 @@ export function TypesProvider({ children }: { children: ReactNode }) {
// Set the types by reducing over the keys of the result data and updating the accumulator.
setTypes(
// Reverse the keys so the tool world does not overlap
Object.keys(result.data)
Object.keys(data)
.reverse()
.reduce((acc, curr) => {
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
Object.keys(data[curr]).forEach((c: keyof APIKindType) => {
acc[c] = curr;
// Add the base classes to the accumulator as well.
result.data[curr][c].base_classes?.forEach((b) => {
data[curr][c].base_classes?.forEach((b) => {
acc[b] = curr;
});
});
@ -90,6 +103,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
}
} catch (error) {
console.error("An error has occurred while fetching types.");
console.log(error);
await getHealth().catch((e) => {
setFetchError(true);
});
@ -108,15 +122,25 @@ export function TypesProvider({ children }: { children: ReactNode }) {
}
function saveComponent(component: NodeDataType, id: string) {
let savedComponentsJSON: localStorageUserType = { components: {} };
if (checkLocalStorageKey(id)) {
let savedComponents = localStorage.getItem(id)!;
let savedComponentsJSON: localStorageUserType =
JSON.parse(savedComponents);
let components = savedComponentsJSON.components;
components[component.type];
savedComponentsJSON.components = components;
localStorage.setItem(id, JSON.stringify(savedComponentsJSON));
savedComponentsJSON = JSON.parse(savedComponents);
}
let components = savedComponentsJSON.components;
let key = component.type;
if (components[key] !== undefined) {
const { newKey, increment } = IncrementObjectKey(components, key);
key = newKey;
}
components[key] = component;
savedComponentsJSON.components = components;
localStorage.setItem(id, JSON.stringify(savedComponentsJSON));
setData((prev) => {
let newData = { ...prev };
newData["custom_components"][key] = component.node;
return newData;
});
}
return (

View file

@ -10,6 +10,7 @@ import {
} from "../../../../components/ui/select-custom";
import { AuthContext } from "../../../../contexts/authContext";
import { TabsContext } from "../../../../contexts/tabsContext";
import { typesContext } from "../../../../contexts/typesContext";
import EditNodeModal from "../../../../modals/EditNodeModal";
import { nodeToolbarPropsType } from "../../../../types/components";
import {
@ -54,6 +55,7 @@ export default function NodeToolbarComponent({
}
const isMinimal = canMinimize();
const { paste } = useContext(TabsContext);
const { saveComponent } = useContext(typesContext);
const reactFlowInstance = useReactFlow();
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
const [selectedValue, setSelectedValue] = useState("");
@ -73,14 +75,8 @@ export default function NodeToolbarComponent({
break;
case "SaveAll":
if (isAuthenticated) {
if (autoLogin) {
console.log("save all");
} else {
}
saveComponent(data, autoLogin ? "auto" : userData?.id!);
}
console.log(isAuthenticated);
console.log(userData);
console.log(autoLogin);
break;
}
};

View file

@ -529,3 +529,16 @@ export function tabsArray(codes: string[], method: number) {
export function checkLocalStorageKey(key: string): boolean {
return localStorage.getItem(key) !== null;
}
export function IncrementObjectKey(
object: object,
key: string
): { newKey: string; increment: number } {
let count = 1;
let newKey = key;
while (object[newKey]) {
newKey = key + " " + `(${count})`;
count++;
}
return { newKey, increment: count };
}