Browse Source

数据源设置界面调整

zhuth 7 years ago
parent
commit
e7279b0f62

+ 2 - 2
app/components/chartDesigner/sections/toolbar.jsx

@@ -50,13 +50,13 @@ class Toolbar extends React.Component {
     createFilterLabel = (filter) => {
         let { label, name, operator, operatorLabel, type, using, value1, value2 } = filter;
         let filterLabel;
-        if(type == 'string') {
+        if(type == 'string' || type == 'index') {
             if(operator == 'null') {
                 filterLabel = `${label} ${operatorLabel}`;
             }else {
                 filterLabel = `${label} ${operatorLabel} ${value1}`;
             }
-        }else if(type == 'number') {
+        }else if(type == 'scale') {
             if(operator == 'null') {
                 filterLabel = `${label} ${operatorLabel}`;
             }else if(operator == 'between') {

+ 1 - 1
app/components/common/navigator.jsx

@@ -17,7 +17,7 @@ class Navigator extends React.Component {
             mode="horizontal"
         >     
             <Menu.Item key="mypage">
-                <Link to='/'><Icon type="home" />我的</Link>
+                <Link to='/home'><Icon type="home" />我的</Link>
             </Menu.Item>
             <Menu.Item key="datasource">
                 <Link to='/dataSource'><Icon type="database" />数据源</Link>

+ 80 - 0
app/components/datasource/accessConfig.jsx

@@ -0,0 +1,80 @@
+import React from 'react'
+import { Modal, Form, Row, Col, Input, InputNumber, Select, Icon, Menu, Dropdown } from 'antd'
+const FormItem = Form.Item
+const SelectOption = Select.Option
+const OptionGroup = Select.OptGroup
+const InputGroup = Input.Group
+const SubMenu = Menu.SubMenu
+const MenuItem = Menu.Item
+const MenuItemGroup = Menu.ItemGroup;
+import { connect } from 'dva'
+import dataSource from '../../models/dataSource'
+
+const DataSourceAccessConfig = ({ dataSource, dispatch }) => {
+
+    const formItemLayout = {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 },
+    };
+
+    const dataSourceLinkMenu = (
+        <Menu
+            className='menu-datasource-link'
+            onClick={() => {
+                dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: '1111adddd' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: '1234' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: {
+                    key: 'oracle',
+                    label: 'ORACLE'
+                } });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: 'orcl' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: 'UAS' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: 'select!#%*(' });
+            }}
+        >
+            <MenuItem>1111</MenuItem>
+            <MenuItem>2222</MenuItem>
+            <MenuItem>33333</MenuItem>
+            <MenuItem>44</MenuItem>
+        </Menu>
+    );
+
+    return (
+        <Form size='small'>
+            <FormItem label='数据源名称' {...formItemLayout}>
+                <Input
+                    value={dataSource.newOne.name}
+                    onChange={(e) => { dispatch({ type: 'dataSource/setNewModelField', name: 'name', value: e.target.value }) }}>
+                </Input>
+            </FormItem>
+            <FormItem label='自定义标签' {...formItemLayout}>
+                <Select
+                    mode="tags"
+                    placeholder='多个标签使用逗号或空格分隔'
+                    tokenSeparators={[',', ' ']}
+                    value={dataSource.newOne.tags}
+                    dropdownStyle={{display: 'none'}}
+                    onChange={(value) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'tags', value: value });
+                    }}
+                >
+                </Select>
+            </FormItem>
+            <FormItem className='textarea-desc' label='说明' {...formItemLayout}>
+                <Input.TextArea
+                    autosize={{ minRows: 2, maxRows: 2 }}
+                    value={dataSource.newOne.description}
+                    onChange={(e) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'description', value: e.target.value });
+                    }}
+                />
+            </FormItem>
+        </Form>
+    );
+}
+
+function mapStateToProps({ present: {dataSource} }) {
+    return { dataSource }
+}
+
+export default connect(mapStateToProps)(DataSourceAccessConfig);

+ 178 - 0
app/components/datasource/baseConfig.jsx

@@ -0,0 +1,178 @@
+import React from 'react'
+import { Button, Form, Row, Col, Input, InputNumber, Select, Icon, Menu, Dropdown, Divider } from 'antd'
+const FormItem = Form.Item
+const SelectOption = Select.Option
+const OptionGroup = Select.OptGroup
+const InputGroup = Input.Group
+const SubMenu = Menu.SubMenu
+const MenuItem = Menu.Item
+const MenuItemGroup = Menu.ItemGroup;
+import { connect } from 'dva'
+import dataSource from '../../models/dataSource'
+
+const DataSourceBaseConfig = ({ dataSource, dispatch }) => {
+
+    const formItemLayout = {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 },
+    };
+
+    const dataSourceLinkMenu = (
+        <Menu
+            className='menu-datasource-link'
+            onClick={() => {
+                dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: '1111adddd' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: '1234' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: {
+                    key: 'oracle',
+                    label: 'ORACLE'
+                } });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: 'orcl' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: 'UAS' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: 'select!#%*(' });
+            }}
+        >
+            <MenuItem>1111</MenuItem>
+            <MenuItem>2222</MenuItem>
+            <MenuItem>33333</MenuItem>
+            <MenuItem>44</MenuItem>
+        </Menu>
+    );
+
+    return (
+        <Form className='form-base' size='small'>
+            <Divider orientation="left">基本配置</Divider>
+            <FormItem label='数据源名称' {...formItemLayout}>
+                <Input
+                    value={dataSource.newOne.name}
+                    onChange={(e) => { dispatch({ type: 'dataSource/setNewModelField', name: 'name', value: e.target.value }) }}>
+                </Input>
+            </FormItem>
+            <Divider orientation="left">连接配置</Divider>
+            <div className='links'>
+                <Dropdown trigger={['click']} overlay={dataSourceLinkMenu}>
+                    <div>使用已存在的数据连接 <Icon type="down" /></div>
+                </Dropdown>
+            </div>
+            <FormItem label='数据库类型' {...formItemLayout}>
+                <Select
+                    value={dataSource.newOne.type}
+                    labelInValue={true}
+                    onChange={(value) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: value} );
+                    }}
+                >
+                    <SelectOption value='oracle'>
+                        ORACLE
+                    </SelectOption>
+                    <SelectOption value='mysql'>
+                        MYSQL
+                    </SelectOption>
+                    <SelectOption value='sqlserver'>
+                        SQLSERVER
+                    </SelectOption>
+                    <SelectOption value='sqlite'>
+                        SQLITE
+                    </SelectOption>
+                </Select>
+            </FormItem>
+            <Row>
+                <Col span={19}>
+                    <FormItem label='数据库地址' {...{
+                        labelCol: { span: 5 },
+                        wrapperCol: { span: 19 }
+                    }}>
+                        <Input
+                            value={dataSource.newOne.address}
+                            onChange={(e) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: e.target.value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+                <Col span={5}>
+                    <FormItem className='input-port' label='端口' {...{
+                        labelCol: { span: 12 },
+                        wrapperCol: { span: 12 }
+                    }}>
+                        <InputNumber
+                            value={dataSource.newOne.port}
+                            onChange={(value) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+            </Row>
+            <FormItem label='数据库名' {...formItemLayout}>
+                <Input
+                    value={dataSource.newOne.dbName}
+                    onChange={(e) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: e.target.value });
+                    }}
+                />
+            </FormItem>
+            <Row>
+                <Col span={12}>
+                    <FormItem label='用户名' {...{
+                        labelCol: { span: 8 },
+                        wrapperCol: { span: 16 }
+                    }}>
+                        <Input
+                            value={dataSource.newOne.userName}
+                            onChange={(e) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: e.target.value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+                <Col span={12}>
+                    <FormItem label='密码' {...{
+                        labelCol: { span: 8 },
+                        wrapperCol: { span: 16 }
+                    }}>
+                        <Input
+                            type='password'
+                            value={dataSource.newOne.password}
+                            onChange={(e) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: e.target.value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+            </Row>
+            <div className='buttons'>
+                <Button size='small'>测试连接</Button>
+            </div>
+            <Divider orientation="left">其他配置</Divider>
+            <FormItem label='标签' {...formItemLayout}>
+                <Select
+                    mode="tags"
+                    placeholder='多个标签使用逗号或空格分隔'
+                    tokenSeparators={[',', ' ']}
+                    value={dataSource.newOne.tags}
+                    dropdownStyle={{display: 'none'}}
+                    onChange={(value) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'tags', value: value });
+                    }}
+                >
+                </Select>
+            </FormItem>
+            <FormItem className='textarea-desc' label='说明' {...formItemLayout}>
+                <Input.TextArea
+                    autosize={{ minRows: 2, maxRows: 5 }}
+                    value={dataSource.newOne.description}
+                    onChange={(e) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'description', value: e.target.value });
+                    }}
+                />
+            </FormItem>
+        </Form>
+    );
+}
+
+function mapStateToProps({ present: {dataSource} }) {
+    return { dataSource }
+}
+
+export default connect(mapStateToProps)(DataSourceBaseConfig);

+ 121 - 0
app/components/datasource/columnConfig.jsx

