index.js 4.2 KB
import React from 'react';
import PropTypes from 'prop-types';
import { Divider } from 'antd';
import modelCreator from './model';
import connect from '../../hoc/stateful';
import TableEx from '../index';
import { push } from '../../../services/route';
import { shallowEqual, arrayJoin } from '../../../utils/helper';
import styles from './index.less';

const createUniqueKey = (columns, key) => {
  if (columns.findIndex(v => v.k === key) === -1) {
    return key;
  } else {
    return createUniqueKey(columns, `_${key}`);
  }
};

const renderButton = (meta) => {
  if (meta.path) {
    const onClick = (e) => {
      e.preventDefault();
      push(meta.path, { ...meta });
    };
    const onKeyDown = (e) => {
      if (e.keyCode === 13) {
        e.preventDefault();
        push(meta.path, { ...meta });
      }
    };
    // noinspection JSUnresolvedVariable
    return (
      <a onClick={onClick} onKeyDown={onKeyDown}>
        {' '}
        {meta.buttonName || 'link'}
        {' '}
      </a>
    );
  }
  throw new Error(`Unsupported button meta: ${JSON.stringify(meta)}.`);
};

class DsTable extends React.Component {
  componentDidMount() {
    const { coordinate, params, dispatchLocal, current = 1, start, end } = this.props;
    dispatchLocal({ type: 'doInit', payload: { coordinate, params, current, start, end } });
  }

  componentWillReceiveProps(nextProps) {
    const { coordinate, params, current, start, end } = nextProps;
    const { dispatchLocal } = this.props;
    if (!shallowEqual(coordinate, this.props.coordinate) || !shallowEqual(params, this.props.params) || current !== this.props.current) {
      dispatchLocal({ type: 'doInit', payload: { coordinate, params, current, start, end } });
    }
  }

  render() {
    const { dispatchLocal, current: outCurrent } = this.props;
    const { parsedMeta, props, columns, current: localCurrent, pageSize, filters, list, num } = this.props.model;
    const current = outCurrent || localCurrent;
    const tableProps = {
      dataSource: list,
      ...props,
      parsedMeta,
      columns,
      filters: filters.map(filter => filter.filter),
      loading: this.props.loading.model,
      pagination: {
        current,
        total: num,
        pageSize,
      },
      onChange: (pagination, theFilters, sorter) => {
        if (current !== pagination.current) {
          if (outCurrent) {
            this.props.onPageChange(pagination.current);
          } else {
            dispatchLocal({ type: 'changeCurrentPage', payload: pagination.current });
          }
        }
        if (pageSize !== pagination.pageSize) {
          dispatchLocal({ type: 'changePageSize', payload: pagination.pageSize });
        }
        const { field, order } = sorter;
        if (field) {
          dispatchLocal({ type: 'doSort', payload: { field, order } });
        }
      },
      onFilter: (theFilters) => {
        dispatchLocal({ type: 'doFilter', payload: theFilters });
      },
    };
    const { columnData, rowData } = parsedMeta.global;
    if (columnData.buttons || rowData.buttons) {
      tableProps.columns = [
        ...columns,
        {
          title: '操作',
          key: createUniqueKey(tableProps.columns, 'operations'),
          fixed: 'right',
          width: 150,
          render: (text, record, rowIndex, meta, globalMeta) => {
            return (
              <div style={{ whiteSpace: 'nowrap' }}>
                { arrayJoin(globalMeta.buttons.map(renderButton), <Divider type="vertical" />) }
              </div>
            );
          },
        },
      ];
    }
    return (
      <div className={styles.wrapper}>
        <div className={styles.container}>
          <TableEx {...tableProps} />
        </div>
      </div>
    );
  }
}

DsTable.propTypes = {
  coordinate: PropTypes.oneOfType(
    [
      PropTypes.string,
      PropTypes.shape({
        containerType: PropTypes.string,
        containerName: PropTypes.string,
        datasourceName: PropTypes.string,
      }),
    ],
  ).isRequired,
  onPageChange: PropTypes.func,
  current: PropTypes.number,
};

DsTable.defaultProps = {
  onPageChange: () => null,
};

export default connect(modelCreator, {
  mapStateToProps: ({ loading }) => ({ loading }),
})(DsTable);