From 70753eb41f7f9e88fada50c64c2c40e4a73fe24f Mon Sep 17 00:00:00 2001 From: Stig Ofstad Date: Tue, 21 May 2024 13:47:10 +0200 Subject: [PATCH] feat(yaml): raw json edit --- .../dm-core-plugins/src/yaml/YamlPlugin.tsx | 100 +++++++++++++++--- packages/dm-core/src/hooks/useDocument.tsx | 5 +- 2 files changed, 85 insertions(+), 20 deletions(-) diff --git a/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx b/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx index 4092ebc81..50e89aa18 100644 --- a/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx +++ b/packages/dm-core-plugins/src/yaml/YamlPlugin.tsx @@ -1,17 +1,35 @@ import { + ErrorGroup, IUIPlugin, Loading, TGenericObject, useDocument, } from '@development-framework/dm-core' -import { Button, Input, Label } from '@equinor/eds-core-react' +import { Button, Input, Label, Switch } from '@equinor/eds-core-react' import DOMPurify from 'dompurify' import hljs from 'highlight.js' -import { ChangeEvent, Dispatch, SetStateAction, useState } from 'react' +import { ChangeEvent, Dispatch, SetStateAction, useRef, useState } from 'react' import { toast } from 'react-toastify' import styled from 'styled-components' import YAML from 'yaml' +const StyledPre = styled.pre` + white-space: -moz-pre-wrap; /* Mozilla, supported since 1999 */ + white-space: -pre-wrap; /* Opera */ + white-space: -o-pre-wrap; /* Opera */ + white-space: pre-wrap; /* CSS3 - Text module (Candidate Recommendation) http://www.w3.org/TR/css3-text/#white-space */ + word-wrap: break-word; /* IE 5.5+ */ + background-color: #e0e3e5; + margin: 0; + padding: 1rem; + border-radius: 0.2rem; + border-style: ridge; + border-width: 0.2rem; + border-color: #193549; + width: 100%; + overflow-y: auto; +` + const CodeContainer = styled.pre` background-color: #193549; margin: 0; @@ -37,13 +55,20 @@ const CodeContainer = styled.pre` const YamlView = (props: { document: TGenericObject + updateDocument: ( + document: TGenericObject, + notify: boolean, + partialUpdate?: boolean | undefined + ) => Promise depth?: number _setDepth?: Dispatch> }) => { - const { document, depth, _setDepth } = props + const { document, depth, _setDepth, updateDocument } = props const asYAML: string = YAML.stringify(document) const asJSON: string = JSON.stringify(document) const highlighted = hljs.highlight(asYAML, { language: 'yaml' }) + const [isEditMode, setIsEditMode] = useState(false) + const textInput = useRef(null) const onClick = (text: string) => { navigator.clipboard.writeText(text) @@ -57,6 +82,16 @@ const YamlView = (props: { } } + const saveChanges = () => { + try { + const parsed = JSON.parse(textInput.current?.innerText || '{}') + updateDocument(parsed, true) + } catch (e) { + console.log(e) + toast.error(`Invalid JSON - ${e.message}`, { autoClose: false }) + } + } + return (
@@ -76,14 +111,37 @@ const YamlView = (props: { label='Depth' />
-
- - setIsEditMode(!isEditMode)} /> - + + {isEditMode ? ( + <> +
+ +
+ + {JSON.stringify(document, null, 2)} + +
+ +
+ + ) : ( + + + + )} ) } @@ -91,15 +149,25 @@ const YamlView = (props: { export const YamlPlugin = (props: IUIPlugin) => { const { idReference } = props const [depth, setDepth] = useState(0) - const { document, isLoading, error } = useDocument( - idReference, - depth - ) + const { document, isLoading, error, updateDocument } = + useDocument(idReference, depth) if (isLoading) return - if (error) throw new Error(JSON.stringify(error, null, 2)) + if (error && !error.message) throw new Error(JSON.stringify(error, null, 2)) return ( - + <> + {error && ( +
+ {error.message} +
+ )} + + ) } diff --git a/packages/dm-core/src/hooks/useDocument.tsx b/packages/dm-core/src/hooks/useDocument.tsx index b3d985de6..bfe990545 100644 --- a/packages/dm-core/src/hooks/useDocument.tsx +++ b/packages/dm-core/src/hooks/useDocument.tsx @@ -106,10 +106,7 @@ export function useDocument( }) .catch((error: AxiosError) => { console.error(error) - if (notify) - toast.error( - 'Unable to update document, with message: ' + error.message - ) + if (notify) toast.error(error.response?.data.message ?? error.message) setError(error.response?.data || { message: error.name, data: error }) }) .finally(() => setLoading(false))