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:
parent
00e25c9495
commit
be69a216de
4 changed files with 57 additions and 24 deletions
|
|
@ -71,7 +71,7 @@ export function AuthProvider({ children }): React.ReactElement {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, []);
|
}, [setUserData, setLoading, autoLogin, setIsAdmin]);
|
||||||
|
|
||||||
function getAuthentication() {
|
function getAuthentication() {
|
||||||
const storedRefreshToken = cookies.get("refresh_token");
|
const storedRefreshToken = cookies.get("refresh_token");
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import _ from "lodash";
|
||||||
import {
|
import {
|
||||||
createContext,
|
createContext,
|
||||||
ReactNode,
|
ReactNode,
|
||||||
|
|
@ -11,7 +12,7 @@ import { APIKindType } from "../types/api";
|
||||||
import { localStorageUserType } from "../types/entities";
|
import { localStorageUserType } from "../types/entities";
|
||||||
import { NodeDataType } from "../types/flow";
|
import { NodeDataType } from "../types/flow";
|
||||||
import { typesContextType } from "../types/typesContext";
|
import { typesContextType } from "../types/typesContext";
|
||||||
import { checkLocalStorageKey } from "../utils/utils";
|
import { checkLocalStorageKey, IncrementObjectKey } from "../utils/utils";
|
||||||
import { alertContext } from "./alertContext";
|
import { alertContext } from "./alertContext";
|
||||||
import { AuthContext } from "./authContext";
|
import { AuthContext } from "./authContext";
|
||||||
|
|
||||||
|
|
@ -44,7 +45,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const [fetchError, setFetchError] = useState(false);
|
const [fetchError, setFetchError] = useState(false);
|
||||||
const { setLoading } = useContext(alertContext);
|
const { setLoading } = useContext(alertContext);
|
||||||
const { getAuthentication } = useContext(AuthContext);
|
const { getAuthentication, autoLogin, userData } = useContext(AuthContext);
|
||||||
const [getFilterEdge, setFilterEdge] = useState([]);
|
const [getFilterEdge, setFilterEdge] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -52,7 +53,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
||||||
if (getAuthentication() === true) {
|
if (getAuthentication() === true) {
|
||||||
getTypes();
|
getTypes();
|
||||||
}
|
}
|
||||||
}, [getAuthentication()]);
|
}, [getAuthentication(), autoLogin, userData]);
|
||||||
|
|
||||||
async function getTypes(): Promise<void> {
|
async function getTypes(): Promise<void> {
|
||||||
// We will keep a flag to handle the case where the component is unmounted before the API call resolves.
|
// 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.
|
// Make sure to only update the state if the component is still mounted.
|
||||||
if (isMounted && result?.status === 200) {
|
if (isMounted && result?.status === 200) {
|
||||||
setLoading(false);
|
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(
|
setTemplates(
|
||||||
Object.keys(result.data).reduce((acc, curr) => {
|
Object.keys(data).reduce((acc, curr) => {
|
||||||
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
|
Object.keys(data[curr]).forEach((c: keyof APIKindType) => {
|
||||||
acc[c] = result.data[curr][c];
|
acc[c] = data[curr][c];
|
||||||
});
|
});
|
||||||
return acc;
|
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.
|
// Set the types by reducing over the keys of the result data and updating the accumulator.
|
||||||
setTypes(
|
setTypes(
|
||||||
// Reverse the keys so the tool world does not overlap
|
// Reverse the keys so the tool world does not overlap
|
||||||
Object.keys(result.data)
|
Object.keys(data)
|
||||||
.reverse()
|
.reverse()
|
||||||
.reduce((acc, curr) => {
|
.reduce((acc, curr) => {
|
||||||
Object.keys(result.data[curr]).forEach((c: keyof APIKindType) => {
|
Object.keys(data[curr]).forEach((c: keyof APIKindType) => {
|
||||||
acc[c] = curr;
|
acc[c] = curr;
|
||||||
// Add the base classes to the accumulator as well.
|
// 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;
|
acc[b] = curr;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -90,6 +103,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("An error has occurred while fetching types.");
|
console.error("An error has occurred while fetching types.");
|
||||||
|
console.log(error);
|
||||||
await getHealth().catch((e) => {
|
await getHealth().catch((e) => {
|
||||||
setFetchError(true);
|
setFetchError(true);
|
||||||
});
|
});
|
||||||
|
|
@ -108,15 +122,25 @@ export function TypesProvider({ children }: { children: ReactNode }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveComponent(component: NodeDataType, id: string) {
|
function saveComponent(component: NodeDataType, id: string) {
|
||||||
|
let savedComponentsJSON: localStorageUserType = { components: {} };
|
||||||
if (checkLocalStorageKey(id)) {
|
if (checkLocalStorageKey(id)) {
|
||||||
let savedComponents = localStorage.getItem(id)!;
|
let savedComponents = localStorage.getItem(id)!;
|
||||||
let savedComponentsJSON: localStorageUserType =
|
savedComponentsJSON = JSON.parse(savedComponents);
|
||||||
JSON.parse(savedComponents);
|
}
|
||||||
let components = savedComponentsJSON.components;
|
let components = savedComponentsJSON.components;
|
||||||
components[component.type];
|
let key = component.type;
|
||||||
|
if (components[key] !== undefined) {
|
||||||
|
const { newKey, increment } = IncrementObjectKey(components, key);
|
||||||
|
key = newKey;
|
||||||
|
}
|
||||||
|
components[key] = component;
|
||||||
savedComponentsJSON.components = components;
|
savedComponentsJSON.components = components;
|
||||||
localStorage.setItem(id, JSON.stringify(savedComponentsJSON));
|
localStorage.setItem(id, JSON.stringify(savedComponentsJSON));
|
||||||
}
|
setData((prev) => {
|
||||||
|
let newData = { ...prev };
|
||||||
|
newData["custom_components"][key] = component.node;
|
||||||
|
return newData;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {
|
||||||
} from "../../../../components/ui/select-custom";
|
} from "../../../../components/ui/select-custom";
|
||||||
import { AuthContext } from "../../../../contexts/authContext";
|
import { AuthContext } from "../../../../contexts/authContext";
|
||||||
import { TabsContext } from "../../../../contexts/tabsContext";
|
import { TabsContext } from "../../../../contexts/tabsContext";
|
||||||
|
import { typesContext } from "../../../../contexts/typesContext";
|
||||||
import EditNodeModal from "../../../../modals/EditNodeModal";
|
import EditNodeModal from "../../../../modals/EditNodeModal";
|
||||||
import { nodeToolbarPropsType } from "../../../../types/components";
|
import { nodeToolbarPropsType } from "../../../../types/components";
|
||||||
import {
|
import {
|
||||||
|
|
@ -54,6 +55,7 @@ export default function NodeToolbarComponent({
|
||||||
}
|
}
|
||||||
const isMinimal = canMinimize();
|
const isMinimal = canMinimize();
|
||||||
const { paste } = useContext(TabsContext);
|
const { paste } = useContext(TabsContext);
|
||||||
|
const { saveComponent } = useContext(typesContext);
|
||||||
const reactFlowInstance = useReactFlow();
|
const reactFlowInstance = useReactFlow();
|
||||||
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
|
const [showModalAdvanced, setShowModalAdvanced] = useState(false);
|
||||||
const [selectedValue, setSelectedValue] = useState("");
|
const [selectedValue, setSelectedValue] = useState("");
|
||||||
|
|
@ -73,14 +75,8 @@ export default function NodeToolbarComponent({
|
||||||
break;
|
break;
|
||||||
case "SaveAll":
|
case "SaveAll":
|
||||||
if (isAuthenticated) {
|
if (isAuthenticated) {
|
||||||
if (autoLogin) {
|
saveComponent(data, autoLogin ? "auto" : userData?.id!);
|
||||||
console.log("save all");
|
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
console.log(isAuthenticated);
|
|
||||||
console.log(userData);
|
|
||||||
console.log(autoLogin);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -529,3 +529,16 @@ export function tabsArray(codes: string[], method: number) {
|
||||||
export function checkLocalStorageKey(key: string): boolean {
|
export function checkLocalStorageKey(key: string): boolean {
|
||||||
return localStorage.getItem(key) !== null;
|
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 };
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue