Browse Source

feat: optimize interactive experience of single node running

master
yangpei 5 years ago
parent
commit
654edbc009
  1. 4
      packages/core/package.json
  2. 45
      packages/core/src/components/codeRun/index.module.less
  3. 181
      packages/core/src/components/codeRun/index.tsx
  4. 535
      packages/core/src/components/codeRun/json.ts
  5. 61
      packages/core/src/components/configSchema/index.module.less
  6. 88
      packages/core/src/components/configSchema/index.tsx
  7. 520
      packages/core/src/components/configSchema/json.ts
  8. 3
      packages/core/src/mods/settingBar/components/code/index.tsx
  9. 5
      packages/core/src/mods/settingBar/components/json/index.tsx

4
packages/core/package.json

@ -42,13 +42,13 @@
"@monaco-editor/react": "^3.7.4", "@monaco-editor/react": "^3.7.4",
"antd": "^4.5.3", "antd": "^4.5.3",
"axios": "^0.21.0", "axios": "^0.21.0",
"form-render": "^0.9.5",
"fr-generator": "^1.0.0", "fr-generator": "^1.0.0",
"jszip": "^3.5.0", "jszip": "^3.5.0",
"lodash.merge": "^4.6.2", "lodash.merge": "^4.6.2",
"query-string": "^6.13.7", "query-string": "^6.13.7",
"react-color": "^2.18.1", "react-color": "^2.18.1",
"react-json-view": "^1.19.1", "react-json-view": "^1.19.1"
"xterm": "^4.9.0"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash.merge": "^4.6.6", "@types/lodash.merge": "^4.6.6",

45
packages/core/src/components/codeRun/index.module.less

@ -1,21 +1,23 @@
.tabPane{
margin:0 20px;
.form{ .container {
height:600px;
overflow-y: auto;
}
.jsonInput {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
height: 600px; height: 100%;
.left{ .left{
padding:10px; padding:10px;
flex:300px; flex:1;
border:1px solid #eee; border:1px solid #eee;
.editor{
width:100%;
height:600px;
}
.visualInput{
width:100%;
}
} }
.right{ .right{
@ -35,27 +37,12 @@
.rightBottom{ .rightBottom{
height:50%; height:50%;
padding:10px;
flex:1; flex:1;
border:1px solid #eee; border:1px solid #eee;
text-align: center;
color:#bfbfbf;
font-size:24px;
line-height: 300px;
} }
} }
} }
.configInput{
display: flex;
flex-direction: row;
justify-content: space-between;
height: 600px;
.left{
height:100%;
flex:1;
}
.right{
height:100%;
flex:1;
}
}
}

181
packages/core/src/components/codeRun/index.tsx

