Cássio Souza 2a2497072d UI updates (#151)
* infer card title

* Infer entry body & image

* infer image

* Better terminology: EntryListing accept a single Collection

* remove log

* Refactored Collections VO into selectors

* use selectors when showning card

* fixed size cards

* Added 'bio' and 'biography' to collection description inference synonyms

* Removed unused card file

* throw error instance

* bugfix for file based collections

* lint

* moved components with css to own folder

* Search Bugfix: More than one collection might be returned

* Changed sidebar implementation. Closes #104 & #152

* Show spinning loading for unpublished entries

* Refactored Sidebar into a separate container

* Make preview widgets more robust
2016-11-11 17:54:58 -02:00

121 lines
4.2 KiB
JavaScript

import React, { PropTypes } from 'react';
import { DragSource, DropTarget, HTML5DragDrop } from 'react-simple-dnd';
import ImmutablePropTypes from 'react-immutable-proptypes';
import { Link } from 'react-router';
import moment from 'moment';
import { Card, CardTitle, CardText, CardActions } from 'react-toolbox/lib/card';
import Button from 'react-toolbox/lib/button';
import { status, statusDescriptions } from '../../constants/publishModes';
import styles from './UnpublishedListing.css';
class UnpublishedListing extends React.Component {
static propTypes = {
entries: ImmutablePropTypes.orderedMap,
handleChangeStatus: PropTypes.func.isRequired,
handlePublish: PropTypes.func.isRequired,
};
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) => {
if (ownStatus !== status.last()) return;
if (window.confirm('Are you sure you want to publish this entry?')) {
this.props.handlePublish(collection, slug, ownStatus);
}
};
renderColumns = (entries, column) => {
if (!entries) return null;
if (!column) {
return entries.entrySeq().map(([currColumn, currEntries]) => (
<DropTarget
key={currColumn}
/* eslint-disable */
onDrop={this.handleChangeStatus.bind(this, currColumn)}
/* eslint-enable */
>
{isHovered => (
<div className={isHovered ? styles.columnHovered : styles.column}>
<h2 className={styles.columnHeading}>
{statusDescriptions.get(currColumn)}
</h2>
{this.renderColumns(currEntries, currColumn)}
</div>
)}
</DropTarget>
));
}
return (
<div>
{
entries.map((entry) => {
// Look for an "author" field. Fallback to username on backend implementation;
const author = entry.getIn(['data', 'author'], entry.getIn(['metaData', 'user']));
const timeStamp = moment(entry.getIn(['metaData', 'timeStamp'])).format('llll');
const link = `editorialworkflow/${ entry.getIn(['metaData', 'collection']) }/${ entry.getIn(['metaData', 'status']) }/${ entry.get('slug') }`;
const slug = entry.get('slug');
const ownStatus = entry.getIn(['metaData', 'status']);
const collection = entry.getIn(['metaData', 'collection']);
return (
<DragSource
key={slug}
slug={slug}
collection={collection}
ownStatus={ownStatus}
>
<div className={styles.draggable}>
<Card className={styles.card}>
<CardTitle
title={entry.getIn(['data', 'title'])}
subtitle={`by ${ author }`}
/>
<CardText>
Last updated: {timeStamp} by {entry.getIn(['metaData', 'user'])}
</CardText>
<CardActions>
<Link to={link}>
<Button>Edit</Button>
</Link>
{
ownStatus === status.last() &&
<Button
accent
/* eslint-disable */
onClick={this.requestPublish.bind(this, collection, slug, ownStatus)}
/* eslint-enable */
>
Publish now
</Button>
}
</CardActions>
</Card>
</div>
</DragSource>
);
})
}
</div>
);
};
render() {
const columns = this.renderColumns(this.props.entries);
return (
<div className={styles.clear}>
<h5>Editorial Workflow</h5>
<div className={styles.container}>
{columns}
</div>
</div>
);
}
}
export default HTML5DragDrop(UnpublishedListing); // eslint-disable-line