create click node modal

This commit is contained in:
AykutSarac 2022-08-13 18:22:51 +03:00
parent c91c9d9d8e
commit 129096f25b
5 changed files with 109 additions and 64 deletions

View File

@ -20,15 +20,15 @@ const ObjectNode: React.FC<CustomNodeProps<[string, string][]>> = ({
(val, idx) =>
val[1] && (
<Styled.StyledRow
data-key={val[1]}
data-key={JSON.stringify(val[1])}
data-x={x}
data-y={y}
key={idx}
width={width}
value={val[1]}
value={JSON.stringify(val[1])}
>
<Styled.StyledKey objectKey>{val[0]}: </Styled.StyledKey>
<Styled.StyledLinkItUrl>{val[1]}</Styled.StyledLinkItUrl>
<Styled.StyledKey objectKey>{JSON.stringify(val[0]).replaceAll('"', "")}: </Styled.StyledKey>
<Styled.StyledLinkItUrl>{JSON.stringify(val[1])}</Styled.StyledLinkItUrl>
</Styled.StyledRow>
)
)}

View File

@ -20,10 +20,10 @@ const TextNode: React.FC<CustomNodeProps<string>> = ({
<Styled.StyledKey
data-x={x}
data-y={y}
data-key={value}
data-key={JSON.stringify(value)}
parent={isParent}
>
<Styled.StyledLinkItUrl>{value}</Styled.StyledLinkItUrl>
<Styled.StyledLinkItUrl>{JSON.stringify(value).replaceAll('"', "")}</Styled.StyledLinkItUrl>
</Styled.StyledKey>
</Styled.StyledText>
</ConditionalWrapper>

View File

@ -13,11 +13,11 @@ import {
NodeProps,
} from "reaflow";
import { CustomNode } from "src/components/CustomNode";
import { NodeModal } from "src/containers/Modals/NodeModal";
import { getEdgeNodes } from "src/containers/Editor/LiveEditor/helpers";
import useConfig from "src/hooks/store/useConfig";
import styled from "styled-components";
import shallow from "zustand/shallow";
import toast from "react-hot-toast";
interface GraphProps {
json: string;
@ -48,6 +48,7 @@ export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
isWidget = false,
...props
}) => {
const [isModalVisible, setModalVisible] = React.useState(false);
const updateSetting = useConfig((state) => state.updateSetting);
const [expand, layout] = useConfig(
(state) => [state.settings.expand, state.settings.layout],
@ -58,6 +59,7 @@ export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
updateSetting("zoomPanPinch", ref);
};
const [selectedNode, setSelectedNode] = React.useState<NodeData | null>(null);
const [nodes, setNodes] = React.useState<NodeData[]>([]);
const [edges, setEdges] = React.useState<EdgeData[]>([]);
const [size, setSize] = React.useState({
@ -86,49 +88,56 @@ export const Graph: React.FC<GraphProps & CanvasContainerProps> = ({
e: React.MouseEvent<SVGElement>,
props: NodeProps
) => {
if (e.detail === 2) {
toast("Object copied to clipboard!");
navigator.clipboard.writeText(JSON.stringify(props.properties.text));
}
setSelectedNode(props.properties);
setModalVisible(true);
};
return (
<StyledEditorWrapper isWidget={isWidget}>
<TransformWrapper
maxScale={1.8}
minScale={0.4}
initialScale={0.7}
wheel={wheelOptions}
onInit={onInit}
>
<TransformComponent
wrapperStyle={{
width: "100%",
height: "100%",
overflow: "hidden",
}}
<>
<StyledEditorWrapper isWidget={isWidget}>
<TransformWrapper
maxScale={1.8}
minScale={0.4}
initialScale={0.7}
wheel={wheelOptions}
onInit={onInit}
>
<Canvas
nodes={nodes}
edges={edges}
maxWidth={size.width + 100}
maxHeight={size.height + 100}
direction={layout}
key={layout}
onCanvasClick={onCanvasClick}
onLayoutChange={onLayoutChange}
node={(props) => (
<CustomNode
onClick={(e) => handleNodeClick(e, props)}
{...props}
/>
)}
zoomable={false}
readonly
{...props}
/>
</TransformComponent>
</TransformWrapper>
</StyledEditorWrapper>
<TransformComponent
wrapperStyle={{
width: "100%",
height: "100%",
overflow: "hidden",
}}
>
<Canvas
nodes={nodes}
edges={edges}
maxWidth={size.width + 100}
maxHeight={size.height + 100}
direction={layout}
key={layout}
onCanvasClick={onCanvasClick}
onLayoutChange={onLayoutChange}
node={(props) => (
<CustomNode
onClick={(e) => handleNodeClick(e, props)}
{...props}
/>
)}
zoomable={false}
readonly
{...props}
/>
</TransformComponent>
</TransformWrapper>
</StyledEditorWrapper>
{!isWidget && selectedNode && (
<NodeModal
selectedNode={selectedNode.text}
visible={isModalVisible}
setVisible={setModalVisible}
/>
)}
</>
);
};

View File

@ -1,22 +1,6 @@
import { CanvasDirection, NodeData, EdgeData } from "reaflow";
import { parser } from "src/utils/json-editor-parser";
const toString = (value: string | object) => {
const isObject = value instanceof Object;
if (isObject) {
const entries = Object.entries(value);
const stringObj = entries.map((val) => [
JSON.stringify(val[0]).replaceAll('"', ""),
JSON.stringify(val[1]),
]);
return Object.fromEntries(stringObj);
}
return String(value);
};
export function getEdgeNodes(
graph: string,
isExpanded: boolean = true
@ -44,7 +28,7 @@ export function getEdgeNodes(
nodes.push({
id: el.id,
text: toString(el.text),
text: el.text,
data: {
isParent: el.parent,
},

View File

@ -0,0 +1,52 @@
import React from "react";
import toast from "react-hot-toast";
import { FiCopy } from "react-icons/fi";
import { Button } from "src/components/Button";
import { Modal } from "src/components/Modal";
import styled from "styled-components";
const StyledTextarea = styled.textarea`
resize: none;
width: 100%;
min-height: 200px;
padding: 10px;
background: ${({ theme }) => theme.BACKGROUND_TERTIARY};
color: ${({ theme }) => theme.INTERACTIVE_NORMAL};
outline: none;
border-radius: 4px;
line-height: 20px;
border: none;
`;
export const NodeModal = ({ selectedNode, visible = true, setVisible }) => {
const handleClipboard = () => {
toast("Content copied to clipboard!");
navigator.clipboard.writeText(JSON.stringify(selectedNode));
setVisible(false);
};
return (
<Modal visible={visible} setVisible={setVisible}>
<Modal.Header>Node Content</Modal.Header>
<Modal.Content>
<StyledTextarea
defaultValue={JSON.stringify(
selectedNode,
(k, v) => {
if (typeof v === "string") return v.replaceAll('"', "");
return v;
},
2
)}
/>
</Modal.Content>
<Modal.Controls setVisible={setVisible}>
<Button status="SECONDARY" onClick={handleClipboard}>
<FiCopy size={18} /> Clipboard
</Button>
</Modal.Controls>
</Modal>
);
};