@ -1,127 +1,130 @@
import React, { useEffect, useRef } from 'react'; import React from 'react';
import Generator from 'fr-generator';
import JsonView from 'react-json-view'; import JsonView from 'react-json-view';
import { Terminal } from 'xterm'; import { Tabs, Form, Input, Button, Space } from 'antd';
import { Tabs } from 'antd';
const { TabPane } = Tabs; const { TabPane } = Tabs;
import CodeEditor from '../codeEditor'; import CodeEditor from '../codeEditor';
import { defaultJson, formatJson, defaultConfig, formatConfig, compData } from './json' import { inputJson, outputJson } from './json'
import styles from './index.module.less'; import styles from './index.module.less';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
interface IProps { interface IProps {
onChange: (value: object) => void onChange: (value: object) => void
} }
interface FormValue { interface MyFormItemProps {
children: object[], type: string
parent: string,
schema: object
} }
// 可视化操作面板 const MyFormItem: React.FC<MyFormItemProps> = (props) => {
const VisualTab: React.FC<IProps> = (props) => {
const onChange = (value: FormValue) => {
props.onChange(value.schema)
}
return ( return (
<div className={styles.form}> <>
<Generator <h3>{props.type}</h3>
settings={[{ <Form.List name={props.type}>
title: '表单组件库', {(fields, { add, remove }) => (
widgets: compData, <>
}]} {fields.map(field => (
onChange={onChange} <Space key={field.key} align="baseline">
/> <Form.Item
</div> {...field}
label="key"
name={[field.name, 'key']}
fieldKey={[field.fieldKey, 'key']}
>
<Input />
</Form.Item>
<Form.Item
{...field}
label="value"
name={[field.name, 'value']}
fieldKey={[field.fieldKey, 'value']}
>
<Input />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}></Button>
</Form.Item>
</>
)}
</Form.List>
</>
) )
} }
// 输入测试用例面板,包括pipe、config、context、payload
const JsonTab: React.FC<IProps> = () => {
const termRef = useRef(document.createElement('div'));
useEffect(() => { const VisualInput: React.FC<IProps> = (props) => {
const term = new Terminal(); const [form] = Form.useForm()
term.open(termRef.current as HTMLDivElement); const PAYLOAD = 'payload', PIPE = 'pipe', CONTEXT = 'context', CONFIG = 'config'
term.write('I\'m \x1B[1;3;31mterminal\x1B[0m $ '); const onChange = () => {
}, []) props.onChange(form.getFieldsValue())
}
return ( return (
<div className={styles.jsonInput}> <div className={styles.visualInput}>
<div className={styles.left}> <Form form={form} name="form" autoComplete="off" onValuesChange={onChange}>
<p></p> <MyFormItem type={PAYLOAD} />
<CodeEditor <MyFormItem type={PIPE} />
width={'100%'} <MyFormItem type={CONTEXT} />
value={defaultJson} <MyFormItem type={CONFIG} />
/> </Form>
</div>
<div className={styles.right}>
<div className={styles.rightTop}>
<p></p>
<JsonView
name={null}
collapsed={false}
enableClipboard={false}
displayDataTypes={false}
displayObjectSize={false}
src={formatJson}
/>
</div>
<div className={styles.rightBottom} ref={termRef}></div>
</div>
</div> </div>
); )
} }
// 输入投放配置config的操作面板,如”投放配置schema“ const CodeRun: React.FC<IProps> = (props) => {
const ConfigTab: React.FC<IProps> = (props) => { const onFormChange = (value: any) => {
props.onChange(value)
}
const onJsonChange = (ev: any, newCode: any): void => {
const codeStr = newCode.slice(15)
const formatCodeStr = codeStr.replace(/ |\/\/.*/g, '').replace(/\s/g, '').replace(/(\w+):/g, '"$1":').replace(/'/g, '"')
try {
props.onChange(JSON.parse(formatCodeStr))
} catch (err) {
props.onChange({})
}
};
return ( return (
<div className={styles.configInput}> <div className={styles.container}>
<div className={styles.left}> <div className={styles.left}>
<p></p> <Tabs
<CodeEditor type="card"
width={'100%'} tabBarGutter={0}
value={defaultConfig} defaultActiveKey={'basic'}
onChange={props.onChange} tabBarStyle={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center' }}
/> >
<TabPane className={styles.tabPane} tab={'可视化'} key={'visualTab'}>
<VisualInput onChange={onFormChange} />
</TabPane>
<TabPane className={styles.tabPane} tab={'JSON输入'} key={'jsonTab'}>
<CodeEditor
value={inputJson}
className={styles.editor}
onChange={onJsonChange}
/>
</TabPane>
</Tabs>
</div> </div>
<div className={styles.right}> <div className={styles.right}>
<div className={styles.rightTop}> <div className={styles.rightTop}>
<p></p> <p></p>
<JsonView <JsonView
name={null} name={null}
collapsed={false} collapsed={false}
enableClipboard={false} enableClipboard={false}
displayDataTypes={false} displayDataTypes={false}
displayObjectSize={false} displayObjectSize={false}
src={formatConfig} src={outputJson}
/> />
</div> </div>
<div className={styles.rightBottom}>
console控制台
</div>
</div> </div>
</div> </div>
);
}
interface ICodeRunProps {
isConfig?: boolean,
onChange: (value: object) => void
}
const CodeRun: React.FC<ICodeRunProps> = (props) => {
return (
<Tabs
type="card"
tabBarGutter={0}
defaultActiveKey={'basic'}
tabBarStyle={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center' }}
>
<TabPane className={styles.tabPane} tab={'可视化'} key={'VisualTab'}>
<VisualTab onChange={props.onChange} />
</TabPane>
<TabPane className={styles.tabPane} tab={'JSON'} key={'JsonTab'}>
{props.isConfig ? <ConfigTab onChange={props.onChange} /> : <JsonTab onChange={props.onChange} />}
</TabPane>
</Tabs>
) )
} }

535
packages/core/src/components/codeRun/json.ts

@ -1,4 +1,4 @@
const defaultJson = `const inputData = { const inputJson = `export default {
// 上游数据 // 上游数据
pipe: { pipe: {
success: false, success: false,
@ -20,543 +20,20 @@ const defaultJson = `const inputData = {
} }
}`; }`;
const formatJson = { const outputJson = {
pipe: { pipe: {
success: false, success: false,
message: '未登录' message: '未登录'
}, },
context: { context: {
data: { data: {
isLogin: false isLogin: false,
name: 'xxx'
} }
},
payload: {
name: 'xxx'
},
config: {
hasLog: true
} }
} }
const defaultConfig = `{
}`;
const formatConfig = {
}
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 { export {
defaultJson, inputJson,
formatJson, outputJson
defaultConfig,
formatConfig,
compData
} }

61
packages/core/src/components/configSchema/index.module.less

@ -0,0 +1,61 @@
.tabPane{
margin:0 20px;
.form{
height:600px;
overflow-y: auto;
}
.jsonInput {
display: flex;
flex-direction: row;
justify-content: space-between;
height: 600px;
.left{
padding:10px;
flex:300px;
border:1px solid #eee;
}
.right{
height:100%;
flex:1;
display: flex;
flex-direction: column;
justify-content: space-between;
.rightTop{
height:50%;
padding:10px;
flex:1;
border:1px solid #eee;
overflow-y: auto;
}
.rightBottom{
height:50%;
padding:10px;
flex:1;
border:1px solid #eee;
}
}
}
.configInput{
display: flex;
flex-direction: row;
justify-content: space-between;
height: 600px;
.left{
height:100%;
flex:1;
}
.right{
height:100%;
flex:1;
}
}
}

88
packages/core/src/components/configSchema/index.tsx

@ -0,0 +1,88 @@
import React from 'react';
import Generator from 'fr-generator';
import JsonView from 'react-json-view';
import { Tabs } from 'antd';
const { TabPane } = Tabs;
import CodeEditor from '../codeEditor';
import { defaultConfig, formatConfig, compData } from './json'
import styles from './index.module.less';
interface IProps {
onChange: (value: object) => void
}
interface FormValue {
children: object[],
parent: string,
schema: object
}
const VisualTab: React.FC<IProps> = (props) => {
const onChange = (value: FormValue) => {
props.onChange(value.schema)
}
return (
<div className={styles.form}>
<Generator
settings={[{
title: '表单组件库',
widgets: compData,
}]}
onChange={onChange}
/>
</div>
)
}
const ConfigTab: React.FC<IProps> = (props) => {
return (
<div className={styles.configInput}>
<div className={styles.left}>
<p></p>
<CodeEditor
width={'100%'}
value={defaultConfig}
onChange={props.onChange}
/>
</div>
<div className={styles.right}>
<div className={styles.rightTop}>
<p></p>
<JsonView
name={null}
collapsed={false}
enableClipboard={false}
displayDataTypes={false}
displayObjectSize={false}
src={formatConfig}
/>
</div>
</div>
</div>
);
}
interface ICodeRunProps {
onChange: (value: object) => void
}
const ConfigSchema: React.FC<ICodeRunProps> = (props) => {
return (
<Tabs
type="card"
tabBarGutter={0}
defaultActiveKey={'basic'}
tabBarStyle={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center' }}
>
<TabPane className={styles.tabPane} tab={'可视化'} key={'VisualTab'}>
<VisualTab onChange={props.onChange} />
</TabPane>
<TabPane className={styles.tabPane} tab={'JSON'} key={'JsonTab'}>
<ConfigTab onChange={props.onChange} />
</TabPane>
</Tabs>
)
}
export default ConfigSchema;

520
packages/core/src/components/configSchema/json.ts

@ -0,0 +1,520 @@
const defaultConfig = `{
}`;
const formatConfig = {
}
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 {
defaultConfig,
formatConfig,
compData
}

3
packages/core/src/mods/settingBar/components/code/index.tsx

@ -95,7 +95,7 @@ const EditModal: React.FC<IEditorModalProps> = (props) => {
} }
}, [visible]); }, [visible]);
useEffect(() => { useEffect(() => {
if(editorInst) { if (editorInst) {
// NOTE: how to add command(https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html#addcommand) // NOTE: how to add command(https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandalonecodeeditor.html#addcommand)
editorInst.addCommand(KeyMod.CtrlCmd | KeyCode.KEY_S, () => { editorInst.addCommand(KeyMod.CtrlCmd | KeyCode.KEY_S, () => {
onSave(editorInst.getValue()); onSave(editorInst.getValue());
@ -126,6 +126,7 @@ const EditModal: React.FC<IEditorModalProps> = (props) => {
}; };
const onChange = (value: any) => { const onChange = (value: any) => {
// 运行节点代码时传入的json,包括payload、pipe、context、config
// console.log({ value }) // console.log({ value })
} }

5
packages/core/src/mods/settingBar/components/json/index.tsx

@ -9,7 +9,7 @@ import JsonView from 'react-json-view';
import { Button, Modal, message } from 'antd'; import { Button, Modal, message } from 'antd';
import { safeParse } from '../../../../utils'; import { safeParse } from '../../../../utils';
import CodeEditor from '../../../../components/codeEditor'; import CodeEditor from '../../../../components/codeEditor';
import CodeRun from '../../../../components/codeRun'; import ConfigSchema from '../../../../components/configSchema';
interface IJsonProps { interface IJsonProps {
value: any; value: any;
@ -96,7 +96,6 @@ const EditModal: React.FC<IEditorModalProps> = (props) => {
} }
}; };
const onChangeJson = (ev: any, newJson: string | undefined = ''): void => { const onChangeJson = (ev: any, newJson: string | undefined = ''): void => {
// TODO 投放配置schema转化、普通json识别
if (newJson !== json) { if (newJson !== json) {
setJson(newJson); setJson(newJson);
} }
@ -121,7 +120,7 @@ const EditModal: React.FC<IEditorModalProps> = (props) => {
language={'json'} language={'json'}
onChange={onChangeJson} onChange={onChangeJson}
/> : /> :
<CodeRun isConfig={true} onChange={onChangeJson} /> <ConfigSchema onChange={onChangeJson} />
} }
</Modal> </Modal>
); );

Loading…
Cancel
Save