Editorial workflow Drag'nDrop

This commit is contained in:
Cássio Zen
2016-09-13 16:00:24 -03:00
parent e2b6e140f3
commit 0b447d483d
10 changed files with 237 additions and 61 deletions

View File

@ -1,16 +1,25 @@
.container {
display: table;
width: 100%;
}
.column {
position: relative;
display: inline-block;
vertical-align: top;
display: table-cell;
text-align: center;
width: 28%;
width: 33%;
height: 100%;
transition: background-color .5s ease;
& h2 {
font-size: 16px;
}
}
.highlighted {
background-color: #e1eeea;
}
.column:not(:last-child) {
margin-right: 8%;
padding-right: 20px;
}
.card {
@ -30,3 +39,10 @@
margin-top: 5px;
}
}
.clear::after {
content:"";
display:block;
clear:both;
}

View File

@ -1,4 +1,6 @@
import React from 'react';
import React, { PropTypes } from 'react';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import ImmutablePropTypes from 'react-immutable-proptypes';
import moment from 'moment';
import { Card } from './UI';
@ -6,16 +8,93 @@ import { Link } from 'react-router';
import { statusDescriptions } from '../constants/publishModes';
import styles from './UnpublishedListing.css';
export default class UnpublishedListing extends React.Component {
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().currentStatus;
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({ connectDragSource, children }) {
return connectDragSource(
<div>
<Card className={styles.card}>
{children}
</Card>
</div>
);
}
const cardDragSpec = {
beginDrag(props) {
return {
slug: props.slug,
collection: props.collection,
currentStatus: props.status
};
}
};
function cardCollect(connect, monitor) {
return {
connectDragSource: connect.dragSource()
};
}
EntryCard = DragSource(CARD, cardDragSpec, cardCollect)(EntryCard);
/*
* The actual exported component implementation
*/
class UnpublishedListing extends React.Component {
constructor(props) {
super(props);
this.renderColumns = this.renderColumns.bind(this);
}
renderColumns(entries, column) {
if (!entries) return;
if (!column) {
return entries.entrySeq().map(([currColumn, currEntries]) => (
<div key={currColumn} className={styles.column}>
<h2>{statusDescriptions.get(currColumn)}</h2>
<Column
key={currColumn}
status={currColumn}
onChangeStatus={this.props.handleChangeStatus}
>
{this.renderColumns(currEntries, currColumn)}
</div>
</Column>
));
} else {
return <div>
@ -25,10 +104,15 @@ export default class UnpublishedListing extends React.Component {
const timeStamp = moment(entry.getIn(['metaData', 'timeStamp'])).format('llll');
const link = `/editorialworkflow/${entry.getIn(['metaData', 'collection'])}/${entry.getIn(['metaData', 'status'])}/${entry.get('slug')}`;
return (
<Card key={entry.get('slug')} className={styles.card}>
<EntryCard
key={entry.get('slug')}
slug={entry.get('slug')}
status={entry.getIn(['metaData', 'status'])}
collection={entry.getIn(['metaData', 'collection'])}
>
<h1><Link to={link}>{entry.getIn(['data', 'title'])}</Link> <small>by {author}</small></h1>
<p>Last updated: {timeStamp} by {entry.getIn(['metaData', 'user'])}</p>
</Card>
</EntryCard>
);
}
)}
@ -40,9 +124,11 @@ export default class UnpublishedListing extends React.Component {
const columns = this.renderColumns(this.props.entries);
return (
<div>
<div className={styles.clear}>
<h1>Editorial Workflow</h1>
<div className={styles.container}>
{columns}
</div>
</div>
);
}
@ -50,4 +136,7 @@ export default class UnpublishedListing extends React.Component {
UnpublishedListing.propTypes = {
entries: ImmutablePropTypes.orderedMap,
handleChangeStatus: PropTypes.func.isRequired,
};
export default DragDropContext(HTML5Backend)(UnpublishedListing);