Commit 4cda2acf by zhaochengxiang

新增保存数据模型接口

parent 5c4f848b
import * as userService from '../service/user';
import * as metadataService from '../service/metadata';
import * as datamodelerService from '../service/datamodeler';
import { call } from 'redux-saga/effects';
export function* getAllSystemAndDatabase() {
......@@ -44,3 +45,56 @@ export function* getAllDataTable(payload) {
export function* getAllFileds(payload) {
return yield call(metadataService.queryAllFields, payload);
}
export function* loadDataModelCatalog() {
return yield call(datamodelerService.loadDataModelCatalog);
}
export function* saveDataModelCatalog(payload) {
return yield call(datamodelerService.saveDataModelCatalog, payload);
}
export function* deleteDataModelCatalog(payload) {
return yield call(datamodelerService.deleteDataModelCatalog, payload);
}
export function* bindCatalogDataModel(payload) {
return yield call(datamodelerService.bindCatalogDataModel, payload);
}
export function* getCurrentDataModelCatalog(payload) {
return yield call(datamodelerService.getCurrentDataModelCatalog, payload);
}
export function* extractExcelContent(payload) {
return yield call(datamodelerService.extractExcelContent, payload);
}
export function* getAllConstraints() {
return yield call(datamodelerService.constraints);
}
//获取初稿
export function* getDraft(payload) {
return yield call(datamodelerService.draft, payload);
}
export function* getSupportedDatatypes() {
return yield call(datamodelerService.getSupportedDatatypes);
}
export function* suggest(payload) {
return yield call(datamodelerService.suggest, payload);
}
export function* saveDataModel(payload) {
return yield call(datamodelerService.saveDataModel, payload);
}
export function* deleteDataModel(payload) {
return yield call(datamodelerService.deleteDataModel, payload);
}
export function* getDataModel(payload) {
return yield call(datamodelerService.getDataModel, payload);
}
\ No newline at end of file
import { filePost, GetJSON, PostJSON } from "../util/axios"
export function loadDataModelCatalog() {
return GetJSON("/datamodeler/easyDataModelerCURD/loadDataModelCatalog");
}
export function saveDataModelCatalog(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/saveDataModelCatalog", payload);
}
export function deleteDataModelCatalog(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/deleteDataModelCatalog", payload);
}
//绑定模型和模型目录
export function bindCatalogDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/catalogDataModel", payload);
}
//读取当前模型目录中的模型
export function getCurrentDataModelCatalog(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/getCurrentDataModelCatalog", payload);
}
export function extractExcelContent(payload) {
return filePost("/datamodeler/easyDataModelerDesign/kickStart", payload);
}
//规则
export function constraints() {
return GetJSON("/datamodeler/easyDataModelerConstraint/constraints");
}
//创建初稿
export function draft(payload) {
return PostJSON("/datamodeler/easyDataModelerDesign/draft", payload);
}
//获取支持的数据类型
export function getSupportedDatatypes() {
return GetJSON("/datamodeler/easyDataModelerDesign/getSupportedDatatypes");
}
export function suggest(payload) {
return PostJSON("/datamodeler/easyDataModelerDesign/suggest", payload);
}
//保存模型
export function saveDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerDesign/saveDataModel", payload);
}
export function deleteDataModel(payload) {
return PostJSON("/datamodeler/easyDataModelerCURD/deleteDataModel", payload);
}
export function getDataModel(payload) {
return GetJSON("/datamodeler/easyDataModelerCURD/getDataModel", payload);
}
......@@ -65,19 +65,16 @@ textplain.interceptors.request.use(
const testA = axios.create({
const fileplain = axios.create({
baseURL,
timeout: 5000,
headers:{'Content-Type':'multipart/form-data'},
processData:true,
processData:false,
validateStatus: (status) => {
return true;
}
});
let __source = null;
export const Cancel = function (msg) {
return new Promise(res => __source && __source.cancel(msg));
......@@ -132,11 +129,14 @@ export function Post(url, payload) {
)
}
export function testPost(url, payload) {
export function filePost(url, payload) {
const { fileList = null,} = payload||{};
let formData = new FormData();
formData.append('attachment',fileList)
return testA.post(url, formData, ).then(
(fileList||[]).forEach(file=> {
formData.append('file', file);
});
return fileplain.post(url, formData, ).then(
callback
)
}
\ No newline at end of file
......@@ -86,3 +86,13 @@ export const paginate = function (items, pageNum = 1, pageSize = 10) {
export const IsArr = function (data) {
return data && Object.prototype.toString.call(data) === '[object Array]';
}
export const generateUUID = function() {
let d = new Date().getTime();
let uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
let r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);
});
return uuid;
}
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Alert } from 'antd';
import ImportActionHeader from './ImportActionHeader';
import ImportActionTable from './ImportActionTable';
import ImportActionIndex from './ImportActionIndex';
// import ImportActionIndex from './ImportActionIndex';
const originData = [];
for (let i = 0; i < 20; i++) {
originData.push({
key: i.toString(),
name: `trade_id${i}`,
cnName: `交易流水${i}`,
type: 'varchar',
length: 32,
desc: '流水单号',
nonnull: true,
primaryKey: false,
distributionKey: false,
zone: false,
});
}
import { dispatchLatest } from '../../../../model';
const ImportAction = (props) => {
const { action } = props;
const [ tableData, setTableData ] = useState([...originData]);
const [indexData, setIndexData] = useState([]);
const [fileds, setFileds] = useState([]);
const { action, hints } = props;
useEffect(() =>{
const [ constraints, setConstraints ] = useState([]);
const [ modelerData, setModelerData ] = useState({});
const _fileds = [];
tableData && tableData.forEach(item => {
_fileds.push(item.name||'');
})
setFileds(_fileds);
const mountRef = useRef();
mountRef.current = true;
//数据表结构变化 索引结构也要跟着变化
const _indexData = (indexData||[]).filter(item => {
let exsit = true;
useEffect(() =>{
(item.fileds||[]).forEach(filed => {
if (_fileds.indexOf(filed) ===-1) {
exsit = false;
}
})
if (mountRef.current) {
mountRef.current = false;
return exsit;
dispatchLatest({
type: 'datamodel.getAllConstraints',
callback: data => {
setConstraints(data||[]);
getDraft((data||[]).length>0?data[0]:{});
}
})
}
setIndexData(_indexData);
//eslint-disable-next-line react-hooks/exhaustive-deps
}, [tableData]);
}, []);
const onTableChange = (data) => {
setTableData(data);
const getDraft = (constraint) => {
dispatchLatest({
type: 'datamodel.getDraft',
payload: {
data: {
hints,
modelerModelingConstraint: constraint
}
},
callback: data => {
setModelerData(data||{});
}
})
}
const onIndexChange = (data) => {
setIndexData(data);
const onTableChange = (data) => {
setModelerData({...modelerData, easyDataModelerDataModelAttributes: data});
}
return (
......@@ -72,8 +63,8 @@ const ImportAction = (props) => {
className='mb-3'
/>
}
<ImportActionTable data={tableData} onChange={onTableChange} editable={action!=='detail'} />
<ImportActionIndex data={indexData} fileds={fileds} onChange={onIndexChange} editable={action!=='detail'} />
<ImportActionTable modelerData={modelerData||{}} onChange={onTableChange} editable={action!=='detail'} />
{/* <ImportActionIndex data={indexData} fileds={fileds} onChange={onIndexChange} editable={action!=='detail'} /> */}
</>
);
};
......
......@@ -3,6 +3,8 @@ import { Table, Input, InputNumber, Form, Typography, Radio, Divider, Button, Ch
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper';
import { generateUUID } from '../../../../util';
import { dispatchLatest } from '../../../../model';
const type = 'DragableTableBodyRow';
......@@ -91,17 +93,17 @@ const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) =>
};
const ImportActionTable = (props) => {
const { data, onChange, editable } = props;
const { modelerData, onChange, editable } = props;
const data = modelerData.easyDataModelerDataModelAttributes||[];
const [form] = Form.useForm();
const [editingKey, setEditingKey] = useState('');
const [recommends, setRecommends] = useState([]);
const [suggests, setSuggests] = useState([]);
const isEditing = (record) => record.key === editingKey;
const isEditing = (record) => record.iid === editingKey;
const onAddClick = () => {
//test
const newData = [{key: -1}, ...data];
const newData = [{iid: generateUUID()}, ...data];
onChange && onChange(newData);
edit(newData[0]);
......@@ -111,17 +113,16 @@ const ImportActionTable = (props) => {
form.setFieldsValue({
name: '',
cnName: '',
type: '',
length: 0,
desc: '',
datatype: {},
remark: '',
...record,
});
setEditingKey(record.key);
setEditingKey(record.iid);
};
const remove = (record) => {
const newData = [...data];
const index = newData.findIndex((item) => record.key === item.key);
const index = newData.findIndex((item) => record.iid === item.iid);
newData.splice(index, 1);
onChange && onChange(newData);
}
......@@ -129,7 +130,7 @@ const ImportActionTable = (props) => {
const cancel = () => {
const newData = [...data];
const index = newData.findIndex((item) => editingKey === item.key);
const index = newData.findIndex((item) => editingKey === item.iid);
const item = newData[index];
if (!item.name || item.name==='') {
......@@ -138,82 +139,58 @@ const ImportActionTable = (props) => {
}
setEditingKey('');
setRecommends([]);
setSuggests([]);
};
const save = () => {
const save = async() => {
try {
setRecommends([]);
const _suggests = [
{
name: '建议1'
},
{
name: '建议2'
}
];
setSuggests(_suggests)
if (_suggests.length === 0) {
constraintSave();
}
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
};
const constraintSave = async () => {
const row = await form.validateFields();
//test
row.key = '-1';
const newData = [...data];
const index = newData.findIndex((item) => editingKey === item.key);
const index = newData.findIndex((item) => editingKey === item.iid);
if (index > -1) {
const item = newData[index];
newData.splice(index, 1, { ...item, ...row });
} else {
newData.push(row);
}
onChange && onChange(newData);
setEditingKey('');
setSuggests([]);
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
};
const onValuesChange = (changedValues, allValues) => {
// console.log('changed values', changedValues);
// console.log('all values', allValues);
setRecommends([
{
name: 'trade_id',
cnName: '流水交易',
type: 'varchar',
length: 32,
desc: '流水交易'
const newData = [...data];
const index = newData.findIndex((item) => editingKey === item.iid);
const item = newData[index];
newData.splice(index, 1, { ...item, ...allValues });
dispatchLatest({
type: 'datamodel.suggest',
payload: {
data: { ...modelerData, easyDataModelerDataModelAttributes: newData },
params: {
easyDataModelerDataModelAttributeIid: editingKey
}
},
{
name: 'trade_id',
cnName: '流水交易交易',
type: 'varchar',
length: 32,
desc: '流水单号'
callback: data => {
setSuggests(data||[]);
}
])
})
};
const onRecommendChange = (e) => {
const onSuggestChange = (e) => {
form.setFieldsValue({
...recommends[e.target.value]
...suggests[e.target.value]
});
setRecommends([]);
setSuggests([]);
};
const columns = [
......@@ -237,50 +214,16 @@ const ImportActionTable = (props) => {
},
{
title: '类型',
dataIndex: 'type',
editable: true,
},
{
title: '长度',
dataIndex: 'length',
editable: true,
},
{
title: '描述',
dataIndex: 'desc',
dataIndex: 'datatype',
editable: true,
},
{
title: '非空',
dataIndex: 'nonnull',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
}
},
{
title: '主键',
dataIndex: 'primaryKey',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
}
},
{
title: '分布键',
dataIndex: 'distributionKey',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
render: (datatype, record, index) => {
return datatype.name||'';
}
},
{
title: '分区',
dataIndex: 'zone',
title: '描述',
dataIndex: 'remark',
editable: true,
render: (text, record, index) => {
return text ? '是': '否';
}
},
{
title: '操作',
......@@ -303,7 +246,7 @@ const ImportActionTable = (props) => {
编辑
</Typography.Link>
<Popconfirm disabled={editingKey !== ''} title="删除字段会删除相关的索引,您确定删除吗?" onConfirm={() => remove(record)}>
<a href="">删除</a>
<a disabled={editingKey !== ''} href="">删除</a>
</Popconfirm>
</>
);
......@@ -320,7 +263,7 @@ const ImportActionTable = (props) => {
...col,
onCell: (record) => ({
record,
inputType: (col.dataIndex==='nonnull'||col.dataIndex==='primaryKey'||col.dataIndex==='distributionKey'||col.dataIndex==='zone') ? 'check' : (col.dataIndex==='length'?'number':'text'),
inputType: 'text',
dataIndex: col.dataIndex,
title: col.title,
editing: isEditing(record),
......@@ -371,9 +314,10 @@ const ImportActionTable = (props) => {
moveRow
}
}}
dataSource={data}
dataSource={data||[]}
columns={mergedColumns}
size='small'
rowKey='iid'
rowClassName="editable-row"
pagination={false}
expandable={{
......@@ -384,30 +328,13 @@ const ImportActionTable = (props) => {
{
suggests && suggests.length>0 && (
<>
<Divider orientation="left">建议</Divider>
<div className='mb-3 ml-7'>
{
suggests && suggests.map((suggest, index) => {
return (
<div key={index} className='mt-3'>{suggest.name||''}</div>
)
})
}
</div>
<Button className='mb-3 ml-7' type='primary' onClick={constraintSave}>强制保存</Button>
</>
)
}
{
recommends && recommends.length>0 && (
<>
<Divider orientation="left">智能推荐</Divider>
<Radio.Group onChange={onRecommendChange} className='mb-3 ml-7'>
<Radio.Group onChange={onSuggestChange} className='mb-3 ml-7'>
{
recommends && recommends.map((recommend, index) => {
suggests && suggests.map((suggest, index) => {
return (
<Radio key={index} value={index} className='mt-3' style={{ display: 'block' }}>
{`${recommend.name||''}`}
{`${suggest.name||''}`}
</Radio>
)
})
......@@ -423,7 +350,7 @@ const ImportActionTable = (props) => {
expandIcon: ({ expanded, onExpand, record }) => {
return <></>;
},
rowExpandable: record => (editingKey!==''&&((recommends||[]).length>0||(suggests||[]).length>0)),
rowExpandable: record => (editingKey!==''&&(suggests||[]).length>0),
expandedRowKeys: [editingKey]
}}
/>
......
......@@ -13,18 +13,26 @@ class ImportExcel extends React.Component {
render() {
const { onChange } = this.props;
const uploadProps = {
onRemove: file => {
this.setState(state => {
const index = state.fileList.indexOf(file)
const newFileList = state.fileList.slice()
newFileList.splice(index, 1)
const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice();
newFileList.splice(index, 1);
onChange && onChange(newFileList);
return {
fileList: newFileList,
}
})
},
beforeUpload: file => {
onChange && onChange([file]);
this.setState(state => ({
fileList: [file],
}))
......
......@@ -6,6 +6,8 @@ import ImportExcel from './ImportExcel';
import ImportMetadata from './ImportMetadata';
import ImportAction from './ImportAction';
import { dispatchLatest } from '../../../../model';
const modes = [
{
title: 'Excel导入',
......@@ -30,7 +32,10 @@ class ImportModal extends React.Component {
super();
this.state = {
step: 0,
radioValue: ''
radioValue: '',
excelFiles: [],
hints: [],
confirmLoading: false,
}
}
......@@ -47,14 +52,38 @@ class ImportModal extends React.Component {
}
next = () => {
const { step, radioValue, excelFiles } = this.state;
if (step===1 && radioValue===0) {
if ((excelFiles||[]).length === 0) {
} else {
this.setState({ confirmLoading: true }, () => {
dispatchLatest({
type: 'datamodel.extractExcelContent',
payload: { fileList: excelFiles },
callback: data => {
this.setState({ confirmLoading: false, hints: data||[], step: (step+1) });
}
})
})
}
return;
}
this.setState({
step: (this.state.step+1)
step: (step+1)
})
}
onImportExcelChange = (files) => {
this.setState({ excelFiles: files||[] });
}
render() {
const { visible, onCancel } = this.props;
const { radioValue, step } = this.state;
const { radioValue, step, confirmLoading, hints } = this.state;
return (
<Modal
......@@ -82,6 +111,7 @@ class ImportModal extends React.Component {
<Button
key="1"
type="primary"
loading={confirmLoading}
style={{ display: (step<2)?'':'none' }}
onClick={this.next}
>
......@@ -90,6 +120,7 @@ class ImportModal extends React.Component {
<Button
key="2"
type="primary"
loading={confirmLoading}
style={{ display: (step===2)?'':'none' }}
>
保存
......@@ -114,7 +145,7 @@ class ImportModal extends React.Component {
</>
}
{
step===1 && radioValue===0 && <ImportExcel />
step===1 && radioValue===0 && <ImportExcel onChange={this.onImportExcelChange} />
}
{
step===1 && radioValue===1 && <></>
......@@ -129,7 +160,7 @@ class ImportModal extends React.Component {
step===1 && radioValue===4 && <></>
}
{
step===2 && <ImportAction />
step===2 && <ImportAction hints={hints} />
}
</>
</Modal>
......
......@@ -3,39 +3,7 @@ import { Tooltip, Tree, message, Button } from "antd";
import { PlusOutlined, EditOutlined, SyncOutlined, DeleteOutlined } from '@ant-design/icons';
import UpdateTreeItemModal from './UpdateTreeItemModal';
const _treeData = [
{
title: 'parent 1',
key: '0-0',
children: [
{
title: 'parent 1-0',
key: '0-0-0',
children: [
{
title: 'leaf',
key: '0-0-0-0',
},
{
title: 'leaf',
key: '0-0-0-1',
},
],
},
{
title: 'parent 1-1',
key: '0-0-1',
children: [
{
title: 'sss',
key: '0-0-1-0',
},
],
},
],
},
];
import { dispatchLatest } from '../../../../model';
class ModelTree extends React.Component {
......@@ -43,7 +11,7 @@ class ModelTree extends React.Component {
super();
this.state = {
loading: false,
treeData: _treeData,
treeData: null,
item: null,
visible: false,
type: null
......@@ -59,11 +27,35 @@ class ModelTree extends React.Component {
this.setState({ loading: true }, () => {
this.setState({ loading: false, treeData: _treeData, item: _treeData[0] }, () => {
dispatchLatest({
type: 'datamodel.loadDataModelCatalog',
callback: data => {
data.key = data.id||'';
data.title = data.name||'';
data.children = data.subCatalogs||[];
function recursion(subCatalogs) {
if ((subCatalogs||[]).length===0) return;
(subCatalogs||[]).forEach(catalog=> {
catalog.key = catalog.id||'';
catalog.title = catalog.name||'';
catalog.children = catalog.subCatalogs||[];
recursion(catalog.subCatalogs);
})
}
recursion(data.subCatalogs);
this.setState({ loading: false, treeData: [ data ], item: data }, () => {
if (onSelect) {
onSelect(_treeData[0].key);
onSelect(data.key);
}
});
}
})
})
}
......@@ -105,6 +97,17 @@ class ModelTree extends React.Component {
return;
}
dispatchLatest({
type: 'datamodel.deleteDataModelCatalog',
payload: {
easyDataModelerCatalogId: item.id
},
callback: () => {
message.success('删除目录成功');
this.getTreeData();
}
});
}
onUpdateTreeItemModalOk = () => {
......
import React from 'react'
import { Modal, Form, Input, Radio } from 'antd'
import React, { useState } from 'react';
import { Modal, Form, Input } from 'antd';
class UpdateTreeItemForm extends React.Component {
import { dispatchLatest } from '../../../../model';
constructor(props){
super(props);
this.state = {
itemType: 'sub',
radioDisable: false
}
}
componentDidMount() {
const { type, item } = this.props;
if (type === 'add') {
if (item) {
this.setState({ itemType: 'sub', radioDisable: false });
} else {
this.setState({ itemType: 'root', radioDisable: true })
}
} else {
this.setState({ itemType: 'sub', radioDisable: true });
}
}
onRadioChange = (e) => {
this.setState({ itemType: e.target.value });
}
class UpdateTreeItemForm extends React.Component {
render() {
const { item, type } = this.props;
const { itemType, radioDisable } = this.state;
const { item, type, form } = this.props;
const formItemLayout = {
labelCol: {
......@@ -46,91 +22,90 @@ class UpdateTreeItemForm extends React.Component {
return (
<Form
{...formItemLayout}
form={form}
name="basic"
initialValues={
type!=='add'?{
title: item?item.title:''
name: item?item.name:'',
remark: item?item.remark:'',
}:null
}
>
{
type==='add'&&<Form.Item label="目录类型">
<Radio.Group
onChange={this.onRadioChange}
value={itemType}
disabled={radioDisable}
>
<Radio value='root'>根目录</Radio>
<Radio value='sub'>子目录</Radio>
</Radio.Group>
</Form.Item>
}
<Form.Item
label="名称"
name="title"
name="name"
rules={[{ required: true, message: '请输入名称!' }]}
>
<Input />
</Form.Item>
<Form.Item
label="描述"
name="remark"
rules={[{ required: true, message: '请输入描述!' }]}
>
<Input />
</Form.Item>
</Form>
);
}
}
class UpdateTreeItemModal extends React.Component {
const UpdateTreeItemModal = (props) => {
constructor() {
super();
this.form = React.createRef();
this.state= {
confirmLoading: false
}
}
const { onOk, type, item, onCancel, visible } = props;
const [ confirmLoading, setConfirmLoading ] = useState(false);
const [form] = Form.useForm();
handleOk = () => {
const { onOk, type } = this.props;
const handleOk = async () => {
this.setState({ confirmLoading: true }, () => {
this.form.current.validateFields((err,values) => {
if (!err) {
if (type==='add' && values.itemType==='root') {
this.setState({ confirmLoading: false });
if (onOk) {
onOk();
setConfirmLoading(true);
try {
const values = await form.validateFields();
let payload = null;
if (type === 'add') {
payload = {
...values,
parentId: item.id
};
} else {
payload = {
...item,
...values,
}
} else if (type==='add' && values.itemType==='sub') {
this.setState({ confirmLoading: false });
if (onOk) {
onOk();
}
} else {
this.setState({ confirmLoading: false });
dispatchLatest({
type: 'datamodel.saveDataModelCatalog',
payload: {
data: payload
},
callback: () => {
setConfirmLoading(false);
if (onOk) {
onOk();
}
}
});
} catch (errInfo) {
console.log('Validate Failed:', errInfo);
}
})
})
}
render() {
const { visible, type, item, onCancel } = this.props;
const { confirmLoading } = this.state;
return (
<Modal
confirmLoading={confirmLoading}
visible={visible}
title={type==='add'?"新增目录":"更新目录"}
destroyOnClose
onOk={this.handleOk}
onOk={handleOk}
onCancel={onCancel}
>
<UpdateTreeItemForm ref={this.form} item={item} type={type} />
<UpdateTreeItemForm form={form} item={item} type={type} />
</Modal>
);
}
}
export default UpdateTreeItemModal;
\ No newline at end of file
......@@ -6,6 +6,8 @@ import ModelTable from './Component/ModelTable';
import ImportModal from './Component/ImportModal';
import ExportModal from './Component/ExportModal';
import { dispatchLatest } from '../../../model';
class Model extends React.Component {
constructor() {
......@@ -16,6 +18,18 @@ class Model extends React.Component {
}
}
onTreeSelect = (key) => {
dispatchLatest({
type: 'datamodel.getCurrentDataModelCatalog',
payload: {
easyDataModelerCatalogId: key
},
callback: data => {
console.log('data model', data);
}
})
}
onImportBtnClick = () => {
this.setState({ importModalVisible: true });
}
......@@ -39,7 +53,7 @@ class Model extends React.Component {
<div style={{ backgroundColor: '#fff', height: '100%' }}>
<Row gutter={10} style={{ height: '100%' }}>
<Col span={6}>
<ModelTree />
<ModelTree onSelect={this.onTreeSelect} />
</Col>
<Col span={18}>
<div
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment