提交 53014a2d authored 作者: vipcxj's avatar vipcxj

最初的数据源到表格组件的实现

上级 c60b339d
import React from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';
import modelCreator from './model';
import connect from '../../hoc/stateful';
import TableEx from '../../../components/table/index';
import config from '../../../utils/config';
import styles from './index.less';
const columns = [{
title: '流程',
dataIndex: 'pName',
key: 'pName',
filterType: 'text',
}, {
title: '任务',
dataIndex: 'nName',
key: 'nName',
filterType: 'text',
}, {
title: '状态',
dataIndex: 'state',
key: 'state',
filterType: 'enum',
filterEnums: [{
text: '状态1',
value: '状态1',
}, {
text: '状态2',
value: '状态2',
}, {
text: '状态3',
value: '状态3',
}, {
text: '状态4',
value: '状态4',
}, {
text: '状态5',
value: '状态5',
}],
}, {
title: '日期',
dataIndex: 'date',
key: 'date',
filterType: 'date',
render(date) {
return date.format(config.defaultDateTimeFormat);
},
}, {
title: '期限',
dataIndex: 'deadline',
key: 'deadline',
render(deadline) {
const now = moment();
const late = deadline.diff(now, 'days', true);
if (late < 0) {
const style = {
color: '#f04134',
};
return <span style={style}>{ `超时 ${deadline.from(now, true)}` }</span>;
} else if (late < 1) {
const style = {
color: '#ffbf00',
};
return <span style={style}>{ `仅剩 ${deadline.to(now, true)}` }</span>;
} else {
const style = {
color: '#00a854',
};
return <span style={style}>{ `还剩 ${deadline.to(now, true)}` }</span>;
}
},
}];
// const columns = [{
// title: '流程',
// dataIndex: 'pName',
// key: 'pName',
// filterType: 'text',
// }, {
// title: '任务',
// dataIndex: 'nName',
// key: 'nName',
// filterType: 'text',
// }, {
// title: '状态',
// dataIndex: 'state',
// key: 'state',
// filterType: 'enum',
// filterEnums: [{
// text: '状态1',
// value: '状态1',
// }, {
// text: '状态2',
// value: '状态2',
// }, {
// text: '状态3',
// value: '状态3',
// }, {
// text: '状态4',
// value: '状态4',
// }, {
// text: '状态5',
// value: '状态5',
// }],
// }, {
// title: '日期',
// dataIndex: 'date',
// key: 'date',
// filterType: 'date',
// render(date) {
// return date.format(config.defaultDateTimeFormat);
// },
// }, {
// title: '期限',
// dataIndex: 'deadline',
// key: 'deadline',
// render(deadline) {
// const now = moment();
// const late = deadline.diff(now, 'days', true);
// if (late < 0) {
// const style = {
// color: '#f04134',
// };
// return <span style={style}>{ `超时 ${deadline.from(now, true)}` }</span>;
// } else if (late < 1) {
// const style = {
// color: '#ffbf00',
// };
// return <span style={style}>{ `仅剩 ${deadline.to(now, true)}` }</span>;
// } else {
// const style = {
// color: '#00a854',
// };
// return <span style={style}>{ `还剩 ${deadline.to(now, true)}` }</span>;
// }
// },
// }];
class DsTable extends React.Component {
......@@ -77,7 +76,6 @@ class DsTable extends React.Component {
constructor(props, context) {
super(props, context);
this.loadData = this::this.loadData;
this.getCurrent = this::this.getCurrent;
this.state = {
filters: [],
current: 1,
......@@ -87,12 +85,6 @@ class DsTable extends React.Component {
componentDidMount() {
this.loadData();
}
getCurrent() {
const { num } = this.props.task;
const pageNum = ((num / this.state.pageSize) | 0) + 1;
const current = this.state.current > pageNum ? pageNum : this.state.current;
return current;
}
loadData() {
const filters0 = this.state.filters
.filter(({ filter }) => !!filter)
......@@ -102,15 +94,16 @@ class DsTable extends React.Component {
]));
const psz = this.state.pageSize; // eslint-disable-line no-shadow
const pst = (this.state.current - 1) * psz;
this.props.dispatchLocal({ type: 'fetchTasks', payload: { pst, psz, filters: filters0 } });
this.props.dispatchLocal({ type: 'fetchData', payload: { coordinate: this.props.coordinate, pst, psz, filters: filters0 } });
}
render() {
const { list, num } = this.props.task;
const { rowKey, columns, list, num } = this.props.model;
const tableProps = {
dataSource: list,
rowKey,
columns,
filters: this.state.filters.map(filter => filter.filter),
loading: this.props.loading.effect.fetchTasks,
loading: this.props.loading.effect.fetchData,
pagination: {
current: this.state.current,
total: num,
......@@ -143,6 +136,19 @@ class DsTable extends React.Component {
}
}
DsTable.propTypes = {
coordinate: PropTypes.oneOfType(
[
PropTypes.string,
PropTypes.shape({
containerType: PropTypes.string,
containerName: PropTypes.string,
datasourceName: PropTypes.string,
}),
],
).isRequired,
};
export default connect(modelCreator, {
mapStateToProps: ({ loading }) => ({ loading }),
})(DsTable);
import moment from 'moment';
import uuid from 'uuid/v4';
import _ from 'lodash';
import { datasourceApi } from '../../../services/datasource';
import { countTasks, fetchTasks } from '../../../services/bpm';
import config from '../../../utils/config';
const prefix = uuid();
......@@ -24,6 +21,12 @@ const getMeta = (property, name, parsed = false, defaultValue) => {
return result.length > 0 ? result[0] : defaultValue;
};
const getRowIndex = (meta) => {
return _(meta.properties || [])
.filter(property => !property.skip)
.findIndex(property => property.key);
};
const makeColumns = (meta) => {
return (meta.properties || [])
.filter(property => !property.skip)
......@@ -40,7 +43,7 @@ const makeColumns = (meta) => {
const getArrayData = ({ dataType, arrayData, singularData }, meta) => {
if (dataType === 'TABLE') {
return arrayData || [];
return (arrayData && arrayData.map(v => _.toPlainObject(v))) || [];
} else if (dataType === 'PROPERTIES') {
const data = [];
(meta.properties || [])
......@@ -48,14 +51,14 @@ const getArrayData = ({ dataType, arrayData, singularData }, meta) => {
.forEach((property) => {
data.push((singularData || {})[property.name]);
});
return [data];
return [_.toPlainObject(data)];
} else {
throw new Error(`Unsupported data type: ${dataType}`);
}
};
const modelCreator = () => {
const name = 'task';
const name = 'model';
const namespace = _.uniqueId(prefix);
return {
name,
......@@ -63,13 +66,15 @@ const modelCreator = () => {
namespace,
state: {
columns: [],
rowKey: '',
num: 0,
list: [],
},
reducers: {
queryMetaSuccess(state, { payload: columns }) {
queryMetaSuccess(state, { payload: { rowKey, columns } }) {
return {
...state,
rowKey,
columns,
}
},
......@@ -90,31 +95,14 @@ const modelCreator = () => {
*fetchData({ payload: { coordinate, pst, psz, params, filters} }, { put, call }) {
const options = { pst, psz, params, filters };
const api = datasourceApi(coordinate);
const meta = api.meta();
yield put({ type: 'queryMetaSuccess', payload: makeColumns(meta) });
const meta = yield call(api.meta);
const rowKey = `${getRowIndex(meta)}`;
yield put({ type: 'queryMetaSuccess', payload: { rowKey, columns: makeColumns(meta) } });
const num = yield call(api.count, options);
yield put({ type: 'queryCountSuccess', payload: num });
const dsb = yield call(api.query, options);
yield put({ type: 'queryTasksSuccess', payload: getArrayData(dsb, meta) });
},
*fetchTasks({ payload: { pst, psz, filters } }, { put, call }) {
const num = Number.parseInt(yield call(countTasks, filters), 10);
yield put({ type: 'queryCountSuccess', payload: num });
const tasks = yield call(fetchTasks, { pst, psz, filters });
yield put({
type: 'queryTasksSuccess',
payload: tasks.map((task) => {
return {
key: `${task.pId}-${task.nId}`,
pName: task.pName,
nName: task.nName,
state: task.state,
date: moment(task.date, config.defaultDateTimeFormat),
deadline: moment(task.deadline, config.defaultDateTimeFormat),
};
}),
});
},
},
subscriptions: {},
},
......
......@@ -12,7 +12,7 @@ const createMenus = () => {
return null;
}
const [cur, ...rest] = path;
const find = _menus.filter(menu => menu.name === cur).pop();
const find = _menus.filter(menu => menu.name === `${cur}`).pop();
if (find) {
if (rest.length === 0) {
return find;
......@@ -24,7 +24,7 @@ const createMenus = () => {
for (const id of path) {
const m = getModule(id);
const menu = {
name: m.id,
name: `${m.id}`,
text: m.name,
children: [],
};
......
......@@ -36,7 +36,7 @@ const authenticated = (nextState, replace) => {
const createRoute = async (app, module) => {
const route = {
path: module.id,
path: `${module.id}`,
name: module.name,
};
if (!module.group) {
......
......@@ -4,7 +4,6 @@ import { Menu, Breadcrumb, Icon } from 'antd';
import { connect } from 'dva';
import { Link } from 'dva/router';
import { fullPath } from '../../utils/helper';
import { getMenuItems } from '../../utils/navigate';
import styles from './header.less';
const MenuItem = Menu.Item;
......@@ -76,7 +75,7 @@ class HeaderPane extends React.Component {
<SubMenu title={domainTitle} key="domain">
{
domainList.map(dm => (
<MenuItem key={dm.id}>
<MenuItem key={`${dm.id}`}>
{ dm.name }
</MenuItem>
))
......@@ -93,7 +92,7 @@ HeaderPane.propTypes = {
user: PropTypes.string,
domain: PropTypes.string,
domainList: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string,
id: PropTypes.number,
name: PropTypes.string,
})),
};
......
import { mapKeys, toPairs, isUndefined, isString, curry } from 'lodash';
import { mapKeys, toPairs, isUndefined, isString, partial } from 'lodash';
import request, { normParams } from '../utils/request';
import { split } from '../utils/filter';
......@@ -14,15 +14,15 @@ export const datasourceApi = (coordinate) => {
} : (coordinate || {});
if (containerType === 'global') {
return {
query: curry(calcGlobalDatasource)(datasourceName),
count: curry(countGlobalDatasource)(datasourceName),
meta: curry(getGlobalDatasourceMeta)(datasourceName),
query: partial(calcGlobalDatasource, datasourceName),
count: partial(countGlobalDatasource, datasourceName),
meta: partial(getGlobalDatasourceMeta, datasourceName),
};
} else if (containerType === 'module') {
return {
query: curry(calcModuleDatasource)(containerName, datasourceName),
count: curry(countModuleDatasource)(containerName, datasourceName),
meta: curry(getModuleDatasourceMeta)(containerName, datasourceName),
query: partial(calcModuleDatasource, containerName, datasourceName),
count: partial(countModuleDatasource, containerName, datasourceName),
meta: partial(getModuleDatasourceMeta, containerName, datasourceName),
};
} else {
throw new Error(`Unsupported containerType: ${containerType}`);
......@@ -34,7 +34,7 @@ const makeQueryParams = ({ pst, psz, filters = [], params = {} }) => {
...toPairs({ pst, psz }),
...parseFilters(filters),
...normParams(mapKeys(params, (v, k) => `p-${k}`)),
].filter(isUndefined);
].filter(v => v && !isUndefined((v[1])));
};
export async function calcGlobalDatasource(name, { pst, psz, filters = [], params = {} }) {
......
export const makeCancelable = (promise, silence = true) => {
let hasCanceled = false;
const canceledError = { isCanceled: true };
const wrappedPromise = new Promise((resolve, reject) => {
promise.then(
val => (hasCanceled ? reject(canceledError) : resolve(val)),
error => (hasCanceled ? reject(canceledError) : reject(error)),
);
});
return {
run: cb => cb(wrappedPromise).catch((err) => {
if (silence && err !== canceledError) {
throw err;
}
}),
cancel() {
hasCanceled = true;
},
};
};
......@@ -6,7 +6,7 @@ import { cookie } from '../utils/config';
import { errors } from '../utils/error';
// eslint-disable-next-line max-len
function parseObject(response, { num2str = true, bool2str = true, nul2str = false, ud2str = false, nil2str = false } = {}) {
function parseObject(response, { num2str = false, bool2str = false, nul2str = false, ud2str = false, nil2str = false } = {}) {
if (response.status === 204) { // no-content
return null;
} else {
......
import React from 'react';
import { partial } from 'lodash';
import { storiesOf } from '@storybook/react';
import dva from 'dva';
import createLoading from 'dva-loading';
import DsTable from '../src/components/table/dstable';
import { makeCancelable } from '../src/utils/promise';
import { login } from '../src/services/login';
import { switchDomain } from '../src/services/domain';
import { allModuleInfos, getModuleConfigure } from '../src/services/modules';
import { setCookie, setLocalStorge } from '../src/utils/helper';
import { cookie, storage } from '../src/utils/config';
......@@ -19,19 +19,9 @@ const loginIt = async (userName, password, domainId) => {
setCookie(cookie.user, userId);
setLocalStorge(storage.userName, userName);
await switchDomain(domainId);
const moduleInfos = await allModuleInfos();
console.log(moduleInfos);
if (moduleInfos.length > 0) {
const module = await getModuleConfigure(moduleInfos[0].name);
console.log(module);
}
};
loginIt('cxj', '111111', 5).catch(err => console.log(err));
const Wrapper = () => Comp => (props) => {
const wrap = () => Comp => (props) => {
const app = dva({});
app.use(createLoading({
effects: true,
......@@ -41,8 +31,50 @@ const Wrapper = () => Comp => (props) => {
return app.start()();
};
const lazy = action => (Comp) => {
class Lazy extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
loading: true,
};
}
componentDidMount() {
this.action = makeCancelable(action());
this.action.run(promise => promise.then(() => {
this.setState({
loading: false,
});
}));
}
componentWillUnmount() {
this.action.cancel();
}
render() {
if (this.state.loading) {
return <div>加载中...</div>;
} else {
const { children, ...rest } = this.props;
return (
<Comp {...rest}>
{ children }
</Comp>
);
}
}
}
return Lazy;
};
storiesOf('a', module)
.add('1', () => {
const Comp = Wrapper()(DsTable);
return <Comp />;
const Comp = lazy(partial(loginIt, 'cxj', '111111', 5))(wrap()(DsTable));
const coordinate = {
containerType: 'module',
containerName: 'query-transfer-order',
datasourceName: 'QueryLeftHousesTranfersTable',
};
return <Comp coordinate={coordinate} />;
});
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论