File size: 3,959 Bytes
f909d7c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
import React from "react";
import { Modal, Stack, Text, ScrollArea, ModalProps, Button } from "@mantine/core";
import { CodeHighlight } from "@mantine/code-highlight";
import Editor from "@monaco-editor/react";
import { VscLock } from "react-icons/vsc";
import { isIframe } from "src/lib/utils/widget";
import useConfig from "src/store/useConfig";
import useFile from "src/store/useFile";
import useGraph from "src/store/useGraph";
import useModal from "src/store/useModal";
import useUser from "src/store/useUser";
const dataToString = (data: any) => {
const text = Array.isArray(data) ? Object.fromEntries(data) : data;
const replacer = (_: string, v: string) => {
if (typeof v === "string") return v.replaceAll('"', "");
return v;
};
return JSON.stringify(text, replacer, 2);
};
export const NodeModal: React.FC<ModalProps> = ({ opened, onClose }) => {
const isPremium = useUser(state => state.premium);
const editContents = useFile(state => state.editContents);
const setVisible = useModal(state => state.setVisible);
const darkmodeEnabled = useConfig(state => (state.darkmodeEnabled ? "vs-dark" : "light"));
const nodeData = useGraph(state => dataToString(state.selectedNode?.text));
const path = useGraph(state => state.selectedNode?.path || "");
const isParent = useGraph(state => state.selectedNode?.data?.isParent);
const [editMode, setEditMode] = React.useState(false);
const [value, setValue] = React.useState(nodeData || "");
const onUpdate = () => {
if (!value) return setEditMode(false);
if (!isPremium) return;
editContents(path!, value, () => {
setEditMode(false);
onModalClose();
});
};
const onModalClose = () => {
setEditMode(false);
setValue("");
onClose();
};
const onEditClick = () => {
if (isPremium) return setEditMode(true);
setVisible("premium")(true);
};
const isEditVisible = React.useMemo(
() => path !== "{Root}" && !isParent && !isIframe(),
[isParent, path]
);
return (
<Modal title="Node Content" size="auto" opened={opened} onClose={onModalClose} centered>
<Stack py="sm" gap="sm">
<Stack gap="xs">
<Text fz="sm" fw={700}>
Content
</Text>
{editMode ? (
<Editor
theme={darkmodeEnabled}
defaultValue={nodeData}
onChange={e => setValue(e!)}
height={200}
language="json"
options={{
readOnly: !editMode,
minimap: {
enabled: false,
},
}}
/>
) : (
<ScrollArea>
<CodeHighlight
code={nodeData}
miw={350}
mah={250}
maw={600}
language="json"
withCopyButton
/>
</ScrollArea>
)}
</Stack>
{isEditVisible && (
<Stack gap="xs">
{editMode ? (
<Button
variant={value ? "filled" : "light"}
color={value ? "green" : "blue"}
onClick={onUpdate}
>
{value.length ? "Update Document" : "Cancel"}
</Button>
) : (
<Button
onClick={onEditClick}
leftSection={!isPremium && <VscLock />}
variant="filled"
>
Edit
</Button>
)}
</Stack>
)}
<Text fz="sm" fw={700}>
Node Path
</Text>
<ScrollArea>
<CodeHighlight
code={path}
miw={350}
mah={250}
language="json"
copyLabel="Copy to clipboard"
copiedLabel="Copied to clipboard"
withCopyButton
/>
</ScrollArea>
</Stack>
</Modal>
);
};
|