feat: fixes json editor errors and misc styling

This commit is contained in:
Jessica Boezwinkle
2022-12-16 13:34:21 +00:00
parent 8eaf05efef
commit efe4f6d861
6 changed files with 56 additions and 24 deletions

View File

@@ -9,7 +9,7 @@
transform: none;
background-color: var(--theme-error-500);
span {
&::after {
border-top-color: var(--theme-error-500);
}
}
}

View File

@@ -1,13 +1,15 @@
import React, { useCallback } from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import Editor from '@monaco-editor/react';
import useField from '../../useField';
import withCondition from '../../withCondition';
import Label from '../../Label';
import { code } from '../../../../../fields/validations';
import Error from '../../Error';
import FieldDescription from '../../FieldDescription';
import { code } from '../../../../../fields/validations';
import Label from '../../Label';
import { Props } from './types';
import useField from '../../useField';
import { useTheme } from '../../../utilities/Theme';
import withCondition from '../../withCondition';
import './index.scss';
@@ -31,6 +33,7 @@ const Code: React.FC<Props> = (props) => {
label,
} = props;
const { theme } = useTheme();
const path = pathFromProps || name;
const memoizedValidate = useCallback((value, options) => {
@@ -74,14 +77,21 @@ const Code: React.FC<Props> = (props) => {
required={required}
/>
<Editor
height="50vh" // for now, should update this to be dynamic
className={`${baseClass}__editor`}
height="35vh"
defaultLanguage={language}
value={value as string || ''}
onChange={readOnly ? () => null : (val) => setValue(val)}
options={{
detectIndentation: true,
minimap: {
enabled: false,
},
readOnly: Boolean(readOnly),
scrollBeyondLastLine: false,
tabSize: 2,
theme: theme === 'dark' ? 'vs-dark' : 'vs',
wordWrap: 'on',
}}
/>
<FieldDescription

View File

@@ -4,6 +4,12 @@
position: relative;
margin-bottom: $baseline;
&__editor {
@include formInput;
height: auto;
padding: 0;
}
&.error {
textarea {
border: 1px solid var(--theme-error-500) !important;

View File

@@ -1,14 +1,16 @@
import React, { useCallback, useEffect, useState } from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import Editor from '@monaco-editor/react';
import useField from '../../useField';
import withCondition from '../../withCondition';
import Label from '../../Label';
import Error from '../../Error';
import FieldDescription from '../../FieldDescription';
import { json } from '../../../../../fields/validations';
import Label from '../../Label';
import { Props } from './types';
import useField from '../../useField';
import useThrottledEffect from '../../../../hooks/useThrottledEffect';
import { useTheme } from '../../../utilities/Theme';
import withCondition from '../../withCondition';
import './index.scss';
@@ -31,11 +33,14 @@ const JSONField: React.FC<Props> = (props) => {
label,
} = props;
const { theme } = useTheme();
const path = pathFromProps || name;
const [stringValue, setStringValue] = useState<string>();
const [jsonError, setJsonError] = useState<string>();
const memoizedValidate = useCallback((value, options) => {
return validate(value, { ...options, required });
}, [validate, required]);
return validate(value, { ...options, required, jsonError });
}, [validate, required, jsonError]);
const {
value,
@@ -49,11 +54,14 @@ const JSONField: React.FC<Props> = (props) => {
condition,
});
const [stringValue, setStringValue] = useState<string>();
useThrottledEffect(() => {
setValue(JSON.parse(stringValue));
}, 200, [setValue, stringValue]);
try {
setValue(JSON.parse(stringValue));
setJsonError(undefined);
} catch (e) {
setJsonError(e);
}
}, 0, [setValue, stringValue]);
useEffect(() => {
setStringValue(JSON.stringify(initialValue, null, 2));
@@ -85,16 +93,21 @@ const JSONField: React.FC<Props> = (props) => {
required={required}
/>
<Editor
height="50vh"
className={`${baseClass}__editor`}
height="35vh"
defaultLanguage="json"
value={stringValue}
onChange={readOnly ? () => null : (val) => setStringValue(val)}
options={{
tabSize: 2,
detectIndentation: true,
minimap: {
enabled: false,
},
readOnly: Boolean(readOnly),
scrollBeyondLastLine: false,
tabSize: 2,
theme: theme === 'dark' ? 'vs-dark' : 'vs',
wordWrap: 'on',
}}
/>
<FieldDescription

View File

@@ -4,6 +4,12 @@
position: relative;
margin-bottom: $baseline;
&__editor {
@include formInput;
height: auto;
padding: 0;
}
&.error {
textarea {
border: 1px solid var(--theme-error-500) !important;

View File

@@ -134,17 +134,14 @@ export const code: Validate<unknown, unknown, CodeField> = (value: string, { t,
};
export const json: Validate<unknown, unknown, JSONField> = (value: string, {
t, required,
t, required, jsonError,
}) => {
if (required && !value) {
return t('validation:required');
}
try {
const incomingJSON = typeof value === 'object' ? JSON.stringify(value) : value;
const validJSON = JSON.parse(incomingJSON);
} catch (err) {
return `Invalid JSON: ${err}`;
if (jsonError !== undefined) {
return t('validation:invalidInput');
}
return true;