@@ -0,0 +1,121 @@
+import React from 'react'
+import { Modal, Form, Row, Col, Input, Button, Select, Icon, Menu, Dropdown, Table, Checkbox, Switch, Divider } from 'antd'
+const FormItem = Form.Item
+const SelectOption = Select.Option
+const OptionGroup = Select.OptGroup
+const InputGroup = Input.Group
+const SubMenu = Menu.SubMenu
+const MenuItem = Menu.Item
+const MenuItemGroup = Menu.ItemGroup;
+import { connect } from 'dva'
+import dataSource from '../../models/dataSource'
+
+const DataSourceColumnConfig = ({ dataSource, dispatch }) => {
+
+    const formItemLayout = {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 },
+    };
+
+    const dataSourceLinkMenu = (
+        <Menu
+            className='menu-datasource-link'
+            onClick={() => {
+                dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: '1111adddd' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: '1234' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: {
+                    key: 'oracle',
+                    label: 'ORACLE'
+                } });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: 'orcl' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: 'UAS' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: 'select!#%*(' });
+            }}
+        >
+            <MenuItem>1111</MenuItem>
+            <MenuItem>2222</MenuItem>
+            <MenuItem>33333</MenuItem>
+            <MenuItem>44</MenuItem>
+        </Menu>
+    );
+
+    const columns = [{
+        title: <div><Checkbox
+            style={{ margin: '0 8px 0 0' }}
+            indeterminate={dataSource.newOne.columns?(dataSource.newOne.columns.filter(c=>c.using).length>0&&dataSource.newOne.columns.filter(c=>c.using).length<(dataSource.newOne.columns.length)):false}
+            indeterminate={false}
+        />启用</div>,
+        dataIndex: 'using',
+        key: 'using',
+        render: () => <Checkbox
+            
+        />
+    }, {
+        title: '列名',
+        dataIndex: 'name',
+        key: 'name',
+    }, {
+        title: '别名',
+        dataIndex: 'alias',
+        key: 'alias',
+    }, {
+        title: '类型',
+        dataIndex: 'type',
+        key: 'type',
+    }, {
+        title: '允许分组',
+        dataIndex: 'groupable',
+        key: 'groupable',
+        render: () => <Switch />
+    }, {
+        title: '允许分段',
+        dataIndex: 'bucketizable',
+        key: 'bucketizable',
+        render: () => <Switch />
+    }, {
+        title: '备注',
+        dataIndex: 'description',
+        key: 'description'
+    }];
+
+    return (
+        <div>
+            <Form size='small'>
+                <Divider orientation="left">数据对象</Divider>
+                <FormItem className='textarea-target'>
+                    <Input.TextArea
+                        placeholder='输入表名或查询SQL'
+                        autosize={{ minRows: 3 }}
+                    />
+                </FormItem>
+                <div className='buttons'>
+                    <Button onClick={() => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'columns', value: [
+                            { key: 0, name: 'rrrrrr', using: false },
+                            { key: 1, name: 'ttttt', using: true },
+                            { key: 2, name: 'ssssss', using: true },
+                            { key: 3, name: 'yyyyyy', using: true },
+                            { key: 4, name: 'uuuuuuu', using: true },
+                            { key: 5, name: 'ggggg', using: true }
+                        ] });
+                    }}>连接</Button>
+                </div>
+            </Form>
+            <Divider orientation="left">结果集数据列</Divider>
+            <Table
+                className='table-columnconfig'
+                dataSource={dataSource.newOne.columns}
+                columns={columns}
+                locale={{
+                    emptyText: '未连接到数据对象'
+                }}
+            />
+        </div>
+    );
+}
+
+function mapStateToProps({ present: {dataSource} }) {
+    return { dataSource }
+}
+
+export default connect(mapStateToProps)(DataSourceColumnConfig);

+ 147 - 0
app/components/datasource/connectConfig.jsx

