All files List.js

74.29% Statements 26/35
61.11% Branches 11/18
88.89% Functions 8/9
74.29% Lines 26/35
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107              6x                                             7x         6x 6x 6x 6x     6x 6x 6x 6x 6x                               6x       7x 6x   7x     7x         7x       1x 1x   1x 1x       13x 13x             13x 7x   6x              
import React, { PropTypes } from 'react';
import {SimpleListTable, ListPagination} from './ListComponents';
import {devOnly, isEquivalent, shallowCopyExcept} from './utils';
import {_buildElement} from './utils-internal';
 
 
function copyProps(props) {
    return shallowCopyExcept({}, props, ['data', 'count', 'renderRow', 'showPagination', 'onPageChanged', 'prepareDataForPage', 'noDataComponent', 'headerAlwaysOn']);
}
 
 
export default class List extends React.Component {
    static propTypes = {
        id : React.PropTypes.string, // list id
        data : React.PropTypes.array, // data array (all available data)
        renderRow : React.PropTypes.func.isRequired, // function(item,index,key) : tr element
        count : React.PropTypes.number, // number of items per page
        onPageChanged : React.PropTypes.func,  // callback function(page) : void (page is 1-indexed)
        prepareDataForPage : React.PropTypes.func, // function(data,page,count) : array of data (page is 1-indexed)
        showPagination : React.PropTypes.bool, // Default: true
        headerAlwaysOn : React.PropTypes.bool,  // if show header and footer when no data is available. Default: true
        noDataComponent : React.PropTypes.oneOfType([ React.PropTypes.func, React.PropTypes.element ])  // component function or element
    };
 
    static defaultProps = {
        showPagination : true,
        headerAlwaysOn : true,
        count : 10,
        id : "list-" + Math.floor(Math.random() * 1000000).toString(22),
        prepareDataForPage : function(data,page,count) {
            return data.slice((page -1)*count, page*count);
        }
    };
 
    constructor(props) {
        super();
        this.state = { };
        this.page = 1;
        Iif (props.renderRow == undefined) {
            throw new Error('Missing function renderRow(item,index,key):component');
        }
        this._handlePageChange = this._handlePageChange.bind(this);
        this._data = this._data.bind(this);
        this.props = props;
        this.htmlProps = copyProps(props);
        this.noDataElement = _buildElement(props.noDataComponent, this.htmlProps, []);
    }
 
    componentWillReceiveProps(nextProps) {
        const updateData = ! isEquivalent(this.props.data, nextProps.data);
        this.htmlProps = copyProps(nextProps);
        if (this.props.noDataComponent != nextProps.noDataComponent) {
            this.noDataElement = _buildElement(nextProps.noDataComponent, this.htmlProps, []);
        }
        this.props = nextProps;
        if (updateData) {
            this._data(nextProps.data, true);
        }
    }
 
    componentDidMount() {
        this._data(this.props.data, true);
    }
 
    _data(data, resetPage) {
        if (resetPage) {
            this.page = 1;
        }
        Iif (data == null || data == undefined) {
            data = [];
        }
        const update = {
            items: this.props.prepareDataForPage(data, this.page, this.props.count),
            total: data.length,
            page:  this.page
        };
        this.setState(update);
    }
 
    _handlePageChange(pg) {
        Eif (this.props.onPageChanged != undefined) {
            this.props.onPageChanged(pg);
        }
        this.page = pg;
        this._data(this.props.data, false);
    }
 
    render() {
        const {items, total, page} = this.state;
        return (
            <div {...this.htmlProps} key={this.id}>
                <SimpleListTable className={this.props.className} id={this.props.id} renderRow={this.props.renderRow} data={items} indexOffset={(page -1) * this.props.count}
                                 headerAlwaysOn={this.props.headerAlwaysOn} noDataElement={this.noDataElement}>
                    {this.props.children}
                </SimpleListTable>
                {(() => {
                    if (items && this.props.showPagination) {
                        return (<ListPagination className={this.props.className} onPageChanged={this._handlePageChange} id={this.props.id} total={total} count={this.props.count} page={page}/>);
                    } else {
                        return null;
                    }
                })()}
            </div>
        );
    }
}