diff --git a/packages/editor-sample/src/App/TemplatePanel/ImportJson/ImportJsonDialog.tsx b/packages/editor-sample/src/App/TemplatePanel/ImportJson/ImportJsonDialog.tsx new file mode 100644 index 0000000..d9e4c63 --- /dev/null +++ b/packages/editor-sample/src/App/TemplatePanel/ImportJson/ImportJsonDialog.tsx @@ -0,0 +1,71 @@ +import React, { useState } from 'react'; + +import { Alert, Button, Dialog, DialogActions, DialogContent, DialogTitle, TextField, Typography } from '@mui/material'; + +import { resetDocument } from '../../../documents/editor/EditorContext'; + +import validateJsonStringValue from './validateJsonStringValue'; + +type ImportJsonDialogProps = { + onClose: () => void; +}; +export default function ImportJsonDialog({ onClose }: ImportJsonDialogProps) { + const [value, setValue] = useState(''); + const [error, setError] = useState(null); + + const handleChange: React.ChangeEventHandler = (ev) => { + const v = ev.currentTarget.value; + setValue(v); + const { error } = validateJsonStringValue(v); + setError(error ?? null); + }; + + let errorAlert = null; + if (error) { + errorAlert = {error}; + } + + return ( + + Import JSON +
{ + ev.preventDefault(); + const { error, data } = validateJsonStringValue(value); + setError(error ?? null); + if (!data) { + return; + } + resetDocument(data); + onClose(); + }} + > + + + Copy and paste an EmailBuilder.js JSON. + + {errorAlert} + + + + + + +
+
+ ); +} diff --git a/packages/editor-sample/src/App/TemplatePanel/ImportJson/index.tsx b/packages/editor-sample/src/App/TemplatePanel/ImportJson/index.tsx new file mode 100644 index 0000000..25f21c8 --- /dev/null +++ b/packages/editor-sample/src/App/TemplatePanel/ImportJson/index.tsx @@ -0,0 +1,26 @@ +import React, { useState } from 'react'; + +import { UploadFileOutlined } from '@mui/icons-material'; +import { IconButton, Tooltip } from '@mui/material'; + +import ImportJsonDialog from './ImportJsonDialog'; + +export default function ImportJson() { + const [open, setOpen] = useState(false); + + let dialog = null; + if (open) { + dialog = setOpen(false)} />; + } + + return ( + <> + + setOpen(true)}> + + + + {dialog} + + ); +} diff --git a/packages/editor-sample/src/App/TemplatePanel/ImportJson/validateJsonStringValue.ts b/packages/editor-sample/src/App/TemplatePanel/ImportJson/validateJsonStringValue.ts new file mode 100644 index 0000000..a81cf74 --- /dev/null +++ b/packages/editor-sample/src/App/TemplatePanel/ImportJson/validateJsonStringValue.ts @@ -0,0 +1,23 @@ +import { EditorConfigurationSchema, TEditorConfiguration } from '../../../documents/editor/core'; + +type TResult = { error: string; data?: undefined } | { data: TEditorConfiguration; error?: undefined }; + +export default function validateTextAreaValue(value: string): TResult { + let jsonObject = undefined; + try { + jsonObject = JSON.parse(value); + } catch { + return { error: 'Invalid json' }; + } + + const parseResult = EditorConfigurationSchema.safeParse(jsonObject); + if (!parseResult.success) { + return { error: 'Invalid JSON schema' }; + } + + if (!parseResult.data.root) { + return { error: 'Missing "root" node' }; + } + + return { data: parseResult.data }; +} diff --git a/packages/editor-sample/src/App/TemplatePanel/index.tsx b/packages/editor-sample/src/App/TemplatePanel/index.tsx index ad6713c..c0cfb1b 100644 --- a/packages/editor-sample/src/App/TemplatePanel/index.tsx +++ b/packages/editor-sample/src/App/TemplatePanel/index.tsx @@ -15,6 +15,7 @@ import ToggleInspectorPanelButton from '../InspectorDrawer/ToggleInspectorPanelB import ToggleSamplesPanelButton from '../SamplesDrawer/ToggleSamplesPanelButton'; import HtmlPanel from './HtmlPanel'; +import ImportJson from './ImportJson'; import JsonPanel from './JsonPanel'; import MainTabsGroup from './MainTabsGroup'; import ShareButton from './ShareButton'; @@ -89,8 +90,11 @@ export default function TemplatePanel() { > - + + + +