@@ -0,0 +1,147 @@
+import React from 'react'
+import { Modal, Form, Row, Col, Input, InputNumber, Select, Icon, Menu, Dropdown } from 'antd'
+const FormItem = Form.Item
+const SelectOption = Select.Option
+const OptionGroup = Select.OptGroup
+const InputGroup = Input.Group
+const SubMenu = Menu.SubMenu
+const MenuItem = Menu.Item
+const MenuItemGroup = Menu.ItemGroup;
+import { connect } from 'dva'
+import dataSource from '../../models/dataSource'
+
+const DataSourceConnectConfig = ({ dataSource, dispatch }) => {
+
+    const formItemLayout = {
+        labelCol: { span: 4 },
+        wrapperCol: { span: 20 },
+    };
+
+    const dataSourceLinkMenu = (
+        <Menu
+            className='menu-datasource-link'
+            onClick={() => {
+                dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: '1111adddd' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: '1234' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: {
+                    key: 'oracle',
+                    label: 'ORACLE'
+                } });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: 'orcl' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: 'UAS' });
+                dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: 'select!#%*(' });
+            }}
+        >
+            <MenuItem>1111</MenuItem>
+            <MenuItem>2222</MenuItem>
+            <MenuItem>33333</MenuItem>
+            <MenuItem>44</MenuItem>
+        </Menu>
+    );
+
+    return (
+        <Form size='small'>
+            <Row>
+                <Col span={19}>
+                    <FormItem label='数据库地址' {...{
+                        labelCol: { span: 5 },
+                        wrapperCol: { span: 19 }
+                    }}>
+                        <Input
+                            value={dataSource.newOne.address}
+                            onChange={(e) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: e.target.value });
+                            }}
+                            prefix={
+                                <Dropdown
+                                    trigger={['click']}
+                                    overlay={dataSourceLinkMenu}
+                                >
+                                    <div style={{cursor: 'pointer'}}><Icon type='down' /></div>
+                                </Dropdown>
+                            }
+                        />
+                    </FormItem>
+                </Col>
+                <Col span={5}>
+                    <FormItem className='input-port' label='端口' {...{
+                        labelCol: { span: 12 },
+                        wrapperCol: { span: 12 }
+                    }}>
+                        <InputNumber
+                            value={dataSource.newOne.port}
+                            onChange={(value) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+            </Row>
+            <FormItem label='数据库类型' {...formItemLayout}>
+                <Select
+                    value={dataSource.newOne.type}
+                    labelInValue={true}
+                    onChange={(value) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: value} );
+                    }}
+                >
+                    <SelectOption value='oracle'>
+                        ORACLE
+                    </SelectOption>
+                    <SelectOption value='mysql'>
+                        MYSQL
+                    </SelectOption>
+                    <SelectOption value='sqlserver'>
+                        SQLSERVER
+                    </SelectOption>
+                    <SelectOption value='sqlite'>
+                        SQLITE
+                    </SelectOption>
+                </Select>
+            </FormItem>
+            <FormItem label='数据库名' {...formItemLayout}>
+                <Input
+                    value={dataSource.newOne.dbName}
+                    onChange={(e) => {
+                        dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: e.target.value });
+                    }}
+                />
+            </FormItem>
+            <Row>
+                <Col span={12}>
+                    <FormItem label='用户名' {...{
+                        labelCol: { span: 8 },
+                        wrapperCol: { span: 16 }
+                    }}>
+                        <Input
+                            value={dataSource.newOne.userName}
+                            onChange={(e) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: e.target.value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+                <Col span={12}>
+                    <FormItem label='密码' {...{
+                        labelCol: { span: 8 },
+                        wrapperCol: { span: 16 }
+                    }}>
+                        <Input
+                            type='password'
+                            value={dataSource.newOne.password}
+                            onChange={(e) => {
+                                dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: e.target.value });
+                            }}
+                        />
+                    </FormItem>
+                </Col>
+            </Row>
+        </Form>
+    );
+}
+
+function mapStateToProps({ present: {dataSource} }) {
+    return { dataSource }
+}
+
+export default connect(mapStateToProps)(DataSourceConnectConfig);

+ 72 - 0
app/components/datasource/createBox.jsx

@@ -0,0 +1,72 @@
+import React from 'react'
+import { Steps, Button } from 'antd'
+const { Step } = Steps
+import { connect } from 'dva'
+import dataSource from '../../models/dataSource'
+
+class CreateBox extends React.Component {
+    constructor(props) {
+        super(props);
+        this.state = {
+            current: 0
+        }
+    };
+
+    next() {
+        const current = this.state.current + 1;
+        this.setState({ current });
+    }
+
+    prev() {
+        const current = this.state.current - 1;
+        this.setState({ current });
+    }
+
+    render() {
+        const { current } = this.state;
+
+        const steps = [{
+            title: 'First',
+            content: 'First-content',
+        }, {
+            title: 'Second',
+            content: 'Second-content',
+        }, {
+            title: 'Last',
+            content: 'Last-content',
+        }];
+
+        return (
+            <div>
+                <Steps current={current}>
+                    {steps.map(item => <Step key={item.title} title={item.title} />)}
+                </Steps>
+                <div className="steps-content">{steps[current].content}</div>
+                <div className="steps-action">
+                    {
+                        current < steps.length - 1
+                        && <Button type="primary" onClick={() => this.next()}>Next</Button>
+                    }
+                    {
+                        current === steps.length - 1
+                        && <Button type="primary" onClick={() => message.success('Processing complete!')}>Done</Button>
+                    }
+                    {
+                        current > 0
+                        && (
+                            <Button style={{ marginLeft: 8 }} onClick={() => this.prev()}>
+                                Previous
+            </Button>
+                        )
+                    }
+                </div>
+            </div>
+        );
+    }
+}
+
+function mapStateToProps({present: {dataSource}}) {
+    return { dataSource }
+}
+
+export default connect(mapStateToProps)(CreateBox)

+ 3 - 3
app/components/datasource/dataSource.less

