@bigfishtv/cockpit
Version:
423 lines (345 loc) • 15.6 kB
JavaScript
;
exports.__esModule = true;
exports.default = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _class, _temp, _initialiseProps;
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _deepEqual = require('deep-equal');
var _deepEqual2 = _interopRequireDefault(_deepEqual);
var _keycode = require('keycode');
var _keycode2 = _interopRequireDefault(_keycode);
var _isEqual2 = require('lodash/isEqual');
var _isEqual3 = _interopRequireDefault(_isEqual2);
var _debounce2 = require('lodash/debounce');
var _debounce3 = _interopRequireDefault(_debounce2);
var _timeUtils = require('../../utils/timeUtils');
var _lifecycleUtils = require('../../utils/lifecycleUtils');
var _tableUtils = require('../../utils/tableUtils');
var _selectKeyUtils = require('../../utils/selectKeyUtils');
var _SortTypes = require('../../constants/SortTypes');
var SortTypes = _interopRequireWildcard(_SortTypes);
var _FixedDataTable = require('./FixedDataTable');
var _FixedDataTable2 = _interopRequireDefault(_FixedDataTable);
var _FixedDataTableCheckboxSelectCell = require('./cell/FixedDataTableCheckboxSelectCell');
var _FixedDataTableCheckboxSelectCell2 = _interopRequireDefault(_FixedDataTableCheckboxSelectCell);
var _FixedDataTableCheckboxSelectHeaderCell = require('./cell/FixedDataTableCheckboxSelectHeaderCell');
var _FixedDataTableCheckboxSelectHeaderCell2 = _interopRequireDefault(_FixedDataTableCheckboxSelectHeaderCell);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var dateTimeFormat = 'YYYY-MM-DDTHH:mm:ssZ';
var _defaultProps = {
uncontrolled: false,
allowSelection: true,
multiselect: true,
stickySelect: false,
data: [],
selectedIds: [],
checkboxSelection: false,
tableWidth: 600,
tableHeight: 500,
fixedWidth: false,
fixedHeight: false,
cellWidth: 180,
rowHeight: 42,
negativeHeight: 167,
associations: [],
defaultSortField: 'modified',
defaultSortDirection: SortTypes.DESC,
componentResolver: function componentResolver() {
return null;
},
attributeModifier: function attributeModifier() {
return {};
},
onSelectionChange: function onSelectionChange() {
return console.warn('[TableView] no onSelectionChange prop provided');
},
onSelect: function onSelect() {
return console.warn('[TableView] no onSelect prop provided');
},
onSortChange: function onSortChange(key, direction, type) {}
/*
{
key: 'enabled',
value: ' ',
width: 30,
Cell: FixedDataTableStatusCell,
},
*/
/**
*
*/
};var TableView = (_temp = _class = function (_Component) {
_inherits(TableView, _Component);
function TableView(props) {
_classCallCheck(this, TableView);
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
_initialiseProps.call(_this);
_this.lastSelectedId = null;
_this.lastSelectedList = [];
_this.handleResize = (0, _debounce3.default)(_this.handleResize, 200);
_this.fieldsHash = (0, _lifecycleUtils.getDataHash)(_this.getTableFields(props));
var columnKey = localStorage[_this.fieldsHash + '_sortField'] || props.defaultSortField;
var sortDirection = localStorage[_this.fieldsHash + '_sortDirection'] || props.defaultSortDirection;
var data = (props.data || []).sort((0, _tableUtils.sortByObjectKey)(columnKey, sortDirection));
_this.state = {
inited: false,
data: data,
preSortedData: props.data,
selectedIds: props.selectedIds,
tableWidth: props.tableWidth,
tableHeight: props.tableHeight,
columnKey: columnKey,
sortDirection: sortDirection
};
return _this;
}
TableView.prototype.getTableFields = function getTableFields() {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.props;
var tableFields = [];
if (props.schema instanceof Array && props.schema.length) tableFields = (0, _tableUtils.getFieldsFromSchemaAndAssociations)(props.schema, props.associations, props.componentResolver, props.attributeModifier);else if (props.fields instanceof Array && props.fields.length) tableFields = (0, _tableUtils.normalizeFields)(props.fields);
if (props.checkboxSelection) {
tableFields = [{
fixed: true,
resizable: false,
order: -999,
width: 28,
Cell: _FixedDataTableCheckboxSelectCell2.default,
HeaderCell: _FixedDataTableCheckboxSelectHeaderCell2.default
}].concat(tableFields);
}
return tableFields;
};
TableView.prototype.componentDidUpdate = function componentDidUpdate() {
localStorage[this.fieldsHash + '_sortField'] = this.state.columnKey;
localStorage[this.fieldsHash + '_sortDirection'] = this.state.sortDirection;
};
TableView.prototype.componentDidMount = function componentDidMount() {
window.addEventListener('resize', this.handleResize);
window.addEventListener('keydown', this.handleKeyDown);
this.handleResize();
};
TableView.prototype.componentWillUnmount = function componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
window.removeEventListener('keydown', this.handleKeyDown);
};
TableView.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
var _this2 = this;
Object.keys(nextProps).map(function (key) {
if (key == 'data') {
if (!(0, _deepEqual2.default)(_this2.state.preSortedData, nextProps.data)) {
var data = _this2.sortData(nextProps.data.map(function (item) {
// this is temporary because dummy data had weird date format, won't break when changed to real data but should be removed
if ('modified' in item) item.modified = (0, _timeUtils.formatDate)(item.modified, dateTimeFormat);
if ('created' in item) item.created = (0, _timeUtils.formatDate)(item.created, dateTimeFormat);
return item;
}));
_this2.setState({ data: data, preSortedData: nextProps.data });
}
// if prop key is in state then update it in state
} else if (key in _this2.state && nextProps[key] != _defaultProps[key] && !(0, _isEqual3.default)(nextProps[key], _this2.state[key])) {
var _this2$setState;
_this2.setState((_this2$setState = {}, _this2$setState[key] = nextProps[key], _this2$setState));
}
});
};
TableView.prototype.handleSelectAll = function handleSelectAll() {
var data = this.state.data;
var selectedIds = data.map(function (row) {
return row.id;
});
this.lastSelectedList = selectedIds.slice();
if (!this.props.uncontrolled) {
this.props.onSelectionChange(selectedIds);
} else {
this.setState({ selectedIds: selectedIds });
}
};
TableView.prototype.handleDeselectAll = function handleDeselectAll() {
this.lastSelectedList = [];
var selectedIds = [];
if (!this.props.uncontrolled) {
this.props.onSelectionChange(selectedIds);
} else {
this.setState({ selectedIds: selectedIds });
}
};
TableView.prototype.sortData = function sortData(data) {
var _state = this.state,
columnKey = _state.columnKey,
sortDirection = _state.sortDirection;
return data.sort((0, _tableUtils.sortByObjectKey)(columnKey, sortDirection));
};
TableView.prototype.render = function render() {
var _state2 = this.state,
inited = _state2.inited,
data = _state2.data,
selectedIds = _state2.selectedIds,
tableWidth = _state2.tableWidth,
tableHeight = _state2.tableHeight,
columnKey = _state2.columnKey,
sortDirection = _state2.sortDirection;
var _props = this.props,
cellWidth = _props.cellWidth,
rowHeight = _props.rowHeight;
var tableFields = this.getTableFields();
return _react2.default.createElement(
'div',
{ ref: 'tableContainer', style: !inited ? { opacity: 0 } : {} },
_react2.default.createElement(_FixedDataTable2.default, _extends({}, this.props, {
uncontrolled: false,
data: data,
fields: tableFields,
selectedIds: selectedIds,
tableWidth: tableWidth,
tableHeight: tableHeight,
cellWidth: cellWidth,
rowHeight: rowHeight,
columnKey: columnKey,
sortDirection: sortDirection,
onSelect: this.handleSelect,
onSelected: this.handleSelected,
onSortChange: this.onSortChange,
onSelectionChange: this.props.onSelectionChange
}))
);
};
return TableView;
}(_react.Component), _class.defaultProps = _defaultProps, _class.propTypes = {
/** Array of objects representing table rows */
data: _propTypes2.default.arrayOf(_propTypes2.default.object),
/** Array of objects representing table columns/schema */
fields: _propTypes2.default.arrayOf(_propTypes2.default.object),
/** array of table schema passed in from backend */
schema: _propTypes2.default.array,
/** array of entity assocations passed in from backend */
assocations: _propTypes2.default.array,
/** Array of selected row ids */
selectedIds: _propTypes2.default.arrayOf(_propTypes2.default.number),
/** Whether or not component should control its own sorting */
uncontrolled: _propTypes2.default.bool,
/** Whether or not to inject a checkbox column to control selection state */
checkboxSelection: _propTypes2.default.bool,
tableWidth: _propTypes2.default.number,
tableHeight: _propTypes2.default.number,
fixedHeight: _propTypes2.default.bool,
fixedWidth: _propTypes2.default.bool,
cellWidth: _propTypes2.default.number,
rowHeight: _propTypes2.default.number,
headerHeight: _propTypes2.default.number,
/** column key to sort by, can even be nested e.g. 'collection.title' */
defaultSortField: _propTypes2.default.string,
defaultSortDirections: _propTypes2.default.oneOf([SortTypes.ASC, SortTypes.DESC]),
/** On row(s) selection change */
onSelectionChange: _propTypes2.default.func,
/** On row double click */
onSelect: _propTypes2.default.func,
/** Component to replace default HeaderCell -- invisibly passed into FixedDataTable */
HeaderCell: _propTypes2.default.func,
/** Component to replace default table cell component -- invisibly passed into FixedDataTable */
DefaultCell: _propTypes2.default.func
}, _initialiseProps = function _initialiseProps() {
var _this3 = this;
this.handleResize = function () {
var tableContainer = _this3.refs.tableContainer;
if (!tableContainer) return;
var boundingRect = tableContainer.getBoundingClientRect();
var _props2 = _this3.props,
negativeHeight = _props2.negativeHeight,
fixedHeight = _props2.fixedHeight,
tableHeight = _props2.tableHeight,
fixedWidth = _props2.fixedWidth,
tableWidth = _props2.tableWidth;
// shortcut logic so we not constantly setting state when not needed
if (_this3.state.inited && fixedWidth && fixedHeight) return;
_this3.setState({
inited: true,
tableWidth: fixedWidth ? tableWidth : boundingRect.width,
tableHeight: fixedHeight ? tableHeight : window.innerHeight - negativeHeight
});
};
this.handleKeyDown = function (event) {
var data = _this3.state.data;
if (!data.length) return;
var key = (0, _keycode2.default)(event);
var activeElement = document.activeElement;
if (!activeElement || activeElement.nodeName !== 'INPUT' && activeElement.nodeName !== 'TEXTAREA') {
if (key === 'up') {
event.preventDefault();
var index = _this3.lastSelectedId === null ? data.length - 1 : data.reduce(function (value, row, i) {
return row.id === _this3.lastSelectedId ? i - 1 : value;
}, null);
_this3.handleSelect(data[index <= 0 ? 0 : index]);
} else if (key === 'down') {
event.preventDefault();
var _index = _this3.lastSelectedId === null ? 0 : data.reduce(function (value, row, i) {
return row.id === _this3.lastSelectedId ? i + 1 : value;
}, null);
_this3.handleSelect(data[_index >= data.length - 1 ? data.length - 1 : _index]);
} else if (key == 'esc') {
event.preventDefault();
_this3.handleDeselectAll();
} else if (key == 'a' && (0, _selectKeyUtils.isCtrlKeyPressed)()) {
event.preventDefault();
_this3.handleSelectAll();
}
}
};
this.handleSelect = function (row) {
var _props3 = _this3.props,
multiselect = _props3.multiselect,
allowSelection = _props3.allowSelection,
stickySelect = _props3.stickySelect,
checkboxSelection = _props3.checkboxSelection;
if (!allowSelection) return;
var selectedIds = _this3.state.selectedIds;
if (!multiselect || !checkboxSelection && !(0, _selectKeyUtils.isCtrlKeyPressed)() && !(0, _selectKeyUtils.isShiftKeyPressed)()) {
selectedIds = selectedIds.length === 1 && selectedIds[0] === row.id && !stickySelect ? [] : [row.id];
} else if ((0, _selectKeyUtils.isShiftKeyPressed)()) {
var data = _this3.state.data;
var lastIndex = data.indexOf(data.filter(function (item) {
return item.id === _this3.lastSelectedId;
})[0]);
var nextIndex = data.indexOf(data.filter(function (item) {
return item.id === row.id;
})[0]);
var lower = Math.min(lastIndex, nextIndex);
var upper = Math.max(lastIndex, nextIndex);
selectedIds = [].concat(_this3.lastSelectedList, data.filter(function (item, i) {
return i >= lower && i <= upper;
}).map(function (item) {
return item.id;
}));
} else if ((0, _selectKeyUtils.isCtrlKeyPressed)() || checkboxSelection) {
selectedIds = selectedIds.indexOf(row.id) >= 0 ? selectedIds.filter(function (id) {
return id !== row.id;
}) : [].concat(selectedIds, [row.id]);
}
// remove any duplicate ids
selectedIds = selectedIds.filter(function (val, i) {
return selectedIds.indexOf(val) === i;
});
_this3.lastSelectedId = row.id;
_this3.lastSelectedList = selectedIds.slice();
if (!_this3.props.uncontrolled) {
_this3.props.onSelectionChange(selectedIds);
} else {
_this3.setState({ selectedIds: selectedIds });
}
};
this.handleSelected = function (row) {
_this3.props.onSelect(row);
};
this.onSortChange = function (columnKey, sortDirection, sortType) {
var data = [].concat(_this3.state.data).sort((0, _tableUtils.sortByObjectKey)(columnKey, sortDirection, sortType));
_this3.props.onSortChange(columnKey, sortDirection, sortType);
_this3.setState({ data: data, columnKey: columnKey, sortDirection: sortDirection });
};
}, _temp);
exports.default = TableView;