diff --git a/packages/core/client/src/schema-component/antd/input/Json.tsx b/packages/core/client/src/schema-component/antd/input/Json.tsx index 009d0f166..5f8e40553 100644 --- a/packages/core/client/src/schema-component/antd/input/Json.tsx +++ b/packages/core/client/src/schema-component/antd/input/Json.tsx @@ -2,19 +2,52 @@ import { Field } from '@formily/core'; import { useField } from '@formily/react'; import { Input } from 'antd'; import { TextAreaProps } from 'antd/es/input'; -import React, { Ref } from 'react'; +import React, { useState, useEffect, Ref } from 'react'; +import { cx, css } from '@emotion/css'; export type JSONTextAreaProps = TextAreaProps & { value?: string; space?: number }; export const Json = React.forwardRef( ({ value, onChange, space = 2, ...props }: JSONTextAreaProps, ref: Ref) => { const field = useField(); + const [text, setText] = useState(''); + useEffect(() => { + try { + if (value != null) { + setText(JSON.stringify(value, null, space)); + } + } catch (ex) { + // + } + }, [space, value]); return ( { + setText(ev.target.value); + try { + if (ev.target.value.trim() !== '') { + JSON.parse(ev.target.value); + } + field.setFeedback({}); + } catch (err) { + field.setFeedback({ + type: 'error', + code: 'JSONSyntaxError', + messages: [err.message], + }); + } + }} + onBlur={(ev) => { try { const v = ev.target.value.trim() !== '' ? JSON.parse(ev.target.value) : null; field.setFeedback({}); diff --git a/packages/core/client/src/schema-component/antd/input/__tests__/Input.test.tsx b/packages/core/client/src/schema-component/antd/input/__tests__/Input.test.tsx index 794ec7e71..364d4a19a 100644 --- a/packages/core/client/src/schema-component/antd/input/__tests__/Input.test.tsx +++ b/packages/core/client/src/schema-component/antd/input/__tests__/Input.test.tsx @@ -136,7 +136,8 @@ describe('Input.JSON', () => { const textarea = container.querySelector('textarea') as HTMLTextAreaElement; const pre = container.querySelector('pre') as HTMLPreElement; fireEvent.change(textarea, { target: { value: '{"name":"nocobase"}' } }); - expect(textarea.value).toBe('{"name":"nocobase"}'); + fireEvent.blur(textarea, { target: { value: '{"name":"nocobase"}' } }); + expect(textarea.value).toBe('{\n "name": "nocobase"\n}'); expect(pre).toMatchInlineSnapshot(`
 {
 
     const textarea = container.querySelector('textarea') as HTMLTextAreaElement;
     fireEvent.change(textarea, { target: { value: '{"name":nocobase}' } });
+    fireEvent.blur(textarea, { target: { value: '{"name":nocobase}' } });
     expect(screen.getByText(`Unexpected token o in JSON at position 9`).innerHTML).toBe(
       `Unexpected token o in JSON at position 9`,
     );
diff --git a/packages/core/client/src/schema-component/antd/variable/JSONInput.tsx b/packages/core/client/src/schema-component/antd/variable/JSONInput.tsx
index 175ec81b0..10c8d105d 100644
--- a/packages/core/client/src/schema-component/antd/variable/JSONInput.tsx
+++ b/packages/core/client/src/schema-component/antd/variable/JSONInput.tsx
@@ -3,7 +3,6 @@ import { Button } from 'antd';
 import { css } from '@emotion/css';
 
 import { Input } from '../input';
-import { useTranslation } from 'react-i18next';
 import { VariableSelect } from './VariableSelect';
 
 // NOTE: https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-onchange-event-in-react-js/46012210#46012210
@@ -19,25 +18,9 @@ function setNativeInputValue(input, value) {
 
 export function JSONInput(props) {
   const inputRef = useRef(null);
-  const { value, space = 2, scope } = props;
-  const { t } = useTranslation();
+  const { scope } = props;
   const options = typeof scope === 'function' ? scope() : scope ?? [];
 
-  function onFormat() {
-    if (!inputRef.current) {
-      return;
-    }
-    if (!value) {
-      return;
-    }
-
-    const { textArea } = inputRef.current.resizableTextArea;
-    const nextValue = JSON.stringify(value, null, space);
-    setNativeInputValue(textArea, nextValue);
-    textArea.setSelectionRange(nextValue.length, nextValue.length);
-    textArea.focus();
-  }
-
   function onInsert(selected) {
     if (!inputRef.current) {
       return;
@@ -73,7 +56,6 @@ export function JSONInput(props) {
           }
         `}
       >
-        
         
       
     
diff --git a/packages/core/client/src/schema-component/antd/variable/__tests__/variable.test.tsx b/packages/core/client/src/schema-component/antd/variable/__tests__/variable.test.tsx
index b13955cef..f826e8b71 100644
--- a/packages/core/client/src/schema-component/antd/variable/__tests__/variable.test.tsx
+++ b/packages/core/client/src/schema-component/antd/variable/__tests__/variable.test.tsx
@@ -61,7 +61,6 @@ describe('Variable', () => {
     const variableSelector = document.querySelector('.ant-select-selector') as HTMLElement;
     expect(input).toBeInTheDocument();
     expect(variableSelector).toBeInTheDocument();
-    expect(screen.getByText('Prettify')).toBeInTheDocument();
 
     // https://testing-library.com/docs/user-event/keyboard/
     await userEvent.type(input, '{{ "a": "');
@@ -71,13 +70,5 @@ describe('Variable', () => {
 
     await userEvent.type(input, '" }');
     expect(input.value).toMatchInlineSnapshot('"{ \\"a\\": \\"{{v1}}\\" }"');
-
-    // 格式化一下
-    await userEvent.click(screen.getByText('Prettify'));
-    expect(input.value).toMatchInlineSnapshot(`
-      "{
-        \\"a\\": \\"{{v1}}\\"
-      }"
-    `);
   });
 });
diff --git a/packages/plugins/workflow/src/client/nodes/request.tsx b/packages/plugins/workflow/src/client/nodes/request.tsx
index 5ca66a2eb..c99337040 100644
--- a/packages/plugins/workflow/src/client/nodes/request.tsx
+++ b/packages/plugins/workflow/src/client/nodes/request.tsx
@@ -1,5 +1,4 @@
 import { ArrayItems } from '@formily/antd';
-import { cx, css } from '@emotion/css';
 
 import { NAMESPACE } from '../locale';
 import { useWorkflowVariableOptions } from '../variable';
@@ -146,13 +145,7 @@ export default {
           minRows: 10,
         },
         placeholder: `{{t("Input request data", { ns: "${NAMESPACE}" })}}`,
-        className: cx(
-          'full-width',
-          css`
-            font-size: 90%;
-            font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
-          `,
-        ),
+        className: 'full-width',
       },
       description: `{{t("Only support standard JSON data", { ns: "${NAMESPACE}" })}}`,
     },