mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-06-06 23:50:48 +00:00
fix
This commit is contained in:
parent
47f55cafce
commit
4dd2eefc90
@ -139,7 +139,7 @@ export default {
|
|||||||
type: 'PanelIcon',
|
type: 'PanelIcon',
|
||||||
props: {
|
props: {
|
||||||
align: 'top',
|
align: 'top',
|
||||||
icon: 'wenjian',
|
icon: 'shujuyuan',
|
||||||
description: '数据源面板',
|
description: '数据源面板',
|
||||||
panelProps: {
|
panelProps: {
|
||||||
floatable: true,
|
floatable: true,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@ali/lowcode-plugin-components-pane",
|
"name": "@ali/lowcode-plugin-components-pane",
|
||||||
"version": "1.0.7-0",
|
"version": "0.1.0-beta.0",
|
||||||
"description": "alibaba lowcode editor component-list plugin",
|
"description": "低代码引擎数据源配置面板",
|
||||||
"files": [
|
"files": [
|
||||||
"es/",
|
"es/",
|
||||||
"lib/"
|
"lib/"
|
||||||
|
|||||||
5
packages/plugin-datasource-pane/DEV.md
Normal file
5
packages/plugin-datasource-pane/DEV.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
## 插件开发
|
||||||
|
|
||||||
|
[https://yuque.antfin-inc.com/ali-lowcode/docs/ip4awq](插件开发文档)。
|
||||||
|
|
||||||
|
本地开发需要在 v14.4.0 的 node 环境下进行。
|
||||||
@ -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 = {
|
type DataSourceType = {
|
||||||
@ -29,17 +69,15 @@ interface DataSourcePaneImportPlugin {
|
|||||||
componentProps?: DataSourcePaneImportPluginCustomProps;
|
componentProps?: DataSourcePaneImportPluginCustomProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataSourcePaneImportPluginCustomProps {
|
interface DataSourcePaneImportPluginComponentProps {
|
||||||
[customPropName: string]: any;
|
onImport?: (dataSourceList: DataSourceConfig[]) => void;
|
||||||
|
onCancel?: () => void;
|
||||||
|
dataSourceTypes?: DataSourceType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DataSourcePaneImportPluginComponentProps extends DataSourcePaneImportPluginCustomProps {
|
interface DataSourcePaneImportPluginCustomProps extends DataSourcePaneImportPluginComponentProps {
|
||||||
onChange: (dataSourceList: DataSourceConfig[]) => void;
|
[customPropName: string]: any;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 插件开发
|
|
||||||
|
|
||||||
[https://yuque.antfin-inc.com/ali-lowcode/docs/ip4awq](插件开发文档)。
|
|
||||||
|
|
||||||
本地开发需要在 v14.4.0 的 node 环境下进行。
|
|
||||||
|
|||||||
@ -2,14 +2,15 @@ TODO
|
|||||||
---
|
---
|
||||||
|
|
||||||
* 多语言
|
* 多语言
|
||||||
* ICON
|
|
||||||
* 支持变量
|
|
||||||
* 定制样式
|
* 定制样式
|
||||||
* 不使用 bind
|
* 不使用 bind
|
||||||
* 表达式 setter 的联想
|
* 表达式 setter 的联想
|
||||||
* [later]表达式和其他类型的切换
|
* [later]表达式和其他类型的切换
|
||||||
|
|
||||||
|
## 提案
|
||||||
|
|
||||||
|
* mock
|
||||||
* 变量,上下文的提案
|
* 变量,上下文的提案
|
||||||
* mock 的提案
|
|
||||||
|
|
||||||
## 问题
|
## 问题
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@ali/lowcode-plugin-datasource-pane",
|
"name": "@ali/lowcode-plugin-datasource-pane",
|
||||||
"version": "1.0.7-0",
|
"version": "0.1.0-beta.3",
|
||||||
"description": "低代码引擎数据源面板",
|
"description": "低代码引擎数据源面板",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"files": [
|
"files": [
|
||||||
"lib"
|
"lib"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "build-scripts build",
|
||||||
|
"cloud-build": "build-scripts build --skip-demo",
|
||||||
"test": "ava",
|
"test": "ava",
|
||||||
"test:snapshot": "ava --update-snapshots"
|
"test:snapshot": "ava --update-snapshots"
|
||||||
},
|
},
|
||||||
@ -29,6 +30,7 @@
|
|||||||
"monaco-editor": "^0.20.0"
|
"monaco-editor": "^0.20.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@alib/build-scripts": "^0.1.3",
|
||||||
"@ali/lowcode-editor-setters": "^1.0.7-0",
|
"@ali/lowcode-editor-setters": "^1.0.7-0",
|
||||||
"@alifd/next": "^1.20.28",
|
"@alifd/next": "^1.20.28",
|
||||||
"@formily/next": "^1.3.2",
|
"@formily/next": "^1.3.2",
|
||||||
@ -40,5 +42,9 @@
|
|||||||
"react-monaco-editor": "^0.40.0",
|
"react-monaco-editor": "^0.40.0",
|
||||||
"styled-components": "^5.2.0",
|
"styled-components": "^5.2.0",
|
||||||
"traverse": "^0.6.6"
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,17 @@
|
|||||||
// @todo schema default
|
// @todo schema default
|
||||||
import React, { PureComponent, ReactElement, FC } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Button } from '@alifd/next';
|
import { Button } from '@alifd/next';
|
||||||
import { SchemaForm, FormButtonGroup, Submit } from '@formily/next';
|
import { SchemaForm, FormButtonGroup, Submit } from '@formily/next';
|
||||||
import { ArrayTable, Input, Switch, NumberPicker } from '@formily/next-components';
|
import { ArrayTable, Input, Switch, NumberPicker } from '@formily/next-components';
|
||||||
import _isPlainObject from 'lodash/isPlainObject';
|
import _isPlainObject from 'lodash/isPlainObject';
|
||||||
import _isArray from 'lodash/isArray';
|
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 _cloneDeep from 'lodash/cloneDeep';
|
||||||
import _mergeWith from 'lodash/mergeWith';
|
import _mergeWith from 'lodash/mergeWith';
|
||||||
import _get from 'lodash/get';
|
import _get from 'lodash/get';
|
||||||
import _tap from 'lodash/tap';
|
|
||||||
import traverse from 'traverse';
|
import traverse from 'traverse';
|
||||||
|
import { DataSourceConfig } from '@ali/lowcode-types';
|
||||||
import { ParamValue, JSFunction } from './form-components';
|
import { ParamValue, JSFunction } from './form-components';
|
||||||
import { DataSourceType, DataSourceConfig } from './types';
|
import { DataSourceType } from './types';
|
||||||
|
|
||||||
// @todo $ref
|
// @todo $ref
|
||||||
|
|
||||||
@ -89,11 +86,11 @@ const SCHEMA = {
|
|||||||
export interface DataSourceFormProps {
|
export interface DataSourceFormProps {
|
||||||
dataSourceType: DataSourceType;
|
dataSourceType: DataSourceType;
|
||||||
dataSource?: DataSourceConfig;
|
dataSource?: DataSourceConfig;
|
||||||
omComplete?: (dataSource: DataSourceConfig) => void;
|
onComplete?: (dataSource: DataSourceConfig) => void;
|
||||||
|
onCancel?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSourceFormState {
|
export type DataSourceFormState = {};
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过是否存在 ID 来决定读写状态
|
* 通过是否存在 ID 来决定读写状态
|
||||||
@ -101,65 +98,63 @@ export interface DataSourceFormState {
|
|||||||
export class DataSourceForm extends PureComponent<DataSourceFormProps, DataSourceFormState> {
|
export class DataSourceForm extends PureComponent<DataSourceFormProps, DataSourceFormState> {
|
||||||
state = {};
|
state = {};
|
||||||
|
|
||||||
handleFormSubmit = (formData) => {
|
handleFormSubmit = (formData: any) => {
|
||||||
// @todo mutable?
|
// @todo mutable?
|
||||||
if (_isArray(_get(formData, 'options.params'))) {
|
if (_isArray(_get(formData, 'options.params'))) {
|
||||||
formData.options.params = formData.options.params.reduce((acc, cur) => {
|
formData.options.params = formData.options.params.reduce((acc: any, cur: any) => {
|
||||||
if (!cur.name) return;
|
if (!cur.name) return acc;
|
||||||
acc[cur.name] = cur.value;
|
acc[cur.name] = cur.value;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
if (_isArray(_get(formData, 'options.headers'))) {
|
if (_isArray(_get(formData, 'options.headers'))) {
|
||||||
formData.options.headers = formData.options.headers.reduce((acc, cur) => {
|
formData.options.headers = formData.options.headers.reduce((acc: any, cur: any) => {
|
||||||
if (!cur.name) return;
|
if (!cur.name) return acc;
|
||||||
acc[cur.name] = cur.value;
|
acc[cur.name] = cur.value;
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
console.log('submit', formData);
|
// console.log('submit', formData);
|
||||||
this.props?.onComplete(formData);
|
this.props.onComplete?.(formData);
|
||||||
};
|
};
|
||||||
|
|
||||||
deriveInitialData = (dataSource = {}) => {
|
handleCancel = () => {
|
||||||
|
this.props.onCancel?.();
|
||||||
|
};
|
||||||
|
|
||||||
|
deriveInitialData = (dataSource: object = {}) => {
|
||||||
const { dataSourceType } = this.props;
|
const { dataSourceType } = this.props;
|
||||||
const result = _cloneDeep(dataSource);
|
const result: any = _cloneDeep(dataSource);
|
||||||
|
|
||||||
if (_isPlainObject(_get(result, 'options.params'))) {
|
if (_isPlainObject(_get(result, 'options.params'))) {
|
||||||
result.options.params = Object.keys(result.options.params).reduce(
|
result.options.params = Object.keys(result.options.params).reduce((acc: any, cur: any) => {
|
||||||
(acc, cur) => {
|
acc.push({
|
||||||
acc.push({
|
name: cur,
|
||||||
name: cur,
|
value: result.options.params[cur],
|
||||||
value: result.options.params[cur]
|
});
|
||||||
});
|
return acc;
|
||||||
return acc;
|
}, []);
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
if (_isPlainObject(_get(result, 'options.headers'))) {
|
if (_isPlainObject(_get(result, 'options.headers'))) {
|
||||||
result.options.headers = Object.keys(result.options.headers).reduce(
|
result.options.headers = Object.keys(result.options.headers).reduce((acc: any, cur: any) => {
|
||||||
(acc, cur) => {
|
acc.push({
|
||||||
acc.push({
|
name: cur,
|
||||||
name: cur,
|
value: result.options.headers[cur],
|
||||||
value: result.options.headers[cur]
|
});
|
||||||
});
|
return acc;
|
||||||
return acc;
|
}, []);
|
||||||
},
|
|
||||||
[]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.type = dataSourceType.type;
|
result.type = dataSourceType.type;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
};
|
||||||
|
|
||||||
deriveSchema = () => {
|
deriveSchema = () => {
|
||||||
const { dataSourceType } = this.props;
|
const { dataSourceType } = this.props;
|
||||||
|
|
||||||
// @todo 减小覆盖的风险
|
// @todo 减小覆盖的风险
|
||||||
const formSchema = _mergeWith({}, SCHEMA, dataSourceType.schema, (objValue, srcValue) => {
|
const formSchema: any = _mergeWith({}, SCHEMA, dataSourceType.schema, (objValue, srcValue) => {
|
||||||
if (_isArray(objValue)) {
|
if (_isArray(objValue)) {
|
||||||
return srcValue;
|
return srcValue;
|
||||||
}
|
}
|
||||||
@ -185,16 +180,11 @@ export class DataSourceForm extends PureComponent<DataSourceFormProps, DataSourc
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
'x-component': 'ParamValue',
|
'x-component': 'ParamValue',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
types: [
|
types: ['string', 'boolean', 'expression', 'number'],
|
||||||
'string',
|
|
||||||
'boolean',
|
|
||||||
'expression',
|
|
||||||
'number'
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
delete formSchema.properties.options.properties.params.properties;
|
delete formSchema.properties.options.properties.params.properties;
|
||||||
}
|
}
|
||||||
@ -218,9 +208,7 @@ export class DataSourceForm extends PureComponent<DataSourceFormProps, DataSourc
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
'x-component': 'ParamValue',
|
'x-component': 'ParamValue',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
types: [
|
types: ['string'],
|
||||||
'string'
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -257,8 +245,12 @@ export class DataSourceForm extends PureComponent<DataSourceFormProps, DataSourc
|
|||||||
Switch,
|
Switch,
|
||||||
JSFunction,
|
JSFunction,
|
||||||
}}
|
}}
|
||||||
labelCol={4}
|
labelCol={{
|
||||||
wrapperCol={19}
|
span: 4,
|
||||||
|
}}
|
||||||
|
wrapperCol={{
|
||||||
|
span: 19,
|
||||||
|
}}
|
||||||
schema={this.deriveSchema()}
|
schema={this.deriveSchema()}
|
||||||
initialValues={this.deriveInitialData(dataSource)}
|
initialValues={this.deriveInitialData(dataSource)}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -1,60 +1,46 @@
|
|||||||
import React, { PureComponent, createRef } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Button, Input, Radio, NumberPicker, Switch } from '@alifd/next';
|
|
||||||
import { connect } from '@formily/react-schema-renderer';
|
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';
|
import MonacoEditor, { EditorWillMount } from 'react-monaco-editor';
|
||||||
|
import _noop from 'lodash/noop';
|
||||||
const { Group: RadioGroup } = Radio;
|
import { editor } from 'monaco-editor';
|
||||||
|
|
||||||
export interface JSFunctionProps {
|
export interface JSFunctionProps {
|
||||||
className: string;
|
className: string;
|
||||||
value: any;
|
value: any;
|
||||||
onChange?: () => void;
|
onChange?: (val: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JSFunctionState {
|
export type JSFunctionState = {};
|
||||||
}
|
|
||||||
|
|
||||||
class JSFunctionComp extends PureComponent<JSFunctionProps, JSFunctionState> {
|
class JSFunctionComp extends PureComponent<JSFunctionProps, JSFunctionState> {
|
||||||
static isFieldComponent = true;
|
static isFieldComponent = true;
|
||||||
|
|
||||||
private monacoRef = createRef<editor.IStandaloneCodeEditor>();
|
static defaultProps = {
|
||||||
|
onChange: _noop,
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props) {
|
private monacoRef: any = null;
|
||||||
super(props);
|
|
||||||
this.handleEditorChange = this.handleEditorChange.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleEditorChange = () => {
|
handleEditorChange = () => {
|
||||||
if (this.monacoRef.current) {
|
if (this.monacoRef) {
|
||||||
if (
|
if (!(this.monacoRef as any).getModelMarkers().find((marker: editor.IMarker) => marker.owner === 'json')) {
|
||||||
!(this.monacoRef.current as editor.IStandaloneCodeEditor)
|
this.props.onChange?.((this.monacoRef as any)?.getModels()?.[0]?.getValue());
|
||||||
.getModelMarkers()
|
|
||||||
.find((marker: editor.IMarker) => marker.owner === 'json')
|
|
||||||
) {
|
|
||||||
this.props?.onChange(this.monacoRef.current?.getModels()?.[0]?.getValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEditorWillMount: EditorWillMount = (editor) => {
|
handleEditorWillMount: EditorWillMount = (editor) => {
|
||||||
(this.monacoRef as MutableRefObject<editor.IStandaloneCodeEditor>).current = editor?.editor;
|
this.monacoRef = editor?.editor;
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { value, onChange } = this.props;
|
const { value } = this.props;
|
||||||
return (
|
return (
|
||||||
<MonacoEditor
|
<MonacoEditor
|
||||||
theme="vs-dark"
|
theme="vs-dark"
|
||||||
width={400}
|
width={400}
|
||||||
height={150}
|
height={150}
|
||||||
defaulvValue={value}
|
defaultValue={value}
|
||||||
language="js"
|
language="js"
|
||||||
onChange={this.handleEditorChange}
|
onChange={this.handleEditorChange}
|
||||||
editorWillMount={this.handleEditorWillMount}
|
editorWillMount={this.handleEditorWillMount}
|
||||||
|
|||||||
@ -19,12 +19,12 @@ type ParamValueType = 'string' | 'number' | 'boolean' | 'expression';
|
|||||||
export interface ParamValueProps {
|
export interface ParamValueProps {
|
||||||
className: string;
|
className: string;
|
||||||
value: any;
|
value: any;
|
||||||
onChange?: () => void;
|
onChange?: (value: any) => void;
|
||||||
types: ParamValueType[];
|
types: ParamValueType[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ParamValueState {
|
export interface ParamValueState {
|
||||||
type: 'string' | 'number' | 'boolean' | '';
|
type: ParamValueType;
|
||||||
}
|
}
|
||||||
|
|
||||||
const TYPE_LABEL_MAP = {
|
const TYPE_LABEL_MAP = {
|
||||||
@ -41,16 +41,17 @@ class ParamValueComp extends PureComponent<ParamValueProps, ParamValueState> {
|
|||||||
types: ['string', 'boolean', 'number', 'expression'],
|
types: ['string', 'boolean', 'number', 'expression'],
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state: ParamValueState = {
|
||||||
type: '',
|
type: 'string',
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props: ParamValueProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state.type = this.getTypeFromValue(this.props.value);
|
this.state.type = this.getTypeFromValue(this.props.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTypeFromValue = (value) => {
|
// @todo
|
||||||
|
getTypeFromValue = (value: any) => {
|
||||||
if (_isBoolean(value)) {
|
if (_isBoolean(value)) {
|
||||||
return 'boolean';
|
return 'boolean';
|
||||||
} else if (_isNumber(value)) {
|
} else if (_isNumber(value)) {
|
||||||
@ -62,36 +63,38 @@ class ParamValueComp extends PureComponent<ParamValueProps, ParamValueState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// @todo 需要再 bind 一次?
|
// @todo 需要再 bind 一次?
|
||||||
handleChange = (value) => {
|
handleChange = (value: any) => {
|
||||||
this.props?.onChange(value);
|
this.props?.onChange?.(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps: ParamValueProps) {
|
||||||
if (this.props.value !== prevProps.value) {
|
if (this.props.value !== prevProps.value) {
|
||||||
this.setState({
|
this.setState({
|
||||||
value: this.props.value,
|
|
||||||
type: this.getTypeFromValue(this.props.value),
|
type: this.getTypeFromValue(this.props.value),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTypeChange = (type) => {
|
handleTypeChange = (type: string) => {
|
||||||
this.setState(({ value }) => {
|
this.setState(
|
||||||
let nextValue = value || '';
|
{
|
||||||
if (type === 'string') {
|
type: type as ParamValueType,
|
||||||
nextValue = nextValue.toString();
|
},
|
||||||
} else if (type === 'number') {
|
() => {
|
||||||
nextValue = nextValue * 1;
|
let nextValue = this.props.value || '';
|
||||||
} else if (type === 'boolean') {
|
const { type } = this.state;
|
||||||
nextValue = nextValue === 'true' || nextValue;
|
if (type === 'string') {
|
||||||
} else if (type === 'expression') {
|
nextValue = nextValue.toString();
|
||||||
nextValue = '';
|
} else if (type === 'number') {
|
||||||
}
|
nextValue = nextValue * 1;
|
||||||
return {
|
} else if (type === 'boolean') {
|
||||||
value: nextValue,
|
nextValue = nextValue === 'true' || nextValue;
|
||||||
type,
|
} else if (type === 'expression') {
|
||||||
};
|
nextValue = '';
|
||||||
});
|
}
|
||||||
|
this.props.onChange?.(nextValue);
|
||||||
|
},
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderTypeSelect = () => {
|
renderTypeSelect = () => {
|
||||||
@ -107,6 +110,7 @@ class ParamValueComp extends PureComponent<ParamValueProps, ParamValueState> {
|
|||||||
value: item,
|
value: item,
|
||||||
}))}
|
}))}
|
||||||
value={type}
|
value={type}
|
||||||
|
onChange={this.handleTypeChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -134,10 +138,10 @@ class ParamValueComp extends PureComponent<ParamValueProps, ParamValueState> {
|
|||||||
return (
|
return (
|
||||||
<div className="param-value">
|
<div className="param-value">
|
||||||
{this.renderTypeSelect()}
|
{this.renderTypeSelect()}
|
||||||
{type === 'string' && <Input onChange={this.handleChange.bind(this)} value={value} />}
|
{type === 'string' && <Input onChange={this.handleChange} value={value} />}
|
||||||
{type === 'boolean' && <Switch onChange={this.handleChange.bind(this)} checked={value} />}
|
{type === 'boolean' && <Switch onChange={this.handleChange} checked={value} />}
|
||||||
{type === 'number' && <NumberPicker onChange={this.handleChange.bind(this)} value={value} />}
|
{type === 'number' && <NumberPicker onChange={this.handleChange} value={value} />}
|
||||||
{type === 'expression' && <ExpressionSetter onChange={this.handleChange.bind(this)} value={value} />}
|
{type === 'expression' && <ExpressionSetter onChange={this.handleChange} value={value} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/indent */
|
||||||
|
// @todo 缩进问题
|
||||||
/**
|
/**
|
||||||
* 源码导入插件
|
* 源码导入插件
|
||||||
* @todo editor 关联 types,并提供详细的出错信息
|
* @todo editor 关联 types,并提供详细的出错信息
|
||||||
*/
|
*/
|
||||||
import React, { PureComponent, createRef, MutableRefObject } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { Button } from '@alifd/next';
|
import { Button } from '@alifd/next';
|
||||||
import _noop from 'lodash/noop';
|
import _noop from 'lodash/noop';
|
||||||
import _isArray from 'lodash/isArray';
|
import _isArray from 'lodash/isArray';
|
||||||
@ -35,7 +37,7 @@ export class DataSourceImportPluginCode extends PureComponent<
|
|||||||
type: 'http',
|
type: 'http',
|
||||||
id: 'test',
|
id: 'test',
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
@ -43,7 +45,7 @@ export class DataSourceImportPluginCode extends PureComponent<
|
|||||||
isCodeValid: true,
|
isCodeValid: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
private monacoRef = createRef<editor.IStandaloneCodeEditor>();
|
private monacoRef: any;
|
||||||
|
|
||||||
constructor(props: DataSourceImportPluginCodeProps) {
|
constructor(props: DataSourceImportPluginCodeProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@ -77,14 +79,12 @@ export class DataSourceImportPluginCode extends PureComponent<
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleComplete = () => {
|
handleComplete = () => {
|
||||||
if (this.monacoRef.current) {
|
if (this.monacoRef) {
|
||||||
if (
|
if (!this.monacoRef.getModelMarkers().find((marker: editor.IMarker) => marker.owner === 'json')) {
|
||||||
!(this.monacoRef.current as editor.IStandaloneCodeEditor)
|
|
||||||
.getModelMarkers()
|
|
||||||
.find((marker: editor.IMarker) => marker.owner === 'json')
|
|
||||||
) {
|
|
||||||
this.setState({ isCodeValid: true });
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,30 +92,28 @@ export class DataSourceImportPluginCode extends PureComponent<
|
|||||||
};
|
};
|
||||||
|
|
||||||
handleEditorChange = () => {
|
handleEditorChange = () => {
|
||||||
if (this.monacoRef.current) {
|
if (this.monacoRef) {
|
||||||
if (
|
if (!this.monacoRef.getModelMarkers().find((marker: editor.IMarker) => marker.owner === 'json')) {
|
||||||
!(this.monacoRef.current as editor.IStandaloneCodeEditor)
|
|
||||||
.getModelMarkers()
|
|
||||||
.find((marker: editor.IMarker) => marker.owner === 'json')
|
|
||||||
) {
|
|
||||||
this.setState({ isCodeValid: true });
|
this.setState({ isCodeValid: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleEditorWillMount: EditorWillMount = (editor) => {
|
handleEditorWillMount: EditorWillMount = (editor) => {
|
||||||
(this.monacoRef as MutableRefObject<editor.IStandaloneCodeEditor>).current = editor?.editor;
|
this.monacoRef = editor?.editor;
|
||||||
// @todo 格式化一次
|
// @todo 格式化一次
|
||||||
};
|
};
|
||||||
|
|
||||||
handleCodeChagne = (code) => {
|
handleCodeChagne = (code: string) => {
|
||||||
this.setState({ code });
|
this.setState({ code });
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { onCancel = _noop } = this.props;
|
const { onCancel = _noop } = this.props;
|
||||||
const { code, isCodeValid } = this.state;
|
const { code, isCodeValid } = this.state;
|
||||||
|
|
||||||
|
// @todo
|
||||||
|
// formatOnType formatOnPaste
|
||||||
return (
|
return (
|
||||||
<div className="lowcode-plugin-datasource-import-plugin-code">
|
<div className="lowcode-plugin-datasource-import-plugin-code">
|
||||||
<MonacoEditor
|
<MonacoEditor
|
||||||
@ -126,13 +124,13 @@ export class DataSourceImportPluginCode extends PureComponent<
|
|||||||
language="json"
|
language="json"
|
||||||
onChange={this.handleEditorChange}
|
onChange={this.handleEditorChange}
|
||||||
editorWillMount={this.handleEditorWillMount}
|
editorWillMount={this.handleEditorWillMount}
|
||||||
formatOnType
|
|
||||||
formatOnPaste
|
|
||||||
/>
|
/>
|
||||||
{!isCodeValid && <p className="error-msg">格式有误</p>}
|
{!isCodeValid && <p className="error-msg">格式有误</p>}
|
||||||
<p className="btns">
|
<p className="btns">
|
||||||
<Button onClick={onCancel}>取消</Button>
|
<Button onClick={onCancel}>取消</Button>
|
||||||
<Button type="primary" onClick={this.handleComplete}>确认</Button>
|
<Button type="primary" onClick={this.handleComplete}>
|
||||||
|
确认
|
||||||
|
</Button>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -19,9 +19,9 @@ export interface DataSourcePaneState {
|
|||||||
active: boolean;
|
active: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BUILTIN_DATASOURCE_TYPES = [
|
const BUILTIN_DATASOURCE_TYPES: DataSourceType[] = [
|
||||||
{
|
{
|
||||||
type: 'http',
|
type: 'fetch',
|
||||||
schema: {
|
schema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
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',
|
name: 'default',
|
||||||
title: '源码',
|
title: '源码',
|
||||||
@ -98,7 +114,7 @@ export default class DataSourcePanePlugin extends PureComponent<DataSourcePanePr
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { importPlugins, dataSourceTypes, editor } = this.props;
|
const { importPlugins, dataSourceTypes = [], editor } = this.props;
|
||||||
const { active } = this.state;
|
const { active } = this.state;
|
||||||
|
|
||||||
if (!active) return null;
|
if (!active) return null;
|
||||||
@ -114,3 +130,5 @@ export default class DataSourcePanePlugin extends PureComponent<DataSourcePanePr
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export * from './types';
|
||||||
|
|||||||
@ -10,6 +10,13 @@ import { DataSourceType } from './types';
|
|||||||
|
|
||||||
const { Column: TableCol } = Table;
|
const { Column: TableCol } = Table;
|
||||||
|
|
||||||
|
function deriveTypeFromValue(val: any) {
|
||||||
|
if (_isBoolean(val)) return 'bool';
|
||||||
|
if (_isNumber(val)) return 'number';
|
||||||
|
if (_isPlainObject(val)) return 'obj';
|
||||||
|
return 'string';
|
||||||
|
}
|
||||||
|
|
||||||
export interface DataSourceListProps {
|
export interface DataSourceListProps {
|
||||||
dataSourceTypes: DataSourceType[];
|
dataSourceTypes: DataSourceType[];
|
||||||
dataSource: DataSourceConfig[];
|
dataSource: DataSourceConfig[];
|
||||||
@ -56,7 +63,7 @@ export default class DataSourceList extends PureComponent<DataSourceListProps, D
|
|||||||
|
|
||||||
deriveListDataSource = () => {
|
deriveListDataSource = () => {
|
||||||
const { filteredType, keyword } = this.state;
|
const { filteredType, keyword } = this.state;
|
||||||
const { dataSource } = this.props;
|
const { dataSource, dataSourceTypes } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
dataSource
|
dataSource
|
||||||
@ -69,63 +76,61 @@ export default class DataSourceList extends PureComponent<DataSourceListProps, D
|
|||||||
<div className="datasource-item-id" title={item.id}>
|
<div className="datasource-item-id" title={item.id}>
|
||||||
{item.id}
|
{item.id}
|
||||||
</div>
|
</div>
|
||||||
<Balloon
|
{!!dataSourceTypes.find((ds) => ds.type === item.type) && (
|
||||||
trigger={<Button size="small">详情</Button>}
|
<Balloon
|
||||||
align="b"
|
trigger={<Button size="small">详情</Button>}
|
||||||
alignEdge
|
align="b"
|
||||||
triggerType="hover"
|
alignEdge
|
||||||
style={{ width: 300 }}
|
triggerType="hover"
|
||||||
>
|
style={{ width: 300 }}
|
||||||
<Table
|
|
||||||
dataSource={_tap(
|
|
||||||
Object.keys(item.options || {}).reduce<TableRow[]>((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,
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<TableCol title="" dataIndex="label" />
|
<Table
|
||||||
<TableCol
|
dataSource={_tap(
|
||||||
title=""
|
Object.keys(item.options || {}).reduce<TableRow[]>((acc, cur) => {
|
||||||
dataIndex="value"
|
// @todo 这里的 ts 处理得不好
|
||||||
cell={(val: any) => (
|
if (_isPlainObject(item.options[cur])) {
|
||||||
<div>
|
Object.keys(item?.options?.[cur] || {}).forEach((curInOption) => {
|
||||||
<Tag>
|
acc.push({
|
||||||
{_isBoolean(val)
|
label: `${cur}.${curInOption}`,
|
||||||
? 'bool'
|
value: (item?.options?.[cur] as any)?.[curInOption],
|
||||||
: _isNumber(val)
|
});
|
||||||
? 'number'
|
});
|
||||||
: _isPlainObject(val)
|
} else if (!_isNil(item.options[cur])) {
|
||||||
? 'obj'
|
// @todo 排除 null
|
||||||
: 'string'}
|
acc.push({
|
||||||
</Tag>
|
label: cur,
|
||||||
{val.toString()}
|
value: item.options[cur],
|
||||||
</div>
|
});
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []),
|
||||||
|
console.log,
|
||||||
)}
|
)}
|
||||||
/>
|
>
|
||||||
</Table>
|
<TableCol title="" dataIndex="label" />
|
||||||
</Balloon>
|
<TableCol
|
||||||
<Button size="small" onClick={this.handleEditDataSource.bind(this, item.id)}>
|
title=""
|
||||||
编辑
|
dataIndex="value"
|
||||||
</Button>
|
cell={(val: any) => (
|
||||||
<Button size="small" onClick={this.handleDuplicateDataSource.bind(this, item.id)}>
|
<div>
|
||||||
复制
|
<Tag>{deriveTypeFromValue(val)}</Tag>
|
||||||
</Button>
|
{val.toString()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</Table>
|
||||||
|
</Balloon>
|
||||||
|
)}
|
||||||
|
{!!dataSourceTypes.find((ds) => ds.type === item.type) && (
|
||||||
|
<Button size="small" onClick={this.handleEditDataSource.bind(this, item.id)}>
|
||||||
|
编辑
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{!!dataSourceTypes.find((ds) => ds.type === item.type) && (
|
||||||
|
<Button size="small" onClick={this.handleDuplicateDataSource.bind(this, item.id)}>
|
||||||
|
复制
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
<Button size="small" onClick={this.handleRemoveDataSource.bind(this, item.id)}>
|
<Button size="small" onClick={this.handleRemoveDataSource.bind(this, item.id)}>
|
||||||
删除
|
删除
|
||||||
</Button>
|
</Button>
|
||||||
@ -142,6 +147,7 @@ export default class DataSourceList extends PureComponent<DataSourceListProps, D
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dataSourceTypes } = this.props;
|
const { dataSourceTypes } = this.props;
|
||||||
|
const { filteredType } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="lowcode-plugin-datasource-pane-list">
|
<div className="lowcode-plugin-datasource-pane-list">
|
||||||
@ -149,11 +155,18 @@ export default class DataSourceList extends PureComponent<DataSourceListProps, D
|
|||||||
hasClear
|
hasClear
|
||||||
onSearch={this.handleSearch}
|
onSearch={this.handleSearch}
|
||||||
filterProps={{}}
|
filterProps={{}}
|
||||||
defaultFilterValue={dataSourceTypes?.[0]?.type}
|
defaultFilterValue={filteredType}
|
||||||
filter={dataSourceTypes.map((type) => ({
|
filter={[
|
||||||
label: type?.type,
|
{
|
||||||
value: type?.type,
|
label: '全部',
|
||||||
}))}
|
value: '',
|
||||||
|
},
|
||||||
|
].concat(
|
||||||
|
dataSourceTypes.map((type) => ({
|
||||||
|
label: type?.type,
|
||||||
|
value: type?.type,
|
||||||
|
})),
|
||||||
|
)}
|
||||||
onFilterChange={this.handleSearchFilterChange}
|
onFilterChange={this.handleSearchFilterChange}
|
||||||
/>
|
/>
|
||||||
<div className="datasource-list">
|
<div className="datasource-list">
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { createIntl } from '@ali/lowcode-editor-core';
|
import { createIntl } from '@ali/lowcode-editor-core';
|
||||||
import en_US from './en-US.json';
|
import enUS from './en-US.json';
|
||||||
import zh_CN from './zh-CN.json';
|
import zhCN from './zh-CN.json';
|
||||||
|
|
||||||
const { intl, intlNode, getLocale, setLocale } = createIntl({
|
const { intl, intlNode, getLocale, setLocale } = createIntl({
|
||||||
'en-US': en_US,
|
'en-US': enUS,
|
||||||
'zh-CN': zh_CN,
|
'zh-CN': zhCN,
|
||||||
});
|
});
|
||||||
|
|
||||||
export { intl, intlNode, getLocale, setLocale };
|
export { intl, intlNode, getLocale, setLocale };
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { DataSource, DataSourceConfig } from '@ali/lowcode-types';
|
|||||||
import { Tab, Button, MenuButton, Message, Dialog } from '@alifd/next';
|
import { Tab, Button, MenuButton, Message, Dialog } from '@alifd/next';
|
||||||
import _cloneDeep from 'lodash/cloneDeep';
|
import _cloneDeep from 'lodash/cloneDeep';
|
||||||
import _uniqueId from 'lodash/uniqueId';
|
import _uniqueId from 'lodash/uniqueId';
|
||||||
import _startsWith from 'lodash/startsWith';
|
|
||||||
import _isArray from 'lodash/isArray';
|
import _isArray from 'lodash/isArray';
|
||||||
import _get from 'lodash/get';
|
import _get from 'lodash/get';
|
||||||
import List from './list';
|
import List from './list';
|
||||||
@ -29,15 +28,12 @@ export interface DataSourcePaneProps {
|
|||||||
onSchemaChange?: (schema: DataSource) => void;
|
onSchemaChange?: (schema: DataSource) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TabItemProps {
|
export interface TabItem {
|
||||||
key: string;
|
key: string;
|
||||||
title: string;
|
title: string;
|
||||||
closeable: boolean;
|
closeable: boolean;
|
||||||
data: any;
|
data?: any;
|
||||||
}
|
content?: any;
|
||||||
|
|
||||||
export interface TabItem {
|
|
||||||
tabItemProps: TabItemProps;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSourcePaneState {
|
export interface DataSourcePaneState {
|
||||||
@ -47,32 +43,18 @@ export interface DataSourcePaneState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourcePaneState> {
|
export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourcePaneState> {
|
||||||
state = {
|
state: DataSourcePaneState = {
|
||||||
dataSourceList: [...(this.props.defaultSchema?.list || [])],
|
dataSourceList: [...(this.props.defaultSchema?.list || [])],
|
||||||
tabItems: [
|
tabItems: [
|
||||||
{
|
{
|
||||||
tabItemProps: {
|
key: TAB_ITEM_LIST,
|
||||||
key: TAB_ITEM_LIST,
|
title: '数据源列表',
|
||||||
title: '数据源列表',
|
closeable: false,
|
||||||
closeable: false,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
activeTabKey: TAB_ITEM_LIST,
|
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[]) => {
|
handleDataSourceListChange = (dataSourceList?: DataSourceConfig[]) => {
|
||||||
if (dataSourceList) {
|
if (dataSourceList) {
|
||||||
this.setState({ dataSourceList });
|
this.setState({ dataSourceList });
|
||||||
@ -99,16 +81,16 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const repeatedDataSourceList = toImport.filter(
|
const repeatedDataSourceList = toImport.filter(
|
||||||
item => !!this.state.dataSourceList.find(
|
(item) => !!this.state.dataSourceList.find((dataSource) => dataSource.id === item.id),
|
||||||
dataSource => dataSource.id === item.id
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
if (repeatedDataSourceList.length > 0) {
|
if (repeatedDataSourceList.length > 0) {
|
||||||
Dialog.confirm({
|
Dialog.confirm({
|
||||||
content: `数据源(${repeatedDataSourceList.map(item => item.id).join(',')})已存在,如果导入会替换原数据源,是否继续?`,
|
content: `数据源(${repeatedDataSourceList
|
||||||
|
.map((item) => item.id)
|
||||||
|
.join(',')})已存在,如果导入会替换原数据源,是否继续?`,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
importDataSourceList();
|
importDataSourceList();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -131,14 +113,12 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if (this.state.dataSourceList.find(
|
if (this.state.dataSourceList.find((dataSource) => dataSource.id === toCreate.id)) {
|
||||||
dataSource => dataSource.id === toCreate.id
|
|
||||||
)) {
|
|
||||||
Dialog.confirm({
|
Dialog.confirm({
|
||||||
content: `数据源(${toCreate.id})已存在,如果导入会替换原数据源,是否继续?`,
|
content: `数据源(${toCreate.id})已存在,如果导入会替换原数据源,是否继续?`,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
create();
|
create();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -179,12 +159,13 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
content: `确定要删除吗?`,
|
content: `确定要删除吗?`,
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
remove();
|
remove();
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleDuplicateDataSource = (dataSourceId: string) => {
|
handleDuplicateDataSource = (dataSourceId: string) => {
|
||||||
const target = this.state.dataSourceList.find((item) => item.id === dataSourceId);
|
const target = this.state.dataSourceList.find((item) => item.id === dataSourceId);
|
||||||
|
if (!target) return;
|
||||||
const cloned = _cloneDeep(target);
|
const cloned = _cloneDeep(target);
|
||||||
|
|
||||||
this.openCreateDataSourceTab({
|
this.openCreateDataSourceTab({
|
||||||
@ -195,6 +176,7 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
|
|
||||||
handleEditDataSource = (dataSourceId: string) => {
|
handleEditDataSource = (dataSourceId: string) => {
|
||||||
const target = this.state.dataSourceList.find((item) => item.id === dataSourceId);
|
const target = this.state.dataSourceList.find((item) => item.id === dataSourceId);
|
||||||
|
if (!target) return;
|
||||||
const cloned = _cloneDeep(target);
|
const cloned = _cloneDeep(target);
|
||||||
|
|
||||||
this.openEditDataSourceTab({
|
this.openEditDataSourceTab({
|
||||||
@ -207,22 +189,18 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
this.setState({ activeTabKey });
|
this.setState({ activeTabKey });
|
||||||
};
|
};
|
||||||
|
|
||||||
openCreateDataSourceTab = (dataSourceTypeName: string) => {
|
openCreateDataSourceTab = (dataSource: DataSourceConfig) => {
|
||||||
const { tabItems } = this.state;
|
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 }) => ({
|
this.setState(({ tabItems }) => ({
|
||||||
tabItems: tabItems.concat({
|
tabItems: tabItems.concat({
|
||||||
tabItemProps: {
|
key: TAB_ITEM_CREATE,
|
||||||
key: TAB_ITEM_CREATE,
|
title: `添加数据源`,
|
||||||
title: `添加数据源`,
|
closeable: true,
|
||||||
closeable: true,
|
data: {
|
||||||
data: {
|
dataSourceType: dataSourceTypes?.find((type) => type.type === dataSource.type),
|
||||||
dataSourceType: dataSourceTypes?.find(
|
|
||||||
type => type.type === dataSourceTypeName
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
@ -232,23 +210,31 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleCreateDataSourceBtnClick = (dataSourceType: string) => {
|
||||||
|
this.openCreateDataSourceTab({
|
||||||
|
type: dataSourceType,
|
||||||
|
} as DataSourceConfig);
|
||||||
|
};
|
||||||
|
|
||||||
|
handleCreateDataSourceMenuBtnClick = (dataSourceType: string) => {
|
||||||
|
this.openCreateDataSourceTab({
|
||||||
|
type: dataSourceType,
|
||||||
|
} as DataSourceConfig);
|
||||||
|
};
|
||||||
|
|
||||||
openEditDataSourceTab = (dataSource: DataSourceConfig) => {
|
openEditDataSourceTab = (dataSource: DataSourceConfig) => {
|
||||||
const { tabItems } = this.state;
|
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 }) => ({
|
this.setState(({ tabItems }) => ({
|
||||||
tabItems: tabItems.concat({
|
tabItems: tabItems.concat({
|
||||||
tabItemProps: {
|
key: TAB_ITEM_EDIT,
|
||||||
key: TAB_ITEM_EDIT,
|
title: '修改数据源',
|
||||||
title: '修改数据源',
|
closeable: true,
|
||||||
closeable: true,
|
data: {
|
||||||
data: {
|
dataSource,
|
||||||
dataSource,
|
dataSourceType: dataSourceTypes?.find((type) => type.type === dataSource.type),
|
||||||
dataSourceType: dataSourceTypes?.find(
|
|
||||||
type => type.type === dataSource.type
|
|
||||||
),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
@ -256,22 +242,20 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
this.setState({ activeTabKey: TAB_ITEM_EDIT });
|
this.setState({ activeTabKey: TAB_ITEM_EDIT });
|
||||||
};
|
};
|
||||||
|
|
||||||
openImportDataSourceTab = (selectedImportPluginName) => {
|
openImportDataSourceTab = (selectedImportPluginName: string) => {
|
||||||
const { tabItems } = this.state;
|
const { tabItems } = this.state;
|
||||||
const { importPlugins } = this.props;
|
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 }) => ({
|
this.setState(({ tabItems }) => ({
|
||||||
tabItems: tabItems.concat({
|
tabItems: tabItems.concat({
|
||||||
tabItemProps: {
|
key: TAB_ITEM_IMPORT,
|
||||||
key: TAB_ITEM_IMPORT,
|
title: `导入数据源-${selectedImportPluginName}`,
|
||||||
title: `导入数据源-${selectedImportPluginName}`,
|
closeable: true,
|
||||||
closeable: true,
|
content: _get(
|
||||||
content: _get(
|
importPlugins?.find((plugin) => selectedImportPluginName === plugin.name),
|
||||||
importPlugins?.find((plugin) => selectedImportPluginName === plugin.name),
|
'component',
|
||||||
'component',
|
),
|
||||||
),
|
|
||||||
},
|
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
this.setState({ activeTabKey: TAB_ITEM_IMPORT });
|
this.setState({ activeTabKey: TAB_ITEM_IMPORT });
|
||||||
@ -283,11 +267,11 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
closeTab = (tabKey: any) => {
|
closeTab = (tabKey: any) => {
|
||||||
this.setState(
|
this.setState(
|
||||||
({ tabItems }) => ({
|
({ tabItems }) => ({
|
||||||
tabItems: tabItems.filter((item) => item.tabItemProps.key !== tabKey),
|
tabItems: tabItems.filter((item) => item.key !== tabKey),
|
||||||
}),
|
}),
|
||||||
() => {
|
() => {
|
||||||
this.setState(({ tabItems }) => ({
|
this.setState(({ tabItems }) => ({
|
||||||
activeTabKey: _get(tabItems, '[0].tabItemProps.key')
|
activeTabKey: _get(tabItems, '[0].key'),
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -298,14 +282,14 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
|
|
||||||
// @todo onSelect 不行?
|
// @todo onSelect 不行?
|
||||||
return [
|
return [
|
||||||
_isArray(dataSourceTypes) && dataSourceTypes.length > 1 ? (
|
_isArray(dataSourceTypes) && dataSourceTypes.length > 0 ? (
|
||||||
<MenuButton label="新建" onItemClick={this.openCreateDataSourceTab}>
|
<MenuButton label="新建" onItemClick={this.handleCreateDataSourceMenuBtnClick}>
|
||||||
{dataSourceTypes.map((type) => (
|
{dataSourceTypes.map((type) => (
|
||||||
<MenuButtonItem key={type.type}>{type.type}</MenuButtonItem>
|
<MenuButtonItem key={type.type}>{type.type}</MenuButtonItem>
|
||||||
))}
|
))}
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
) : _isArray(dataSourceTypes) && dataSourceTypes.length === 1 ? (
|
) : _isArray(dataSourceTypes) && dataSourceTypes.length === 1 ? (
|
||||||
<Button onClick={this.openCreateDataSourceTab.bind(this, dataSourceTypes[0].type)}>新建</Button>
|
<Button onClick={this.handleCreateDataSourceBtnClick.bind(this, dataSourceTypes[0].type)}>新建</Button>
|
||||||
) : null,
|
) : null,
|
||||||
_isArray(importPlugins) && importPlugins.length > 1 ? (
|
_isArray(importPlugins) && importPlugins.length > 1 ? (
|
||||||
<MenuButton label="导入" onItemClick={this.openImportDataSourceTab}>
|
<MenuButton label="导入" onItemClick={this.openImportDataSourceTab}>
|
||||||
@ -322,7 +306,7 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
// 更通用的处理
|
// 更通用的处理
|
||||||
renderTabItemContentByKey = (tabItemKey: any, data: any) => {
|
renderTabItemContentByKey = (tabItemKey: any, data: any) => {
|
||||||
const { dataSourceList, tabItems } = this.state;
|
const { dataSourceList, tabItems } = this.state;
|
||||||
const { dataSourceTypes } = this.props;
|
const { dataSourceTypes = [] } = this.props;
|
||||||
|
|
||||||
if (tabItemKey === TAB_ITEM_LIST) {
|
if (tabItemKey === TAB_ITEM_LIST) {
|
||||||
return (
|
return (
|
||||||
@ -336,16 +320,17 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
);
|
);
|
||||||
} else if (tabItemKey === TAB_ITEM_EDIT) {
|
} else if (tabItemKey === TAB_ITEM_EDIT) {
|
||||||
const dataSourceType = dataSourceTypes.find((type) => type.type === data?.dataSource.type);
|
const dataSourceType = dataSourceTypes.find((type) => type.type === data?.dataSource.type);
|
||||||
return (
|
if (dataSourceType) {
|
||||||
<DataSourceForm
|
return (
|
||||||
dataSourceType={dataSourceType}
|
<DataSourceForm
|
||||||
dataSource={data?.dataSource}
|
dataSourceType={dataSourceType}
|
||||||
onComplete={this.handleUpdateDataSource}
|
dataSource={data?.dataSource}
|
||||||
onCancel={this.closeTab.bind(this, TAB_ITEM_EDIT)}
|
onComplete={this.handleUpdateDataSource}
|
||||||
/>
|
onCancel={this.closeTab.bind(this, TAB_ITEM_EDIT)}
|
||||||
);
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
} else if (tabItemKey === TAB_ITEM_CREATE) {
|
} else if (tabItemKey === TAB_ITEM_CREATE) {
|
||||||
const tabItemData = tabItems.find((tabItem) => tabItem.tabItemProps.key === tabItemKey);
|
|
||||||
return (
|
return (
|
||||||
<DataSourceForm
|
<DataSourceForm
|
||||||
dataSourceType={data?.dataSourceType}
|
dataSourceType={data?.dataSourceType}
|
||||||
@ -354,18 +339,23 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (tabItemKey === TAB_ITEM_IMPORT) {
|
} 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) {
|
if (tabItemData) {
|
||||||
const Content = tabItemData.tabItemProps.content;
|
const Content = tabItemData.content;
|
||||||
return <Content dataSourceTypes={dataSourceTypes} onCancel={this.closeTab.bind(this, tabItemKey)} onImport={this.handleImportDataSourceList} />;
|
return (
|
||||||
|
<Content
|
||||||
|
dataSourceTypes={dataSourceTypes}
|
||||||
|
onCancel={this.closeTab.bind(this, tabItemKey)}
|
||||||
|
onImport={this.handleImportDataSourceList}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dataSourceList, activeTabKey, tabItems } = this.state;
|
const { activeTabKey, tabItems } = this.state;
|
||||||
const { importPlugins, dataSourceTypes } = this.props;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="lowcode-plugin-datasource-pane">
|
<div className="lowcode-plugin-datasource-pane">
|
||||||
@ -375,10 +365,8 @@ export class DataSourcePane extends PureComponent<DataSourcePaneProps, DataSourc
|
|||||||
onChange={this.handleTabChange}
|
onChange={this.handleTabChange}
|
||||||
onClose={this.closeTab}
|
onClose={this.closeTab}
|
||||||
>
|
>
|
||||||
{tabItems.map((item) => (
|
{tabItems.map((item: TabItem) => (
|
||||||
<TabItem {...item.tabItemProps}>
|
<TabItem {...item}>{this.renderTabItemContentByKey(item.key, item.data)}</TabItem>
|
||||||
{this.renderTabItemContentByKey(item.tabItemProps.key, item.tabItemProps.data)}
|
|
||||||
</TabItem>
|
|
||||||
))}
|
))}
|
||||||
</Tab>
|
</Tab>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { JSONSchema4 } from '@types/json-schema';
|
import { JSONSchema6 } from 'json-schema';
|
||||||
|
|
||||||
export type DataSourceType = {
|
export type DataSourceType = {
|
||||||
type: string;
|
type: string;
|
||||||
schema: JSONSchema4
|
schema: JSONSchema6;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -9,11 +9,11 @@ export interface DataSourcePaneImportPlugin {
|
|||||||
componentProps?: DataSourcePaneImportPluginCustomProps;
|
componentProps?: DataSourcePaneImportPluginCustomProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSourcePaneImportPluginCustomProps {
|
export interface DataSourcePaneImportPluginCustomProps extends DataSourcePaneImportPluginComponentProps {
|
||||||
[customPropName: string]: any;
|
[customPropName: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSourcePaneImportPluginComponentProps extends DataSourcePaneImportPluginCustomProps {
|
export interface DataSourcePaneImportPluginComponentProps {
|
||||||
dataSourceTypes: DataSourceType[];
|
dataSourceTypes: DataSourceType[];
|
||||||
onImport?: (dataSourceList: DataSourceConfig[]) => void;
|
onImport?: (dataSourceList: DataSourceConfig[]) => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user