@@ -91,9 +91,9 @@
 }
 
 .newdatasource-box {
-    top: 80px;
-    height: 512px;
-    width: 600px !important;
+    top: 0px;
+    height: 90%;
+    width: 90% !important;
     .ant-modal-content {
         height: 100%;
         .ant-modal-body {

+ 123 - 117
app/components/datasource/dataSourceBox.jsx

@@ -57,137 +57,143 @@ const DataSourceBox = ({operation, dispatch, dataSource, visibleBox, hideBox, fo
             maskClosable={false}
             destroyOnClose={true}
         >
-            <Form size='small'>
-                <FormItem label='数据源名称' {...formItemLayout}>
-                    <Input
-                        value={dataSource.newOne.name}
-                        onChange={(e) => { dispatch({ type: 'dataSource/setNewModelField', name: 'name', value: e.target.value }) }}>
-                    </Input>
-                </FormItem>
-                <Row>
-                    <Col span={19}>
-                        <FormItem label='数据库地址' {...{
-                            labelCol: { span: 5 },
-                            wrapperCol: { span: 19 }
-                        }}>
+            <Row>
+                <Col span={12}>
+                    <Form size='small'>
+                        <FormItem label='数据源名称' {...formItemLayout}>
                             <Input
-                                value={dataSource.newOne.address}
-                                onChange={(e) => {
-                                    dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: e.target.value });
-                                }}
-                                prefix={
-                                    <Dropdown
-                                        trigger={['click']}
-                                        overlay={dataSourceLinkMenu}
-                                    >
-                                        <div style={{cursor: 'pointer'}}><Icon type='down' /></div>
-                                    </Dropdown>
-                                }
-                            />
+                                value={dataSource.newOne.name}
+                                onChange={(e) => { dispatch({ type: 'dataSource/setNewModelField', name: 'name', value: e.target.value }) }}>
+                            </Input>
                         </FormItem>
-                    </Col>
-                    <Col span={5}>
-                        <FormItem className='input-port' label='端口' {...{
-                            labelCol: { span: 12 },
-                            wrapperCol: { span: 12 }
-                        }}>
-                            <InputNumber
-                                value={dataSource.newOne.port}
+                        <Row>
+                            <Col span={19}>
+                                <FormItem label='数据库地址' {...{
+                                    labelCol: { span: 5 },
+                                    wrapperCol: { span: 19 }
+                                }}>
+                                    <Input
+                                        value={dataSource.newOne.address}
+                                        onChange={(e) => {
+                                            dispatch({ type: 'dataSource/setNewModelField', name: 'address', value: e.target.value });
+                                        }}
+                                        prefix={
+                                            <Dropdown
+                                                trigger={['click']}
+                                                overlay={dataSourceLinkMenu}
+                                            >
+                                                <div style={{cursor: 'pointer'}}><Icon type='down' /></div>
+                                            </Dropdown>
+                                        }
+                                    />
+                                </FormItem>
+                            </Col>
+                            <Col span={5}>
+                                <FormItem className='input-port' label='端口' {...{
+                                    labelCol: { span: 12 },
+                                    wrapperCol: { span: 12 }
+                                }}>
+                                    <InputNumber
+                                        value={dataSource.newOne.port}
+                                        onChange={(value) => {
+                                            dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: value });
+                                        }}
+                                    />
+                                </FormItem>
+                            </Col>
+                        </Row>
+                        <FormItem label='数据库类型' {...formItemLayout}>
+                            <Select
+                                value={dataSource.newOne.type}
+                                labelInValue={true}
                                 onChange={(value) => {
-                                    dispatch({ type: 'dataSource/setNewModelField', name: 'port', value: value });
+                                    dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: value} );
                                 }}
-                            />
+                            >
+                                <SelectOption value='oracle'>
+                                    ORACLE
+                                </SelectOption>
+                                <SelectOption value='mysql'>
+                                    MYSQL
+                                </SelectOption>
+                                <SelectOption value='sqlserver'>
+                                    SQLSERVER
+                                </SelectOption>
+                                <SelectOption value='sqlite'>
+                                    SQLITE
+                                </SelectOption>
+                            </Select>
                         </FormItem>
-                    </Col>
-                </Row>
-                <FormItem label='数据库类型' {...formItemLayout}>
-                    <Select
-                        value={dataSource.newOne.type}
-                        labelInValue={true}
-                        onChange={(value) => {
-                            dispatch({ type: 'dataSource/setNewModelField', name: 'type', value: value} );
-                        }}
-                    >
-                        <SelectOption value='oracle'>
-                            ORACLE
-                        </SelectOption>
-                        <SelectOption value='mysql'>
-                            MYSQL
-                        </SelectOption>
-                        <SelectOption value='sqlserver'>
-                            SQLSERVER
-                        </SelectOption>
-                        <SelectOption value='sqlite'>
-                            SQLITE
-                        </SelectOption>
-                    </Select>
-                </FormItem>
-                <FormItem label='数据库名' {...formItemLayout}>
-                    <Input
-                        value={dataSource.newOne.dbName}
-                        onChange={(e) => {
-                            dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: e.target.value });
-                        }}
-                    />
-                </FormItem>
-                <Row>
-                    <Col span={12}>
-                        <FormItem label='用户名' {...{
-                            labelCol: { span: 8 },
-                            wrapperCol: { span: 16 }
-                        }}>
+                        <FormItem label='数据库名' {...formItemLayout}>
                             <Input
-                                value={dataSource.newOne.userName}
+                                value={dataSource.newOne.dbName}
                                 onChange={(e) => {
-                                    dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: e.target.value });
+                                    dispatch({ type: 'dataSource/setNewModelField', name: 'dbName', value: e.target.value });
                                 }}
                             />
                         </FormItem>
