zhuth 7 жил өмнө
parent
commit
988128a696

+ 13 - 20
src/components/chart/list.jsx

@@ -6,6 +6,7 @@ import ChooseDataSourceBox from './chooseDataSourceBox'
 import { dateFormat } from '../../utils/baseUtils'
 import Ellipsis from 'ant-design-pro/lib/Ellipsis'
 import 'ant-design-pro/dist/ant-design-pro.css'
+import GroupSelector from '../datasource/groupSelector'
 const { Content } = Layout
 const { Search } = Input
 const CardGrid = Card.Grid
@@ -307,9 +308,9 @@ class ChartList extends React.Component {
     }
 
     render() {
-        const { visibleBox, visibleGroupMenu } = this.state;
+        const { visibleBox } = this.state;
         const { dispatch, chart } = this.props;
-
+        const TAG_COLOR = ['blue'];
         return (
             <Layout className='chart-list'>
                 <Content>
@@ -345,26 +346,18 @@ class ChartList extends React.Component {
                                 </Popover>
                                 <Breadcrumb className='group' separator=">">
                                     <Breadcrumb.Item>
-                                        <Dropdown
-                                            trigger={['click']}
-                                            onVisibleChange={this.handleVisibleChange}
-                                            visible={visibleGroupMenu}
-                                            overlay={(
-                                            <Menu>
-                                                {this.createGroupMenu()}
-                                            </Menu>
-                                        )}>
-                                            <Tag color='blue'>{chart.currentGroup[0].label}</Tag>
-                                        </Dropdown>
+                                        <GroupSelector model={chart} modelName='chart'>
+                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]} >
+                                                {chart.currentGroup[0].label}
+                                            </Tag>
+                                        </GroupSelector>
                                     </Breadcrumb.Item>
                                     {chart.currentGroup[1] && (<Breadcrumb.Item>
-                                        <Dropdown trigger={['click']} overlay={(
-                                            <Menu>
-                                                {this.createSubGroupMenu()}
-                                            </Menu>
-                                        )}>
-                                            <Tag color='blue'>{chart.currentGroup[1].label}</Tag>
-                                        </Dropdown>
+                                        <GroupSelector model={chart} modelName='chart'>
+                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]}>
+                                                {chart.currentGroup[1].label}
+                                            </Tag>
+                                        </GroupSelector>
                                     </Breadcrumb.Item>)}
                                 </Breadcrumb>
                             </Col>

+ 2 - 2
src/components/datasource/dataConnectBox.jsx

@@ -45,10 +45,10 @@ class DataConnectBox extends React.Component {
                 footer={
                     <Row>
                         <Col className='validatemessage' span={12}>
-                            {dataConnect.newOne.invalid ? '数据连接配置有误!' : ''}
+                            {dataConnect.newOne.invalid !== undefined ? (dataConnect.newOne.invalid ? <span style={{ color: '#F5222D' }}>数据连接配置有误</span> : <span style={{ color: '#52C41A' }}>测试通过</span>) : ''}
                         </Col>
                         <Col span={12}>
-                            <Button onClick={() => dispatch({ type:'dataConnect/remoteValidate'})}>测试</Button>
+                            <Button disabled={dataConnect.newOne.validating} onClick={() => dispatch({ type:'dataConnect/remoteValidate'})}>测试</Button>
                             {/* <Button onClick={() => dispatch({ type:'dataConnect/resetNewModel'})}>清空</Button> */}
                             <Button onClick={() => {this.hideBox()}}>取 消</Button>
                             <Button className={dataConnect.newOne.validating ? 'ant-btn-loading' : ''} type="primary" onClick={() => {this.okHandler()}}>

+ 16 - 21
src/components/datasource/dataSource.jsx

@@ -3,6 +3,7 @@ import { Layout, Row, Col, Input, Button, Table, Icon, Menu, Dropdown, Card, Bre
 import { connect } from 'dva'
 import './dataSource.less'
 import { dateFormat } from '../../utils/baseUtils'
+import GroupSelector from './groupSelector'
 const { Content } = Layout
 const { Search } = Input
 const { TreeNode } = Tree
@@ -122,7 +123,9 @@ class DataSource extends React.Component {
                 <Menu.Item key={p.code} onClick={() => {
                     dispatch({ type: 'dataSource/setCurrentGroup', group1: p });
                     this.hideGroupMenu();
-                }}><span style={{ fontWeight: selectedRecord ? (
+                }}><span className={selectedRecord ? (
+                    selectedRecord.groupCode+'' === p.code+'' ? 'selected' : ''
+                ) : dataSource.currentGroup[0] && (dataSource.currentGroup[0].code === p.code) ? 'selected' : ''} style={{ fontWeight: selectedRecord ? (
                     selectedRecord.groupCode+'' === p.code+'' ? 'bold' : 'normal'
                 ) : dataSource.currentGroup[0] && (dataSource.currentGroup[0].code === p.code) ? 'bold' : 'normal' }}>{p.label}</span></Menu.Item>
             );
@@ -140,7 +143,7 @@ class DataSource extends React.Component {
             return (
                 <Menu.Item key={c.code} onClick={() => {
                     dispatch({ type: 'dataSource/setCurrentGroup', group1: parentGroup, group2: c });
-                }}><span style={{ fontWeight: subGroup && (subGroup.code === c.code) ? 'bold' : 'normal' }}>{c.label}</span></Menu.Item>
+                }}><span className={subGroup && (subGroup.code === c.code) ? 'selected' : ''} style={{ fontWeight: subGroup && (subGroup.code === c.code) ? 'bold' : 'normal' }}>{c.label}</span></Menu.Item>
             );
         })
     }
