Add lodash cloneDeep and useUpdateNodeInternals to GenericNode component, and updateNodeCode to CodeTabsComponent and CodeAreaModal components

This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-03-10 01:09:01 -03:00
commit d8bd04edef
3 changed files with 57 additions and 6 deletions

View file

@ -1,5 +1,6 @@
import { cloneDeep } from "lodash";
import { useCallback, useEffect, useState } from "react";
import { NodeToolbar } from "reactflow";
import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
import ShadTooltip from "../../components/ShadTooltipComponent";
import IconComponent from "../../components/genericIconComponent";
import InputComponent from "../../components/inputComponent";
@ -9,6 +10,7 @@ import Loading from "../../components/ui/loading";
import { Textarea } from "../../components/ui/textarea";
import Xmark from "../../components/ui/xmark";
import {
NATIVE_CATEGORIES,
RUN_TIMESTAMP_PREFIX,
STATUS_BUILD,
STATUS_BUILDING,
@ -20,6 +22,7 @@ import { useDarkStore } from "../../stores/darkStore";
import useFlowStore from "../../stores/flowStore";
import useFlowsManagerStore from "../../stores/flowsManagerStore";
import { useTypesStore } from "../../stores/typesStore";
import { APIClassType } from "../../types/api";
import { validationStatusType } from "../../types/components";
import { NodeDataType } from "../../types/flow";
import { handleKeyDown, scapedJSONStringfy } from "../../utils/reactflowUtils";
@ -39,10 +42,16 @@ export default function GenericNode({
yPos: number;
}): JSX.Element {
const types = useTypesStore((state) => state.types);
const templates = useTypesStore((state) => state.templates);
const deleteNode = useFlowStore((state) => state.deleteNode);
const flowPool = useFlowStore((state) => state.flowPool);
const buildFlow = useFlowStore((state) => state.buildFlow);
const setNode = useFlowStore((state) => state.setNode);
const addToOutdatedNodes = useFlowStore((state) => state.addToOutdatedNodes);
const updateNodeInternals = useUpdateNodeInternals();
const removeFromOutdatedNodes = useFlowStore(
(state) => state.removeFromOutdatedNodes
);
const setErrorData = useAlertStore((state) => state.setErrorData);
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
const [inputName, setInputName] = useState(false);
@ -51,6 +60,7 @@ export default function GenericNode({
const [nodeDescription, setNodeDescription] = useState(
data.node?.description!
);
const [isOutdated, setIsOutdated] = useState(false);
const buildStatus = useFlowStore(
(state) => state.flowBuildStatus[data.id]?.status
);
@ -65,6 +75,51 @@ export default function GenericNode({
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
useEffect(() => {
// This one should run only once
// first check if data.type in NATIVE_CATEGORIES
// if not return
if (!NATIVE_CATEGORIES.includes(types[data.type])) return;
const thisNodeTemplate = templates[data.type].template;
// if the template does not have a code key
// return
if (!thisNodeTemplate.code) return;
const currentCode = thisNodeTemplate.code.value;
const thisNodesCode = data.node!.template.code.value;
if (currentCode !== thisNodesCode) {
addToOutdatedNodes(data.id);
setIsOutdated(true);
} else {
// remove the node from the outdatedNodes
removeFromOutdatedNodes(data.id);
setIsOutdated(false);
}
// template.code can be undefined
}, [data.node?.template.code.value]);
const updateNodeCode = useCallback(
(newNodeClass: APIClassType, code: string, name: string) => {
setNode(data.id, (oldNode) => {
let newNode = cloneDeep(oldNode);
newNode.data = {
...newNode.data,
node: newNodeClass,
description: newNodeClass.description ?? data.node!.description,
display_name: newNodeClass.display_name ?? data.node!.display_name,
};
newNode.data.node.template[name].value = code;
return newNode;
});
updateNodeInternals(data.id);
},
[data.id, data.node, setNode]
);
if (!data.node!.template) {
setErrorData({
title: `Error in component ${data.node!.display_name}`,
@ -305,6 +360,7 @@ export default function GenericNode({
showNode={showNode}
openAdvancedModal={false}
onCloseAdvancedModal={() => {}}
updateNodeCode={updateNodeCode}
selected={selected}
></NodeToolbarComponent>
</NodeToolbar>

View file

@ -55,8 +55,6 @@ export default function CodeTabsComponent({
const dark = useDarkStore((state) => state.dark);
const unselectAll = useFlowStore((state) => state.unselectAll);
const setNodes = useFlowStore((state) => state.setNodes);
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
useEffect(() => {

View file

@ -23,7 +23,6 @@ import {
import { postCustomComponent, postValidateCode } from "../../controllers/API";
import useAlertStore from "../../stores/alertStore";
import { useDarkStore } from "../../stores/darkStore";
import useFlowStore from "../../stores/flowStore";
import { CodeErrorDataTypeAPI } from "../../types/api";
import { codeAreaModalPropsType } from "../../types/components";
import BaseModal from "../baseModal";
@ -45,14 +44,12 @@ export default function CodeAreaModal({
? [myOpen, mySetOpen]
: useState(false);
const dark = useDarkStore((state) => state.dark);
const unselectAll = useFlowStore((state) => state.unselectAll);
const [height, setHeight] = useState<string | null>(null);
const setSuccessData = useAlertStore((state) => state.setSuccessData);
const setErrorData = useAlertStore((state) => state.setErrorData);
const [error, setError] = useState<{
detail: CodeErrorDataTypeAPI;
} | null>(null);
const nodes = useFlowStore((state) => state.nodes);
useEffect(() => {
// if nodeClass.template has more fields other than code and dynamic is true