-                    </Col>
-                    <Col span={12}>
-                        <FormItem label='密码' {...{
-                            labelCol: { span: 8 },
-                            wrapperCol: { span: 16 }
-                        }}>
-                            <Input
-                                type='password'
-                                value={dataSource.newOne.password}
+                        <Row>
+                            <Col span={12}>
+                                <FormItem label='用户名' {...{
+                                    labelCol: { span: 8 },
+                                    wrapperCol: { span: 16 }
+                                }}>
+                                    <Input
+                                        value={dataSource.newOne.userName}
+                                        onChange={(e) => {
+                                            dispatch({ type: 'dataSource/setNewModelField', name: 'userName', value: e.target.value });
+                                        }}
+                                    />
+                                </FormItem>
+                            </Col>
+                            <Col span={12}>
+                                <FormItem label='密码' {...{
+                                    labelCol: { span: 8 },
+                                    wrapperCol: { span: 16 }
+                                }}>
+                                    <Input
+                                        type='password'
+                                        value={dataSource.newOne.password}
+                                        onChange={(e) => {
+                                            dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: e.target.value });
+                                        }}
+                                    />
+                                </FormItem>
+                            </Col>
+                        </Row>
+                        <FormItem className='textarea-target' label='加载对象' {...formItemLayout}>
+                            <Input.TextArea
+                                placeholder='输入表名或查询SQL'
+                                autosize={{ minRows: 3 }}
+                            />
+                        </FormItem>
+                        <FormItem label='自定义标签' {...formItemLayout}>
+                            <Select
+                                mode="tags"
+                                placeholder='多个标签使用逗号或空格分隔'
+                                tokenSeparators={[',', ' ']}
+                                value={dataSource.newOne.tags}
+                                dropdownStyle={{display: 'none'}}
+                                onChange={(value) => {
+                                    dispatch({ type: 'dataSource/setNewModelField', name: 'tags', value: value });
+                                }}
+                            >
+                            </Select>
+                        </FormItem>
+                        <FormItem className='textarea-desc' label='说明' {...formItemLayout}>
+                            <Input.TextArea
+                                autosize={{ minRows: 2, maxRows: 2 }}
+                                value={dataSource.newOne.description}
                                 onChange={(e) => {
-                                    dispatch({ type: 'dataSource/setNewModelField', name: 'password', value: e.target.value });
+                                    dispatch({ type: 'dataSource/setNewModelField', name: 'description', value: e.target.value });
                                 }}
                             />
                         </FormItem>
-                    </Col>
-                </Row>
-                <FormItem className='textarea-target' label='加载对象' {...formItemLayout}>
-                    <Input.TextArea
-                        placeholder='输入表名或查询SQL'
-                        autosize={{ minRows: 3 }}
-                    />
-                </FormItem>
-                <FormItem label='自定义标签' {...formItemLayout}>
-                    <Select
-                        mode="tags"
-                        placeholder='多个标签使用逗号或空格分隔'
-                        tokenSeparators={[',', ' ']}
-                        value={dataSource.newOne.tags}
-                        dropdownStyle={{display: 'none'}}
-                        onChange={(value) => {
-                            dispatch({ type: 'dataSource/setNewModelField', name: 'tags', value: value });
-                        }}
-                    >
-                    </Select>
-                </FormItem>
-                <FormItem className='textarea-desc' label='说明' {...formItemLayout}>
-                    <Input.TextArea
-                        autosize={{ minRows: 2, maxRows: 2 }}
-                        value={dataSource.newOne.description}
-                        onChange={(e) => {
-                            dispatch({ type: 'dataSource/setNewModelField', name: 'description', value: e.target.value });
-                        }}
-                    />
-                </FormItem>
-            </Form>
+                    </Form>
+                </Col>
+                <Col span={12}>
+                </Col>
+            </Row>
         </Modal>
     )
 }

+ 74 - 0
app/components/datasource/dataSourceDetail.jsx

@@ -0,0 +1,74 @@
+import React from 'react'
+import { Layout, Steps, Button } from 'antd'
+const { Header, Content } = Layout
+const Step = Steps.Step
+import { Link } from 'react-router-dom'
+import BaseConfig from './baseConfig'
+import ConnectConfig from './connectConfig'
+import ColumnConfig from './columnConfig'
+import AccessConfig from './accessConfig'
+import './dataSourceDetail.less'
+
+class DataSourceDetail extends React.Component {
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            current: 0
+        }
+    }
+
+    next() {
+        const current = this.state.current + 1;
+        this.setState({ current });
+    }
+
+    prev() {
+        const current = this.state.current - 1;
+        this.setState({ current });
+    }
+
+    render() {
+        const { current } = this.state;
+        const steps = [{
+            title: '属性配置',
+            content: <BaseConfig />
+        }, {
+            title: '数据列配置',
+            content: <ColumnConfig />
+        }, {
+            title: '权限配置',
+            content: <AccessConfig />
+        }];
+        return (
+            <Layout className='layout-datasource-detail'>
+                <Content className='content'>
+                    <Steps className='steps-body' current={current}>
+                        {steps.map(item => <Step key={item.title} title={item.title} />)}
+                    </Steps>
+                    <div className="steps-content">
+                        {steps[current].content}
+                    </div>
+                    <div className="steps-action">
+                        {
+                            current > 0 && (
+                            <Button onClick={() => this.prev()}>
+                                上一步
+                            </Button>)
+                        }
+                        {
+                            current < steps.length - 1
+                            && <Button type="primary" onClick={() => this.next()}>下一步</Button>
+                        }
+                        {
+                            current === steps.length - 1
+                            && <Button type="primary" onClick={() => message.success('Processing complete!')}>完成</Button>
+                        }
+                    </div>
+                </Content>
+            </Layout>
+        )
+    }
+}
+
+export default DataSourceDetail;

