diff --git a/packages/core/src/components/configSchema/index.module.less b/packages/core/src/components/configSchema/index.module.less deleted file mode 100644 index 29767c1..0000000 --- a/packages/core/src/components/configSchema/index.module.less +++ /dev/null @@ -1,10 +0,0 @@ -.tabPane{ - .form{ - height:600px; - overflow-y: auto; - margin:0 20px; - } - .configInput{ - height: 600px; - } -} diff --git a/packages/core/src/components/configSchema/index.tsx b/packages/core/src/components/configSchema/index.tsx deleted file mode 100644 index 01722ae..0000000 --- a/packages/core/src/components/configSchema/index.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useState, useRef } from 'react'; -import Generator from 'fr-generator'; -import { Tabs } from 'antd'; -const { TabPane } = Tabs; -import CodeEditor from '../codeEditor'; -import { compData } from './json' -import styles from './index.module.less'; -interface IProps { - onChange: (value: object) => void -} - -const ConfigSchema: React.FC = (props) => { - const [code, setCode] = useState('') - const [schema, setSchema] = useState({}) - const formRef = useRef() - - // 同步代码 - const tabChange = () => { - // 可视化同步到编辑器 - // @ts-ignore - const formSchema = formRef.current && formRef.current.getValue() - setSchema(formSchema) - setCode(JSON.stringify(formSchema, null, 2)) - - // 编辑器同步到可视化 - try { - const codeObj = JSON.parse(code) - setSchema(codeObj) - // @ts-ignore - formRef.current.setValue(codeObj) - } catch (error) { - console.log('can\'t parse code string to form schema, the error is:', error.message); - } - } - - const codeChange = (ev: any, newCode: any) => { - setCode(newCode) - } - - return ( - - -
- -
-
- -
- -
-
-
- ) -} - -export default ConfigSchema; diff --git a/packages/core/src/components/configSchema/json.ts b/packages/core/src/components/configSchema/json.ts deleted file mode 100644 index 52ef4bd..0000000 --- a/packages/core/src/components/configSchema/json.ts +++ /dev/null @@ -1,510 +0,0 @@ -const compData = [ - { - "text": '简单输入框', - "name": 'input', - "schema": { - "title": "简单输入框", - "type": "string", - "ui:options": { - "placeholder": "名称" - } - } - }, - { - "text": '简单文本编辑框', - "name": 'textarea', - "schema": { - "title": "简单文本编辑框", - "type": "string", - "format": "textarea" - } - }, - { - "text": '带清空x按钮', - "name": 'inputX', - "schema": { - "title": "字符串", - "description": "带清空x按钮", - "type": "string", - "default": "input placeholder", - "ui:options": { - "allowClear": true - }, - "ui:width": "50%" - } - }, - { - "text": '前置/后置标签', - "name": 'stringPreSub', - "schema": { - "title": "前置/后置标签", - "type": "string", - "ui:options": { - "addonBefore": "长度", - "addonAfter": "px" - }, - "ui:width": "50%" - } - }, - { - "text": '颜色选择', - "name": 'color', - "schema": { - "title": "颜色选择", - "type": "string", - "format": "color" - } - }, - { - "text": '日期选择', - "name": 'date', - "schema": { - "title": "日期选择", - "type": "string", - "format": "date" - } - }, - { - "text": '上传文件', - "name": 'upload', - "schema": { - "title": "上传文件", - "type": "string", - "format": "upload", - "ui:options": { - "action": "https://www.mocky.io/v2/5cc8019d300000980a055e76" - } - } - }, - { - "text": 'number类', - "name": 'allNumber', - "schema": { - "title": "number类", - "type": "object", - "properties": { - "number1": { - "title": "数字输入框", - "description": "1 - 1000", - "type": "number", - "min": 1, - "max": 1000 - }, - "number2": { - "title": "带滑动条", - "type": "number", - "ui:widget": "slider" - } - } - } - }, - { - "text": 'boolean类', - "name": 'allBoolean', - "schema": { - "title": "boolean类", - "type": "object", - "properties": { - "radio": { - "title": "是否通过", - "type": "boolean" - }, - "switch": { - "title": "开关控制", - "type": "boolean", - "ui:widget": "switch" - } - } - } - }, - { - "text": 'range类', - "name": 'allRange', - "schema": { - "title": "range类", - "type": "object", - "properties": { - "dateRange": { - "title": "日期范围", - "type": "range", - "format": "dateTime", - "ui:options": { - "placeholder": [ - "开始时间", - "结束时间" - ] - } - } - } - } - }, - { - "text": '选择类', - "name": 'allEnum', - "schema": { - "title": "选择类", - "type": "object", - "properties": { - "select": { - "title": "单选", - "type": "string", - "enum": [ - "a", - "b", - "c" - ], - "enumNames": [ - "早", - "中", - "晚" - ] - }, - "radio": { - "title": "单选", - "type": "string", - "enum": [ - "a", - "b", - "c" - ], - "enumNames": [ - "早", - "中", - "晚" - ], - "ui:widget": "radio" - }, - "multiSelect": { - "title": "多选", - "description": "下拉多选", - "type": "array", - "items": { - "type": "string" - }, - "enum": [ - "A", - "B", - "C", - "D" - ], - "enumNames": [ - "杭州", - "武汉", - "湖州", - "贵阳" - ], - "ui:widget": "multiSelect" - }, - "boxes": { - "title": "多选", - "description": "checkbox", - "type": "array", - "items": { - "type": "string" - }, - "enum": [ - "A", - "B", - "C", - "D" - ], - "enumNames": [ - "杭州", - "武汉", - "湖州", - "贵阳" - ] - } - } - } - }, - { - "text": '可折叠对象', - "name": 'obj1', - "schema": { - "title": "可折叠对象", - "description": "这是个对象类型", - "type": "object", - "ui:options": { - "collapsed": true - }, - "properties": { - "input1": { - "title": "输入框1", - "type": "string" - }, - "input2": { - "title": "输入框2", - "type": "string" - } - } - } - }, - { - "text": '对象数组', - "name": 'listName2', - "schema": { - "title": "对象数组", - "description": "对象数组嵌套功能", - "type": "array", - "minItems": 1, - "maxItems": 3, - "ui:displayType": "row", - "items": { - "type": "object", - "properties": { - "input1": { - "title": "简单输入框", - "type": "string" - }, - "selet1": { - "title": "单选", - "type": "string", - "enum": [ - "a", - "b", - "c" - ], - "enumNames": [ - "早", - "中", - "晚" - ] - } - } - } - } - }, - { - "text": 'url输入框', - "name": 'url', - "schema": { - "title": "url输入框", - "type": "string", - "format": "url" - } - }, - { - "text": '图片展示', - "name": 'image', - "schema": { - "title": "图片展示", - "type": "string", - "format": "image" - } - }, - { - "text": 'email输入框', - "name": 'email', - "schema": { - "title": "email输入框", - "type": "string", - "format": "email" - } - }, - { - "text": 'list套list', - "name": 'listAndList', - "schema": { - "title": "list套list", - "type": "array", - "items": { - "type": "object", - "properties": { - "input1": { - "title": "简单输入框", - "type": "string" - }, - "list4": { - "title": "数组", - "type": "array", - "items": { - "type": "object", - "properties": { - "input1": { - "title": "输入框1", - "type": "string" - }, - "input2": { - "title": "输入框2", - "type": "string" - } - } - }, - "ui:options": { - "drawer": true - } - } - } - } - } - }, - { - "text": '整体隐藏', - "name": 'hide', - "schema": { - "title": "整体隐藏", - "type": "object", - "properties": { - "showMore": { - "title": "显示更多", - "type": "boolean" - }, - "x1": { - "title": "输入框1", - "type": "string", - "ui:hidden": "{{rootValue.showMore === false}}" - }, - "x2": { - "title": "输入框2", - "type": "string", - "ui:hidden": "{{rootValue.showMore === false}}" - } - } - } - }, - { - "text": '选项联动', - "name": 'link', - "schema": { - "title": "选项联动", - "type": "object", - "properties": { - "bi": { - "title": "汇款币种", - "type": "string", - "enum": [ - "rmb", - "dollar" - ], - "enumNames": [ - "人民币", - "美元" - ] - }, - "inputName": { - "title": "金额", - "description": "{{rootValue.bi === 'dollar' ? '一次汇款不超过150美元':'一次汇款不超过1000元'}}", - "type": "string", - "ui:options": { - "addonBefore": "{{rootValue.bi === 'rmb'? '¥':'$'}}", - "addonAfter": "{{rootValue.bi === 'rmb'? '元':'美元'}}" - } - } - } - } - }, - { - "text": '动态增加', - "name": 'listAdd', - "schema": { - "title": "列表/显示不同组件", - "type": "object", - "properties": { - "ruleList": { - "title": "球员筛选", - "type": "array", - "items": { - "type": "object", - "properties": { - "attr": { - "title": "标准", - "type": "string", - "enum": [ - "goal", - "league" - ], - "enumNames": [ - "入球数", - "所在联盟" - ], - "ui:width": "40%" - }, - "relation": { - "title": "-", - "type": "string", - "enum": [ - ">", - "<", - "=" - ], - "ui:hidden": "{{rootValue.attr === 'league'}}", - "ui:width": "20%" - }, - "goal": { - "title": "入球数", - "type": "string", - "pattern": "^[0-9]+$", - "message": { - "pattern": "输入正确得分" - }, - "ui:hidden": "{{rootValue.attr !== 'goal'}}", - "ui:width": "40%" - }, - "league": { - "title": "名称", - "type": "string", - "enum": [ - "a", - "b", - "c" - ], - "enumNames": [ - "西甲", - "英超", - "中超" - ], - "ui:hidden": "{{rootValue.attr !== 'league'}}", - "ui:width": "40%" - } - } - } - } - } - } - }, - { - "text": '时间选择', - "name": 'timeSelect', - "schema": { - "title": "时间选择", - "type": "string", - "format": "time" - } - }, - { - "text": '日期范围', - "name": 'dateRangeSelect', - "schema": { - "title": "日期范围", - "type": "range", - "format": "date" - } - }, - { - "text": '日期选择(到日)', - "name": 'dateSelect', - "schema": { - "title": "日期选择", - "type": "string", - "format": "date", - "ui:options": { - "format": "YY/MM/DD" - } - } - }, - { - "text": '日期选择(到秒)', - "name": 'dateSelectToSecond', - "schema": { - "title": "日期选择", - "description": "精确到秒", - "type": "string", - "format": "dateTime" - } - } -] - -export { - compData -} diff --git a/packages/core/src/components/form/index.tsx b/packages/core/src/components/form/index.tsx new file mode 100644 index 0000000..9e4505f --- /dev/null +++ b/packages/core/src/components/form/index.tsx @@ -0,0 +1,91 @@ +import React from 'react'; +import { Form, Input, Switch, Select, Radio, Checkbox, DatePicker, TimePicker } from 'antd'; +import moment from 'moment'; +const FormItem = Form.Item +const { RangePicker } = DatePicker; +const { Option } = Select; + +interface INum { + label: string, + value: string +} + +interface IProps { + schema: { + schema: { + type: string, + properties: { [key: string]: any } + } + } +} + +const MyForm: React.FC = (props) => { + const layout = { + labelCol: { span: 6 }, + wrapperCol: { span: 18 } + }; + + return ( +
+ {props.schema?.schema?.properties && Object.keys(props.schema.schema.properties).map((key: string) => { + const obj = props.schema.schema.properties[key] + const options: INum[] = obj.enum ? obj.enum.map((item: string, idx: number) => { + return { label: item, value: obj.enumNames[idx] } + }) : [] + let ele = null + // 输入框 + if (obj.type === 'string' && !obj.hasOwnProperty('format') && !obj.hasOwnProperty('enum')) { + ele = + } + // 编辑框 + if (obj.type === 'string' && obj.format === 'textarea') { + ele = + } + // switch + if (obj.type === 'boolean' && obj['ui:widget'] === 'switch') { + ele = + } + // 下拉单选 + if (obj.type === 'string' && obj.hasOwnProperty('enum') && !obj.hasOwnProperty('ui:widget')) { + ele = + } + // 点击单选 + if (obj.type === 'string' && obj.hasOwnProperty('enum') && obj['ui:widget'] === 'radio') { + ele = + } + // 下拉多选 + if (obj.type === 'array' && obj.hasOwnProperty('enum') && obj['ui:widget'] === 'multiSelect') { + ele = + } + // 点击多选 + if (obj.type === 'array' && obj.hasOwnProperty('enum') && !obj.hasOwnProperty('ui:widget')) { + ele = + } + // 时间选择 + if (obj.type === 'string' && obj.format === 'time') { + ele = + } + // 日期范围 + if (obj.type === 'range' && obj.format === 'date') { + ele = + } + // 日期选择 + if (obj.type === 'string' && obj.format === 'date') { + ele = + } + return + {ele} + + })} + + ); +}; + +export default MyForm diff --git a/packages/core/src/mods/settingBar/components/input/index.module.less b/packages/core/src/mods/settingBar/components/input/index.module.less index 8b3412a..ebb7619 100644 --- a/packages/core/src/mods/settingBar/components/input/index.module.less +++ b/packages/core/src/mods/settingBar/components/input/index.module.less @@ -1,9 +1,4 @@ -.container { - - margin-top: 20px; - .titleText { font-size: 14px; - margin-bottom: 10px; + width:150px; } -} diff --git a/packages/core/src/mods/settingBar/components/input/index.tsx b/packages/core/src/mods/settingBar/components/input/index.tsx index 3ee7431..8153cee 100644 --- a/packages/core/src/mods/settingBar/components/input/index.tsx +++ b/packages/core/src/mods/settingBar/components/input/index.tsx @@ -22,7 +22,7 @@ const Input: React.FC = (props) => { } }; return ( -
+

{title}

diff --git a/packages/core/src/mods/settingBar/components/json/index.module.less b/packages/core/src/mods/settingBar/components/json/index.module.less index d3f000e..99c3b83 100644 --- a/packages/core/src/mods/settingBar/components/json/index.module.less +++ b/packages/core/src/mods/settingBar/components/json/index.module.less @@ -1,18 +1,29 @@ .container { - margin-top: 20px; - .titleText { - font-size: 14px; - margin-bottom: 10px; - } - - .btn { - margin-top: 5px; + .header{ + display:flex; + flex-direction: row; + justify-content:space-between; + + .titleText { + font-size: 14px; + margin-bottom: 10px; + } } } .editModal { + .tabPane{ + .form{ + height:600px; + overflow-y: auto; + margin:0 20px; + } + .configInput{ + height: 600px; + } + } :global { .ant-modal-body { diff --git a/packages/core/src/mods/settingBar/components/json/index.tsx b/packages/core/src/mods/settingBar/components/json/index.tsx index 03c974f..0dd661c 100644 --- a/packages/core/src/mods/settingBar/components/json/index.tsx +++ b/packages/core/src/mods/settingBar/components/json/index.tsx @@ -1,27 +1,29 @@ -import React, { useState, useEffect } from 'react'; - +import React, { useState, useEffect, useRef } from 'react'; +import Generator from 'fr-generator'; import 'antd/es/modal/style'; import 'antd/es/button/style'; import 'antd/es/message/style'; -import styles from './index.module.less'; - import JsonView from 'react-json-view'; -import { Button, Modal, message } from 'antd'; +import { Button, Tabs, Modal, message, Card } from 'antd'; +const { TabPane } = Tabs; import { safeParse } from '../../../../utils'; import CodeEditor from '../../../../components/codeEditor'; -import ConfigSchema from '../../../../components/configSchema'; +import MyForm from '../../../../components/form' +import { compData } from './json' +import styles from './index.module.less'; interface IJsonProps { value: any; name: string; title: string; - onlyInput?: boolean; + isConfig?: boolean; // true为为可视化、json联动输入框,false为普通json输入框 onValueChange: (value: string) => void; } const Json: React.FC = (props) => { - const { title, value, onValueChange } = props; + const { title, value, isConfig, onValueChange } = props; const [visible, setVisible] = useState(false); + const [schema, setSchema] = useState({}) // events const onClickEdit = (): void => { @@ -34,30 +36,35 @@ const Json: React.FC = (props) => { setVisible(false); onValueChange(newJson); }; + const changeSchema = (schema: object) => { + setVisible(false); + setSchema(schema); + } return ( -
-

{title}

- 编辑}> + {!isConfig && - + />} + + {/* @ts-ignore */} + {isConfig && } + -
+ ); }; @@ -65,14 +72,44 @@ interface IEditorModalProps { visible: boolean; title: string; value: string; - onlyInput?: boolean; + isConfig?: boolean; onOk: (val: string) => void; onCancel: () => void; + changeSchema: (val: object) => void } const EditModal: React.FC = (props) => { const { visible, title, value, onOk, onCancel } = props; const [json, setJson] = useState(''); + const formRef = useRef() + + const tabChange = (tab: string) => { + const JSON_TAB = 'JsonTab' + const VISUAL_TAB = 'VisualTab' + if (tab === JSON_TAB) form2code() // 可视化同步到编辑器 + if (tab === VISUAL_TAB) code2form() // 编辑器同步到可视化 + } + + const form2code = () => { + // @ts-ignore + const formSchema = formRef.current && formRef.current.getValue() + setJson(JSON.stringify(formSchema, null, 2)) + } + + const code2form = () => { + try { + const codeObj = JSON.parse(json) + // @ts-ignore + formRef.current.setValue(codeObj) + } catch (error) { + console.log('can\'t parse code string to form schema, the error is:', error.message); + } + } + + const onJsonChange = (ev: any, newJson: string | undefined = ''): void => { + setJson(newJson) + props.isConfig && code2form() + } // life useEffect(() => { @@ -88,23 +125,29 @@ const EditModal: React.FC = (props) => { // events const onClickOk = (): void => { try { - JSON.parse(json); - onOk(json); + if (props.isConfig) { + if (JSON.stringify(JSON.parse(json)) === '{}') { + // @ts-ignore + const value = formRef.current && formRef.current.getValue() + props.changeSchema(value) + setJson(value) + } else { + props.changeSchema(JSON.parse(json)) + } + } else { + JSON.parse(json); + onOk(json); + } } catch (error) { message.error('内容必须是合法json'); console.log('save failed, the error is:', error.message); } }; - const onChangeJson = (ev: any, newJson: string | undefined = ''): void => { - if (newJson !== json) { - setJson(newJson); - } - }; return ( = (props) => { onOk={onClickOk} onCancel={onCancel} > - {props.onlyInput ? + {props.isConfig ? + + +
+ +
+
+ +
+ +
+
+
: : - + onChange={onJsonChange} + /> }
); diff --git a/packages/core/src/mods/settingBar/components/json/json.ts b/packages/core/src/mods/settingBar/components/json/json.ts new file mode 100644 index 0000000..0687b9a --- /dev/null +++ b/packages/core/src/mods/settingBar/components/json/json.ts @@ -0,0 +1,145 @@ +const compData = [ + { + "text": '输入框', + "name": 'input', + "schema": { + "title": "输入框", + "type": "string" + } + }, + { + "text": '编辑框', + "name": 'textarea', + "schema": { + "title": "编辑框", + "type": "string", + "format": "textarea" + } + }, + { + "text": '开关控制', + "name": 'allBoolean', + "schema": { + "title": "开关控制", + "type": "boolean", + "ui:widget": "switch" + } + }, + { + "text": '下拉单选', + "name": 'select', + "schema": { + "title": "下拉单选", + "type": "string", + "enum": [ + "a", + "b", + "c" + ], + "enumNames": [ + "早", + "中", + "晚" + ] + } + }, + { + "text": '点击单选', + "name": 'select', + "schema": { + "title": "点击单选", + "type": "string", + "enum": [ + "a", + "b", + "c" + ], + "enumNames": [ + "早", + "中", + "晚" + ], + "ui:widget": "radio" + } + }, + { + "text": '下拉多选', + "name": 'multiSelect', + "schema": { + "title": "下拉多选", + "description": "可以选择多项", + "type": "array", + "items": { + "type": "string" + }, + "enum": [ + "A", + "B", + "C", + "D" + ], + "enumNames": [ + "1", + "2", + "3", + "4" + ], + "ui:widget": "multiSelect" + } + }, + { + "text": '点击多选', + "name": 'checkbox', + "schema": { + "title": "多选", + "description": "可以勾选多个", + "type": "array", + "items": { + "type": "string" + }, + "enum": [ + "A", + "B", + "C", + "D" + ], + "enumNames": [ + "1", + "2", + "3", + "4" + ] + } + }, + { + "text": '时间选择', + "name": 'timeSelect', + "schema": { + "title": "时间选择", + "type": "string", + "format": "time" + } + }, + { + "text": '日期范围', + "name": 'dateRangeSelect', + "schema": { + "title": "日期范围", + "type": "range", + "format": "date" + } + }, + { + "text": '日期选择', + "name": 'dateSelect', + "schema": { + "title": "日期选择", + "type": "string", + "format": "date" + } + } +] + +export { + compData +} diff --git a/packages/core/src/mods/settingBar/index.tsx b/packages/core/src/mods/settingBar/index.tsx index f12e25b..3228e0d 100644 --- a/packages/core/src/mods/settingBar/index.tsx +++ b/packages/core/src/mods/settingBar/index.tsx @@ -39,9 +39,9 @@ const SettingBar: React.FC = (props) => { - + {/* - + */} diff --git a/packages/core/src/mods/settingBar/mods/basic/index.module.less b/packages/core/src/mods/settingBar/mods/basic/index.module.less index 6dd7c2b..43fbbce 100644 --- a/packages/core/src/mods/settingBar/mods/basic/index.module.less +++ b/packages/core/src/mods/settingBar/mods/basic/index.module.less @@ -1,9 +1,15 @@ .container { - padding: 0 20px; - height: 100%; - overflow: scroll; + height: 800px; + overflow-y: auto; + &::-webkit-scrollbar { + display: none; + } + + .input{ + margin-top:20px; + } } .depsInfoModalContent { padding-top: 20px; -} \ No newline at end of file +} diff --git a/packages/core/src/mods/settingBar/mods/basic/index.tsx b/packages/core/src/mods/settingBar/mods/basic/index.tsx index 42612e3..6e8ec6f 100644 --- a/packages/core/src/mods/settingBar/mods/basic/index.tsx +++ b/packages/core/src/mods/settingBar/mods/basic/index.tsx @@ -5,7 +5,7 @@ import React, { import styles from './index.module.less'; -import { Modal } from 'antd'; +import { Modal, Card } from 'antd'; import { Cell, Graph } from '@antv/x6'; import JsonView from 'react-json-view'; import Json from '../../components/json'; @@ -92,35 +92,33 @@ const Basic: React.FC = (props) => { return (
- - {selectedCell.shape === 'imove-start' && ( - - )} - - + + + {selectedCell.shape === 'imove-start' && ( +
+ +
+ )} +
+
); };