From 1a7e3498b38e80382e1ded6404f89ad11b67b269 Mon Sep 17 00:00:00 2001 From: goatmanjah Date: Tue, 18 Nov 2025 00:25:17 -0500 Subject: [PATCH] changes 4 class changes 4 class --- pnpm-lock.yaml | 14 +-- src/features/modals/NodeModal/index.tsx | 136 +++++++++++++++++++----- 2 files changed, 114 insertions(+), 36 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 10f909157b4..030c017a06a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1060,8 +1060,8 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001718: - resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + caniuse-lite@1.0.30001755: + resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} chalk@3.0.0: resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} @@ -4009,7 +4009,7 @@ snapshots: camelize@1.0.1: {} - caniuse-lite@1.0.30001718: {} + caniuse-lite@1.0.30001755: {} chalk@3.0.0: dependencies: @@ -4319,7 +4319,7 @@ snapshots: eslint: 8.56.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0) - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.56.0) eslint-plugin-react: 7.37.5(eslint@8.56.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.56.0) @@ -4353,7 +4353,7 @@ snapshots: tinyglobby: 0.2.13 unrs-resolver: 1.7.2 optionalDependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0) transitivePeerDependencies: - supports-color @@ -4368,7 +4368,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1)(eslint@8.56.0): + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.32.1(eslint@8.56.0)(typescript@5.8.2))(eslint@8.56.0))(eslint@8.56.0))(eslint@8.56.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -5232,7 +5232,7 @@ snapshots: '@next/env': 14.2.28 '@swc/helpers': 0.5.5 busboy: 1.6.0 - caniuse-lite: 1.0.30001718 + caniuse-lite: 1.0.30001755 graceful-fs: 4.2.11 postcss: 8.4.31 react: 18.3.1 diff --git a/src/features/modals/NodeModal/index.tsx b/src/features/modals/NodeModal/index.tsx index caba85febac..d8c885efcd3 100644 --- a/src/features/modals/NodeModal/index.tsx +++ b/src/features/modals/NodeModal/index.tsx @@ -1,69 +1,147 @@ -import React from "react"; +import React, { useEffect, useState } 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, + Textarea, + Button, + Group, +} from "@mantine/core"; import { CodeHighlight } from "@mantine/code-highlight"; import type { NodeData } from "../../../types/graph"; import useGraph from "../../editor/views/GraphView/stores/useGraph"; +import useFile from "../../../store/useFile"; -// return object from json removing array and object fields const normalizeNodeData = (nodeRows: NodeData["text"]) => { if (!nodeRows || nodeRows.length === 0) return "{}"; if (nodeRows.length === 1 && !nodeRows[0].key) return `${nodeRows[0].value}`; - const obj = {}; - nodeRows?.forEach(row => { - if (row.type !== "array" && row.type !== "object") { - if (row.key) obj[row.key] = row.value; + const obj: Record = {}; + nodeRows.forEach(row => { + if (row.type !== "array" && row.type !== "object" && row.key) { + obj[row.key] = row.value; } }); + return JSON.stringify(obj, null, 2); }; -// return json path in the format $["customer"] const jsonPathToString = (path?: NodeData["path"]) => { if (!path || path.length === 0) return "$"; - const segments = path.map(seg => (typeof seg === "number" ? seg : `"${seg}"`)); - return `$[${segments.join("][")}]`; + const segs = path.map(seg => (typeof seg === "number" ? seg : `"${seg}"`)); + return `$[${segs.join("][")}]`; +}; + +const getNodeAtPath = (root: any, path: NodeData["path"]) => { + if (!path || path.length === 0) return root; + let cursor = root; + for (let i = 0; i < path.length; i++) { + cursor = cursor[path[i]]; + } + return cursor; }; export const NodeModal = ({ opened, onClose }: ModalProps) => { const nodeData = useGraph(state => state.selectedNode); + const contents = useFile(state => state.contents); + const setContents = useFile(state => state.setContents); + + const [isEditing, setIsEditing] = useState(false); + const [draft, setDraft] = useState("{}"); + + useEffect(() => { + if (nodeData?.text) { + setDraft(normalizeNodeData(nodeData.text)); + } else { + setDraft("{}"); + } + setIsEditing(false); + }, [opened, nodeData]); + + const handleEdit = () => setIsEditing(true); + + const handleCancel = () => { + if (nodeData?.text) setDraft(normalizeNodeData(nodeData.text)); + setIsEditing(false); + }; + + const handleSave = () => { + if (!nodeData) return; + + const fullJson = JSON.parse(contents); + const editedObject = JSON.parse(draft); + + const target = getNodeAtPath(fullJson, nodeData.path); + + Object.assign(target, editedObject); + + const updated = JSON.stringify(fullJson, null, 2); + setContents({ contents: updated }); + + setIsEditing(false); + }; + return ( - - Content - + Content - - - + + {isEditing ? ( + <> + +