+ 55 - 0
app/components/datasource/dataSourceDetail.less

@@ -0,0 +1,55 @@
+.layout-datasource-detail {
+    .content {
+        padding: 10px;
+        .steps-body {
+            padding: 0 20%;
+        }
+        .steps-content {
+            padding: 10px 0;
+            .ant-divider {
+                margin: 10px 0;
+                .ant-divider-inner-text {
+                    font-weight: bold;
+                }
+            }
+            .ant-form {
+                .buttons {
+                    float: right;
+                    margin-top: 4px;
+                    button {
+                        margin-left: 4px;
+                    }
+                }
+            }
+            .form-base {
+                .links {
+                    display: flex;
+                    justify-content: flex-end;
+                    .ant-dropdown-trigger {
+                        margin-right: 4px;
+                        color: rgb(24, 144, 255);
+                        height: 32px;
+                        line-height: 2.2;
+                    }
+                }
+                .ant-input-number > .ant-input-number-handler-wrap {
+                    display: none;
+                }
+                textarea {
+                    margin-top: 4px;
+                }
+            }
+            .table-columnconfig {
+                .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
+                    padding: 10px 16px;
+                }
+            }
+        }
+        .steps-action {
+            float: right;
+            button {
+                margin-left: 8px;
+            }
+        }
+    }
+}

+ 23 - 11
app/components/datasource/datasource.jsx

@@ -1,10 +1,11 @@
 import React from 'react'
-import { Tabs, Input, Button, Table, Icon, Tag, Menu, Dropdown } from 'antd'
+import { Tabs, Input, Button, Table, Icon, Tag, Menu, Dropdown, Modal } from 'antd'
 const { TabPane } = Tabs
 const { Search } = Input
 import { connect } from 'dva'
 import { Link } from 'react-router-dom'
 import DataSourceBox from './dataSourceBox'
+import CreateBox from './createBox'
 import dataSource from '../../models/dataSource'
 import './dataSource.less'
 
