From 4dd2eefc90ae65b0d1f039e639966bd86782b11a Mon Sep 17 00:00:00 2001 From: "muyun.my" Date: Tue, 22 Sep 2020 11:10:17 +0800 Subject: [PATCH] fix --- packages/demo/src/editor/config.js | 2 +- packages/plugin-components-pane/package.json | 4 +- packages/plugin-datasource-pane/DEV.md | 5 + packages/plugin-datasource-pane/README.md | 56 +++++- packages/plugin-datasource-pane/TODO.md | 7 +- packages/plugin-datasource-pane/package.json | 10 +- .../src/datasource-form.tsx | 96 +++++----- .../src/form-components/jsfunction.tsx | 44 ++--- .../src/form-components/param-value.tsx | 66 ++++--- .../src/import-plugins/code.tsx | 42 ++--- packages/plugin-datasource-pane/src/index.tsx | 26 ++- packages/plugin-datasource-pane/src/list.tsx | 135 ++++++++------ .../src/locale/index.ts | 8 +- packages/plugin-datasource-pane/src/pane.tsx | 176 ++++++++---------- .../src/types/datasource-type.ts | 4 +- .../src/types/import-plugin.ts | 4 +- 16 files changed, 367 insertions(+), 318 deletions(-) create mode 100644 packages/plugin-datasource-pane/DEV.md diff --git a/packages/demo/src/editor/config.js b/packages/demo/src/editor/config.js index 5965260f8..c929c11fe 100644 --- a/packages/demo/src/editor/config.js +++ b/packages/demo/src/editor/config.js @@ -139,7 +139,7 @@ export default { type: 'PanelIcon', props: { align: 'top', - icon: 'wenjian', + icon: 'shujuyuan', description: '数据源面板', panelProps: { floatable: true, diff --git a/packages/plugin-components-pane/package.json b/packages/plugin-components-pane/package.json index fd27716b6..6da23ef30 100644 --- a/packages/plugin-components-pane/package.json +++ b/packages/plugin-components-pane/package.json @@ -1,7 +1,7 @@ { "name": "@ali/lowcode-plugin-components-pane", - "version": "1.0.7-0", - "description": "alibaba lowcode editor component-list plugin", + "version": "0.1.0-beta.0", + "description": "低代码引擎数据源配置面板", "files": [ "es/", "lib/" diff --git a/packages/plugin-datasource-pane/DEV.md b/packages/plugin-datasource-pane/DEV.md new file mode 100644 index 000000000..7d5e947b5 --- /dev/null +++ b/packages/plugin-datasource-pane/DEV.md @@ -0,0 +1,5 @@ +## 插件开发 + +[https://yuque.antfin-inc.com/ali-lowcode/docs/ip4awq](插件开发文档)。 + +本地开发需要在 v14.4.0 的 node 环境下进行。 diff --git a/packages/plugin-datasource-pane/README.md b/packages/plugin-datasource-pane/README.md index 4e0213a43..c8233772b 100644 --- a/packages/plugin-datasource-pane/README.md +++ b/packages/plugin-datasource-pane/README.md @@ -2,9 +2,49 @@ 对页面的数据源进行管理(新建,编辑,导入)。 +一个 pluginProps 的例子 + +``` +{ + importPlugins: [ + { + name: 'code', + title: '源码', + content: DataSourceImportPluginCode, + }, + ], + dataSourceTypes: [ + { + type: 'mopen', + schema: { + type: 'object', + properties: { + options: { + type: 'object', + properties: { + uri: { + title: 'api', + }, + v: { + title: 'v', + type: 'string', + }, + appKey: { + title: 'appKey', + type: 'string', + }, + }, + }, + }, + }, + }, + ], +} +``` + ## 数据源类型定义 -内置 fetch 和 mtop 类型,支持传入自定义类型。 +内置 fetch,mtop,jsonp 类型,支持传入自定义类型。 ``` type DataSourceType = { @@ -29,17 +69,15 @@ interface DataSourcePaneImportPlugin { componentProps?: DataSourcePaneImportPluginCustomProps; } -interface DataSourcePaneImportPluginCustomProps { - [customPropName: string]: any; +interface DataSourcePaneImportPluginComponentProps { + onImport?: (dataSourceList: DataSourceConfig[]) => void; + onCancel?: () => void; + dataSourceTypes?: DataSourceType[]; } -interface DataSourcePaneImportPluginComponentProps extends DataSourcePaneImportPluginCustomProps { - onChange: (dataSourceList: DataSourceConfig[]) => void; +interface DataSourcePaneImportPluginCustomProps extends DataSourcePaneImportPluginComponentProps { + [customPropName: string]: any; } ``` -## 插件开发 -[https://yuque.antfin-inc.com/ali-lowcode/docs/ip4awq](插件开发文档)。 - -本地开发需要在 v14.4.0 的 node 环境下进行。 diff --git a/packages/plugin-datasource-pane/TODO.md b/packages/plugin-datasource-pane/TODO.md index 3fbe5ebc5..e5fd18a65 100644 --- a/packages/plugin-datasource-pane/TODO.md +++ b/packages/plugin-datasource-pane/TODO.md @@ -2,14 +2,15 @@ TODO --- * 多语言 -* ICON -* 支持变量 * 定制样式 * 不使用 bind * 表达式 setter 的联想 * [later]表达式和其他类型的切换 + +## 提案 + +* mock * 变量,上下文的提案 -* mock 的提案 ## 问题 diff --git a/packages/plugin-datasource-pane/package.json b/packages/plugin-datasource-pane/package.json index 467a74399..7b27c81d9 100644 --- a/packages/plugin-datasource-pane/package.json +++ b/packages/plugin-datasource-pane/package.json @@ -1,13 +1,14 @@ { "name": "@ali/lowcode-plugin-datasource-pane", - "version": "1.0.7-0", + "version": "0.1.0-beta.3", "description": "低代码引擎数据源面板", "main": "lib/index.js", "files": [ "lib" ], "scripts": { - "build": "tsc", + "build": "build-scripts build", + "cloud-build": "build-scripts build --skip-demo", "test": "ava", "test:snapshot": "ava --update-snapshots" }, @@ -29,6 +30,7 @@ "monaco-editor": "^0.20.0" }, "dependencies": { + "@alib/build-scripts": "^0.1.3", "@ali/lowcode-editor-setters": "^1.0.7-0", "@alifd/next": "^1.20.28", "@formily/next": "^1.3.2", @@ -40,5 +42,9 @@ "react-monaco-editor": "^0.40.0", "styled-components": "^5.2.0", "traverse": "^0.6.6" + }, + "homepage": "https://unpkg.alibaba-inc.com/@ali/lowcode-plugin-datasource-pane@0.1.0-beta.1/build/index.html", + "publishConfig": { + "registry": "https://registry.npm.alibaba-inc.com" } } diff --git a/packages/plugin-datasource-pane/src/datasource-form.tsx b/packages/plugin-datasource-pane/src/datasource-form.tsx index b4c2170c3..ecc89632d 100644 --- a/packages/plugin-datasource-pane/src/datasource-form.tsx +++ b/packages/plugin-datasource-pane/src/datasource-form.tsx @@ -1,20 +1,17 @@ // @todo schema default -import React, { PureComponent, ReactElement, FC } from 'react'; +import React, { PureComponent } from 'react'; import { Button } from '@alifd/next'; import { SchemaForm, FormButtonGroup, Submit } from '@formily/next'; import { ArrayTable, Input, Switch, NumberPicker } from '@formily/next-components'; import _isPlainObject from 'lodash/isPlainObject'; import _isArray from 'lodash/isArray'; -import _isNumber from 'lodash/isNumber'; -import _isString from 'lodash/isString'; -import _isBoolean from 'lodash/isBoolean'; import _cloneDeep from 'lodash/cloneDeep'; import _mergeWith from 'lodash/mergeWith'; import _get from 'lodash/get'; -import _tap from 'lodash/tap'; import traverse from 'traverse'; +import { DataSourceConfig } from '@ali/lowcode-types'; import { ParamValue, JSFunction } from './form-components'; -import { DataSourceType, DataSourceConfig } from './types'; +import { DataSourceType } from './types'; // @todo $ref @@ -89,11 +86,11 @@ const SCHEMA = { export interface DataSourceFormProps { dataSourceType: DataSourceType; dataSource?: DataSourceConfig; - omComplete?: (dataSource: DataSourceConfig) => void; + onComplete?: (dataSource: DataSourceConfig) => void; + onCancel?: () => void; } -export interface DataSourceFormState { -} +export type DataSourceFormState = {}; /** * 通过是否存在 ID 来决定读写状态 @@ -101,65 +98,63 @@ export interface DataSourceFormState { export class DataSourceForm extends PureComponent { state = {}; - handleFormSubmit = (formData) => { + handleFormSubmit = (formData: any) => { // @todo mutable? if (_isArray(_get(formData, 'options.params'))) { - formData.options.params = formData.options.params.reduce((acc, cur) => { - if (!cur.name) return; + formData.options.params = formData.options.params.reduce((acc: any, cur: any) => { + if (!cur.name) return acc; acc[cur.name] = cur.value; return acc; }, {}); } if (_isArray(_get(formData, 'options.headers'))) { - formData.options.headers = formData.options.headers.reduce((acc, cur) => { - if (!cur.name) return; + formData.options.headers = formData.options.headers.reduce((acc: any, cur: any) => { + if (!cur.name) return acc; acc[cur.name] = cur.value; return acc; }, {}); } - console.log('submit', formData); - this.props?.onComplete(formData); + // console.log('submit', formData); + this.props.onComplete?.(formData); }; - deriveInitialData = (dataSource = {}) => { + handleCancel = () => { + this.props.onCancel?.(); + }; + + deriveInitialData = (dataSource: object = {}) => { const { dataSourceType } = this.props; - const result = _cloneDeep(dataSource); + const result: any = _cloneDeep(dataSource); if (_isPlainObject(_get(result, 'options.params'))) { - result.options.params = Object.keys(result.options.params).reduce( - (acc, cur) => { - acc.push({ - name: cur, - value: result.options.params[cur] - }); - return acc; - }, - [] - ); + result.options.params = Object.keys(result.options.params).reduce((acc: any, cur: any) => { + acc.push({ + name: cur, + value: result.options.params[cur], + }); + return acc; + }, []); } if (_isPlainObject(_get(result, 'options.headers'))) { - result.options.headers = Object.keys(result.options.headers).reduce( - (acc, cur) => { - acc.push({ - name: cur, - value: result.options.headers[cur] - }); - return acc; - }, - [] - ); + result.options.headers = Object.keys(result.options.headers).reduce((acc: any, cur: any) => { + acc.push({ + name: cur, + value: result.options.headers[cur], + }); + return acc; + }, []); } result.type = dataSourceType.type; return result; - } + }; deriveSchema = () => { const { dataSourceType } = this.props; // @todo 减小覆盖的风险 - const formSchema = _mergeWith({}, SCHEMA, dataSourceType.schema, (objValue, srcValue) => { + const formSchema: any = _mergeWith({}, SCHEMA, dataSourceType.schema, (objValue, srcValue) => { if (_isArray(objValue)) { return srcValue; } @@ -185,16 +180,11 @@ export class DataSourceForm extends PureComponent diff --git a/packages/plugin-datasource-pane/src/form-components/jsfunction.tsx b/packages/plugin-datasource-pane/src/form-components/jsfunction.tsx index 03dbb5cfe..531d8341b 100644 --- a/packages/plugin-datasource-pane/src/form-components/jsfunction.tsx +++ b/packages/plugin-datasource-pane/src/form-components/jsfunction.tsx @@ -1,60 +1,46 @@ -import React, { PureComponent, createRef } from 'react'; -import { Button, Input, Radio, NumberPicker, Switch } from '@alifd/next'; +import React, { PureComponent } from 'react'; import { connect } from '@formily/react-schema-renderer'; -import _isPlainObject from 'lodash/isPlainObject'; -import _isArray from 'lodash/isArray'; -import _isNumber from 'lodash/isNumber'; -import _isString from 'lodash/isString'; -import _isBoolean from 'lodash/isBoolean'; -import _get from 'lodash/get'; -import _tap from 'lodash/tap'; import MonacoEditor, { EditorWillMount } from 'react-monaco-editor'; - -const { Group: RadioGroup } = Radio; +import _noop from 'lodash/noop'; +import { editor } from 'monaco-editor'; export interface JSFunctionProps { className: string; value: any; - onChange?: () => void; + onChange?: (val: any) => void; } -export interface JSFunctionState { -} +export type JSFunctionState = {}; class JSFunctionComp extends PureComponent { static isFieldComponent = true; - private monacoRef = createRef(); + static defaultProps = { + onChange: _noop, + }; - constructor(props) { - super(props); - this.handleEditorChange = this.handleEditorChange.bind(this); - } + private monacoRef: any = null; handleEditorChange = () => { - if (this.monacoRef.current) { - if ( - !(this.monacoRef.current as editor.IStandaloneCodeEditor) - .getModelMarkers() - .find((marker: editor.IMarker) => marker.owner === 'json') - ) { - this.props?.onChange(this.monacoRef.current?.getModels()?.[0]?.getValue()); + if (this.monacoRef) { + if (!(this.monacoRef as any).getModelMarkers().find((marker: editor.IMarker) => marker.owner === 'json')) { + this.props.onChange?.((this.monacoRef as any)?.getModels()?.[0]?.getValue()); } } }; handleEditorWillMount: EditorWillMount = (editor) => { - (this.monacoRef as MutableRefObject).current = editor?.editor; + this.monacoRef = editor?.editor; }; render() { - const { value, onChange } = this.props; + const { value } = this.props; return ( void; + onChange?: (value: any) => void; types: ParamValueType[]; } export interface ParamValueState { - type: 'string' | 'number' | 'boolean' | ''; + type: ParamValueType; } const TYPE_LABEL_MAP = { @@ -41,16 +41,17 @@ class ParamValueComp extends PureComponent { types: ['string', 'boolean', 'number', 'expression'], }; - state = { - type: '', + state: ParamValueState = { + type: 'string', }; - constructor(props) { + constructor(props: ParamValueProps) { super(props); this.state.type = this.getTypeFromValue(this.props.value); } - getTypeFromValue = (value) => { + // @todo + getTypeFromValue = (value: any) => { if (_isBoolean(value)) { return 'boolean'; } else if (_isNumber(value)) { @@ -62,36 +63,38 @@ class ParamValueComp extends PureComponent { }; // @todo 需要再 bind 一次? - handleChange = (value) => { - this.props?.onChange(value); + handleChange = (value: any) => { + this.props?.onChange?.(value); }; - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: ParamValueProps) { if (this.props.value !== prevProps.value) { this.setState({ - value: this.props.value, type: this.getTypeFromValue(this.props.value), }); } } - handleTypeChange = (type) => { - this.setState(({ value }) => { - let nextValue = value || ''; - if (type === 'string') { - nextValue = nextValue.toString(); - } else if (type === 'number') { - nextValue = nextValue * 1; - } else if (type === 'boolean') { - nextValue = nextValue === 'true' || nextValue; - } else if (type === 'expression') { - nextValue = ''; - } - return { - value: nextValue, - type, - }; - }); + handleTypeChange = (type: string) => { + this.setState( + { + type: type as ParamValueType, + }, + () => { + let nextValue = this.props.value || ''; + const { type } = this.state; + if (type === 'string') { + nextValue = nextValue.toString(); + } else if (type === 'number') { + nextValue = nextValue * 1; + } else if (type === 'boolean') { + nextValue = nextValue === 'true' || nextValue; + } else if (type === 'expression') { + nextValue = ''; + } + this.props.onChange?.(nextValue); + }, + ); }; renderTypeSelect = () => { @@ -107,6 +110,7 @@ class ParamValueComp extends PureComponent { value: item, }))} value={type} + onChange={this.handleTypeChange} /> ); } @@ -134,10 +138,10 @@ class ParamValueComp extends PureComponent { return (
{this.renderTypeSelect()} - {type === 'string' && } - {type === 'boolean' && } - {type === 'number' && } - {type === 'expression' && } + {type === 'string' && } + {type === 'boolean' && } + {type === 'number' && } + {type === 'expression' && }
); } diff --git a/packages/plugin-datasource-pane/src/import-plugins/code.tsx b/packages/plugin-datasource-pane/src/import-plugins/code.tsx index 4dacccdd6..e3141dccb 100644 --- a/packages/plugin-datasource-pane/src/import-plugins/code.tsx +++ b/packages/plugin-datasource-pane/src/import-plugins/code.tsx @@ -1,8 +1,10 @@ +/* eslint-disable @typescript-eslint/indent */ +// @todo 缩进问题 /** * 源码导入插件 * @todo editor 关联 types,并提供详细的出错信息 */ -import React, { PureComponent, createRef, MutableRefObject } from 'react'; +import React, { PureComponent } from 'react'; import { Button } from '@alifd/next'; import _noop from 'lodash/noop'; import _isArray from 'lodash/isArray'; @@ -35,7 +37,7 @@ export class DataSourceImportPluginCode extends PureComponent< type: 'http', id: 'test', }, - ] + ], }; state = { @@ -43,7 +45,7 @@ export class DataSourceImportPluginCode extends PureComponent< isCodeValid: true, }; - private monacoRef = createRef(); + private monacoRef: any; constructor(props: DataSourceImportPluginCodeProps) { super(props); @@ -77,14 +79,12 @@ export class DataSourceImportPluginCode extends PureComponent< }; handleComplete = () => { - if (this.monacoRef.current) { - if ( - !(this.monacoRef.current as editor.IStandaloneCodeEditor) - .getModelMarkers() - .find((marker: editor.IMarker) => marker.owner === 'json') - ) { + if (this.monacoRef) { + if (!this.monacoRef.getModelMarkers().find((marker: editor.IMarker) => marker.owner === 'json')) { this.setState({ isCodeValid: true }); - this.props?.onImport(this.deriveValue(JSON.parse(_last(this.monacoRef.current.getModels()).getValue()))); + const model: any = _last(this.monacoRef.getModels()); + if (!model) return; + this.props.onImport?.(this.deriveValue(JSON.parse(model.getValue()))); return; } } @@ -92,30 +92,28 @@ export class DataSourceImportPluginCode extends PureComponent< }; handleEditorChange = () => { - if (this.monacoRef.current) { - if ( - !(this.monacoRef.current as editor.IStandaloneCodeEditor) - .getModelMarkers() - .find((marker: editor.IMarker) => marker.owner === 'json') - ) { + if (this.monacoRef) { + if (!this.monacoRef.getModelMarkers().find((marker: editor.IMarker) => marker.owner === 'json')) { this.setState({ isCodeValid: true }); } } }; handleEditorWillMount: EditorWillMount = (editor) => { - (this.monacoRef as MutableRefObject).current = editor?.editor; + this.monacoRef = editor?.editor; // @todo 格式化一次 }; - handleCodeChagne = (code) => { + handleCodeChagne = (code: string) => { this.setState({ code }); - } + }; render() { const { onCancel = _noop } = this.props; const { code, isCodeValid } = this.state; + // @todo + // formatOnType formatOnPaste return (
{!isCodeValid &&

格式有误

}

- +

); diff --git a/packages/plugin-datasource-pane/src/index.tsx b/packages/plugin-datasource-pane/src/index.tsx index 2f0a3650e..435e0fad8 100644 --- a/packages/plugin-datasource-pane/src/index.tsx +++ b/packages/plugin-datasource-pane/src/index.tsx @@ -19,9 +19,9 @@ export interface DataSourcePaneState { active: boolean; } -const BUILTIN_DATASOURCE_TYPES = [ +const BUILTIN_DATASOURCE_TYPES: DataSourceType[] = [ { - type: 'http', + type: 'fetch', schema: { type: 'object', properties: { @@ -56,9 +56,25 @@ const BUILTIN_DATASOURCE_TYPES = [ }, }, }, + { + type: 'jsonp', + schema: { + type: 'object', + properties: { + options: { + type: 'object', + properties: { + method: { + enum: ['GET'], + }, + }, + }, + }, + }, + }, ]; -const BUILTIN_IMPORT_PLUGINS = [ +const BUILTIN_IMPORT_PLUGINS: DataSourcePaneImportPlugin[] = [ { name: 'default', title: '源码', @@ -98,7 +114,7 @@ export default class DataSourcePanePlugin extends PureComponent { const { filteredType, keyword } = this.state; - const { dataSource } = this.props; + const { dataSource, dataSourceTypes } = this.props; return ( dataSource @@ -69,63 +76,61 @@ export default class DataSourceList extends PureComponent {item.id} - 详情} - align="b" - alignEdge - triggerType="hover" - style={{ width: 300 }} - > - ((acc, cur) => { - // @todo 这里的 ts 处理得不好 - if (_isPlainObject(item.options[cur])) { - Object.keys(item?.options?.[cur] || {}).forEach((curInOption) => { - acc.push({ - label: `${cur}.${curInOption}`, - value: (item?.options?.[cur] as any)?.[curInOption], - }); - }); - } else if (!_isNil(item.options[cur])) { - // @todo 排除 null - acc.push({ - label: cur, - value: item.options[cur], - }); - } - return acc; - }, []), - console.log, - )} + {!!dataSourceTypes.find((ds) => ds.type === item.type) && ( + 详情} + align="b" + alignEdge + triggerType="hover" + style={{ width: 300 }} > - - ( -
- - {_isBoolean(val) - ? 'bool' - : _isNumber(val) - ? 'number' - : _isPlainObject(val) - ? 'obj' - : 'string'} - - {val.toString()} -
+
((acc, cur) => { + // @todo 这里的 ts 处理得不好 + if (_isPlainObject(item.options[cur])) { + Object.keys(item?.options?.[cur] || {}).forEach((curInOption) => { + acc.push({ + label: `${cur}.${curInOption}`, + value: (item?.options?.[cur] as any)?.[curInOption], + }); + }); + } else if (!_isNil(item.options[cur])) { + // @todo 排除 null + acc.push({ + label: cur, + value: item.options[cur], + }); + } + return acc; + }, []), + console.log, )} - /> -
-
- - + > + + ( +
+ {deriveTypeFromValue(val)} + {val.toString()} +
+ )} + /> + + + )} + {!!dataSourceTypes.find((ds) => ds.type === item.type) && ( + + )} + {!!dataSourceTypes.find((ds) => ds.type === item.type) && ( + + )} @@ -142,6 +147,7 @@ export default class DataSourceList extends PureComponent @@ -149,11 +155,18 @@ export default class DataSourceList extends PureComponent ({ - label: type?.type, - value: type?.type, - }))} + defaultFilterValue={filteredType} + filter={[ + { + label: '全部', + value: '', + }, + ].concat( + dataSourceTypes.map((type) => ({ + label: type?.type, + value: type?.type, + })), + )} onFilterChange={this.handleSearchFilterChange} />
diff --git a/packages/plugin-datasource-pane/src/locale/index.ts b/packages/plugin-datasource-pane/src/locale/index.ts index 26507f0ef..49de985ed 100644 --- a/packages/plugin-datasource-pane/src/locale/index.ts +++ b/packages/plugin-datasource-pane/src/locale/index.ts @@ -1,10 +1,10 @@ import { createIntl } from '@ali/lowcode-editor-core'; -import en_US from './en-US.json'; -import zh_CN from './zh-CN.json'; +import enUS from './en-US.json'; +import zhCN from './zh-CN.json'; const { intl, intlNode, getLocale, setLocale } = createIntl({ - 'en-US': en_US, - 'zh-CN': zh_CN, + 'en-US': enUS, + 'zh-CN': zhCN, }); export { intl, intlNode, getLocale, setLocale }; diff --git a/packages/plugin-datasource-pane/src/pane.tsx b/packages/plugin-datasource-pane/src/pane.tsx index 7c71e8508..2604c9f9f 100644 --- a/packages/plugin-datasource-pane/src/pane.tsx +++ b/packages/plugin-datasource-pane/src/pane.tsx @@ -6,7 +6,6 @@ import { DataSource, DataSourceConfig } from '@ali/lowcode-types'; import { Tab, Button, MenuButton, Message, Dialog } from '@alifd/next'; import _cloneDeep from 'lodash/cloneDeep'; import _uniqueId from 'lodash/uniqueId'; -import _startsWith from 'lodash/startsWith'; import _isArray from 'lodash/isArray'; import _get from 'lodash/get'; import List from './list'; @@ -29,15 +28,12 @@ export interface DataSourcePaneProps { onSchemaChange?: (schema: DataSource) => void; } -export interface TabItemProps { +export interface TabItem { key: string; title: string; closeable: boolean; - data: any; -} - -export interface TabItem { - tabItemProps: TabItemProps; + data?: any; + content?: any; } export interface DataSourcePaneState { @@ -47,32 +43,18 @@ export interface DataSourcePaneState { } export class DataSourcePane extends PureComponent { - state = { + state: DataSourcePaneState = { dataSourceList: [...(this.props.defaultSchema?.list || [])], tabItems: [ { - tabItemProps: { - key: TAB_ITEM_LIST, - title: '数据源列表', - closeable: false, - }, + key: TAB_ITEM_LIST, + title: '数据源列表', + closeable: false, }, ], activeTabKey: TAB_ITEM_LIST, }; - constructor(props) { - super(props); - // this.handleDataSourceListChange = this.handleDataSourceListChange.bind(this); - // this.handleImportDataSourceList = this.handleImportDataSourceList.bind(this); - // this.handleCreateDataSource = this.handleCreateDataSource.bind(this); - // this.handleUpdateDataSource = this.handleUpdateDataSource.bind(this); - // this.handleRemoveDataSource = this.handleRemoveDataSource.bind(this); - // this.handleDuplicateDataSource = this.handleDuplicateDataSource.bind(this); - // this.handleEditDataSource = this.handleEditDataSource.bind(this); - // this.handleTabChange = this.handleTabChange.bind(this); - } - handleDataSourceListChange = (dataSourceList?: DataSourceConfig[]) => { if (dataSourceList) { this.setState({ dataSourceList }); @@ -99,16 +81,16 @@ export class DataSourcePane extends PureComponent !!this.state.dataSourceList.find( - dataSource => dataSource.id === item.id - ) + (item) => !!this.state.dataSourceList.find((dataSource) => dataSource.id === item.id), ); if (repeatedDataSourceList.length > 0) { Dialog.confirm({ - content: `数据源(${repeatedDataSourceList.map(item => item.id).join(',')})已存在,如果导入会替换原数据源,是否继续?`, + content: `数据源(${repeatedDataSourceList + .map((item) => item.id) + .join(',')})已存在,如果导入会替换原数据源,是否继续?`, onOk: () => { importDataSourceList(); - } + }, }); return; } @@ -131,14 +113,12 @@ export class DataSourcePane extends PureComponent dataSource.id === toCreate.id - )) { + if (this.state.dataSourceList.find((dataSource) => dataSource.id === toCreate.id)) { Dialog.confirm({ content: `数据源(${toCreate.id})已存在,如果导入会替换原数据源,是否继续?`, onOk: () => { create(); - } + }, }); return; } @@ -179,12 +159,13 @@ export class DataSourcePane extends PureComponent { remove(); - } + }, }); }; handleDuplicateDataSource = (dataSourceId: string) => { const target = this.state.dataSourceList.find((item) => item.id === dataSourceId); + if (!target) return; const cloned = _cloneDeep(target); this.openCreateDataSourceTab({ @@ -195,6 +176,7 @@ export class DataSourcePane extends PureComponent { const target = this.state.dataSourceList.find((item) => item.id === dataSourceId); + if (!target) return; const cloned = _cloneDeep(target); this.openEditDataSourceTab({ @@ -207,22 +189,18 @@ export class DataSourcePane extends PureComponent { + openCreateDataSourceTab = (dataSource: DataSourceConfig) => { const { tabItems } = this.state; - const { dataSourceTypes } = this.props; + const { dataSourceTypes = [] } = this.props; - if (!tabItems.find((item) => item.tabItemProps.key === TAB_ITEM_CREATE)) { + if (!tabItems.find((item) => item.key === TAB_ITEM_CREATE)) { this.setState(({ tabItems }) => ({ tabItems: tabItems.concat({ - tabItemProps: { - key: TAB_ITEM_CREATE, - title: `添加数据源`, - closeable: true, - data: { - dataSourceType: dataSourceTypes?.find( - type => type.type === dataSourceTypeName - ), - }, + key: TAB_ITEM_CREATE, + title: `添加数据源`, + closeable: true, + data: { + dataSourceType: dataSourceTypes?.find((type) => type.type === dataSource.type), }, }), })); @@ -232,23 +210,31 @@ export class DataSourcePane extends PureComponent { + this.openCreateDataSourceTab({ + type: dataSourceType, + } as DataSourceConfig); + }; + + handleCreateDataSourceMenuBtnClick = (dataSourceType: string) => { + this.openCreateDataSourceTab({ + type: dataSourceType, + } as DataSourceConfig); + }; + openEditDataSourceTab = (dataSource: DataSourceConfig) => { const { tabItems } = this.state; - const { dataSourceTypes } = this.props; + const { dataSourceTypes = [] } = this.props; - if (!tabItems.find((item) => item.tabItemProps.key === TAB_ITEM_EDIT)) { + if (!tabItems.find((item) => item.key === TAB_ITEM_EDIT)) { this.setState(({ tabItems }) => ({ tabItems: tabItems.concat({ - tabItemProps: { - key: TAB_ITEM_EDIT, - title: '修改数据源', - closeable: true, - data: { - dataSource, - dataSourceType: dataSourceTypes?.find( - type => type.type === dataSource.type - ), - }, + key: TAB_ITEM_EDIT, + title: '修改数据源', + closeable: true, + data: { + dataSource, + dataSourceType: dataSourceTypes?.find((type) => type.type === dataSource.type), }, }), })); @@ -256,22 +242,20 @@ export class DataSourcePane extends PureComponent { + openImportDataSourceTab = (selectedImportPluginName: string) => { const { tabItems } = this.state; const { importPlugins } = this.props; - if (!tabItems.find((item) => item.tabItemProps.key === `${TAB_ITEM_IMPORT}_${selectedImportPluginName}`)) { + if (!tabItems.find((item) => item.key === `${TAB_ITEM_IMPORT}_${selectedImportPluginName}`)) { this.setState(({ tabItems }) => ({ tabItems: tabItems.concat({ - tabItemProps: { - key: TAB_ITEM_IMPORT, - title: `导入数据源-${selectedImportPluginName}`, - closeable: true, - content: _get( - importPlugins?.find((plugin) => selectedImportPluginName === plugin.name), - 'component', - ), - }, + key: TAB_ITEM_IMPORT, + title: `导入数据源-${selectedImportPluginName}`, + closeable: true, + content: _get( + importPlugins?.find((plugin) => selectedImportPluginName === plugin.name), + 'component', + ), }), })); this.setState({ activeTabKey: TAB_ITEM_IMPORT }); @@ -283,11 +267,11 @@ export class DataSourcePane extends PureComponent { this.setState( ({ tabItems }) => ({ - tabItems: tabItems.filter((item) => item.tabItemProps.key !== tabKey), + tabItems: tabItems.filter((item) => item.key !== tabKey), }), () => { this.setState(({ tabItems }) => ({ - activeTabKey: _get(tabItems, '[0].tabItemProps.key') + activeTabKey: _get(tabItems, '[0].key'), })); }, ); @@ -298,14 +282,14 @@ export class DataSourcePane extends PureComponent 1 ? ( - + _isArray(dataSourceTypes) && dataSourceTypes.length > 0 ? ( + {dataSourceTypes.map((type) => ( {type.type} ))} ) : _isArray(dataSourceTypes) && dataSourceTypes.length === 1 ? ( - + ) : null, _isArray(importPlugins) && importPlugins.length > 1 ? ( @@ -322,7 +306,7 @@ export class DataSourcePane extends PureComponent { const { dataSourceList, tabItems } = this.state; - const { dataSourceTypes } = this.props; + const { dataSourceTypes = [] } = this.props; if (tabItemKey === TAB_ITEM_LIST) { return ( @@ -336,16 +320,17 @@ export class DataSourcePane extends PureComponent type.type === data?.dataSource.type); - return ( - - ); + if (dataSourceType) { + return ( + + ); + } } else if (tabItemKey === TAB_ITEM_CREATE) { - const tabItemData = tabItems.find((tabItem) => tabItem.tabItemProps.key === tabItemKey); return ( ); } else if (tabItemKey === TAB_ITEM_IMPORT) { - const tabItemData = tabItems.find((tabItem) => tabItem.tabItemProps.key === tabItemKey); + const tabItemData = tabItems.find((tabItem) => tabItem.key === tabItemKey); if (tabItemData) { - const Content = tabItemData.tabItemProps.content; - return ; + const Content = tabItemData.content; + return ( + + ); } } return null; }; render() { - const { dataSourceList, activeTabKey, tabItems } = this.state; - const { importPlugins, dataSourceTypes } = this.props; + const { activeTabKey, tabItems } = this.state; return (
@@ -375,10 +365,8 @@ export class DataSourcePane extends PureComponent - {tabItems.map((item) => ( - - {this.renderTabItemContentByKey(item.tabItemProps.key, item.tabItemProps.data)} - + {tabItems.map((item: TabItem) => ( + {this.renderTabItemContentByKey(item.key, item.data)} ))}
diff --git a/packages/plugin-datasource-pane/src/types/datasource-type.ts b/packages/plugin-datasource-pane/src/types/datasource-type.ts index 88533593f..630f9dc29 100644 --- a/packages/plugin-datasource-pane/src/types/datasource-type.ts +++ b/packages/plugin-datasource-pane/src/types/datasource-type.ts @@ -1,6 +1,6 @@ -import { JSONSchema4 } from '@types/json-schema'; +import { JSONSchema6 } from 'json-schema'; export type DataSourceType = { type: string; - schema: JSONSchema4 + schema: JSONSchema6; }; diff --git a/packages/plugin-datasource-pane/src/types/import-plugin.ts b/packages/plugin-datasource-pane/src/types/import-plugin.ts index f3a999241..074e2f106 100644 --- a/packages/plugin-datasource-pane/src/types/import-plugin.ts +++ b/packages/plugin-datasource-pane/src/types/import-plugin.ts @@ -9,11 +9,11 @@ export interface DataSourcePaneImportPlugin { componentProps?: DataSourcePaneImportPluginCustomProps; } -export interface DataSourcePaneImportPluginCustomProps { +export interface DataSourcePaneImportPluginCustomProps extends DataSourcePaneImportPluginComponentProps { [customPropName: string]: any; } -export interface DataSourcePaneImportPluginComponentProps extends DataSourcePaneImportPluginCustomProps { +export interface DataSourcePaneImportPluginComponentProps { dataSourceTypes: DataSourceType[]; onImport?: (dataSourceList: DataSourceConfig[]) => void; onCancel?: () => void;