diff --git a/packages/core/src/components/codeRun/index.module.less b/packages/core/src/components/codeRun/index.module.less index d0a0b05..c8af33f 100644 --- a/packages/core/src/components/codeRun/index.module.less +++ b/packages/core/src/components/codeRun/index.module.less @@ -39,10 +39,13 @@ height:50%; flex:1; border:1px solid #eee; - text-align: center; - color:#bfbfbf; - font-size:24px; - line-height: 300px; + + .placeholder{ + text-align: center; + color:#bfbfbf; + font-size:18px; + line-height: 300px; + } } } } diff --git a/packages/core/src/components/codeRun/index.tsx b/packages/core/src/components/codeRun/index.tsx index 5370fda..bbb388d 100644 --- a/packages/core/src/components/codeRun/index.tsx +++ b/packages/core/src/components/codeRun/index.tsx @@ -3,12 +3,10 @@ import JsonView from 'react-json-view'; import { Tabs, Form, Input, Button, Space } from 'antd'; const { TabPane } = Tabs; import CodeEditor from '../codeEditor'; +import Console from '../console'; import { inputJson, outputJson } from './json' import styles from './index.module.less'; import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'; -interface IProps { - onChange: (value: object) => void -} interface MyFormItemProps { type: string } @@ -51,8 +49,11 @@ const MyFormItem: React.FC = (props) => { ) } +interface VisualInputProps { + onChange: (value: object) => void +} -const VisualInput: React.FC = (props) => { +const VisualInput: React.FC = (props) => { const [form] = Form.useForm() const PAYLOAD = 'payload', PIPE = 'pipe', CONTEXT = 'context', CONFIG = 'config' const onChange = () => { @@ -70,8 +71,12 @@ const VisualInput: React.FC = (props) => { ) } +interface CodeRunProps { + onChange: (value: object) => void, + hasConsole: boolean +} -const CodeRun: React.FC = (props) => { +const CodeRun: React.FC = (props) => { const onFormChange = (value: any) => { props.onChange(value) } @@ -120,7 +125,10 @@ const CodeRun: React.FC = (props) => { />
- 我是console控制台 + {props.hasConsole ? + : +

目前没有任何console内容哦

+ }
diff --git a/packages/core/src/components/console/index.tsx b/packages/core/src/components/console/index.tsx new file mode 100644 index 0000000..10a0042 --- /dev/null +++ b/packages/core/src/components/console/index.tsx @@ -0,0 +1,67 @@ +import React, { useEffect } from 'react' +import Log from './log' +import logStore, { ConsoleType } from './store' + +const MyConsole: React.FC = () => { + const console: any = {} + + useEffect(() => { + executeConsole() + }, []) + + const processLog = (item: ConsoleType) => { + const { logType } = item + let { infos = [] } = item + if (!infos.length) return + infos = [].slice.call(infos || []) + logStore.addLog({ logType, infos }) + printOriginLog(item) + } + + const clearLog = () => { + logStore.clearLog() + } + + const printOriginLog = (item: ConsoleType) => { + const { logType, infos } = item + if (typeof console[logType] === 'function') { + console[logType].apply(window.console, infos) + } + } + + const executeConsole = () => { + if (!window.console) { + return + } + + // 模拟浏览器中的console方法 + const methodList = ['log', 'info', 'warn', 'debug', 'error'] + methodList.map(method => { + // @ts-ignore + console[method] = window.console[method] + }) + + methodList.map(method => { + // @ts-ignore + window.console[method] = (...args: any[]) => { + processLog({ + logType: method, + infos: args + }) + } + }) + + window.console.clear = (...args: any[]) => { + clearLog() + console.clear.apply(window.console, args) + } + } + + return ( +
+ +
+ ) +} + +export default MyConsole diff --git a/packages/core/src/components/console/log/index.tsx b/packages/core/src/components/console/log/index.tsx new file mode 100644 index 0000000..6d449f6 --- /dev/null +++ b/packages/core/src/components/console/log/index.tsx @@ -0,0 +1,59 @@ +import React from 'react' +import DataView from '../logView' +import { ConsoleType } from '../store' + +interface Props { + logList: ConsoleType[] +} + +const Log: React.FC = (props) => { + const renderLogList = (logList: ConsoleType[]) => { + return logList.map((log: ConsoleType, index: number) => { + const dataView = log.infos.map((info: any, i: number) => { + return typeof info !== 'object' || info === null ? +
{`${info}`}
: + + }) + let ele = null + + // 根据不同console类型展示不同的样式 + switch (log.logType) { + case 'warn': + ele =
+ {dataView} +
+ break + case 'log': + ele =
+ {dataView} +
+ break + case 'error': + ele =
+
{dataView}
+
+ break + } + return ele + }) + } + + return ( +
{renderLogList(props.logList)}
+ ) +} + +export default Log diff --git a/packages/core/src/components/console/logView/dataItem.tsx b/packages/core/src/components/console/logView/dataItem.tsx new file mode 100644 index 0000000..9184dfd --- /dev/null +++ b/packages/core/src/components/console/logView/dataItem.tsx @@ -0,0 +1,114 @@ +import React, { useState, useEffect } from 'react' +// import DataList from './dataList' +import Simple from './simple' +import styles from './index.module.less' + +const previewComplex = (data: any) => { + if (Array.isArray(data)) { + return Array[{data.length}] + } + switch (typeof data) { + case 'function': + return {data.name || 'fn'}() + case 'object': + case 'undefined': + case null: + return '{…}' + } + return null +} + +interface Props { + startOpen?: boolean + noSort?: boolean + name: string + value: any +} + +interface State { + open: boolean + loading?: boolean +} + +const DataItem: React.FC = (props) => { + const [state, setState] = useState({ open: !!props.startOpen, loading: false }) + let opener = null + let children = null + let { name } = props + let preview + + useEffect(() => { + if (state.open && props.value) { + setState({ loading: true, open: true }) + } + }, []) + + useEffect(() => { + const data = props.value + const otype = typeof data + let complex = true + + if ( + otype === 'number' || + otype === 'string' || + data == null || + otype === 'boolean' + ) { + preview = + complex = false + } else { + preview = previewComplex(data) + } + + const open = state.open + + if (complex && Object.keys(props.value).length) { + opener = ( +
+ {open ? + : + + } +
+ ) + } + + // if (complex && open) { + // children = + // } + + if (name.length > 50) { + name = name.slice(0, 50) + '…' + } + }, [props]) + + const toggleOpen = () => { + return () => { + const data = props.value + const isArray = Array.isArray(data) + + if (state.loading) return + if (!isArray && !Object.keys(props.value).length) return + if (isArray && data.length === 0) return + + setState({ + open: !state.open + }) + } + } + + return ( +
  • +
    + {opener} +
    + {name ? `${name}:` : ''} +
    +
    {preview}
    +
    + {children} +
  • + ) +} + +export default DataItem diff --git a/packages/core/src/components/console/logView/dataList.tsx b/packages/core/src/components/console/logView/dataList.tsx new file mode 100644 index 0000000..39236ee --- /dev/null +++ b/packages/core/src/components/console/logView/dataList.tsx @@ -0,0 +1,64 @@ +import React, { useState, useEffect } from 'react' +import DataItem from './dataItem' +import styles from './index.module.less' + +interface DataListProps { + data: any + startOpen?: boolean + noSort?: boolean +} + +const alphanumericSort = (a: string, b: string): number => { + if ('' + +a === a) { + if ('' + +b !== b) { + return -1 + } + return +a < +b ? -1 : 1 + } + return a < b ? -1 : 1 +} + +const DataList: React.FC = (props) => { + const [element, setElement] = useState([]) + const renderItem = (name: string, key: string) => { + const data = props.data + return ( + + ) + } + + useEffect(() => { + const { data } = props + if (!data) return + + const isArray = Array.isArray(data) + const ele: any[] = [] + if (isArray) { + data.forEach((item: any, i: number) => { + ele.push(renderItem(String(i), String(i))) + }) + } else { + const names = Object.keys(data) + if (!props.noSort) { + names.sort(alphanumericSort) + } + names.forEach((name, i) => { + ele.push(renderItem(name, name)) + }) + } + setElement(ele) + }) + + return ( + !element.length ? +
    {Array.isArray(props.data) ? 'Empty array' : 'Empty object'}
    : +
      {element}
    + ) +} + +export default DataList diff --git a/packages/core/src/components/console/logView/index.module.less b/packages/core/src/components/console/logView/index.module.less new file mode 100644 index 0000000..151b694 --- /dev/null +++ b/packages/core/src/components/console/logView/index.module.less @@ -0,0 +1,48 @@ +.codeContainer { + padding: 10px; + font-size: 12px; + list-style: none; + margin: 0; + padding: 0; +} + +.codeBox { + display: flex; + position: relative; +} + +.codeVal { + display: flex; + white-space: pre; + word-break: break-word; + margin-left: 10px; + flex: 1; + color: #183691; +} + +.codeKey { + margin-left: 5px; + color: #905; +} + +.opener { + cursor: pointer; + margin-left: -10px; + position: absolute; +} + +.openerOpen { + border-color: #bbb transparent transparent transparent; + border-style: solid; + border-width: 6px 4px 0 4px; + display: inline-block; + vertical-align: middle; +} + +.openerClose { + border-color: transparent transparent transparent #bbb; + border-style: solid; + border-width: 4px 0 4px 6px; + display: inline-block; + vertical-align: middle; +} diff --git a/packages/core/src/components/console/logView/index.tsx b/packages/core/src/components/console/logView/index.tsx new file mode 100644 index 0000000..f414a93 --- /dev/null +++ b/packages/core/src/components/console/logView/index.tsx @@ -0,0 +1,61 @@ +import React, { useState, useEffect } from 'react' +import DataList from './dataList' +import styles from './index.module.less' + +interface DataViewProps { + data: any + startOpen?: boolean +} + +interface State { + open: boolean +} + +const DataView: React.FC = (props) => { + const [state, setState] = useState({ open: !!props.startOpen }) + let children = null + let preview + + const toggleOpen = () => { + return () => { + setState({ + open: !state.open + }) + } + } + + useEffect(() => { + const { data } = props + const { open } = state + if (!data) { + return + } + const isArray = Array.isArray(data) + children = open ? : null + if (isArray) { + preview = '[...]' + } else { + preview = '{...}' + } + }, [props]) + + return ( +
      +
    • +
      +
      + {state.open ? ( + + ) : ( + + )} +
      +
      {preview}
      +
      + {children} +
    • +
    + ) +} + +export default DataView diff --git a/packages/core/src/components/console/logView/simple.tsx b/packages/core/src/components/console/logView/simple.tsx new file mode 100644 index 0000000..6384d13 --- /dev/null +++ b/packages/core/src/components/console/logView/simple.tsx @@ -0,0 +1,28 @@ +import React, { useState, useEffect } from 'react' + +interface Props { + data: any +} + +const Simple: React.FC = (props) => { + const [data, setData] = useState(props.data) + + const valueToText = (value: any) => { + if (value === undefined) { + return 'undefined' + } else if (typeof value === 'number') { + return value.toString() + } + return JSON.stringify(value) + } + + useEffect(() => { + if (typeof data === 'string' && data.length > 200) { + setData(data.slice(0, 200) + '…') + } + }, [props]) + + return
    {valueToText(data)}
    +} + +export default Simple diff --git a/packages/core/src/components/console/store/index.ts b/packages/core/src/components/console/store/index.ts new file mode 100644 index 0000000..6be5f1b --- /dev/null +++ b/packages/core/src/components/console/store/index.ts @@ -0,0 +1,35 @@ +export interface ConsoleType { + logType: string + infos: any[] +} + +export class ConsoleStore { + logList: ConsoleType[] = [] + logType: string = 'All' + + addLog(log: ConsoleType) { + this.logList.push(log) + } + + clearLog() { + this.logList = [] + } + + get computeLogList() { + let ret: ConsoleType[] = [] + if (this.logType === 'All') { + ret = this.logList + } else { + ret = this.logList.filter((item) => { + return item.logType === this.logType.toLowerCase() + }) + } + return ret + } + + changeLogType(type: string) { + this.logType = type + } +} + +export default new ConsoleStore() diff --git a/packages/core/src/mods/settingBar/components/code/index.tsx b/packages/core/src/mods/settingBar/components/code/index.tsx index 7528b83..ba225e2 100644 --- a/packages/core/src/mods/settingBar/components/code/index.tsx +++ b/packages/core/src/mods/settingBar/components/code/index.tsx @@ -158,7 +158,7 @@ const EditModal: React.FC = (props) => { onOk={onRunOk} onCancel={onRunCancel} > - + ); diff --git a/packages/core/src/mods/settingBar/mods/testCase/index.tsx b/packages/core/src/mods/settingBar/mods/testCase/index.tsx index d854d36..5cf3e11 100644 --- a/packages/core/src/mods/settingBar/mods/testCase/index.tsx +++ b/packages/core/src/mods/settingBar/mods/testCase/index.tsx @@ -62,7 +62,7 @@ const EditModal: React.FC = (props): JSX.Element => { onOk={onOk} onCancel={onCancel} > - + ); };