@@ -229,7 +232,7 @@ class DataSource extends React.Component {
     render() {
         
         const { dataSource, dispatch } = this.props;
-        const { selectedRecord, visibleGroupMenu } = this.state;
+        const { selectedRecord } = this.state;
 
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterLabel = dataSource.filterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
@@ -369,26 +372,18 @@ class DataSource extends React.Component {
                                 </Popover>
                                 <Breadcrumb className='group' separator=">">
                                     <Breadcrumb.Item>
-                                        <Dropdown
-                                            trigger={['click']}
-                                            onVisibleChange={this.handleVisibleChange}
-                                            visible={visibleGroupMenu}
-                                            overlay={(
-                                            <Menu>
-                                                {this.createGroupMenu()}
-                                            </Menu>
-                                        )}>
-                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]}>{dataSource.currentGroup[0].label}</Tag>
-                                        </Dropdown>
+                                        <GroupSelector model={dataSource} modelName='dataSource'>
+                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]} >
+                                                {dataSource.currentGroup[0].label}
+                                            </Tag>
+                                        </GroupSelector>
                                     </Breadcrumb.Item>
                                     {dataSource.currentGroup[1] && (<Breadcrumb.Item>
-                                        <Dropdown trigger={['click']} overlay={(
-                                            <Menu>
-                                                {this.createSubGroupMenu()}
-                                            </Menu>
-                                        )}>
-                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]}>{dataSource.currentGroup[1].label}</Tag>
-                                        </Dropdown>
+                                        <GroupSelector model={dataSource} modelName='dataSource'>
+                                            <Tag color={TAG_COLOR[Math.ceil(Math.random()*TAG_COLOR.length) - 1]}>
+                                                {dataSource.currentGroup[1].label}
+                                            </Tag>
+                                        </GroupSelector>
                                     </Breadcrumb.Item>)}
                                 </Breadcrumb>
                             </Col>

+ 69 - 0
src/components/datasource/groupSelector.jsx