@@ -13,6 +14,7 @@ class DataSource extends React.Component {
         super(props);
         this.state = {
             operation: 'create', // 打开数据编辑界面的类型
+            visibleCreateBox: false,
             visibleBox: false, // 数据编辑界面显示标识
             selectedCode: -1, // 当前选中的table行code
             filterDropdownVisible: false,
@@ -20,6 +22,12 @@ class DataSource extends React.Component {
         }
     };
 
+    showCreateBox = () => {
+        this.setState({
+            visibleCreateBox: true
+        });
+    }
+
     showDataSourceBox = (o) => {
         this.setState({
             operation: o,
@@ -53,7 +61,6 @@ class DataSource extends React.Component {
         const { dataSource, dispatch } = this.props;
         const { search, visibleBox, operation, selectedCode } = this.state;
         
-        console.log(dataSource.list);
         const moreOperatingMenu = (
             <Menu className='operationmenu'>
                 <Menu.Item
@@ -191,19 +198,24 @@ class DataSource extends React.Component {
                             placeholder="请输入关键字"
                             onSearch={value => console.log(value)}
                         />
-                        <Button onClick={() => {
-                            dispatch({ type: 'dataSource/resetNewModel' });
-                            this.showDataSourceBox('create')}
-                        }>
-                            {/* <Link to='./'> */}
-                                <Icon type="plus" />添加数据源
-                            {/* </Link> */}
+                        <Button>
+                            <Link to='/dataSource/111'><Icon type="plus" />添加数据源</Link>
                         </Button>
                         <DataSourceBox operation={operation} visibleBox={visibleBox} hideBox={this.hideBox} />
+                        <Modal
+                            title='添加数据源'
+                            maskClosable={false}
+                            destroyOnClose={true}
+                            visible={this.state.visibleCreateBox}
+                            onOk={() => { this.setState({ visibleCreateBox: false }) }}
+                            onCancel={() => { this.setState({ visibleCreateBox: false }) }}
+                        >
+                            <CreateBox />
+                        </Modal>
                     </div>
                 }
             >
-                <TabPane className='datasource-tab public-datasource' tab="公共数据源" key="1" >
+                <TabPane className='datasource-tab public-datasource' tab="数据源" key="1" >
                     <Table
                         className='datasource-table public-datasource-table'
                         columns={columns}
@@ -219,7 +231,7 @@ class DataSource extends React.Component {
                         }}
                     />
                 </TabPane>
-                <TabPane className='datasource-tab my-datasource' tab="我的数据源" key="2" >
+                <TabPane className='datasource-tab my-datasource' tab="数据库连接" key="2" >
                     <Table
                         className='datasource-table my-datasource-table'
                         columns={columns}

+ 8 - 3
app/models/chartDesigner.js

@@ -1,6 +1,7 @@
+import { routerRedux } from 'dva/router'
 import * as service from '../services/chartDesigner'
 import { delay } from '../utils/baseUtils'
-import URLS from '../constants/url';
+import URLS from '../constants/url'
 
 export default {
     namespace: 'chartDesigner',
@@ -159,12 +160,16 @@ export default {
                 },
             });
         },
+        * redirect ({ payload }, { put }) {
+            yield put(routerRedux.push('/'));
+        },
     },
     subscriptions: {
         setup({ dispatch, history }) {
           return history.listen(({ pathname, query }) => {
-            if (pathname === '/users') {
-              dispatch({ type: 'fetch', payload: query });
+            if (pathname === '/home') {
+                console.log(111);
+                dispatch({ type: 'redirect'});
             }
           });
         },

+ 1 - 1
app/models/dataSource.js

@@ -16,7 +16,7 @@ export default {
                     type: {key: 'oracle', label: 'ORACLE'},
                     address: '2',
                     port: '3',
-                    table: ['aa', 'b'],
+                    target: 'select * from employee',
                     creator: 'zhuth',
                     createTime: new Date(),
                     userName: '2222',

+ 7 - 8
app/routes/mainLayout.js

@@ -1,12 +1,12 @@
-import React from 'react';
-import { Layout, Menu, Tabs } from 'antd';
-import { Route, Switch } from 'dva/router';
-const { Header, Content } = Layout;
+import React from 'react'
+import { Layout, Menu, Tabs } from 'antd'
+import { Route, Switch } from 'dva/router'
+const { Header, Content } = Layout
 import Navigator from '../components/common/navigator'
 import Welcome from '../components/myPage/welcome'
 import ChartDesigner from '../components/chartDesigner/layout'
 import DataSource from '../components/datasource/dataSource'
-import DataColumn from '../components/datasource/dataColumn'
+import DataSourceDetail from '../components/datasource/dataSourceDetail'
 
 import './mainLayout.less';
 
@@ -19,9 +19,8 @@ const MainLayout = (history) => {
             <Content className='main-content'>
                 <Switch>
                     <Route exact path='/' component={Welcome}/>
-                    <Route path='/chartDesigner' component={ChartDesigner}/>
-                    <Route path='/dataSource' component={DataSource}/>
-                    <Route path='/dataSourceDetail' component={DataSource}/>
+                    <Route exact path='/dataSource' component={DataSource}/>
+                    <Route path='/dataSource/:code' component={DataSourceDetail}/>
                 </Switch>
             </Content>
         </Layout>

+ 5 - 2
app/routes/mainLayout.less

@@ -20,8 +20,11 @@ html,body,#root{
     }
     .main-content {
         height: 100%;
-        margin: 0 10%;
+        padding: 0 10%;
         background-color: white;
-        padding: 5px;
+        overflow: auto;
     }
 }
+.ant-input-number {
+    width: 100% !important;
+}

+ 5 - 5
app/routes/router.js

@@ -1,10 +1,10 @@
-import React from 'react';
+import React from 'react'
 import { LocaleProvider, Layout,  } from 'antd'
-import { Router, Route, Switch } from 'dva/router';
-import MainLayout from './mainLayout';
-import ChartDesigner from '../components/chartDesigner/layout';
+import { Router, Route, Switch } from 'dva/router'
+import MainLayout from './mainLayout'
+import ChartDesigner from '../components/chartDesigner/layout'
 // 由于 antd 组件的默认文案是英文,所以需要修改为中文
-import zhCN from 'antd/lib/locale-provider/zh_CN';
+import zhCN from 'antd/lib/locale-provider/zh_CN'
 
 function RouterConfig({ history }) {
   return (

+ 15 - 1
app/utils/baseUtils.js

@@ -132,4 +132,18 @@ Date.prototype.format = function (fmt) {
         if (new RegExp("(" + k + ")").test(fmt))
             fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
     return fmt;
-}
+}
+Array.prototype.distinct = function () { 
+    var arr = this,
+          i,   obj = {},
+          result = [],
+          len = arr.length; 
+    for (i = 0; i < arr.length; i++) {  
+        if (!obj[arr[i]]) { //如果能查找到,证明数组元素重复了
+               
+            obj[arr[i]] = 1;   
+            result.push(arr[i]);  
+        } 
+    } 
+    return result;
+};