Introduce React-Trello in place of React-Kanban
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
19
client/src/components/trello-board/controllers/Board.jsx
Normal file
19
client/src/components/trello-board/controllers/Board.jsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { BoardContainer } from "../index.jsx";
|
||||
import classNames from "classnames";
|
||||
import { useState } from "react";
|
||||
import { v1 } from "uuid";
|
||||
|
||||
const Board = ({ id, className, components, ...additionalProps }) => {
|
||||
const [storeId] = useState(id || v1());
|
||||
|
||||
const allClassNames = classNames("react-trello-board", className || "");
|
||||
|
||||
return (
|
||||
<>
|
||||
<components.GlobalStyle />
|
||||
<BoardContainer components={components} {...additionalProps} id={storeId} className={allClassNames} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Board;
|
||||
@@ -0,0 +1,294 @@
|
||||
import React, { Component } from "react";
|
||||
import { bindActionCreators } from "redux";
|
||||
import { connect } from "react-redux";
|
||||
import Container from "../dnd/Container";
|
||||
import Draggable from "../dnd/Draggable";
|
||||
import PropTypes from "prop-types";
|
||||
import pick from "lodash/pick";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import Lane from "./Lane";
|
||||
import { PopoverWrapper } from "react-popopo";
|
||||
|
||||
import * as actions from "../../../redux/trello/trello.actions.js";
|
||||
|
||||
class BoardContainer extends Component {
|
||||
state = {
|
||||
addLaneMode: false
|
||||
};
|
||||
|
||||
get groupName() {
|
||||
const { id } = this.props;
|
||||
return `TrelloBoard${id}`;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { actions, eventBusHandle } = this.props;
|
||||
actions.loadBoard(this.props.data);
|
||||
if (eventBusHandle) {
|
||||
this.wireEventBus();
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { data, reducerData, onDataChange, actions } = this.props;
|
||||
|
||||
if (this.props.reducerData && !isEqual(reducerData, prevProps.reducerData)) {
|
||||
onDataChange(this.props.reducerData);
|
||||
}
|
||||
|
||||
if (data && !isEqual(data, prevProps.data)) {
|
||||
actions.loadBoard(data);
|
||||
onDataChange(data);
|
||||
}
|
||||
}
|
||||
|
||||
onDragStart = ({ payload }) => {
|
||||
const { handleLaneDragStart } = this.props;
|
||||
handleLaneDragStart(payload.id);
|
||||
};
|
||||
|
||||
onLaneDrop = ({ removedIndex, addedIndex, payload }) => {
|
||||
const { actions, handleLaneDragEnd } = this.props;
|
||||
if (removedIndex !== addedIndex) {
|
||||
actions.moveLane({ oldIndex: removedIndex, newIndex: addedIndex });
|
||||
handleLaneDragEnd(removedIndex, addedIndex, payload);
|
||||
}
|
||||
};
|
||||
|
||||
getCardDetails = (laneId, cardIndex) => {
|
||||
return this.props.reducerData.lanes.find((lane) => lane.id === laneId).cards[cardIndex];
|
||||
};
|
||||
|
||||
getLaneDetails = (index) => {
|
||||
return this.props.reducerData.lanes[index];
|
||||
};
|
||||
|
||||
wireEventBus = () => {
|
||||
const { actions, eventBusHandle } = this.props;
|
||||
let eventBus = {
|
||||
publish: (event) => {
|
||||
switch (event.type) {
|
||||
case "ADD_CARD":
|
||||
return actions.addCard({ laneId: event.laneId, card: event.card });
|
||||
case "UPDATE_CARD":
|
||||
return actions.updateCard({ laneId: event.laneId, card: event.card });
|
||||
case "REMOVE_CARD":
|
||||
return actions.removeCard({ laneId: event.laneId, cardId: event.cardId });
|
||||
case "REFRESH_BOARD":
|
||||
return actions.loadBoard(event.data);
|
||||
case "MOVE_CARD":
|
||||
return actions.moveCardAcrossLanes({
|
||||
fromLaneId: event.fromLaneId,
|
||||
toLaneId: event.toLaneId,
|
||||
cardId: event.cardId,
|
||||
index: event.index
|
||||
});
|
||||
case "UPDATE_CARDS":
|
||||
return actions.updateCards({ laneId: event.laneId, cards: event.cards });
|
||||
case "UPDATE_CARD":
|
||||
return actions.updateCard({ laneId: event.laneId, updatedCard: event.card });
|
||||
case "UPDATE_LANES":
|
||||
return actions.updateLanes(event.lanes);
|
||||
case "UPDATE_LANE":
|
||||
return actions.updateLane(event.lane);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
eventBusHandle(eventBus);
|
||||
};
|
||||
|
||||
// + add
|
||||
hideEditableLane = () => {
|
||||
this.setState({ addLaneMode: false });
|
||||
};
|
||||
|
||||
showEditableLane = () => {
|
||||
this.setState({ addLaneMode: true });
|
||||
};
|
||||
|
||||
addNewLane = (params) => {
|
||||
this.hideEditableLane();
|
||||
this.props.actions.addLane(params);
|
||||
this.props.onLaneAdd(params);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
id,
|
||||
components,
|
||||
reducerData,
|
||||
draggable,
|
||||
laneDraggable,
|
||||
laneDragClass,
|
||||
laneDropClass,
|
||||
style,
|
||||
onDataChange,
|
||||
onCardAdd,
|
||||
onCardUpdate,
|
||||
onCardClick,
|
||||
onBeforeCardDelete,
|
||||
onCardDelete,
|
||||
onLaneScroll,
|
||||
onLaneClick,
|
||||
onLaneAdd,
|
||||
onLaneDelete,
|
||||
onLaneUpdate,
|
||||
editable,
|
||||
canAddLanes,
|
||||
laneStyle,
|
||||
onCardMoveAcrossLanes,
|
||||
t,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
const { addLaneMode } = this.state;
|
||||
// Stick to whitelisting attributes to segregate board and lane props
|
||||
const passthroughProps = pick(this.props, [
|
||||
"onCardMoveAcrossLanes",
|
||||
"onLaneScroll",
|
||||
"onLaneDelete",
|
||||
"onLaneUpdate",
|
||||
"onCardClick",
|
||||
"onBeforeCardDelete",
|
||||
"onCardDelete",
|
||||
"onCardAdd",
|
||||
"onCardUpdate",
|
||||
"onLaneClick",
|
||||
"laneSortFunction",
|
||||
"draggable",
|
||||
"laneDraggable",
|
||||
"cardDraggable",
|
||||
"collapsibleLanes",
|
||||
"canAddLanes",
|
||||
"hideCardDeleteIcon",
|
||||
"tagStyle",
|
||||
"handleDragStart",
|
||||
"handleDragEnd",
|
||||
"cardDragClass",
|
||||
"editLaneTitle",
|
||||
"t"
|
||||
]);
|
||||
|
||||
return (
|
||||
<components.BoardWrapper style={style} {...otherProps} draggable={false}>
|
||||
<PopoverWrapper>
|
||||
<Container
|
||||
orientation="horizontal"
|
||||
onDragStart={this.onDragStart}
|
||||
dragClass={laneDragClass}
|
||||
dropClass={laneDropClass}
|
||||
onDrop={this.onLaneDrop}
|
||||
lockAxis="x"
|
||||
getChildPayload={(index) => this.getLaneDetails(index)}
|
||||
groupName={this.groupName}
|
||||
>
|
||||
{reducerData.lanes.map((lane, index) => {
|
||||
const { id, droppable, ...otherProps } = lane;
|
||||
const laneToRender = (
|
||||
<Lane
|
||||
key={id}
|
||||
boardId={this.groupName}
|
||||
components={components}
|
||||
id={id}
|
||||
getCardDetails={this.getCardDetails}
|
||||
index={index}
|
||||
droppable={droppable === undefined ? true : droppable}
|
||||
style={laneStyle || lane.style || {}}
|
||||
labelStyle={lane.labelStyle || {}}
|
||||
cardStyle={this.props.cardStyle || lane.cardStyle}
|
||||
editable={editable && !lane.disallowAddingCard}
|
||||
{...otherProps}
|
||||
{...passthroughProps}
|
||||
/>
|
||||
);
|
||||
return draggable && laneDraggable ? <Draggable key={lane.id}>{laneToRender}</Draggable> : laneToRender;
|
||||
})}
|
||||
</Container>
|
||||
</PopoverWrapper>
|
||||
{canAddLanes && (
|
||||
<Container orientation="horizontal">
|
||||
{editable && !addLaneMode ? (
|
||||
<components.NewLaneSection t={t} onClick={this.showEditableLane} />
|
||||
) : (
|
||||
addLaneMode && <components.NewLaneForm onCancel={this.hideEditableLane} onAdd={this.addNewLane} t={t} />
|
||||
)}
|
||||
</Container>
|
||||
)}
|
||||
</components.BoardWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
BoardContainer.propTypes = {
|
||||
id: PropTypes.string,
|
||||
components: PropTypes.object,
|
||||
actions: PropTypes.object,
|
||||
data: PropTypes.object.isRequired,
|
||||
reducerData: PropTypes.object,
|
||||
onDataChange: PropTypes.func,
|
||||
eventBusHandle: PropTypes.func,
|
||||
onLaneScroll: PropTypes.func,
|
||||
onCardClick: PropTypes.func,
|
||||
onBeforeCardDelete: PropTypes.func,
|
||||
onCardDelete: PropTypes.func,
|
||||
onCardAdd: PropTypes.func,
|
||||
onCardUpdate: PropTypes.func,
|
||||
onLaneAdd: PropTypes.func,
|
||||
onLaneDelete: PropTypes.func,
|
||||
onLaneClick: PropTypes.func,
|
||||
onLaneUpdate: PropTypes.func,
|
||||
laneSortFunction: PropTypes.func,
|
||||
draggable: PropTypes.bool,
|
||||
collapsibleLanes: PropTypes.bool,
|
||||
editable: PropTypes.bool,
|
||||
canAddLanes: PropTypes.bool,
|
||||
hideCardDeleteIcon: PropTypes.bool,
|
||||
handleDragStart: PropTypes.func,
|
||||
handleDragEnd: PropTypes.func,
|
||||
handleLaneDragStart: PropTypes.func,
|
||||
handleLaneDragEnd: PropTypes.func,
|
||||
style: PropTypes.object,
|
||||
tagStyle: PropTypes.object,
|
||||
laneDraggable: PropTypes.bool,
|
||||
cardDraggable: PropTypes.bool,
|
||||
cardDragClass: PropTypes.string,
|
||||
laneDragClass: PropTypes.string,
|
||||
laneDropClass: PropTypes.string,
|
||||
onCardMoveAcrossLanes: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
BoardContainer.defaultProps = {
|
||||
t: (v) => v,
|
||||
onDataChange: () => {},
|
||||
handleDragStart: () => {},
|
||||
handleDragEnd: () => {},
|
||||
handleLaneDragStart: () => {},
|
||||
handleLaneDragEnd: () => {},
|
||||
onCardUpdate: () => {},
|
||||
onLaneAdd: () => {},
|
||||
onLaneDelete: () => {},
|
||||
onCardMoveAcrossLanes: () => {},
|
||||
onLaneUpdate: () => {},
|
||||
editable: false,
|
||||
canAddLanes: false,
|
||||
hideCardDeleteIcon: false,
|
||||
draggable: false,
|
||||
collapsibleLanes: false,
|
||||
laneDraggable: true,
|
||||
cardDraggable: true,
|
||||
cardDragClass: "react_trello_dragClass",
|
||||
laneDragClass: "react_trello_dragLaneClass",
|
||||
laneDropClass: ""
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => {
|
||||
return state.trello.lanes ? { reducerData: state.trello } : {};
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
actions: bindActionCreators({ ...actions }, dispatch)
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(BoardContainer);
|
||||
328
client/src/components/trello-board/controllers/Lane.jsx
Normal file
328
client/src/components/trello-board/controllers/Lane.jsx
Normal file
@@ -0,0 +1,328 @@
|
||||
import React, { Component } from "react";
|
||||
import classNames from "classnames";
|
||||
import PropTypes from "prop-types";
|
||||
import { bindActionCreators } from "redux";
|
||||
import { connect } from "react-redux";
|
||||
import isEqual from "lodash/isEqual";
|
||||
import cloneDeep from "lodash/cloneDeep";
|
||||
import { v1 } from "uuid";
|
||||
|
||||
import Container from "../dnd/Container.jsx";
|
||||
import Draggable from "../dnd/Draggable.jsx";
|
||||
|
||||
import * as actions from "../../../redux/trello/trello.actions.js";
|
||||
|
||||
class Lane extends Component {
|
||||
state = {
|
||||
loading: false,
|
||||
currentPage: this.props.currentPage,
|
||||
addCardMode: false,
|
||||
collapsed: false,
|
||||
isDraggingOver: false
|
||||
};
|
||||
|
||||
get groupName() {
|
||||
const { boardId } = this.props;
|
||||
return `TrelloBoard${boardId}Lane`;
|
||||
}
|
||||
|
||||
handleScroll = (evt) => {
|
||||
const node = evt.target;
|
||||
const elemScrollPosition = node.scrollHeight - node.scrollTop - node.clientHeight;
|
||||
const { onLaneScroll } = this.props;
|
||||
// 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;
|
||||
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 });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
sortCards(cards, sortFunction) {
|
||||
if (!cards) return [];
|
||||
if (!sortFunction) return cards;
|
||||
return cards.concat().sort(function (card1, card2) {
|
||||
return sortFunction(card1, card2);
|
||||
});
|
||||
}
|
||||
|
||||
laneDidMount = (node) => {
|
||||
if (node) {
|
||||
node.addEventListener("scroll", this.handleScroll);
|
||||
}
|
||||
};
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if (!isEqual(this.props.cards, nextProps.cards)) {
|
||||
this.setState({
|
||||
currentPage: nextProps.currentPage
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
};
|
||||
|
||||
handleCardClick = (e, card) => {
|
||||
const { onCardClick } = this.props;
|
||||
onCardClick && onCardClick(card.id, card.metadata, card.laneId);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
showEditableCard = () => {
|
||||
this.setState({ addCardMode: true });
|
||||
};
|
||||
|
||||
hideEditableCard = () => {
|
||||
this.setState({ addCardMode: false });
|
||||
};
|
||||
|
||||
addNewCard = (params) => {
|
||||
const laneId = this.props.id;
|
||||
const id = v1();
|
||||
this.hideEditableCard();
|
||||
let card = { id, ...params };
|
||||
this.props.actions.addCard({ laneId, card });
|
||||
this.props.onCardAdd(card, laneId);
|
||||
};
|
||||
|
||||
onDragStart = ({ payload }) => {
|
||||
const { handleDragStart } = this.props;
|
||||
handleDragStart && handleDragStart(payload.id, payload.laneId);
|
||||
};
|
||||
|
||||
shouldAcceptDrop = (sourceContainerOptions) => {
|
||||
return this.props.droppable && sourceContainerOptions.groupName === this.groupName;
|
||||
};
|
||||
|
||||
onDragEnd = (laneId, result) => {
|
||||
const { handleDragEnd } = this.props;
|
||||
const { addedIndex, payload } = result;
|
||||
|
||||
if (this.state.isDraggingOver) {
|
||||
this.setState({ isDraggingOver: false });
|
||||
}
|
||||
|
||||
if (addedIndex != null) {
|
||||
const newCard = { ...cloneDeep(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;
|
||||
}
|
||||
};
|
||||
|
||||
updateCard = (updatedCard) => {
|
||||
this.props.actions.updateCard({ laneId: this.props.id, card: updatedCard });
|
||||
this.props.onCardUpdate(this.props.id, updatedCard);
|
||||
};
|
||||
|
||||
renderDragContainer = (isDraggingOver) => {
|
||||
const {
|
||||
id,
|
||||
cards,
|
||||
laneSortFunction,
|
||||
editable,
|
||||
hideCardDeleteIcon,
|
||||
cardDraggable,
|
||||
cardDragClass,
|
||||
cardDropClass,
|
||||
tagStyle,
|
||||
cardStyle,
|
||||
components,
|
||||
t
|
||||
} = this.props;
|
||||
const { addCardMode, collapsed } = this.state;
|
||||
|
||||
const showableCards = collapsed ? [] : cards;
|
||||
|
||||
const cardList = this.sortCards(showableCards, laneSortFunction).map((card, idx) => {
|
||||
const onDeleteCard = () => this.removeCard(card.id);
|
||||
const cardToRender = (
|
||||
<components.Card
|
||||
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}
|
||||
{...card}
|
||||
/>
|
||||
);
|
||||
return cardDraggable && (!card.hasOwnProperty("draggable") || card.draggable) ? (
|
||||
<Draggable key={card.id}>{cardToRender}</Draggable>
|
||||
) : (
|
||||
<span key={card.id}>{cardToRender}</span>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<components.ScrollableLane ref={this.laneDidMount} isDraggingOver={isDraggingOver}>
|
||||
<Container
|
||||
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}
|
||||
</Container>
|
||||
{editable && !addCardMode && <components.AddCardLink onClick={this.showEditableCard} laneId={id} />}
|
||||
{addCardMode && <components.NewCardForm onCancel={this.hideEditableCard} laneId={id} onAdd={this.addNewCard} />}
|
||||
</components.ScrollableLane>
|
||||
);
|
||||
};
|
||||
|
||||
removeLane = () => {
|
||||
const { id } = this.props;
|
||||
this.props.actions.removeLane({ laneId: id });
|
||||
this.props.onLaneDelete(id);
|
||||
};
|
||||
|
||||
updateTitle = (value) => {
|
||||
this.props.actions.updateLane({ id: this.props.id, title: value });
|
||||
this.props.onLaneUpdate(this.props.id, { title: value });
|
||||
};
|
||||
|
||||
renderHeader = (pickedProps) => {
|
||||
const { components } = this.props;
|
||||
return (
|
||||
<components.LaneHeader
|
||||
{...pickedProps}
|
||||
onDelete={this.removeLane}
|
||||
onDoubleClick={this.toggleLaneCollapsed}
|
||||
updateTitle={this.updateTitle}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
toggleLaneCollapsed = () => {
|
||||
this.props.collapsibleLanes && this.setState((state) => ({ collapsed: !state.collapsed }));
|
||||
};
|
||||
|
||||
render() {
|
||||
const { loading, isDraggingOver, collapsed } = this.state;
|
||||
const {
|
||||
id,
|
||||
cards,
|
||||
collapsibleLanes,
|
||||
components,
|
||||
onLaneClick,
|
||||
onLaneScroll,
|
||||
onCardClick,
|
||||
onCardAdd,
|
||||
onBeforeCardDelete,
|
||||
onCardDelete,
|
||||
onLaneDelete,
|
||||
onLaneUpdate,
|
||||
onCardUpdate,
|
||||
onCardMoveAcrossLanes,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
const allClassNames = classNames("react-trello-lane", this.props.className || "");
|
||||
const showFooter = collapsibleLanes && cards.length > 0;
|
||||
return (
|
||||
<components.Section
|
||||
{...otherProps}
|
||||
key={id}
|
||||
onClick={() => onLaneClick && onLaneClick(id)}
|
||||
draggable={false}
|
||||
className={allClassNames}
|
||||
>
|
||||
{this.renderHeader({ id, cards, ...otherProps })}
|
||||
{this.renderDragContainer(isDraggingOver)}
|
||||
{loading && <components.Loader />}
|
||||
{showFooter && <components.LaneFooter onClick={this.toggleLaneCollapsed} collapsed={collapsed} />}
|
||||
</components.Section>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Lane.propTypes = {
|
||||
actions: PropTypes.object,
|
||||
id: PropTypes.string.isRequired,
|
||||
boardId: PropTypes.string,
|
||||
title: PropTypes.node,
|
||||
index: PropTypes.number,
|
||||
laneSortFunction: PropTypes.func,
|
||||
style: PropTypes.object,
|
||||
cardStyle: PropTypes.object,
|
||||
tagStyle: PropTypes.object,
|
||||
titleStyle: PropTypes.object,
|
||||
labelStyle: PropTypes.object,
|
||||
cards: PropTypes.array,
|
||||
label: PropTypes.string,
|
||||
currentPage: PropTypes.number,
|
||||
draggable: PropTypes.bool,
|
||||
collapsibleLanes: PropTypes.bool,
|
||||
droppable: PropTypes.bool,
|
||||
onCardMoveAcrossLanes: PropTypes.func,
|
||||
onCardClick: PropTypes.func,
|
||||
onBeforeCardDelete: PropTypes.func,
|
||||
onCardDelete: PropTypes.func,
|
||||
onCardAdd: PropTypes.func,
|
||||
onCardUpdate: PropTypes.func,
|
||||
onLaneDelete: PropTypes.func,
|
||||
onLaneUpdate: PropTypes.func,
|
||||
onLaneClick: PropTypes.func,
|
||||
onLaneScroll: PropTypes.func,
|
||||
editable: PropTypes.bool,
|
||||
laneDraggable: PropTypes.bool,
|
||||
cardDraggable: PropTypes.bool,
|
||||
cardDragClass: PropTypes.string,
|
||||
cardDropClass: PropTypes.string,
|
||||
canAddLanes: PropTypes.bool
|
||||
};
|
||||
|
||||
Lane.defaultProps = {
|
||||
style: {},
|
||||
titleStyle: {},
|
||||
labelStyle: {},
|
||||
label: undefined,
|
||||
editable: false,
|
||||
onLaneUpdate: () => {},
|
||||
onCardAdd: () => {},
|
||||
onCardUpdate: () => {}
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
actions: bindActionCreators(actions, dispatch)
|
||||
});
|
||||
|
||||
export default connect(null, mapDispatchToProps)(Lane);
|
||||
Reference in New Issue
Block a user