Merge pull request #414 from coralproject/streams-to-stories

change Stream > Story sometimes
This commit is contained in:
Kim Gardner
2017-03-20 10:21:56 -07:00
committed by gaba
7 changed files with 201 additions and 14 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
import React from 'react';
import {Router, Route, IndexRoute, IndexRedirect, browserHistory} from 'react-router';
import Streams from 'containers/Streams/Streams';
import Stories from 'containers/Stories/Stories';
import Configure from 'containers/Configure/Configure';
import LayoutContainer from 'containers/LayoutContainer';
import InstallContainer from 'containers/Install/InstallContainer';
@@ -21,7 +21,7 @@ const routes = (
<IndexRoute component={Dashboard} />
<Route path='community' component={CommunityContainer} />
<Route path='configure' component={Configure} />
<Route path='streams' component={Streams} />
<Route path='stories' component={Stories} />
<Route path='dashboard' component={Dashboard} />
{/* Community Routes */}
@@ -23,9 +23,9 @@ const CoralDrawer = ({handleLogout, restricted = false}) => (
{lang.t('configure.moderate')}
</Link>
<Link className={styles.navLink}
to="/admin/streams"
to="/admin/stories"
activeClassName={styles.active}>
{lang.t('configure.streams')}
{lang.t('configure.stories')}
</Link>
<Link className={styles.navLink}
to="/admin/community"
@@ -30,9 +30,9 @@ const CoralHeader = ({handleLogout, restricted = false}) => (
<Link
id='streamsNav'
className={styles.navLink}
to="/admin/streams"
to="/admin/stories"
activeClassName={styles.active}>
{lang.t('configure.streams')}
{lang.t('configure.stories')}
</Link>
<Link
id='communityNav'
@@ -1,5 +1,5 @@
import React, {Component} from 'react';
import styles from './Streams.css';
import styles from './Stories.css';
import {connect} from 'react-redux';
import I18n from 'coral-framework/modules/i18n/i18n';
import {fetchAssets, updateAssetState} from '../../actions/assets';
@@ -12,7 +12,7 @@ import EmptyCard from 'coral-admin/src/components/EmptyCard';
const limit = 25;
class Streams extends Component {
class Stories extends Component {
state = {
search: '',
@@ -182,6 +182,6 @@ const mapDispatchToProps = (dispatch) => {
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Streams);
export default connect(mapStateToProps, mapDispatchToProps)(Stories);
const lang = new I18n(translations);
@@ -0,0 +1,187 @@
import React, {Component} from 'react';
import styles from './Stories.css';
import {connect} from 'react-redux';
import I18n from 'coral-framework/modules/i18n/i18n';
import {fetchAssets, updateAssetState} from '../../actions/assets';
import translations from '../../translations.json';
import {Link} from 'react-router';
import {Pager, Icon} from 'coral-ui';
import {DataTable, TableHeader, RadioGroup, Radio} from 'react-mdl';
import EmptyCard from 'coral-admin/src/components/EmptyCard';
const limit = 25;
class Stories extends Component {
state = {
search: '',
sort: 'desc',
filter: 'all',
statusMenus: {},
timer: null,
page: 0
}
componentDidMount () {
this.props.fetchAssets(0, limit, '', this.state.sortBy);
}
onSettingChange = (setting) => (e) => {
let options = this.state;
this.setState({[setting]: e.target.value});
options[setting] = e.target.value;
this.props.fetchAssets(0, limit, options.search, options.sort, options.filter);
}
onSearchChange = (e) => {
const search = e.target.value;
this.setState((prevState) => {
prevState.search = search;
clearTimeout(prevState.timer);
const fetchAssets = this.props.fetchAssets;
prevState.timer = setTimeout(() => {
fetchAssets(0, limit, search, this.state.sort, this.state.filter);
}, 350);
return prevState;
});
}
renderDate = (date) => {
const d = new Date(date);
return `${d.getMonth() + 1}/${d.getDate()}/${d.getFullYear()}`;
}
onStatusClick = (closeStream, id, statusMenuOpen) => () => {
if (statusMenuOpen) {
this.setState(prev => {
prev.statusMenus[id] = false;
return prev;
});
this.props.updateAssetState(id, closeStream ? Date.now() : null)
.then(() => {
const {search, sort, filter, page} = this.state;
this.props.fetchAssets(page, limit, search, sort, filter);
});
} else {
this.setState(prev => {
prev.statusMenus[id] = true;
return prev;
});
}
}
renderTitle = (title, {id}) => <Link to={`/admin/moderate/${id}`}>{title}</Link>
renderStatus = (closedAt, {id}) => {
const closed = closedAt && new Date(closedAt).getTime() < Date.now();
const statusMenuOpen = this.state.statusMenus[id];
return <div className={styles.statusMenu}>
<div
className={closed ? styles.statusMenuClosed : styles.statusMenuOpen}
onClick={this.onStatusClick(closed, id, statusMenuOpen)}>
{!statusMenuOpen && <Icon className={styles.statusMenuIcon} name='keyboard_arrow_down'/>}
{closed ? lang.t('streams.closed') : lang.t('streams.open')}
</div>
{
statusMenuOpen &&
<div
className={!closed ? styles.statusMenuClosed : styles.statusMenuOpen}
onClick={this.onStatusClick(!closed, id, statusMenuOpen)}>
{!closed ? lang.t('streams.closed') : lang.t('streams.open')}
</div>
}
</div>;
}
onPageClick = (page) => {
this.setState({page});
const {search, sort, filter} = this.state;
this.props.fetchAssets((page - 1) * limit, limit, search, sort, filter);
}
render () {
const {search, sort, filter} = this.state;
const {assets} = this.props;
const assetsIds = assets.ids.map((id) => assets.byId[id]);
return (
<div className={styles.container}>
<div className={styles.leftColumn}>
<div className={styles.searchBox}>
<Icon name='search' className={styles.searchIcon}/>
<input
type='text'
value={search}
className={styles.searchBoxInput}
onChange={this.onSearchChange}
placeholder={lang.t('streams.search')}/>
</div>
<div className={styles.optionHeader}>{lang.t('streams.filter-streams')}</div>
<div className={styles.optionDetail}>{lang.t('streams.stream-status')}</div>
<RadioGroup
name='status filter'
value={filter}
childContainer='div'
onChange={this.onSettingChange('filter')}
className={styles.radioGroup}
>
<Radio value='all'>{lang.t('streams.all')}</Radio>
<Radio value='open'>{lang.t('streams.open')}</Radio>
<Radio value='closed'>{lang.t('streams.closed')}</Radio>
</RadioGroup>
<div className={styles.optionHeader}>{lang.t('streams.sort-by')}</div>
<RadioGroup
name='sort by'
value={sort}
childContainer='div'
onChange={this.onSettingChange('sort')}
className={styles.radioGroup}
>
<Radio value='desc'>{lang.t('streams.newest')}</Radio>
<Radio value='asc'>{lang.t('streams.oldest')}</Radio>
</RadioGroup>
</div>
{
assetsIds.length
? <div className={styles.mainContent}>
<DataTable className={styles.streamsTable} rows={assetsIds} onClick={this.goToModeration}>
<TableHeader name="title" cellFormatter={this.renderTitle}>{lang.t('streams.article')}</TableHeader>
<TableHeader name="publication_date" cellFormatter={this.renderDate}>
{lang.t('streams.pubdate')}
</TableHeader>
<TableHeader name="closedAt" cellFormatter={this.renderStatus} className={styles.status}>
{lang.t('streams.status')}
</TableHeader>
</DataTable>
<Pager
totalPages={Math.ceil((assets.count || 0) / limit)}
page={this.state.page}
onNewPageHandler={this.onPageClick} />
</div>
: <EmptyCard>{lang.t('streams.empty_result')}</EmptyCard>
}
</div>
);
}
}
const mapStateToProps = ({assets}) => {
return {
assets: assets.toJS()
};
};
const mapDispatchToProps = (dispatch) => {
return {
fetchAssets: (...args) => {
dispatch(fetchAssets.apply(this, args));
},
updateAssetState: (...args) => dispatch(updateAssetState.apply(this, args))
};
};
export default connect(mapStateToProps, mapDispatchToProps)(Stories);
const lang = new I18n(translations);
+5 -5
View File
@@ -94,7 +94,7 @@
"moderate": "Moderate",
"configure": "Configure",
"community": "Community",
"streams": "Streams",
"stories": "Stories",
"closed-comments-desc": "Write a message to be displayed when when your comment stream is closed and no longer accepting comments.",
"closed-comments-label": "Write a message...",
"hours": "Hours",
@@ -152,9 +152,9 @@
"sort-by": "Sort By",
"open": "Open",
"closed": "Closed",
"article": "Article",
"article": "Story",
"pubdate": "Publication Date",
"status": "Status"
"status": "Stream Status"
}
},
"es": {
@@ -253,7 +253,7 @@
"moderate": "Moderar",
"configure": "Configurar",
"community": "Comunidad",
"streams": "Streams",
"stories": "Artículos",
"closed-comments-desc": "Escribe un mensaje que será mostrado cuando los comentarios estén cerrados y no se acepten más comentarios.",
"closed-comments-label": "Escribe un mensaje...",
"never": "Nunca",
@@ -300,7 +300,7 @@
"sort-by": "",
"open": "",
"closed": "",
"article": "",
"article": "artículo",
"pubdate": "",
"status": ""
}