Browse Source

调整部分组件定义方式/增加接口请求测试

zhuth 7 years ago
parent
commit
a82f2039ba

+ 33 - 33
app/components/chartDesigner/header.jsx

@@ -7,43 +7,43 @@ import { connect } from 'dva';
 import { ActionCreators } from 'redux-undo';
 import chartDesigner from '../../models/chartDesigner';
 
-class Header extends React.Component {
-    render() {
-        const props = this.props;
-        return (
-            <div className='header'>
-                <div className='header-item toolbar-title'>
-                    <Input
-                        ref='titleInput'
-                        className='input-title' 
-                        addonAfter={<Icon type="edit" 
-                            onClick={() => {
-                                const input = this.refs.titleInput
-                                input.focus()
-                            }}
-                        />}
-                        onChange={(e) => {
-                            props.dispatch({ type: 'chartDesigner/setTitle', text: e.target.value});
+const Header = ({ chartDesigner, dispatch }) => {
+    return (
+        <div className='header'>
+            <div className='header-item toolbar-title'>
+                <Input
+                    className='input-title' 
+                    addonAfter={<Icon type="edit" 
+                        onClick={() => {
+                            const input = this.refs.titleInput
+                            input.focus()
                         }}
-                        value={props.chartDesigner.header.label}
-                    />
-                </div>
-                <div className='header-item toolbar-buttons'>
-                    <div className=''>
-                        <Button className='button-uodo' icon='undo' onClick={() => {
-                            props.dispatch(ActionCreators.undo());
-                        }}>撤销</Button>
-                        <Button className='button-redo' onClick={() => {
-                            props.dispatch(ActionCreators.redo());
-                        }}>重做</Button>
-                        <Button className='button-uodo' >预览</Button>
-                        <Button className='button-uodo' >保存</Button>
-                    </div>
+                    />}
+                    onChange={(e) => {
+                        dispatch({ type: 'chartDesigner/setTitle', text: e.target.value });
+                    }}
+                    value={chartDesigner.header.label}
+                />
+            </div>
+            <div className='header-item toolbar-buttons'>
+                <div className=''>
+                    <Button onClick={() => {
+                        dispatch({ type: 'chartDesigner/a'});
+                    }}>请求测试</Button>
+                    <Button className='button-uodo' icon='undo' onClick={() => {
+                        dispatch(ActionCreators.undo());
+                    }}>撤销</Button>
+                    <Button className='button-redo' onClick={() => {
+                        dispatch(ActionCreators.redo());
+                    }}>重做</Button>
+                    <Button className='button-uodo' >预览</Button>
+                    <Button className='button-uodo' >保存</Button>
                 </div>
             </div>
-        )
-    }
+        </div>
+    )
 }
+
 function mapStateToProps({ present: { chartDesigner } }) {
     return { chartDesigner: chartDesigner }
 }

+ 1 - 3
app/components/chartDesigner/sections/aggregateTableConfigForm.jsx

@@ -28,8 +28,6 @@ class AggregateTableConfigForm extends React.Component {
             return option.checked == true;
         }
 		
-		const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;
-
 		const { formItemLayout } = props
         
 		return (
@@ -66,4 +64,4 @@ function mapStateToProps({ present: { chartDesigner } }) {
     return { chartDesigner: chartDesigner }
 }
 
-export default Form.create()(connect(mapStateToProps)(AggregateTableConfigForm));
+export default connect(mapStateToProps)(AggregateTableConfigForm);

+ 135 - 39
app/components/chartDesigner/sections/barConfigForm.jsx

@@ -1,51 +1,147 @@
 import React from 'react';
-import { Form, Select } from 'antd';
+import { Form, Select, Tag, Cascader, Dropdown, Menu } from 'antd';
 const FormItem = Form.Item;
 const { Option } = Select;
 import { connect } from 'dva';
 import chartDesigner from '../../../models/chartDesigner';
+import './barConfigForm.less';
 
-class barConfigForm extends React.Component {
-	render() {
-		const props = this.props;
-        const columns = props.chartDesigner.columns;
-		const { formItemLayout } = props;
-
-		return (
-			<Form hideRequiredMark={true}>
-				<FormItem label='横轴' {...formItemLayout}>
-					<Select
-						value={props.chartDesigner.barConfig.xAixs}
-						labelInValue={true}
-						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/barConfig/setXAixs', xAixs: value});
-						}}
-					>
-						{columns.map((c, i)=>{
-							return (<Option key={i} value={c.name}>{c.label}</Option>)
-						})}
-					</Select>
-				</FormItem>
-				<FormItem label='纵轴' {...formItemLayout}>
-					<Select 
-						value={props.chartDesigner.barConfig.yAixs}
-						labelInValue={true}
-						onChange={(value) => {
-							props.dispatch({ type: 'chartDesigner/barConfig/setYAixs', yAixs: value});
-						}}
-					>
-						{columns.map((c, i)=>{
-							return (<Option key={i} value={c.name}>{c.label}</Option>)
-						})}
-					</Select>
-				</FormItem>
-			</Form>
-		);
-	}
+const barConfigForm = ({ chartDesigner, dispatch, formItemLayout }) => {
+	
+	
+	const columns = chartDesigner.columns;
+
+	const menu = <Menu>
+		<Menu.Item>
+		<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">1st menu item</a>
+		</Menu.Item>
+		<Menu.Item>
+		<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">2nd menu item</a>
+		</Menu.Item>
+		<Menu.Item>
+		<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">3rd menu item</a>
+		</Menu.Item>
+	</Menu>
+
+	return (
+		<Form hideRequiredMark={true}>
+			<FormItem label='横轴' {...formItemLayout}>
+				<Select
+					value={chartDesigner.barConfig.xAxis}
+					labelInValue={true}
+					onChange={(value) => {
+						dispatch({ type: 'chartDesigner/barConfig/setXAxis', xAxis: value});
+					}}
+				>
+					{columns.map((c, i)=>{
+						return (<Option key={i} value={c.name}>{c.label}</Option>)
+					})}
+				</Select>
+			</FormItem>
+			<FormItem label='纵轴' {...formItemLayout}>
+				<Cascader
+					className='barconfig-yxais'
+					value={chartDesigner.barConfig.yAxis}
+					allowClear={true}
+					options={columns.map((c, i)=>{
+						// return (<Option key={i} value={c.name}>{c.label}</Option>)
+						return {
+							value: c.name,
+							label: c.label,
+							children: [{
+								value: 'sum',
+								label: '和计'
+							}, {
+								value: 'avg',
+								label: '平均值'
+							}, {
+								value: 'median',
+								label: '中位数'
+							}, {
+								value: 'count',
+								label: '计数'
+							}, {
+								value: 'distinctCount',
+								label: '不重复计数'
+							}, {
+								value: 'max',
+								label: '最大'
+							}, {
+								value: 'min',
+								label: '最小'
+							}]
+						}
+					})}
+					onChange={(value) => {
+						dispatch({ type: 'chartDesigner/barConfig/setYAxis', yAxis: value});
+					}}
+					displayRender={(label, selectedOptions) => {
+						let menu = selectedOptions.length > 0 ? <Menu>
+							{selectedOptions[0].children.map((c, i) => {
+								return <Menu.Item key={i}>{c.label}</Menu.Item>
+							})}
+						</Menu>: [];
+						let tag = selectedOptions.length > 0 ? <Dropdown
+							trigger='click'
+							overlay={menu}
+						>
+							<Tag size='small'>{label[1]}</Tag>
+						</Dropdown>
+						: null;
+
+						return <div>
+							{tag}
+							<span>{label[0]}</span>
+						</div>
+					}}
+				>
+				</Cascader>
+			</FormItem>
+		</Form>
+	);
 }
 
+// class barConfigForm extends React.Component {
+// 	render() {
+// 		const props = this.props;
+//         const columns = props.chartDesigner.columns;
+// 		const { formItemLayout } = props;
+
+// 		return (
+// 			<Form hideRequiredMark={true}>
+// 				<FormItem label='横轴' {...formItemLayout}>
+// 					<Select
+// 						value={props.chartDesigner.barConfig.xAxis}
+// 						labelInValue={true}
+// 						onChange={(value) => {
+// 							props.dispatch({ type: 'chartDesigner/barConfig/setXAxis', xAxis: value});
+// 						}}
+// 					>
+// 						{columns.map((c, i)=>{
+// 							return (<Option key={i} value={c.name}>{c.label}</Option>)
+// 						})}
+// 					</Select>
+// 				</FormItem>
+// 				<FormItem label='纵轴' {...formItemLayout}>
+// 					<Select 
+// 						value={props.chartDesigner.barConfig.yAxis}
+// 						labelInValue={true}
+// 						onChange={(value) => {
+// 							props.dispatch({ type: 'chartDesigner/barConfig/setYAxis', yAxis: value});
+// 						}}
+// 					>
+// 						{columns.map((c, i)=>{
+// 							return (<Option key={i} value={c.name}>{c.label}</Option>)
+// 						})}
+// 					</Select>
+// 				</FormItem>
+// 			</Form>
+// 		);
+// 	}
+// }
+
 function mapStateToProps({ present: { chartDesigner } }) {
     return { chartDesigner: chartDesigner }
 }
 
-export default Form.create()(connect(mapStateToProps)(barConfigForm));
+export default connect(mapStateToProps)(barConfigForm);

+ 5 - 0
app/components/chartDesigner/sections/barConfigForm.less

@@ -0,0 +1,5 @@
+.barconfig-yxais {
+    .ant-cascader-picker-label {
+        height: 100%;
+    }
+}

+ 1 - 0
app/index.js

@@ -1,6 +1,7 @@
 import dva from 'dva';
 import undoable from 'redux-undo';
 import chartDesigner from './models/chartDesigner'
+import './utils/baseUtils';
 
 // 1. Initialize
 const app = dva({

+ 41 - 9
app/models/chartDesigner.js

@@ -1,3 +1,7 @@
+import * as service from '../services/chartDesigner'
+import { delay } from '../utils/baseUtils'
+import deepAssign from '../utils/deepAssign';
+
 export default {
     namespace: 'chartDesigner',
     state: {
@@ -62,7 +66,10 @@ export default {
         filters: []
     },
     reducers: {
+        setModel(state, action) {
+        },
         setTitle(state, action) {
+            console.log(action);
             let newState = Object.assign({}, state, {
                 header: {
                     label: action.text
@@ -134,10 +141,10 @@ export default {
         /**
          * 柱状图设置-设置横轴
          */
-        'barConfig/setXAixs'(state, action) {
+        'barConfig/setXAxis'(state, action) {
             const barConfig = state.barConfig;
             let newBarConfig = Object.assign({}, barConfig, {
-                xAixs: action.xAixs
+                xAxis: action.xAxis
             });
             let newState = Object.assign({}, state, {
                 barConfig: newBarConfig
@@ -147,10 +154,10 @@ export default {
         /**
          * 柱状图设置-设置纵轴
          */
-        'barConfig/setYAixs'(state, action) {
+        'barConfig/setYAxis'(state, action) {
             const barConfig = state.barConfig;
             let newBarConfig = Object.assign({}, barConfig, {
-                yAixs: action.yAixs
+                yAxis: action.yAxis
             });
             let newState = Object.assign({}, state, {
                 barConfig: newBarConfig
@@ -200,9 +207,34 @@ export default {
         }
     },
     effects: {
-        // *test(action, { put, call }) {
-        //     yield call(delay, 1000);
-        //     yield put({ type: 'chartDesigner/setTitle', text: 'ttttttt' });
-        // }
-    }
+        *['a'](action, { call, put }) {
+            const data = yield call(service.fetch);
+            console.log(data);
+            yield put({ type: 'setTitle', text: '和哈哈哈哈哈哈' });
+        },
+        *test({payload:todo},{put,call}){
+           
+            yield put({type:'filters/setUsing', action: { key: 0 }})
+        },
+        *fetch({ payload: { page = 1 } }, { call, put }) {
+            const { data, headers } = yield call(usersService.fetch, { page });
+            yield put({
+                type: 'save',
+                payload: {
+                    data,
+                    total: parseInt(headers['x-total-count'], 10),
+                    page: parseInt(page, 10),
+                },
+            });
+        },
+    },
+    subscriptions: {
+        setup({ dispatch, history }) {
+          return history.listen(({ pathname, query }) => {
+            if (pathname === '/users') {
+              dispatch({ type: 'fetch', payload: query });
+            }
+          });
+        },
+    },
 };

+ 25 - 0
app/services/chartDesigner.js

@@ -0,0 +1,25 @@
+import request from '../utils/request'
+
+export function fetch() {
+  return request(`http://localhost:8001/api/users?_page=1&_limit=3`);
+}
+
+export function remove(id) {
+  return request(`/api/users/${id}`, {
+    method: 'DELETE',
+  });
+}
+
+export function patch(id, values) {
+  return request(`/api/users/${id}`, {
+    method: 'PATCH',
+    body: JSON.stringify(values),
+  });
+}
+
+export function create(values) {
+  return request('/api/users', {
+    method: 'POST',
+    body: JSON.stringify(values),
+  });
+}

+ 7 - 1
app/utils/baseUtils.js

@@ -108,7 +108,13 @@ function hashcode(obj) {
     return hash;
 }
 
-export { remove, isEqual, isEmptyObject, getUrlParam, hashcode };
+function delay(timeout) {
+    return new Promise(resolve => {
+        setTimeout(resolve, timeout);
+    });
+}
+
+export { remove, isEqual, isEmptyObject, getUrlParam, hashcode, delay };
 
 Date.prototype.format = function (fmt) {
     var o = {

+ 73 - 0
app/utils/deepAssign.js

@@ -0,0 +1,73 @@
+function isObj(x){	
+	var type = typeof x;
+	return x !== null && (type === 'object' || type === 'function');
+}
+
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var propIsEnumerable = Object.prototype.propertyIsEnumerable;
+
+function toObject(val) {
+	if (val === null || val === undefined) {
+		throw new TypeError('Cannot convert undefined or null to object');
+	}
+
+	return Object(val);
+}
+
+function assignKey(to, from, key) {
+	var val = from[key];
+
+	if (val === undefined || val === null) {
+		return;
+	}
+
+	if (hasOwnProperty.call(to, key)) {
+		if (to[key] === undefined || to[key] === null) {
+			throw new TypeError('Cannot convert undefined or null to object (' + key + ')');
+		}
+	}
+
+	if (!hasOwnProperty.call(to, key) || !isObj(val)) {
+		to[key] = val;
+	} else {
+		to[key] = assign(Object(to[key]), from[key]);
+	}
+}
+
+function assign(to, from) {
+	if (to === from) {
+		return to;
+	}
+
+	from = Object(from);
+
+	for (var key in from) {
+		if (hasOwnProperty.call(from, key)) {
+			assignKey(to, from, key);
+		}
+	}
+
+	if (Object.getOwnPropertySymbols) {
+		var symbols = Object.getOwnPropertySymbols(from);
+
+		for (var i = 0; i < symbols.length; i++) {
+			if (propIsEnumerable.call(from, symbols[i])) {
+				assignKey(to, from, symbols[i]);
+			}
+		}
+	}
+
+	return to;
+}
+
+function deepAssign(target) {
+	target = toObject(target);
+
+	for (var s = 1; s < arguments.length; s++) {
+		assign(target, arguments[s]);
+	}
+
+	return target;
+};
+
+exports.module = deepAssign;

+ 30 - 0
app/utils/request.js

@@ -0,0 +1,30 @@
+import fetch from 'dva/fetch';
+
+function parseJSON(response) {
+  return response.json();
+}
+
+function checkStatus(response) {
+  if (response.status >= 200 && response.status < 300) {
+    return response;
+  }
+
+  const error = new Error(response.statusText);
+  error.response = response;
+  throw error;
+}
+
+/**
+ * Requests a URL, returning a promise.
+ *
+ * @param  {string} url       The URL we want to request
+ * @param  {object} [options] The options we want to pass to "fetch"
+ * @return {object}           An object containing either "data" or "err"
+ */
+export default function request(url, options) {
+  return fetch(url, options)
+    .then(checkStatus)
+    .then(parseJSON)
+    .then(data => ({ data }))
+    .catch(err => ({ err }));
+}