Skip to content

Commit 8c4782a

Browse files
authored
feat: schema editor support json to schema (#639)
1 parent 112e304 commit 8c4782a

File tree

5 files changed

+128
-58
lines changed

5 files changed

+128
-58
lines changed

packages/react-schema-editor/README.md

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,47 @@ import { SchemaEditor } from './src'
1414

1515
function SchemaEditorDemo() {
1616
const [schema, setSchema] = React.useState({
17-
title: '动态表单示例',
18-
type: 'object',
19-
"properties": {
20-
"username": {
21-
"title": "用户名",
22-
"type": "string",
23-
"x-component-props": {
24-
"placeholder": "请输入用户名",
25-
"onChange": "function(value) \n{console.log('input onChange', value, this.field, this.field.getValue('note'))"
26-
}
27-
},
28-
"password": {
29-
"title": "密码",
30-
"type": "string",
31-
"x-component": "Input",
32-
"x-component-props": {
33-
"htmlType": "password",
34-
"placeholder": "请输入密码"
35-
}
36-
},
37-
"note": {
38-
"title": "备注",
39-
"type": "string",
40-
"x-component": "TextArea",
41-
"x-component-props": {
42-
"placeholder": "something"
43-
}
44-
},
45-
"agreement": {
46-
"title": "同意",
47-
"type": "string",
48-
"x-component": "Checkbox",
49-
"x-component-props": {
50-
"disabled": "{{!this.field.getValue('username')}}",
51-
"defaultChecked": true
17+
title: '动态表单示例',
18+
type: 'object',
19+
"properties": {
20+
"username": {
21+
"title": "用户名",
22+
"type": "string",
23+
"x-component-props": {
24+
"placeholder": "请输入用户名",
25+
"onChange": "function(value) \n{console.log('input onChange', value, this.field, this.field.getValue('note'))"
26+
}
27+
},
28+
"password": {
29+
"title": "密码",
30+
"type": "string",
31+
"x-component": "Input",
32+
"x-component-props": {
33+
"htmlType": "password",
34+
"placeholder": "请输入密码"
35+
}
36+
},
37+
"note": {
38+
"title": "备注",
39+
"type": "string",
40+
"x-component": "TextArea",
41+
"x-component-props": {
42+
"placeholder": "something"
43+
}
44+
},
45+
"agreement": {
46+
"title": "同意",
47+
"type": "string",
48+
"x-component": "Checkbox",
49+
"x-component-props": {
50+
"disabled": "{{!this.field.getValue('username')}}",
51+
"defaultChecked": true
52+
}
5253
}
5354
}
54-
}
55-
})
55+
})
5656

57+
// return <div>Hello</div>
5758
return <SchemaEditor schema={schema} onChange={setSchema} />
5859
}
5960

packages/react-schema-editor/src/__tests__/index.spec.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,24 @@ describe('json object transform', () => {
2323
const validResult = {
2424
title: '',
2525
type: 'object',
26-
properties: [
27-
{
26+
properties: {
27+
string: {
2828
title: '',
2929
type: 'string',
3030
example: 'input test',
3131
enum: [],
3232
description: '',
3333
'x-component': 'Input'
3434
},
35-
{
35+
boolean: {
3636
title: '',
3737
type: 'boolean',
3838
example: true,
3939
enum: [],
4040
description: '',
4141
'x-component': 'Input'
4242
},
43-
{
43+
checkbox: {
4444
title: '',
4545
type: 'array',
4646
items: {
@@ -54,15 +54,15 @@ describe('json object transform', () => {
5454
description: '',
5555
'x-component': 'Input'
5656
},
57-
{
57+
date: {
5858
title: '',
5959
type: 'string',
6060
example: '2019-12-12',
6161
enum: [],
6262
description: '',
6363
'x-component': 'Input'
6464
},
65-
{
65+
daterange: {
6666
title: '',
6767
type: 'array',
6868
items: {
@@ -76,55 +76,55 @@ describe('json object transform', () => {
7676
description: '',
7777
'x-component': 'Input'
7878
},
79-
{
79+
number: {
8080
title: '',
8181
type: 'number',
8282
example: 1,
8383
enum: [],
8484
description: '',
8585
'x-component': 'Input'
8686
},
87-
{
87+
radio: {
8888
title: '',
8989
type: 'string',
9090
example: '2',
9191
enum: [],
9292
description: '',
9393
'x-component': 'Input'
9494
},
95-
{
95+
rating: {
9696
title: '',
9797
type: 'number',
9898
example: 4,
9999
enum: [],
100100
description: '',
101101
'x-component': 'Input'
102102
},
103-
{
103+
select: {
104104
title: '',
105105
type: 'string',
106106
example: '1',
107107
enum: [],
108108
description: '',
109109
'x-component': 'Input'
110110
},
111-
{
111+
textarea: {
112112
title: '',
113113
type: 'string',
114114
example: 'test text',
115115
enum: [],
116116
description: '',
117117
'x-component': 'Input'
118118
},
119-
{
119+
time: {
120120
title: '',
121121
type: 'string',
122122
example: '00:00:04',
123123
enum: [],
124124
description: '',
125125
'x-component': 'Input'
126126
},
127-
{
127+
transfer: {
128128
title: '',
129129
type: 'array',
130130
items: {
@@ -138,15 +138,15 @@ describe('json object transform', () => {
138138
description: '',
139139
'x-component': 'Input'
140140
},
141-
{
141+
year: {
142142
title: '',
143143
type: 'string',
144144
example: '2013-01-01 00:00:00',
145145
enum: [],
146146
description: '',
147147
'x-component': 'Input'
148148
}
149-
],
149+
},
150150
description: ''
151151
}
152152

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React, { useState } from 'react'
2+
import { Input, Modal, Button } from 'antd'
3+
import { json2schema } from '../utils/json2schema'
4+
5+
const { TextArea } = Input
6+
7+
interface IJsonDialogProps {
8+
onChange: (schema: any) => void
9+
}
10+
11+
const JsonDialog: React.FC<IJsonDialogProps> = ({ onChange }) => {
12+
const [jsonDialogVisible, setJsonDialogVisible] = useState(false)
13+
const [json, setJson] = useState('')
14+
15+
const handleShowJsonDialog = () => {
16+
setJsonDialogVisible(true)
17+
}
18+
19+
const handleHideJsonDialog = () => {
20+
setJsonDialogVisible(false)
21+
}
22+
23+
const handleJsonChange = e => {
24+
const { value } = e.target
25+
setJson(value)
26+
}
27+
28+
const handleOk = () => {
29+
try {
30+
if (!json) {
31+
return
32+
}
33+
const jsonSchema = json2schema(JSON.parse(json))
34+
handleHideJsonDialog()
35+
onChange(jsonSchema)
36+
} catch (err) {
37+
// console.log(err)
38+
}
39+
}
40+
41+
return (
42+
<div>
43+
<Button type="primary" onClick={handleShowJsonDialog}>
44+
快速生成
45+
</Button>
46+
<Modal
47+
title="请输入JSON"
48+
visible={jsonDialogVisible}
49+
onOk={handleOk}
50+
onCancel={handleHideJsonDialog}
51+
>
52+
<TextArea
53+
value={json}
54+
onChange={handleJsonChange}
55+
placeholder=""
56+
autoSize={{ minRows: 10, maxRows: 10 }}
57+
/>
58+
</Modal>
59+
</div>
60+
)
61+
}
62+
63+
export default JsonDialog

packages/react-schema-editor/src/index.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React, { useState } from 'react'
2-
import { Button, Radio, Tabs } from 'antd'
2+
import { Radio, Tabs } from 'antd'
33
import * as fp from 'lodash/fp'
44
import _ from 'lodash'
55
import { SchemaTree } from './components/SchemaTree'
66
import FieldEditor from './components/FieldEditor'
77
import { SchemaCode } from './components/SchemaCode'
8+
import JsonDialog from './components/JsonDialog'
89
// import { SchemaPreview } from './components/SchemaPreview'
910
import { ComponentTypes } from './utils/types'
1011
import {
@@ -32,7 +33,7 @@ export const SchemaEditor: React.FC<{
3233
const [componentType, setComponentType] = useState(
3334
getDefaultComponentType({ showAntdComponents, showFusionComponents })
3435
)
35-
const [selectedPath, setSelectedPath] = React.useState(null)
36+
const [selectedPath, setSelectedPath] = useState(null)
3637

3738
const selectedPaths = (selectedPath && selectedPath.split('.')) || []
3839
const fieldKey =
@@ -48,6 +49,10 @@ export const SchemaEditor: React.FC<{
4849

4950
const handleCodeChange = () => {}
5051

52+
const handleSchemaChange = (schema: string) => {
53+
onChange(schema)
54+
}
55+
5156
const isRoot = selectedPath === 'root'
5257

5358
const selectedSchema =
@@ -56,7 +61,7 @@ export const SchemaEditor: React.FC<{
5661
return (
5762
<div className={`schema-editor ${className}`}>
5863
<div className="schema-menus">
59-
<Button type="primary">快速生成</Button>
64+
<JsonDialog onChange={handleSchemaChange} />
6065
{(showAntdComponents || showFusionComponents) && (
6166
<span className="select-component-type">
6267
选择组件类型:

packages/react-schema-editor/src/utils/json2schema.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ export function json2schema(json: any, parentsPath?: string) {
1313
schema = schema || {
1414
title: '',
1515
type,
16-
properties: Object.keys(json).map(key =>
17-
json2schema(json[key], newParentsPath + '.' + key)
18-
),
16+
properties: Object.keys(json).reduce((result, key) => {
17+
result[key] = json2schema(json[key], newParentsPath + '.' + key)
18+
return result
19+
}, {}),
1920
description: ''
2021
}
2122
} else if (type === 'array') {

0 commit comments

Comments
 (0)