@@ -0,0 +1,69 @@
+import React from 'react'
+import { Popover, Row, Col, Icon, Divider } from 'antd'
+import { connect } from 'dva'
+import './groupSelector.less'
+
+class GroupSelector extends React.Component {
+
+    constructor(props) {
+        super(props);
+        this.state = {
+            visible: false
+        }
+    }
+
+    hide = () => {
+        this.setState({
+            visible: false,
+        });
+    }
+
+    handleVisibleChange = (visible) => {
+        this.setState({ visible });
+    }
+
+    render() {
+        const { model, modelName, children, dispatch } = this.props;
+        const { visible } = this.state;
+        const grouplist = model.groupList;
+        const pgroups = grouplist.filter(g => g.pcode === '-1');
+
+        const currentGroup = model.currentGroup;
+
+        return (
+            <Popover
+                overlayClassName='groupselector'
+                placement="bottomLeft"
+                trigger='click'
+                visible={visible}
+                onVisibleChange={this.handleVisibleChange}
+                content={
+                    [{code: 'all', label: '全部分组'}].concat(pgroups).map(p => {
+                        let cgroups = grouplist.filter(g => g.pcode === p.code);
+                        return <Row type='flex' justify='left' key={`gr-${p.code}`}>
+                            <Col key={`rc-${p.code}`} onClick={() => {
+                                this.hide();
+                                dispatch({ type: modelName + '/setCurrentGroup', group1: p });
+                            }}>
+                                {<span className={`group${currentGroup[0].code === p.code ? ' selected' : ''}`}>{p.label}</span>}<Icon type="right" />
+                            </Col>
+                            {
+                                cgroups.map((c, i) => <Col key={c.code} onClick={() => {
+                                    this.hide();
+                                    dispatch({ type: modelName + '/setCurrentGroup', group1: p, group2: c });
+                                }}>
+                                    {<span className={`group${currentGroup[1] ? (currentGroup[1].code === c.code ? ' selected' : '') : ''}`}>{c.label}</span>}
+                                    {i === cgroups.length-1 ? '' : <Divider className='group-divider' type="vertical" />}
+                                </Col>)
+                            }
+                        </Row>
+                    })
+                }
+            >
+                { children }
+            </Popover>
+        );
+    }
+}
+
+export default connect()(GroupSelector);

+ 21 - 0
src/components/datasource/groupSelector.less

@@ -0,0 +1,21 @@
+.groupselector {
+    .group {
+        cursor: pointer;
+        margin: 0 6px;
+        &:hover {
+            transition: color 0.25s cubic-bezier(0.31, 0.93, 1, 1);
+            color: #1890ff;
+            opacity: .7;
+        }
+        .anticon-right {
+            margin-left: 6px;
+        }
+        .group-divider {
+            color: rgba(0, 0, 0, 0.45);
+            margin: 0 8px 0 14px;
+        }
+    }
+    .selected {
+        color: #1890ff;
+    }
+}

+ 0 - 2
src/components/datasource/otherConfig.jsx

@@ -1,8 +1,6 @@
 import React from 'react'
 import { Form, Input, Select } from 'antd'
 import { connect } from 'dva'
-import '../../models/dataSource'
-import '../../models/dataConnect'
 const FormItem = Form.Item
 
 const OtherConfig = ({ dataSource, dataConnect, dispatch, mode }) => {

+ 1 - 1
src/models/chart.js

@@ -127,7 +127,7 @@ export default {
                             creator: d.createBy,
                             createTime: d.createDate,
                             description: d.describes || '',
-                            groupCode: d.chartsGroup+'' === '-1' ? 'all' : d.chartsGroup
+                            groupCode: d.chartsGroup+'' === '-1' ? 'all' : d.chartsGroup + ''
                         }
                     })
                     yield put({ type: 'list', list: list });

+ 51 - 40
src/models/dataConnect.js

