Przeglądaj źródła

loading状态控制

zhuth 6 lat temu
rodzic
commit
99e7a36dfa

+ 3 - 0
src/components/chart/list.jsx

@@ -17,6 +17,7 @@ import TransferBox from '../common/selectUserBox/selectUserBox'
 import DeleteBox from '../common/deleteBox/deleteBox'
 import { arrayToTree } from '../../utils/baseUtils'
 import ListFilter from '../common/listFilter/index'
+import Loading from '../common/loading/index'
 import './list.less'
 const { Content } = Layout
 const CardGrid = Card.Grid
@@ -410,11 +411,13 @@ class ChartList extends React.Component {
 
     render() {
         const { dispatch, chart } = this.props;
+        const { listLoading } = chart;
         const { visibleChooseDataSourceBox, visibleDistributeBox, visibleGroupManageMentBox, visibleTransferBox, visibleDeleteBox, selectedRecord, noGroup, pageSize, page } = this.state;
         let reduceList =  this.onReduce();
         let viewList = this.onPage(reduceList);
         return (
             <Layout className='layout-chart'>
+                <Loading visible={listLoading} />
                 <Content>
                     <Card bordered={false} title={
                         <Row className='tools' type='flex' justify='space-between'>

+ 31 - 0
src/components/common/loading/index.jsx

@@ -0,0 +1,31 @@
+import React from 'react'
+import { Spin, Icon } from 'antd'
+
+class Loading extends React.Component {
+
+    state = {
+        width: '100%',
+        height: '100%',
+    }
+
+    componentDidMount() {
+        let loadingEl = this.loadingRef;
+        let containerEl = loadingEl.parentElement;
+        let width = containerEl.offsetWidth;
+        let height = containerEl.offsetHeight;
+        this.setState({
+            width: `${width}px`,
+            height: `${height}px`,
+        });
+    }
+
+    render() {
+        const { visible } = this.props;
+        const { width, height } = this.state;
+
+        return <div ref={node => this.loadingRef = node} style={{ display: visible ? 'block' : 'none', position: 'absolute', height, width, zIndex: '4', background: 'rgba(51,51,51,.1)' }}>
+            <Spin style={{ display: 'inline-block', position: 'absolute', top: '50%', left: '50%', margin: '-10px' }} indicator={<Icon type="loading" style={{ fontSize: 24 }} spin />} />
+        </div>
+    }
+}
+export default Loading

+ 5 - 5
src/components/dashboard/layout.jsx

@@ -3,18 +3,20 @@ import { connect } from 'dva'
 import { Layout, Spin, Icon } from 'antd'
 import DashboardMenu from './menu'
 import DashboardList from './list'
+import Loading from '../common/loading/index'
 import './layout.less'
 const { Sider, Content } = Layout
 
 class DashboardLayout extends React.Component {
 
     render() {
-        const { loading, dashboard, dispatch } = this.props;
+        const { siderLoading, dashboard, dispatch } = this.props;
         const { currentMenu, currentMenuParents } = dashboard;
         return <Layout
             className='layout-dashboard'
         >
             <Sider width={300}>
+                <Loading visible={siderLoading} />
                 <DashboardMenu
                     model={dashboard}
                     editable={true}
@@ -90,10 +92,8 @@ class DashboardLayout extends React.Component {
                             ] })
                         }
                     }}
+                    silentFetch={true}
                 />
-                <div style={{ display: loading ? 'block' : 'none', position: 'absolute', height: '100%', width: '100%', top: '0px', zIndex: '4', background: 'rgba(51,51,51,.1)' }}>
-                    <Spin style={{ display: 'inline-block', position: 'absolute', top: '50%', left: '50%', margin: '-10px' }} indicator={<Icon type="loading" style={{ fontSize: 24 }} spin />}/>
-                </div>
             </Sider>
             <Content>
                 <DashboardList />
@@ -111,6 +111,6 @@ function mapStateToProps({ present: { loading, dashboard }}) {
         }
     }
 
