UNPKG

react-trello

Version:

Pluggable components to add a trello like kanban board to your application

391 lines (354 loc) 14.3 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _redux = require("redux"); var _reactRedux = require("react-redux"); var _isEqual = _interopRequireDefault(require("lodash/isEqual")); var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep")); var _pick = _interopRequireDefault(require("lodash/pick")); var _v = _interopRequireDefault(require("uuid/v1")); var _Container = _interopRequireDefault(require("../dnd/Container")); var _Draggable = _interopRequireDefault(require("../dnd/Draggable")); var laneActions = _interopRequireWildcard(require("../actions/LaneActions")); class Lane extends _react.Component { constructor(...args) { super(...args); (0, _defineProperty2.default)(this, "state", { loading: false, currentPage: this.props.currentPage, addCardMode: false, collapsed: false, isDraggingOver: false }); (0, _defineProperty2.default)(this, "handleScroll", evt => { const node = evt.target; const elemScrollPosition = node.scrollHeight - node.scrollTop - node.clientHeight; const onLaneScroll = this.props.onLaneScroll; // In some browsers and/or screen sizes a decimal rest value between 0 and 1 exists, so it should be checked on < 1 instead of < 0 if (elemScrollPosition < 1 && onLaneScroll && !this.state.loading) { const currentPage = this.state.currentPage; this.setState({ loading: true }); const nextPage = currentPage + 1; onLaneScroll(nextPage, this.props.id).then(moreCards => { if ((moreCards || []).length > 0) { this.props.actions.paginateLane({ laneId: this.props.id, newCards: moreCards, nextPage: nextPage }); } this.setState({ loading: false }); }); } }); (0, _defineProperty2.default)(this, "laneDidMount", node => { if (node) { node.addEventListener('scroll', this.handleScroll); } }); (0, _defineProperty2.default)(this, "removeCard", cardId => { if (this.props.onBeforeCardDelete && typeof this.props.onBeforeCardDelete === 'function') { this.props.onBeforeCardDelete(() => { this.props.onCardDelete && this.props.onCardDelete(cardId, this.props.id); this.props.actions.removeCard({ laneId: this.props.id, cardId: cardId }); }); } else { this.props.onCardDelete && this.props.onCardDelete(cardId, this.props.id); this.props.actions.removeCard({ laneId: this.props.id, cardId: cardId }); } }); (0, _defineProperty2.default)(this, "handleCardClick", (e, card) => { const onCardClick = this.props.onCardClick; onCardClick && onCardClick(card.id, card.metadata, card.laneId); e.stopPropagation(); }); (0, _defineProperty2.default)(this, "showEditableCard", () => { this.setState({ addCardMode: true }); }); (0, _defineProperty2.default)(this, "hideEditableCard", () => { this.setState({ addCardMode: false }); }); (0, _defineProperty2.default)(this, "addNewCard", params => { const laneId = this.props.id; const id = (0, _v.default)(); this.hideEditableCard(); let card = (0, _objectSpread2.default)({ id }, params); this.props.actions.addCard({ laneId, card }); this.props.onCardAdd(card, laneId); }); (0, _defineProperty2.default)(this, "onDragStart", ({ payload }) => { const handleDragStart = this.props.handleDragStart; handleDragStart && handleDragStart(payload.id, payload.laneId); }); (0, _defineProperty2.default)(this, "shouldAcceptDrop", sourceContainerOptions => { return this.props.droppable && sourceContainerOptions.groupName === this.groupName; }); (0, _defineProperty2.default)(this, "onDragEnd", (laneId, result) => { const handleDragEnd = this.props.handleDragEnd; const addedIndex = result.addedIndex, payload = result.payload; if (this.state.isDraggingOver) { this.setState({ isDraggingOver: false }); } if (addedIndex != null) { const newCard = (0, _objectSpread2.default)({}, (0, _cloneDeep.default)(payload), { laneId }); const response = handleDragEnd ? handleDragEnd(payload.id, payload.laneId, laneId, addedIndex, newCard) : true; if (response === undefined || !!response) { this.props.actions.moveCardAcrossLanes({ fromLaneId: payload.laneId, toLaneId: laneId, cardId: payload.id, index: addedIndex }); this.props.onCardMoveAcrossLanes(payload.laneId, laneId, payload.id, addedIndex); } return response; } }); (0, _defineProperty2.default)(this, "updateCard", updatedCard => { this.props.actions.updateCard({ laneId: this.props.id, card: updatedCard }); this.props.onCardUpdate(this.props.id, updatedCard); }); (0, _defineProperty2.default)(this, "renderDragContainer", isDraggingOver => { const _this$props = this.props, id = _this$props.id, cards = _this$props.cards, laneSortFunction = _this$props.laneSortFunction, editable = _this$props.editable, hideCardDeleteIcon = _this$props.hideCardDeleteIcon, cardDraggable = _this$props.cardDraggable, cardDragClass = _this$props.cardDragClass, cardDropClass = _this$props.cardDropClass, tagStyle = _this$props.tagStyle, cardStyle = _this$props.cardStyle, components = _this$props.components, t = _this$props.t; const _this$state = this.state, addCardMode = _this$state.addCardMode, collapsed = _this$state.collapsed; const showableCards = collapsed ? [] : cards; const cardList = this.sortCards(showableCards, laneSortFunction).map((card, idx) => { const onDeleteCard = () => this.removeCard(card.id); const cardToRender = _react.default.createElement(components.Card, (0, _extends2.default)({ key: card.id, index: idx, style: card.style || cardStyle, className: "react-trello-card", onDelete: onDeleteCard, onClick: e => this.handleCardClick(e, card), onChange: updatedCard => this.updateCard(updatedCard), showDeleteButton: !hideCardDeleteIcon, tagStyle: tagStyle, cardDraggable: cardDraggable, editable: editable, t: t }, card)); return cardDraggable && (!card.hasOwnProperty('draggable') || card.draggable) ? _react.default.createElement(_Draggable.default, { key: card.id }, cardToRender) : _react.default.createElement("span", { key: card.id }, cardToRender); }); return _react.default.createElement(components.ScrollableLane, { ref: this.laneDidMount, isDraggingOver: isDraggingOver }, _react.default.createElement(_Container.default, { orientation: "vertical", groupName: this.groupName, dragClass: cardDragClass, dropClass: cardDropClass, onDragStart: this.onDragStart, onDrop: e => this.onDragEnd(id, e), onDragEnter: () => this.setState({ isDraggingOver: true }), onDragLeave: () => this.setState({ isDraggingOver: false }), shouldAcceptDrop: this.shouldAcceptDrop, getChildPayload: index => this.props.getCardDetails(id, index) }, cardList), editable && !addCardMode && _react.default.createElement(components.AddCardLink, { onClick: this.showEditableCard, t: t, laneId: id }), addCardMode && _react.default.createElement(components.NewCardForm, { onCancel: this.hideEditableCard, t: t, laneId: id, onAdd: this.addNewCard })); }); (0, _defineProperty2.default)(this, "removeLane", () => { const id = this.props.id; this.props.actions.removeLane({ laneId: id }); this.props.onLaneDelete(id); }); (0, _defineProperty2.default)(this, "updateTitle", value => { this.props.actions.updateLane({ id: this.props.id, title: value }); this.props.onLaneUpdate(this.props.id, { title: value }); }); (0, _defineProperty2.default)(this, "renderHeader", pickedProps => { const components = this.props.components; return _react.default.createElement(components.LaneHeader, (0, _extends2.default)({}, pickedProps, { onDelete: this.removeLane, onDoubleClick: this.toggleLaneCollapsed, updateTitle: this.updateTitle })); }); (0, _defineProperty2.default)(this, "toggleLaneCollapsed", () => { this.props.collapsibleLanes && this.setState(state => ({ collapsed: !state.collapsed })); }); } sortCards(cards, sortFunction) { if (!cards) return []; if (!sortFunction) return cards; return cards.concat().sort(function (card1, card2) { return sortFunction(card1, card2); }); } UNSAFE_componentWillReceiveProps(nextProps) { if (!(0, _isEqual.default)(this.props.cards, nextProps.cards)) { this.setState({ currentPage: nextProps.currentPage }); } } get groupName() { const boardId = this.props.boardId; return "TrelloBoard".concat(boardId, "Lane"); } render() { const _this$state2 = this.state, loading = _this$state2.loading, isDraggingOver = _this$state2.isDraggingOver, collapsed = _this$state2.collapsed; const _this$props2 = this.props, id = _this$props2.id, cards = _this$props2.cards, collapsibleLanes = _this$props2.collapsibleLanes, components = _this$props2.components, onLaneClick = _this$props2.onLaneClick, onLaneScroll = _this$props2.onLaneScroll, onCardClick = _this$props2.onCardClick, onCardAdd = _this$props2.onCardAdd, onBeforeCardDelete = _this$props2.onBeforeCardDelete, onCardDelete = _this$props2.onCardDelete, onLaneDelete = _this$props2.onLaneDelete, onLaneUpdate = _this$props2.onLaneUpdate, onCardUpdate = _this$props2.onCardUpdate, onCardMoveAcrossLanes = _this$props2.onCardMoveAcrossLanes, otherProps = (0, _objectWithoutProperties2.default)(_this$props2, ["id", "cards", "collapsibleLanes", "components", "onLaneClick", "onLaneScroll", "onCardClick", "onCardAdd", "onBeforeCardDelete", "onCardDelete", "onLaneDelete", "onLaneUpdate", "onCardUpdate", "onCardMoveAcrossLanes"]); const allClassNames = (0, _classnames.default)('react-trello-lane', this.props.className || ''); const showFooter = collapsibleLanes && cards.length > 0; return _react.default.createElement(components.Section, (0, _extends2.default)({}, otherProps, { key: id, onClick: () => onLaneClick && onLaneClick(id), draggable: false, className: allClassNames }), this.renderHeader((0, _objectSpread2.default)({ id, cards }, otherProps)), this.renderDragContainer(isDraggingOver), loading && _react.default.createElement(components.Loader, null), showFooter && _react.default.createElement(components.LaneFooter, { onClick: this.toggleLaneCollapsed, collapsed: collapsed })); } } Lane.propTypes = { actions: _propTypes.default.object, id: _propTypes.default.string.isRequired, boardId: _propTypes.default.string, title: _propTypes.default.node, index: _propTypes.default.number, laneSortFunction: _propTypes.default.func, style: _propTypes.default.object, cardStyle: _propTypes.default.object, tagStyle: _propTypes.default.object, titleStyle: _propTypes.default.object, labelStyle: _propTypes.default.object, cards: _propTypes.default.array, label: _propTypes.default.string, currentPage: _propTypes.default.number, draggable: _propTypes.default.bool, collapsibleLanes: _propTypes.default.bool, droppable: _propTypes.default.bool, onCardMoveAcrossLanes: _propTypes.default.func, onCardClick: _propTypes.default.func, onBeforeCardDelete: _propTypes.default.func, onCardDelete: _propTypes.default.func, onCardAdd: _propTypes.default.func, onCardUpdate: _propTypes.default.func, onLaneDelete: _propTypes.default.func, onLaneUpdate: _propTypes.default.func, onLaneClick: _propTypes.default.func, onLaneScroll: _propTypes.default.func, editable: _propTypes.default.bool, laneDraggable: _propTypes.default.bool, cardDraggable: _propTypes.default.bool, cardDragClass: _propTypes.default.string, cardDropClass: _propTypes.default.string, canAddLanes: _propTypes.default.bool, t: _propTypes.default.func.isRequired }; Lane.defaultProps = { style: {}, titleStyle: {}, labelStyle: {}, label: undefined, editable: false, onLaneUpdate: () => {}, onCardAdd: () => {}, onCardUpdate: () => {} }; const mapDispatchToProps = dispatch => ({ actions: (0, _redux.bindActionCreators)(laneActions, dispatch) }); var _default = (0, _reactRedux.connect)(null, mapDispatchToProps)(Lane); exports.default = _default;