@@ -59,7 +59,7 @@ export default {
             let newOne = state.newOne;
             let validInfo = state.validInfo;
             newOne[name] = value;
-            newOne.invalid = false;
+            delete newOne.invalid;
             (rules && (Object.prototype.toString.call(rules) === '[object Array]')) && rules.map((r) => {
                 return validInfo[name] = RULE[r](value);
             });
@@ -72,6 +72,7 @@ export default {
             for(let i = 0; i < fields.length; i++) {
                 newOne[fields[i]['name']] = fields[i]['value'];
             }
+            delete newOne.invalid;
             return Object.assign({}, state, {newOne});
         },
         setNewModel(state, action) {
@@ -109,6 +110,7 @@ export default {
                     url: URLS.DATACONNECT_LIST,
                     body: {}
                 });
+                console.log('请求数据连接配置列表',  res);
                 if(!res.err && res.data.code > 0) {
                     let data = res.data.data.map((r, i) => {
                         return {
@@ -173,27 +175,32 @@ export default {
                 const dataConnect = yield select(state => state.present.dataConnect);
                 const model = dataConnect.newOne;
 
-                // 设置validating为true
-                yield put({ type: 'setNewModelField', name: 'validating', value: true });
-                // 调用检测接口检测连接配置是否合法
-                let validBody = {
-                    name: model.name,
-                    addrass: model.address,
-                    port: model.port,
-                    databaseType: model.dbType,
-                    dataName: model.dbName,
-                    userName: model.userName,
-                    passWord: model.password
+                let flag = false;
+                if(model.invalid === false) {
+                    flag = true;
+                }else {
+                    // 设置validating为true
+                    yield put({ type: 'setNewModelField', name: 'validating', value: true });
+                    // 调用检测接口检测连接配置是否合法
+                    let validBody = {
+                        name: model.name,
+                        addrass: model.address,
+                        port: model.port,
+                        databaseType: model.dbType,
+                        dataName: model.dbName,
+                        userName: model.userName,
+                        passWord: model.password
+                    }
+                    const validRes = yield call(service.fetch, {
+                        url: URLS.DATACONNECT_VALIDATE,
+                        body: validBody
+                    });
+                    flag = !validRes.err && validRes.data.code > 0
+                    // 设置validating为false
+                    yield put({ type: 'setNewModelField', name: 'validating', value: false });
                 }
-                const validRes = yield call(service.fetch, {
-                    url: URLS.DATACONNECT_VALIDATE,
-                    body: validBody
-                });
 
-                // 设置validating为false
-                yield put({ type: 'setNewModelField', name: 'validating', value: false });
-
-                if(!validRes.err && validRes.data.code > 0) {
+                if(flag) {
                     // 如果合法
                     // 设置valid为true
                     yield put({ type: 'setNewModelInvalid', name: 'invalid', value: false });
@@ -232,27 +239,31 @@ export default {
                 const dataConnect = yield select(state => state.present.dataConnect);
                 const model = dataConnect.newOne;
 
-                // 设置validating为true
-                yield put({ type: 'setNewModelField', name: 'validating', value: true });
-                // 调用检测接口检测连接配置是否合法
-                let validBody = {
-                    name: model.name,
-                    addrass: model.address,
-                    port: model.port,
-                    databaseType: model.dbType,
-                    dataName: model.dbName,
-                    userName: model.userName,
-                    passWord: model.password
+                let flag = false;
+                if(model.invalid === false) {
+                    flag = true;
+                }else {
+                    // 设置validating为true
+                    yield put({ type: 'setNewModelField', name: 'validating', value: true });
+                    // 调用检测接口检测连接配置是否合法
+                    let validBody = {
+                        name: model.name,
+                        addrass: model.address,
+                        port: model.port,
+                        databaseType: model.dbType,
+                        dataName: model.dbName,
+                        userName: model.userName,
+                        passWord: model.password
+                    }
+                    const validRes = yield call(service.fetch, {
+                        url: URLS.DATACONNECT_VALIDATE,
+                        body: validBody
+                    });
+                    flag = !validRes.err && validRes.data.code > 0;
+                    // 设置validating为false
+                    yield put({ type: 'setNewModelField', name: 'validating', value: false });
                 }
-                const validRes = yield call(service.fetch, {
-                    url: URLS.DATACONNECT_VALIDATE,
-                    body: validBody
-                });
-
-                // 设置validating为false
-                yield put({ type: 'setNewModelField', name: 'validating', value: false });
-
-                if(!validRes.err && validRes.data.code > 0) {
+                if(flag) {
                     // 如果合法
                     // 设置valid为true
                     yield put({ type: 'setNewModelInvalid', name: 'invalid', value: false });

+ 1 - 1
src/models/dataSource.js

@@ -190,7 +190,7 @@ export default {
                             createTime: new Date(r.createDate),
                             tags: tags,
                             description: r.note,
-                            groupCode: r.group+'' === '-1' || 'all'
+                            groupCode: r.connectorGroup+'' === '-1' ? 'all' : r.connectorGroup+''
                         }
                     });
                     console.log('数据源list', res, data);

+ 2 - 6
src/models/main.js

@@ -25,12 +25,8 @@ export default {
                 maxCount: 3,
             });
             return history.listen(({ pathname, query }) => {
-                if(pathname.endsWith('/')) { // 去掉最后的斜杠以正确匹配路由设置
-                    dispatch(routerRedux.push(pathname.substring(0, pathname.length - 1)));
-                }else {
-                    let page = pathname.match(/\/(\w*)/)[1];
-                    dispatch({ type: 'setPage', page });
-                }
+                let page = pathname.match(/\/(\w*)/)[1];
+                dispatch({ type: 'setPage', page });
             })
         }
     }