diff --git a/src/features/modals/NodeModal/index.tsx b/src/features/modals/NodeModal/index.tsx index caba85febac..895d1df5d6a 100644 --- a/src/features/modals/NodeModal/index.tsx +++ b/src/features/modals/NodeModal/index.tsx @@ -1,9 +1,11 @@ import React from "react"; import type { ModalProps } from "@mantine/core"; -import { Modal, Stack, Text, ScrollArea, Flex, CloseButton } from "@mantine/core"; +import { Modal, Stack, Text, ScrollArea, Flex, CloseButton, Button, Group, TextInput } from "@mantine/core"; import { CodeHighlight } from "@mantine/code-highlight"; +import { MdEdit } from "react-icons/md"; import type { NodeData } from "../../../types/graph"; import useGraph from "../../editor/views/GraphView/stores/useGraph"; +import useJson from "../../../store/useJson"; // return object from json removing array and object fields const normalizeNodeData = (nodeRows: NodeData["text"]) => { @@ -28,6 +30,64 @@ const jsonPathToString = (path?: NodeData["path"]) => { export const NodeModal = ({ opened, onClose }: ModalProps) => { const nodeData = useGraph(state => state.selectedNode); + const [isEditing, setIsEditing] = React.useState(false); + const [editingIndex, setEditingIndex] = React.useState(-1); + const [editValue, setEditValue] = React.useState(""); + + const json = useJson(state => state.json); + const setJson = useJson(state => state.setJson); + + React.useEffect(() => { + if (editingIndex >= 0 && nodeData?.text?.[editingIndex]?.value !== undefined) { + setEditValue(String(nodeData.text[editingIndex].value)); + } + }, [nodeData, editingIndex]); + + const handleEditClick = (index: number) => { + setEditingIndex(index); + setIsEditing(true); + }; + + const handleSave = () => { + if (!nodeData?.path || editingIndex < 0) return; + + try { + const jsonObj = JSON.parse(json); + let current = jsonObj; + + // Navigate to the parent object/array + for (let i = 0; i < nodeData.path.length - 1; i++) { + current = current[nodeData.path[i]]; + } + + // Update the value + const lastKey = nodeData.path[nodeData.path.length - 1]; + + // Try to parse as number, boolean, or null first + let newValue: any = editValue; + if (editValue === "null") { + newValue = null; + } else if (editValue === "true") { + newValue = true; + } else if (editValue === "false") { + newValue = false; + } else if (!isNaN(Number(editValue)) && editValue !== "") { + newValue = Number(editValue); + } + + current[lastKey] = newValue; + setJson(JSON.stringify(jsonObj)); + setIsEditing(false); + setEditingIndex(-1); + } catch (error) { + console.error("Failed to update value:", error); + } + }; + + const handleCancel = () => { + setIsEditing(false); + setEditingIndex(-1); + }; return ( @@ -39,15 +99,56 @@ export const NodeModal = ({ opened, onClose }: ModalProps) => { - - - + {!isEditing ? ( + <> + + + + {nodeData?.text && nodeData.text.length > 0 && ( + + {nodeData.text.map((row, index) => { + if (row.type === "array" || row.type === "object") return null; + return ( + + ); + })} + + )} + + ) : ( + <> + setEditValue(e.currentTarget.value)} + autoFocus + /> + + + + + + )} JSON Path