Add lodash cloneDeep and useUpdateNodeInternals to GenericNode component, and updateNodeCode to CodeTabsComponent and CodeAreaModal components
This commit is contained in:
parent
cfbbddd95c
commit
d8bd04edef
3 changed files with 57 additions and 6 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
|
import { cloneDeep } from "lodash";
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { useCallback, useEffect, useState } from "react";
|
||||||
import { NodeToolbar } from "reactflow";
|
import { NodeToolbar, useUpdateNodeInternals } from "reactflow";
|
||||||
import ShadTooltip from "../../components/ShadTooltipComponent";
|
import ShadTooltip from "../../components/ShadTooltipComponent";
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
import InputComponent from "../../components/inputComponent";
|
import InputComponent from "../../components/inputComponent";
|
||||||
|
|
@ -9,6 +10,7 @@ import Loading from "../../components/ui/loading";
|
||||||
import { Textarea } from "../../components/ui/textarea";
|
import { Textarea } from "../../components/ui/textarea";
|
||||||
import Xmark from "../../components/ui/xmark";
|
import Xmark from "../../components/ui/xmark";
|
||||||
import {
|
import {
|
||||||
|
NATIVE_CATEGORIES,
|
||||||
RUN_TIMESTAMP_PREFIX,
|
RUN_TIMESTAMP_PREFIX,
|
||||||
STATUS_BUILD,
|
STATUS_BUILD,
|
||||||
STATUS_BUILDING,
|
STATUS_BUILDING,
|
||||||
|
|
@ -20,6 +22,7 @@ import { useDarkStore } from "../../stores/darkStore";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
import useFlowStore from "../../stores/flowStore";
|
||||||
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
import useFlowsManagerStore from "../../stores/flowsManagerStore";
|
||||||
import { useTypesStore } from "../../stores/typesStore";
|
import { useTypesStore } from "../../stores/typesStore";
|
||||||
|
import { APIClassType } from "../../types/api";
|
||||||
import { validationStatusType } from "../../types/components";
|
import { validationStatusType } from "../../types/components";
|
||||||
import { NodeDataType } from "../../types/flow";
|
import { NodeDataType } from "../../types/flow";
|
||||||
import { handleKeyDown, scapedJSONStringfy } from "../../utils/reactflowUtils";
|
import { handleKeyDown, scapedJSONStringfy } from "../../utils/reactflowUtils";
|
||||||
|
|
@ -39,10 +42,16 @@ export default function GenericNode({
|
||||||
yPos: number;
|
yPos: number;
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
const types = useTypesStore((state) => state.types);
|
const types = useTypesStore((state) => state.types);
|
||||||
|
const templates = useTypesStore((state) => state.templates);
|
||||||
const deleteNode = useFlowStore((state) => state.deleteNode);
|
const deleteNode = useFlowStore((state) => state.deleteNode);
|
||||||
const flowPool = useFlowStore((state) => state.flowPool);
|
const flowPool = useFlowStore((state) => state.flowPool);
|
||||||
const buildFlow = useFlowStore((state) => state.buildFlow);
|
const buildFlow = useFlowStore((state) => state.buildFlow);
|
||||||
const setNode = useFlowStore((state) => state.setNode);
|
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 setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
const name = nodeIconsLucide[data.type] ? data.type : types[data.type];
|
||||||
const [inputName, setInputName] = useState(false);
|
const [inputName, setInputName] = useState(false);
|
||||||
|
|
@ -51,6 +60,7 @@ export default function GenericNode({
|
||||||
const [nodeDescription, setNodeDescription] = useState(
|
const [nodeDescription, setNodeDescription] = useState(
|
||||||
data.node?.description!
|
data.node?.description!
|
||||||
);
|
);
|
||||||
|
const [isOutdated, setIsOutdated] = useState(false);
|
||||||
const buildStatus = useFlowStore(
|
const buildStatus = useFlowStore(
|
||||||
(state) => state.flowBuildStatus[data.id]?.status
|
(state) => state.flowBuildStatus[data.id]?.status
|
||||||
);
|
);
|
||||||
|
|
@ -65,6 +75,51 @@ export default function GenericNode({
|
||||||
|
|
||||||
const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot);
|
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) {
|
if (!data.node!.template) {
|
||||||
setErrorData({
|
setErrorData({
|
||||||
title: `Error in component ${data.node!.display_name}`,
|
title: `Error in component ${data.node!.display_name}`,
|
||||||
|
|
@ -305,6 +360,7 @@ export default function GenericNode({
|
||||||
showNode={showNode}
|
showNode={showNode}
|
||||||
openAdvancedModal={false}
|
openAdvancedModal={false}
|
||||||
onCloseAdvancedModal={() => {}}
|
onCloseAdvancedModal={() => {}}
|
||||||
|
updateNodeCode={updateNodeCode}
|
||||||
selected={selected}
|
selected={selected}
|
||||||
></NodeToolbarComponent>
|
></NodeToolbarComponent>
|
||||||
</NodeToolbar>
|
</NodeToolbar>
|
||||||
|
|
|
||||||
|
|
@ -55,8 +55,6 @@ export default function CodeTabsComponent({
|
||||||
const dark = useDarkStore((state) => state.dark);
|
const dark = useDarkStore((state) => state.dark);
|
||||||
const unselectAll = useFlowStore((state) => state.unselectAll);
|
const unselectAll = useFlowStore((state) => state.unselectAll);
|
||||||
|
|
||||||
const setNodes = useFlowStore((state) => state.setNodes);
|
|
||||||
|
|
||||||
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
const [errorDuplicateKey, setErrorDuplicateKey] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import {
|
||||||
import { postCustomComponent, postValidateCode } from "../../controllers/API";
|
import { postCustomComponent, postValidateCode } from "../../controllers/API";
|
||||||
import useAlertStore from "../../stores/alertStore";
|
import useAlertStore from "../../stores/alertStore";
|
||||||
import { useDarkStore } from "../../stores/darkStore";
|
import { useDarkStore } from "../../stores/darkStore";
|
||||||
import useFlowStore from "../../stores/flowStore";
|
|
||||||
import { CodeErrorDataTypeAPI } from "../../types/api";
|
import { CodeErrorDataTypeAPI } from "../../types/api";
|
||||||
import { codeAreaModalPropsType } from "../../types/components";
|
import { codeAreaModalPropsType } from "../../types/components";
|
||||||
import BaseModal from "../baseModal";
|
import BaseModal from "../baseModal";
|
||||||
|
|
@ -45,14 +44,12 @@ export default function CodeAreaModal({
|
||||||
? [myOpen, mySetOpen]
|
? [myOpen, mySetOpen]
|
||||||
: useState(false);
|
: useState(false);
|
||||||
const dark = useDarkStore((state) => state.dark);
|
const dark = useDarkStore((state) => state.dark);
|
||||||
const unselectAll = useFlowStore((state) => state.unselectAll);
|
|
||||||
const [height, setHeight] = useState<string | null>(null);
|
const [height, setHeight] = useState<string | null>(null);
|
||||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||||
const [error, setError] = useState<{
|
const [error, setError] = useState<{
|
||||||
detail: CodeErrorDataTypeAPI;
|
detail: CodeErrorDataTypeAPI;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
const nodes = useFlowStore((state) => state.nodes);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if nodeClass.template has more fields other than code and dynamic is true
|
// if nodeClass.template has more fields other than code and dynamic is true
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue