"use strict";
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
};
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
            t[p[i]] = s[p[i]];
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var every = require("lodash/every");
var filter = require("lodash/filter");
var find = require("lodash/find");
var includes = require("lodash/includes");
var isArray = require("lodash/isArray");
var isFunction = require("lodash/isFunction");
var isPlainObject = require("lodash/isPlainObject");
var map = require("lodash/map");
var reject = require("lodash/reject");
var reverse = require("lodash/reverse");
var some = require("lodash/some");
var sortBy = require("lodash/sortBy");
var React = require("react");
var FaSort = require("react-icons/lib/fa/sort");
var styled_components_1 = require("styled-components");
var theme_1 = require("../../theme");
var Button_1 = require("../Button");
var Pager_1 = require("../Pager");
var TableRow_1 = require("./TableRow");
var highlightStyle = "\n\tbackground-color: " + theme_1.default.colors.info.light + ";\n";
var BaseTableWrapper = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n\toverflow-x: auto;\n\tmax-width: 100%;\n"], ["\n\toverflow-x: auto;\n\tmax-width: 100%;\n"])));
var BaseTable = styled_components_1.default.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n\tdisplay: table;\n\twidth: 100%;\n\tborder-spacing: 0;\n\n\t> [data-display='table-head'] {\n\t\tdisplay: table-header-group;\n\t\tbackground-color: #f2f2f2;\n\n\t\t> [data-display='table-row'] {\n\t\t\tdisplay: table-row;\n\n\t\t\t> [data-display='table-cell'] {\n\t\t\t\tdisplay: table-cell;\n\t\t\t\ttext-align: left;\n\t\t\t\tpadding-left: 40px;\n\t\t\t\tpadding-top: 10px;\n\t\t\t\tpadding-bottom: 10px;\n\t\t\t\tfont-size: 16px;\n\t\t\t}\n\t\t}\n\t}\n\n\t> [data-display='table-body'] {\n\t\tdisplay: table-row-group;\n\n\t\t> [data-display='table-row'] {\n\t\t\tdisplay: table-row;\n\t\t\ttext-decoration: none;\n\t\t\tcolor: inherit;\n\n\t\t\t> [data-display='table-cell'] {\n\t\t\t\tdisplay: table-cell;\n\t\t\t\tfont-size: 14px;\n\t\t\t\ttext-align: left;\n\t\t\t\tpadding-top: 14px;\n\t\t\t\tpadding-bottom: 14px;\n\t\t\t\tpadding-left: 40px;\n\t\t\t\ttext-decoration: none;\n\t\t\t\tcolor: inherit;\n\t\t\t}\n\n\t\t\t> a[data-display='table-cell'] {\n\t\t\t\tcursor: ", ";\n\t\t\t}\n\n\t\t\t&:nth-of-type(even) {\n\t\t\t\tbackground-color: #f8f8f8;\n\t\t\t}\n\n\t\t\t&: hover {\n\t\t\t\ttext-decoration: none;\n\t\t\t\tcolor: inherit;\n\t\t\t\t", ";\n\t\t\t}\n\n\t\t\t&[data-highlight='true'] {\n\t\t\t\t", " > [data-display=\"table-cell\"]:first-child {\n\t\t\t\t\tbox-shadow: inset 3px 0px 0 ", ";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n"], ["\n\tdisplay: table;\n\twidth: 100%;\n\tborder-spacing: 0;\n\n\t> [data-display='table-head'] {\n\t\tdisplay: table-header-group;\n\t\tbackground-color: #f2f2f2;\n\n\t\t> [data-display='table-row'] {\n\t\t\tdisplay: table-row;\n\n\t\t\t> [data-display='table-cell'] {\n\t\t\t\tdisplay: table-cell;\n\t\t\t\ttext-align: left;\n\t\t\t\tpadding-left: 40px;\n\t\t\t\tpadding-top: 10px;\n\t\t\t\tpadding-bottom: 10px;\n\t\t\t\tfont-size: 16px;\n\t\t\t}\n\t\t}\n\t}\n\n\t> [data-display='table-body'] {\n\t\tdisplay: table-row-group;\n\n\t\t> [data-display='table-row'] {\n\t\t\tdisplay: table-row;\n\t\t\ttext-decoration: none;\n\t\t\tcolor: inherit;\n\n\t\t\t> [data-display='table-cell'] {\n\t\t\t\tdisplay: table-cell;\n\t\t\t\tfont-size: 14px;\n\t\t\t\ttext-align: left;\n\t\t\t\tpadding-top: 14px;\n\t\t\t\tpadding-bottom: 14px;\n\t\t\t\tpadding-left: 40px;\n\t\t\t\ttext-decoration: none;\n\t\t\t\tcolor: inherit;\n\t\t\t}\n\n\t\t\t> a[data-display='table-cell'] {\n\t\t\t\tcursor: ",
    ";\n\t\t\t}\n\n\t\t\t&:nth-of-type(even) {\n\t\t\t\tbackground-color: #f8f8f8;\n\t\t\t}\n\n\t\t\t&: hover {\n\t\t\t\ttext-decoration: none;\n\t\t\t\tcolor: inherit;\n\t\t\t\t",
    ";\n\t\t\t}\n\n\t\t\t&[data-highlight='true'] {\n\t\t\t\t", " > [data-display=\"table-cell\"]:first-child {\n\t\t\t\t\tbox-shadow: inset 3px 0px 0 ", ";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n"])), function (props) {
    return !!props.onRowClick || !!props.getRowHref ? 'pointer' : 'auto';
}, function (props) {
    return !!props.onRowClick || !!props.getRowHref || !!props.onCheck
        ? highlightStyle
        : '';
}, highlightStyle, theme_1.default.colors.info.main);
var HeaderButton = styled_components_1.default(Button_1.default)(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n\tdisplay: block;\n"], ["\n\tdisplay: block;\n"])));
var Table = (function (_super) {
    __extends(Table, _super);
    function Table(props) {
        var _this = _super.call(this, props) || this;
        _this.setRowSelection = function (selectedRows) {
            var _a = _this.props, rowKey = _a.rowKey, data = _a.data;
            if (!rowKey) {
                return;
            }
            if (selectedRows.length === 0) {
                _this.setState({ allChecked: false, checkedItems: [] });
                return;
            }
            var selectedRowsIds = map(selectedRows, rowKey);
            var checkedItems = [];
            var allChecked = false;
            if (data) {
                checkedItems = filter(_this.props.data, function (x) {
                    return includes(selectedRowsIds, x[rowKey]);
                });
                allChecked = data.length > 0 && checkedItems.length === data.length;
            }
            _this.setState({ allChecked: allChecked, checkedItems: checkedItems });
        };
        _this.toggleAllChecked = function () {
            var data = _this.props.data;
            var allChecked = !_this.state.allChecked;
            var checkedItems = allChecked ? (data || []).slice() : [];
            if (_this.props.onCheck) {
                _this.props.onCheck(checkedItems);
            }
            _this.setState({ allChecked: allChecked, checkedItems: checkedItems });
        };
        _this.toggleChecked = function (e) {
            var rowKey = _this.props.rowKey;
            var key = e.currentTarget.dataset.key;
            if (!rowKey || !key) {
                return false;
            }
            var item = _this.getElementFromKey(key);
            if (!item) {
                return;
            }
            var identifier = item[rowKey];
            var isChecked = !_this.isChecked(item);
            var checkedItems = isChecked
                ? _this.state.checkedItems.concat(item)
                : reject(_this.state.checkedItems, (_a = {}, _a[rowKey] = identifier, _a));
            if (_this.props.onCheck) {
                _this.props.onCheck(checkedItems);
            }
            _this.setState({
                allChecked: _this.isEachRowChecked(checkedItems),
                checkedItems: checkedItems,
            });
            var _a;
        };
        _this.toggleSort = function (e) {
            var field = e.currentTarget.dataset.field;
            var sort = _this.state.sort;
            if (!field) {
                return;
            }
            var nextSort = {
                field: field,
                reverse: false,
            };
            if (sort.field === field) {
                nextSort = { field: sort.field, reverse: !sort.reverse };
            }
            _this.setState({ sort: nextSort });
            if (_this.props.onSort) {
                _this.props.onSort(nextSort);
            }
        };
        _this.onRowClick = function (e) {
            if (!_this.props.onRowClick) {
                return;
            }
            if (!_this.props.rowKey) {
                return console.warn('onRowClick requires that you provide a `rowKey` property');
            }
            var key = e.currentTarget.dataset.key;
            if (!key) {
                return console.warn('onRowClick called on an element without a key set');
            }
            var row = _this.getElementFromKey(key);
            if (row) {
                _this.props.onRowClick(row, e);
            }
        };
        _this.resetPager = function () {
            _this.setState({ page: 0 });
        };
        _this.incrementPage = function () {
            _this.setState({ page: _this.state.page + 1 });
        };
        _this.decrementPage = function () {
            _this.setState({ page: _this.state.page - 1 });
        };
        if (props.onCheck && !props.rowKey) {
            throw new Error('A `rowKey` property must be provided if using `onCheck` with a Table component');
        }
        var sortState = props.sort || {
            reverse: false,
            field: null,
        };
        _this.state = {
            allChecked: false,
            sort: sortState,
            checkedItems: [],
            page: 0,
        };
        return _this;
    }
    Table.prototype.componentWillReceiveProps = function (newProps) {
        if (newProps.sort !== this.props.sort) {
            this.setState({ sort: newProps.sort });
        }
    };
    Table.prototype.isChecked = function (item) {
        var rowKey = this.props.rowKey;
        if (!rowKey) {
            return false;
        }
        var identifier = item[rowKey];
        return some(this.state.checkedItems, (_a = {}, _a[rowKey] = identifier, _a));
        var _a;
    };
    Table.prototype.isHighlighted = function (item) {
        if (!this.props.highlightedRows ||
            this.props.highlightedRows.length === 0) {
            return false;
        }
        var rowKey = this.props.rowKey;
        if (!rowKey) {
            return false;
        }
        var identifier = item[rowKey];
        return includes(this.props.highlightedRows, identifier);
    };
    Table.prototype.isEachRowChecked = function (checkedItems) {
        var rowKey = this.props.rowKey;
        if (!rowKey) {
            return false;
        }
        var selectedKeys = map(checkedItems, rowKey);
        return every(this.props.data, function (x) { return includes(selectedKeys, x[rowKey]); });
    };
    Table.prototype.sortData = function (data) {
        var sort = this.state.sort;
        if (sort.field === null) {
            return data;
        }
        var column = find(this.props.columns, { field: sort.field });
        if (!column) {
            return data;
        }
        var collection;
        if (isFunction(column.sortable)) {
            collection = data.slice().sort(column.sortable);
        }
        else {
            collection = sortBy(data.slice(), function (item) {
                var sortableValue = item[sort.field];
                return isPlainObject(sortableValue)
                    ? sortableValue.value
                    : sortableValue;
            });
        }
        if (sort.reverse) {
            reverse(collection);
        }
        return collection;
    };
    Table.prototype.getElementFromKey = function (key) {
        var _a = this.props, data = _a.data, rowKey = _a.rowKey;
        if (!data) {
            return;
        }
        if (rowKey) {
            return find(data, function (element) { return "" + element[rowKey] === key; });
        }
        return data[Number(key)];
    };
    Table.prototype.render = function () {
        var _this = this;
        var _a = this.props, columns = _a.columns, data = _a.data, usePager = _a.usePager, itemsPerPage = _a.itemsPerPage, pagerPosition = _a.pagerPosition, rowAnchorAttributes = _a.rowAnchorAttributes, rowKey = _a.rowKey, props = __rest(_a, ["columns", "data", "usePager", "itemsPerPage", "pagerPosition", "rowAnchorAttributes", "rowKey"]);
        var getRowHref = props.getRowHref, getRowClass = props.getRowClass;
        var _b = this.state, page = _b.page, sort = _b.sort;
        var items = data || [];
        var totalItems = items.length;
        var _itemsPerpage = itemsPerPage || 50;
        var _pagerPosition = pagerPosition || 'top';
        var lowerBound = usePager ? page * _itemsPerpage : 0;
        var upperBound = usePager
            ? Math.min((page + 1) * _itemsPerpage, totalItems)
            : totalItems;
        var sortedData = this.sortData(items).slice(lowerBound, upperBound);
        return (React.createElement(React.Fragment, null,
            !!usePager &&
                (_pagerPosition === 'top' || _pagerPosition === 'both') && (React.createElement(Pager_1.default, { totalItems: totalItems, itemsPerPage: _itemsPerpage, page: page, nextPage: this.incrementPage, prevPage: this.decrementPage, mb: 2 })),
            React.createElement(BaseTableWrapper, null,
                React.createElement(BaseTable, __assign({}, props),
                    React.createElement("div", { "data-display": "table-head" },
                        React.createElement("div", { "data-display": "table-row" },
                            this.props.onCheck && (React.createElement("div", { "data-display": "table-cell" },
                                React.createElement("input", { checked: this.state.allChecked, onChange: this.toggleAllChecked, type: "checkbox" }))),
                            map(columns, function (item) {
                                if (item.sortable) {
                                    return (React.createElement("div", { "data-display": "table-cell", key: item.field },
                                        React.createElement(HeaderButton, { "data-field": item.field, plaintext: true, primary: sort.field === item.field, onClick: _this.toggleSort },
                                            item.label || item.field,
                                            "\u00A0",
                                            React.createElement(FaSort, { style: { display: 'inline-block' }, color: sort.field === item.field
                                                    ? theme_1.default.colors.info.main
                                                    : '' }))));
                                }
                                return (React.createElement("div", { "data-display": "table-cell", key: item.field }, item.label || item.field));
                            }))),
                    React.createElement("div", { "data-display": "table-body" },
                        this.props.tbodyPrefix,
                        map(sortedData, function (row, i) {
                            var isChecked = _this.props.onCheck
                                ? _this.isChecked(row)
                                : false;
                            var isHighlighted = _this.isHighlighted(row);
                            var key = rowKey ? row[rowKey] : i;
                            var href = !!getRowHref ? getRowHref(row) : undefined;
                            var classNamesList = isFunction(getRowClass)
                                ? getRowClass(row)
                                : [];
                            var className = isArray(classNamesList)
                                ? classNamesList.join(' ')
                                : '';
                            return (React.createElement(TableRow_1.TableRow, { isChecked: isChecked, isHighlighted: isHighlighted, key: key, keyAttribute: key, href: href, data: row, showCheck: !!_this.props.onCheck, columns: columns, attributes: rowAnchorAttributes, checkboxAttributes: _this.props.rowCheckboxAttributes, toggleChecked: _this.toggleChecked, onRowClick: _this.onRowClick, className: className }));
                        })))),
            !!usePager &&
                (_pagerPosition === 'bottom' || _pagerPosition === 'both') && (React.createElement(Pager_1.default, { totalItems: totalItems, itemsPerPage: _itemsPerpage, page: page, nextPage: this.incrementPage, prevPage: this.decrementPage, mb: 2 }))));
    };
    return Table;
}(React.Component));
exports.default = Table;
var templateObject_1, templateObject_2, templateObject_3;