-    return { loading: flag, dashboard }
+    return { siderLoading: flag, dashboard }
 }
 export default connect(mapStateToProps)(DashboardLayout)

+ 3 - 2
src/components/dashboard/list.jsx

@@ -8,7 +8,7 @@ import DeleteBox from '../common/deleteBox/deleteBox'
 import ShareBox from './shareBox'
 import CopyBox from './copyBox'
 import ListFilter from '../common/listFilter/index'
-// import EllipsisTooltip from '../common/ellipsisTooltip/index'
+import Loading from '../common/loading/index'
 import CusIcon from '../common/cusIcon/index'
 import './list.less'
 const { Content } = Layout
@@ -191,7 +191,7 @@ class DashboardList extends React.Component {
         const { visibleShareBox, shareUrl, visibleDistributeBox, visibleTransferBox, visibleDeleteBox,
             visibleCopyBox, selectedRecord, defaultSelectedGroups, defaultSelectedUsers } = this.state
         const { currentUser } = main;
-        const { menuTree, filterItem, currentMenu, currentMenuParents } = dashboard;
+        const { listLoading, menuTree, filterItem, currentMenu, currentMenuParents } = dashboard;
 
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         let filterLabel = dashboard.filterLabel ? (dashboard.filterLabel + '').replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1') : ''; // 添加转义符号
@@ -337,6 +337,7 @@ class DashboardList extends React.Component {
 
         return (
             <Layout className='dashboard-view'>
+                <Loading visible={listLoading}/>
                 <Content>
                     <Card bordered={false} className="dashboard-body" title={
                         <Row className='dashboard-tools' type='flex' justify='space-between'>

+ 3 - 4
src/components/dashboard/menu.jsx

@@ -273,15 +273,14 @@ class DashboardMenu extends React.Component {
     }
 
     render() {
-        const { dashboard, dispatch, hideHeader, editable, model, onSearch: propsOnSearch, onMenuDelete } = this.props;
+        const { dashboard, dispatch, hideHeader, editable, model, onSearch: propsOnSearch, onMenuDelete, silentFetch } = this.props;
         const { visibleDeleteBox, selectedMenu } = this.state;
         const { menuTree } = dashboard;
-        const { menuFilterLabel, menuExpandedKeys, menuSelectedKeys, menuAutoExpandParent } = model;
+        const { menuLoading, menuFilterLabel, menuExpandedKeys, menuSelectedKeys, menuAutoExpandParent } = model;
         const reg = new RegExp('([+ \\- & | ! ( ) { } \\[ \\] ^ \" ~ * ? : ( ) \/])', 'g'); // 需要转义的字符
         const regLabel = menuFilterLabel.replace(new RegExp('(\\\\)', 'g'), '\\$1').replace(reg, '\\$1'); // 添加转义符号
 
         return <div className='menu-container' style={ hideHeader ? { paddingTop: 0 } : { paddingTop: '48px' } }>
-            
             {!hideHeader && <div className='menu-search'>
                 <Search
                     value={menuFilterLabel}
@@ -300,7 +299,7 @@ class DashboardMenu extends React.Component {
                     }}
                 />
                 <Button onClick={() => {
-                    dispatch({ type: 'dashboard/remoteMenuTree', mandatory: true });
+                    dispatch({ type: 'dashboard/remoteMenuTree', mandatory: true, silent: silentFetch });
                     dispatch({ type: 'dashboard/setFields', fields: [
                         { name: 'menuFilterLabel', value: '' },
                         { name: 'menuAutoExpandParent', value: false },

+ 3 - 1
src/components/dataConnect/list.jsx

@@ -5,6 +5,7 @@ import DeleteBox from '../common/deleteBox/deleteBox'
 import EmptyContent from '../common/emptyContent/index'
 import DataConnectBox from '../dataSourceDetail/dataConnectBox'
 import ListFilter from '../common/listFilter/index'
+import Loading from '../common/loading/index'
 import './list.less'
 const CardGrid = Card.Grid
 const { Content } = Layout
@@ -231,11 +232,12 @@ class DataConnect extends React.Component {
 
     render() {
         const { dataConnect, dispatch } = this.props;
-        const { selected } = dataConnect;
+        const { listLoading, selected } = dataConnect;
         const { visibleDeleteBox } = this.state;
 
         return (
             <Layout className='layout-dataconnect'>
+                <Loading visible={listLoading} />
                 <Content>
                     <Card bordered={false} title={
                         <Row className='tools' type='flex' justify='space-between'>

+ 3 - 0
src/components/dataSource/list.jsx

@@ -10,6 +10,7 @@ import DeleteBox from '../common/deleteBox/deleteBox'
 import DataPreview from '../common/dataPreview/dataPreview'
 import ListFilter from '../common/listFilter/index'
 import EllipsisTooltip from '../common/ellipsisTooltip/index'
+import Loading from '../common/loading/index'
 import './list.less'
 const { Content } = Layout
 const { Option } = Select
@@ -227,6 +228,7 @@ class DataSource extends React.Component {
 
     render() {
         const { main, dataSource, dispatch } = this.props;
+        const { listLoading } = dataSource;
         const { selectedRecord, visibleTransferBox, visibleGroupManageMentBox, visibleCopyBox, visibleDeleteBox, visibleDataPreviewBox, noGroup } = this.state;
         const { currentUser } = main;
         const treeData = arrayToTree(dataSource.groupList, '-1', 'code', 'pcode', 'children');
@@ -378,6 +380,7 @@ class DataSource extends React.Component {
 
         return ( 
             <Layout className='layout-datasource'>
+                <Loading visible={listLoading} />
                 <Content>
                     <Card bordered={false} className='datasource-body' title={
                         <Row className='datasource-tools' type='flex' justify='space-between'>

+ 10 - 4
src/components/homePage/sider.jsx

@@ -3,6 +3,7 @@ import { Layout, Input, Button, Icon } from 'antd'
 import { connect } from 'dva'
 import DashboardCollection from './collection'
 import DashboardMenu from '../dashboard/menu'
+import Loading from '../common/loading/index'
 import './sider.less'
 
 const { Header, Content } = Layout
@@ -34,9 +35,10 @@ class MenuLayout extends React.Component {
 
     render() {
         const { home, dispatch,dashboard } = this.props;
-        const { menuFilterLabel, collectionDashboards } = home;
+        const { siderLoading, menuFilterLabel, collectionDashboards } = home;
 
         return <Layout className='home-menu'>
+            <Loading visible={siderLoading}/>
             <Header>
                 <Input.Search
                     className='search'
@@ -53,12 +55,17 @@ class MenuLayout extends React.Component {
                     }}
                 />
                 <Button className='refresh' onClick={() => {
-                    dispatch({ type: 'dashboard/remoteMenuTree', mandatory: true });
                     dispatch({ type: 'home/setFields', fields: [
+                        { name: 'siderLoading', value: true },
                         { name: 'menuFilterLabel', value: '' },
                         { name: 'menuAutoExpandParent', value: false },
                     ] });
-                    dispatch({ type: 'home/fetchCollectionDashboardList', mandatory: true });
+                    dispatch({ type: 'dashboard/remoteMenuTree', mandatory: true, silent: true });
+                    dispatch({ type: 'home/fetchCollectionDashboardList', mandatory: true, silent: true }).then(() => {
+                        dispatch({ type: 'home/setFields', fields: [
+                            { name: 'siderLoading', value: false },
+                        ] });
+                    });
                 }}><Icon type='sync' /></Button>
             </Header>
             <Content>
@@ -77,7 +84,6 @@ class MenuLayout extends React.Component {
                         ] });
                     }}
                     onSelect={selectedMenu => {
-                        console.log('onSelect');
                         // dispatch({ type: 'home/setField', name: 'menuSelectedKeys', value: selectedKeys })
                         if(selectedMenu && selectedMenu.type === 'dashboard') {
                             dispatch({ type: 'home/openTab', tab: {

+ 7 - 0
src/models/chart.js

@@ -7,6 +7,7 @@ export default {
     namespace: 'chart',
     state: {
         originData: {
+            listLoading: false,
             list: [],
             filterLabel: '',
             typeLabel: 'name',
@@ -62,6 +63,7 @@ export default {
             ],
             filterItem: { name: 'name', label: '名称', type: 'string' }, // 已选过滤字段
             listScrollTop: 0, // 记录列表界面滚动条位置
+            page: 1, // 分页器当前所在页码
         },
     },
     reducers: {
@@ -188,6 +190,9 @@ export default {
                 if(!action.mandatory && chart.list.length > 0) {
                     return chart.list;
                 }
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'listLoading', value: true });
+                }
                 const res = yield call(service.fetch, {
                     url: URLS.CHART_LIST,
                     method: 'GET',
@@ -223,6 +228,8 @@ export default {
                 }
             }catch(e) {
                 message.error('请求图表列表失败: ' + e.message);
+            }finally {
+                yield put({ type: 'setField', name: 'listLoading', value: false });
             }
         },
         *remoteDetail(action, { select, call, put }) {

+ 19 - 2
src/models/dashboard.js

@@ -10,11 +10,13 @@ export default {
     namespace: 'dashboard',
     state: {
         originData: {
+            listLoading: false,
             list: [],
             newOne: {
                 defaultSelectedGroups: [],
                 defaultSelectedUsers: []
             },
+            menuLoading: false,
             menuList: [],
             menuTree: [],
             menuExpandedKeys: ['-1'],
@@ -76,6 +78,9 @@ export default {
                 if(!action.mandatory && dashboard.list.length > 0) {
                     return;
                 }
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'listLoading', value: true });
+                }
                 const res = yield call(service.fetch, {
                     url: URLS.DASHBOARD_LIST,
                     method: 'GET',
@@ -128,6 +133,8 @@ export default {
                 }
             }catch(e) {
                 message.error('请求报表列表失败: ' + e.message)
+            }finally {
+                yield put({ type: 'setField', name: 'listLoading', value: false });
             }
         },
         *remoteDetail(action, { select, call, put }) {
@@ -305,6 +312,9 @@ export default {
                 return {menuList: dashboard.menuList, menuTree: dashboard.menuTree};
             }
             try{
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'menuLoading', value: true });
+                }
                 const res = yield call(service.fetch, {
                     url: URLS.DASHBOARD_MENU_TREE,
                     method: 'GET'
@@ -347,6 +357,8 @@ export default {
             }catch(e) {
                 message.error('获取报表目录失败: ' + e.message);
                 return false;
+            }finally {
+                yield put({ type: 'setField', name: 'menuLoading', value: false });
             }
         },
         *remoteAddMenu(action, { put, call, select }) {
@@ -453,6 +465,9 @@ export default {
         *remoteMenuDashboardList(action, { put, call, select }) {
             const { menuCode } = action;
             try {
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'listLoading', value: true });
+                }
                 const res = yield call(service.fetch, {
                     url: URLS.DASHBOARD_MENU_DASHBOARD_LIST + '/' + menuCode,
                     method: 'GET',
@@ -500,10 +515,12 @@ export default {
                     })
                     yield put({ type: 'list', list: list });
                 }else {
-                    message.error('获取看板列表失败: ' + (res.err || res.data.msg));
+                    message.error('获取报表列表失败: ' + (res.err || res.data.msg));
                 }
             }catch(e) {
-                message.error('获取看板列表失败: ' + e.message);
+                message.error('获取报表列表失败: ' + e.message);
+            }finally {
+                yield put({ type: 'setField', name: 'listLoading', value: false });
             }
         },
         *share(action, { put, call, select }) {

+ 20 - 0
src/models/dataConnect.js

@@ -6,6 +6,7 @@ export default {
     namespace: 'dataConnect',
     state: {
         originData: {
+            listLoading: false,
             list: [],
             newOne: {},
             filterLabel: '',
@@ -17,6 +18,20 @@ export default {
         },
     },
     reducers: {
+        setField(state, action) {
+            const { name, value } = action;
+            let obj = {};
+            obj[name] = value;
+            let newState = Object.assign({}, state, obj);
+            return Object.assign({}, newState);
+        },
+        setFields(state, action) {
+            const { fields } = action;
+            let obj = {};
+            fields.map(f => (obj[f.name] = f.value));
+            let newState = Object.assign({}, state, obj);
+            return Object.assign({}, newState);
+        },
         list(state, action) {
             const data = action.data;
             return Object.assign({}, state, {list: data});
@@ -135,6 +150,9 @@ export default {
                 if(!action.mandatory && dataConnect.list.length > 0) {
                     return;
                 }
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'listLoading', value: true });
+                }
                 const res = yield call(service.fetch, {
                     url: URLS.DATACONNECT_LIST,
                     method: 'GET',
@@ -162,6 +180,8 @@ export default {
                 }
             }catch(e) {
                 message.error('读取数据链接配置列表错误: ' + e.message);
+            }finally {
+                yield put({ type: 'setField', name: 'listLoading', value: false });
             }
         },
         *remoteValidate(action, { select, call, put, takeEvery, takeLatest }) {

+ 6 - 0
src/models/dataSource.js

@@ -6,6 +6,7 @@ export default {
     namespace: 'dataSource',
     state: {
         originData: {
+            listLoading: false,
             list: [],
             filterLabel: '',
             invalidSQL: false,
@@ -169,6 +170,9 @@ export default {
                 if(!action.mandatory && dataSource.list.length > 0) {
                     return;
                 }
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'listLoading', value: true });
+                }
                 const res = yield call(service.fetch, {
                     url: URLS.DATASOURCE_LIST,
                     method: 'GET',
@@ -211,6 +215,8 @@ export default {
                 }
             }catch(e) {
                 message.error('读取数据源列表错误: ' + e.message);
+            }finally {
+                yield put({ type: 'setField', name: 'listLoading', value: false });
             }
             
         },

+ 11 - 1
src/models/home.js

@@ -9,6 +9,9 @@ export default {
     namespace: 'home',
     state: {
         originData: {
+            siderLoading: false,
+            menuLoading: false,
+            collectionLoading: false,
             menuExpandedKeys: ['-1'],
             menuSelectedKeys: [],
             menuFilterLabel: '',
@@ -132,7 +135,10 @@ export default {
                 const { collectionDashboards } = home;
                 const { mandatory } = action;
                 if(collectionDashboards.length > 0 && !mandatory) {
-                    return;
+                    return false;
+                }
+                if(!action.silent) {
+                    yield put({ type: 'setField', name: 'collectionLoading', value: true });
                 }
                 const res = yield call(service.fetch, {
                     url: URLS.DASHBOARD_COLLECT_LIST,
@@ -144,11 +150,15 @@ export default {
                         name: d.NAME
                     }));
                     yield put({ type: 'setField', name: 'collectionDashboards', value: list });
+                    return list;
                 }else {
                     message.error('获取收藏列表失败: ' + (res.err || res.data.msg));
+                    return false;
                 }
             }catch(e) {
                 message.error('获取收藏列表失败: ' + e.message);
+            }finally {
+                yield put({ type: 'setField', name: 'collectionLoading', value: false });
             }
         },
         *collect(action, { select, put, call }) {