refactor dragndrop

This commit is contained in:
Cássio Zen 2016-09-15 15:50:33 -03:00
parent ae64ce73ea
commit 9914b5a668
2 changed files with 35 additions and 88 deletions

View File

@ -88,9 +88,8 @@
"prismjs": "^1.5.1", "prismjs": "^1.5.1",
"react-addons-css-transition-group": "^15.3.1", "react-addons-css-transition-group": "^15.3.1",
"react-datetime": "^2.6.0", "react-datetime": "^2.6.0",
"react-dnd": "^2.1.4",
"react-dnd-html5-backend": "^2.1.2",
"react-portal": "^2.2.1", "react-portal": "^2.2.1",
"react-simple-dnd": "^0.1.2",
"selection-position": "^1.0.0", "selection-position": "^1.0.0",
"semaphore": "^1.0.5", "semaphore": "^1.0.5",
"slate": "^0.13.6" "slate": "^0.13.6"

View File

@ -1,6 +1,5 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd'; import { DragSource, DropTarget, HTML5DragDrop } from 'react-simple-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import moment from 'moment'; import moment from 'moment';
import { Card } from './UI'; import { Card } from './UI';
@ -8,78 +7,21 @@ import { Link } from 'react-router';
import { status, statusDescriptions } from '../constants/publishModes'; import { status, statusDescriptions } from '../constants/publishModes';
import styles from './UnpublishedListing.css'; import styles from './UnpublishedListing.css';
const CARD = 'card';
/*
* Column DropTarget Component
*/
function Column({ connectDropTarget, status, isOver, children }) {
const className = isOver ? `${styles.column} ${styles.highlighted}` : styles.column;
return connectDropTarget(
<div className={className}>
<h2>{statusDescriptions.get(status)}</h2>
{children}
</div>
);
}
const columnTargetSpec = {
drop(props, monitor) {
const slug = monitor.getItem().slug;
const collection = monitor.getItem().collection;
const oldStatus = monitor.getItem().ownStatus;
props.onChangeStatus(collection, slug, oldStatus, props.status);
}
};
function columnCollect(connect, monitor) {
return {
connectDropTarget: connect.dropTarget(),
isOver: monitor.isOver()
};
}
Column = DropTarget(CARD, columnTargetSpec, columnCollect)(Column);
/*
* Card DropTarget Component
*/
function EntryCard({ slug, collection, ownStatus, onRequestPublish, connectDragSource, children }) {
return connectDragSource(
<div>
<Card className={styles.card}>
{children}
{(ownStatus === status.last()) &&
<button onClick={onRequestPublish}>Publish now</button>
}
</Card>
</div>
);
}
const cardDragSpec = {
beginDrag(props) {
return {
slug: props.slug,
collection: props.collection,
ownStatus: props.ownStatus
};
}
};
function cardCollect(connect, monitor) {
return {
connectDragSource: connect.dragSource()
};
}
EntryCard = DragSource(CARD, cardDragSpec, cardCollect)(EntryCard);
/*
* The actual exported component implementation
*/
class UnpublishedListing extends React.Component { class UnpublishedListing extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.renderColumns = this.renderColumns.bind(this); this.renderColumns = this.renderColumns.bind(this);
this.handleChangeStatus = this.handleChangeStatus.bind(this);
this.requestPublish = this.requestPublish.bind(this); this.requestPublish = this.requestPublish.bind(this);
} }
handleChangeStatus(newStatus, dragProps) {
const slug = dragProps.slug;
const collection = dragProps.collection;
const oldStatus = dragProps.ownStatus;
this.props.handleChangeStatus(collection, slug, oldStatus, newStatus);
}
requestPublish(collection, slug, ownStatus) { requestPublish(collection, slug, ownStatus) {
if (ownStatus !== status.last()) return; if (ownStatus !== status.last()) return;
if (window.confirm('Are you sure you want to publish this entry?')) { if (window.confirm('Are you sure you want to publish this entry?')) {
@ -91,14 +33,17 @@ class UnpublishedListing extends React.Component {
if (!entries) return; if (!entries) return;
if (!column) { if (!column) {
/* eslint-disable */
return entries.entrySeq().map(([currColumn, currEntries]) => ( return entries.entrySeq().map(([currColumn, currEntries]) => (
<Column <DropTarget key={currColumn} onDrop={this.handleChangeStatus.bind(this, currColumn)}>
key={currColumn} {(isOver) => (
status={currColumn} <div className={isOver ? `${styles.column} ${styles.highlighted}` : styles.column}>
onChangeStatus={this.props.handleChangeStatus} <h2>{statusDescriptions.get(currColumn)}</h2>
> {this.renderColumns(currEntries, currColumn)}
{this.renderColumns(currEntries, currColumn)} </div>
</Column> )}
</DropTarget>
/* eslint-enable */
)); ));
} else { } else {
return <div> return <div>
@ -108,19 +53,22 @@ class UnpublishedListing extends React.Component {
const timeStamp = moment(entry.getIn(['metaData', 'timeStamp'])).format('llll'); const timeStamp = moment(entry.getIn(['metaData', 'timeStamp'])).format('llll');
const link = `/editorialworkflow/${entry.getIn(['metaData', 'collection'])}/${entry.getIn(['metaData', 'status'])}/${entry.get('slug')}`; const link = `/editorialworkflow/${entry.getIn(['metaData', 'collection'])}/${entry.getIn(['metaData', 'status'])}/${entry.get('slug')}`;
const slug = entry.get('slug'); const slug = entry.get('slug');
const status = entry.getIn(['metaData', 'status']); const ownStatus = entry.getIn(['metaData', 'status']);
const collection = entry.getIn(['metaData', 'collection']); const collection = entry.getIn(['metaData', 'collection']);
return ( return (
<EntryCard /* eslint-disable */
key={slug} <DragSource key={slug} slug={slug} collection={collection} ownStatus={ownStatus}>
slug={slug} <div className={styles.drag}>
ownStatus={status} <Card className={styles.card}>
collection={collection} <h2><Link to={link}>{entry.getIn(['data', 'title'])}</Link> <small>by {author}</small></h2>
onRequestPublish={this.requestPublish.bind(this, collection, slug, status)} // eslint-disable-line <p>Last updated: {timeStamp} by {entry.getIn(['metaData', 'user'])}</p>
> {(ownStatus === status.last()) &&
<h2><Link to={link}>{entry.getIn(['data', 'title'])}</Link> <small>by {author}</small></h2> <button onClick={this.requestPublish.bind(this, collection, slug, status)}>Publish now</button>
<p>Last updated: {timeStamp} by {entry.getIn(['metaData', 'user'])}</p> }
</EntryCard> </Card>
</div>
</DragSource>
/* eslint-enable */
); );
} }
)} )}
@ -147,4 +95,4 @@ UnpublishedListing.propTypes = {
handlePublish: PropTypes.func.isRequired, handlePublish: PropTypes.func.isRequired,
}; };
export default DragDropContext(HTML5Backend)(UnpublishedListing); export default HTML5DragDrop(UnpublishedListing);