From d8ec0094822d083b16af5fdf15db2fe193919061 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 8 Nov 2016 17:16:24 -0700 Subject: [PATCH 1/3] Added linting to the client --- .eslintignore | 1 - client/.eslintrc.json | 23 ++++ client/coral-admin/src/actions/comments.js | 16 +-- client/coral-admin/src/components/App.js | 22 +-- client/coral-admin/src/components/Comment.js | 26 ++-- .../coral-admin/src/components/CommentBox.js | 22 +-- .../coral-admin/src/components/CommentList.js | 90 ++++++------ .../coral-admin/src/components/EmbedLink.js | 30 ++-- client/coral-admin/src/components/Header.js | 19 ++- client/coral-admin/src/components/Modal.js | 10 +- .../src/components/ModerationKeysModal.js | 21 ++- client/coral-admin/src/components/Page.js | 10 +- .../src/containers/CommentStream.js | 42 +++--- .../coral-admin/src/containers/Configure.js | 44 +++--- .../src/containers/ModerationQueue.js | 65 ++++----- client/coral-admin/src/index.js | 8 +- client/coral-admin/src/reducers/comments.js | 54 ++++---- client/coral-admin/src/reducers/index.js | 6 +- client/coral-admin/src/services/config.js | 8 +- client/coral-admin/src/services/store.js | 10 +- .../coral-admin/src/services/talk-adapter.js | 48 +++---- client/coral-admin/src/translations.js | 58 ++++---- .../coral-embed-stream/src/CommentStream.js | 101 +++++++------- client/coral-embed-stream/src/index.js | 14 +- .../__tests__/store/authReducer.js | 34 ++--- .../__tests__/store/itemActions.spec.js | 130 +++++++++--------- .../__tests__/store/itemReducer.spec.js | 85 ++++++------ .../store/notificationReducer.spec.js | 38 ++--- client/coral-framework/i18n/i18n.js | 58 ++++---- client/coral-framework/index.js | 16 +-- .../notification/Notification.js | 14 +- client/coral-framework/store/actions/auth.js | 12 +- .../coral-framework/store/actions/config.js | 16 +-- client/coral-framework/store/actions/items.js | 104 +++++++------- .../store/actions/notification.js | 12 +- client/coral-framework/store/reducers/auth.js | 20 +-- .../coral-framework/store/reducers/config.js | 24 ++-- .../coral-framework/store/reducers/index.js | 12 +- .../coral-framework/store/reducers/items.js | 40 +++--- .../store/reducers/notification.js | 20 +-- client/coral-framework/store/store.js | 8 +- client/coral-plugin-author-name/AuthorName.js | 10 +- .../CommentCount.js | 26 ++-- client/coral-plugin-commentbox/CommentBox.js | 50 +++---- .../__tests__/commentBox.spec.js | 34 ++--- .../CommentContent.js | 18 +-- .../__tests__/commentContent.spec.js | 16 +-- client/coral-plugin-flags/FlagButton.js | 30 ++-- client/coral-plugin-pubdate/PubDate.js | 14 +- client/coral-plugin-replies/ReplyBox.js | 12 +- client/coral-plugin-replies/ReplyButton.js | 18 +-- client/coral-plugin-replies/index.js | 6 +- package.json | 2 + 53 files changed, 821 insertions(+), 806 deletions(-) create mode 100644 client/.eslintrc.json diff --git a/.eslintignore b/.eslintignore index 6cb6a3bc3..1521c8b76 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1 @@ -client dist diff --git a/client/.eslintrc.json b/client/.eslintrc.json new file mode 100644 index 000000000..a935eaec6 --- /dev/null +++ b/client/.eslintrc.json @@ -0,0 +1,23 @@ +{ + "env": { + "browser": true, + "es6": true, + "mocha": true + }, + "extends": "../.eslintrc.json", + "parserOptions": { + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + }, + "sourceType": "module" + }, + "parser": "babel-eslint", + "plugins": [ + "react" + ], + "rules": { + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error" + } +} diff --git a/client/coral-admin/src/actions/comments.js b/client/coral-admin/src/actions/comments.js index 04751276e..e4a55a893 100644 --- a/client/coral-admin/src/actions/comments.js +++ b/client/coral-admin/src/actions/comments.js @@ -4,15 +4,15 @@ */ export const updateStatus = (status, id) => (dispatch, getState) => { - dispatch({ type: 'COMMENT_STATUS_UPDATE', id, status }) - dispatch({ type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id) }) -} + dispatch({type: 'COMMENT_STATUS_UPDATE', id, status}); + dispatch({type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id)}); +}; export const flagComment = id => (dispatch, getState) => { - dispatch({ type: 'COMMENT_FLAG', id }) - dispatch({ type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id) }) -} + dispatch({type: 'COMMENT_FLAG', id}); + dispatch({type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id)}); +}; export const createComment = (name, body) => dispatch => { - dispatch({ type: 'COMMENT_CREATE', name, body }) -} + dispatch({type: 'COMMENT_CREATE', name, body}); +}; diff --git a/client/coral-admin/src/components/App.js b/client/coral-admin/src/components/App.js index 81eea850f..0239aa177 100644 --- a/client/coral-admin/src/components/App.js +++ b/client/coral-admin/src/components/App.js @@ -1,16 +1,16 @@ -import React from 'react' -import { Provider } from 'react-redux' -import 'material-design-lite' -import { Router, Route, browserHistory } from 'react-router' -import ModerationQueue from 'containers/ModerationQueue' -import store from 'services/store' -import CommentStream from 'containers/CommentStream' -import EmbedLink from 'components/EmbedLink' -import Configure from 'containers/Configure' +import React from 'react'; +import {Provider} from 'react-redux'; +import 'material-design-lite'; +import {Router, Route, browserHistory} from 'react-router'; +import ModerationQueue from 'containers/ModerationQueue'; +import store from 'services/store'; +import CommentStream from 'containers/CommentStream'; +import EmbedLink from 'components/EmbedLink'; +import Configure from 'containers/Configure'; export default class App extends React.Component { - render (props) { + render () { return ( @@ -20,6 +20,6 @@ export default class App extends React.Component { - ) + ); } } diff --git a/client/coral-admin/src/components/Comment.js b/client/coral-admin/src/components/Comment.js index 7406d42db..da08945a9 100644 --- a/client/coral-admin/src/components/Comment.js +++ b/client/coral-admin/src/components/Comment.js @@ -1,10 +1,10 @@ -import React from 'react' -import { Button, Icon } from 'react-mdl' -import timeago from 'timeago.js' -import styles from './CommentList.css' -import I18n from 'coral-framework/i18n/i18n' -import translations from '../translations' +import React from 'react'; +import {Button, Icon} from 'react-mdl'; +import timeago from 'timeago.js'; +import styles from './CommentList.css'; +import I18n from 'coral-framework/i18n/i18n'; +import translations from '../translations'; // Render a single comment for the list export default props => ( @@ -30,17 +30,17 @@ export default props => ( {props.comment.get('body')} -) +); // Check if an action can be performed over a comment const canShowAction = (action, comment) => { - const status = comment.get('status') - const flagged = comment.get('flagged') + const status = comment.get('status'); + const flagged = comment.get('flagged'); if (action === 'flag' && (status || flagged === true)) { - return false + return false; } - return true -} + return true; +}; -const lang = new I18n(translations) +const lang = new I18n(translations); diff --git a/client/coral-admin/src/components/CommentBox.js b/client/coral-admin/src/components/CommentBox.js index f0f0adbf2..ce3438960 100644 --- a/client/coral-admin/src/components/CommentBox.js +++ b/client/coral-admin/src/components/CommentBox.js @@ -1,23 +1,23 @@ -import React from 'react' -import styles from './CommentBox.css' -import { Button } from 'react-mdl' +import React from 'react'; +import styles from './CommentBox.css'; +import {Button} from 'react-mdl'; // Renders a comment box for creating a new comment export default class CommentBox extends React.Component { constructor (props) { - super(props) - this.state = { name: '', body: '' } - this.onSubmit = this.onSubmit.bind(this) + super(props); + this.state = {name: '', body: ''}; + this.onSubmit = this.onSubmit.bind(this); } onSubmit () { - const { name, body } = this.state - this.props.onSubmit({ name, body }) - this.setState({ body: '', name: '' }) + const {name, body} = this.state; + this.props.onSubmit({name, body}); + this.setState({body: '', name: ''}); } - render (props, { name, body }) { + render (props, {name, body}) { return (
@@ -30,6 +30,6 @@ export default class CommentBox extends React.Component {
- ) + ); } } diff --git a/client/coral-admin/src/components/CommentList.js b/client/coral-admin/src/components/CommentList.js index 02367911f..ae74272e7 100644 --- a/client/coral-admin/src/components/CommentList.js +++ b/client/coral-admin/src/components/CommentList.js @@ -1,99 +1,99 @@ -import React from 'react' -import styles from './CommentList.css' -import key from 'keymaster' -import Hammer from 'hammerjs' -import Comment from 'components/Comment' +import React from 'react'; +import styles from './CommentList.css'; +import key from 'keymaster'; +import Hammer from 'hammerjs'; +import Comment from 'components/Comment'; // Each action has different meaning and configuration const actions = { - 'reject': { status: 'Rejected', icon: 'close', key: 'r' }, - 'approve': { status: 'Approved', icon: 'done', key: 't' }, - 'flag': { status: 'flagged', icon: 'flag', filter: 'Untouched' } -} + 'reject': {status: 'Rejected', icon: 'close', key: 'r'}, + 'approve': {status: 'Approved', icon: 'done', key: 't'}, + 'flag': {status: 'flagged', icon: 'flag', filter: 'Untouched'} +}; // Renders a comment list and allow performing actions export default class CommentList extends React.Component { constructor (props) { - super(props) + super(props); - this.state = { active: null } - this.onClickAction = this.onClickAction.bind(this) + this.state = {active: null}; + this.onClickAction = this.onClickAction.bind(this); } // remove key handlers before leaving componentWillUnmount () { - this.unbindKeyHandlers() + this.unbindKeyHandlers(); } // add key handlers and gestures componentDidMount () { - this.bindKeyHandlers() + this.bindKeyHandlers(); // this.bindGestures() // need to check whether we're on a mobile device or this throws an Error } // If entering to singleview and no active, active is the first eleement componentWillReceiveProps (nextProps) { if (nextProps.singleView && !this.state.active) { - this.setState({ active: nextProps.commentIds.get(0) }) + this.setState({active: nextProps.commentIds.get(0)}); } } // Add swipe to approve or reject bindGestures () { - const { actions } = this.props - this._hammer = new Hammer(this.base) - this._hammer.get('swipe').set({ direction: Hammer.DIRECTION_HORIZONTAL }) + const {actions} = this.props; + this._hammer = new Hammer(this.base); + this._hammer.get('swipe').set({direction: Hammer.DIRECTION_HORIZONTAL}); if (actions.indexOf('reject') !== -1) { - this._hammer.on('swipeleft', () => this.props.singleView && this.actionKeyHandler('Rejected')) + this._hammer.on('swipeleft', () => this.props.singleView && this.actionKeyHandler('Rejected')); } if (actions.indexOf('approve') !== -1) { - this._hammer.on('swiperight', () => this.props.singleView && this.actionKeyHandler('Approved')) + this._hammer.on('swiperight', () => this.props.singleView && this.actionKeyHandler('Approved')); } } // Add key handlers. Each action has one and added j/k for moving around bindKeyHandlers () { this.props.actions.filter(action => actions[action].key).forEach(action => { - key(actions[action].key, 'commentList', () => this.props.isActive && this.actionKeyHandler(actions[action].status)) - }) - key('j', 'commentList', () => this.props.isActive && this.moveKeyHandler('down')) - key('k', 'commentList', () => this.props.isActive && this.moveKeyHandler('up')) - key.setScope('commentList') + key(actions[action].key, 'commentList', () => this.props.isActive && this.actionKeyHandler(actions[action].status)); + }); + key('j', 'commentList', () => this.props.isActive && this.moveKeyHandler('down')); + key('k', 'commentList', () => this.props.isActive && this.moveKeyHandler('up')); + key.setScope('commentList'); } // Perform an action using the keys only if the comment is active actionKeyHandler (action) { if (this.props.isActive && this.state.active) { - this.onClickAction(action, this.state.active) + this.onClickAction(action, this.state.active); } } // move around with j/k moveKeyHandler (direction) { if (!this.props.isActive) { - return + return; } - const { commentIds } = this.props - const { active } = this.state + const {commentIds} = this.props; + const {active} = this.state; // check boundaries - if (active == null || !commentIds.size) { - this.setState({ active: commentIds.get(0) }) + if (active === null || !commentIds.size) { + this.setState({active: commentIds.get(0)}); } else if (direction === 'up' && active !== commentIds.first()) { - this.setState({ active: commentIds.get(commentIds.indexOf(active) - 1) }) + this.setState({active: commentIds.get(commentIds.indexOf(active) - 1)}); } else if (direction === 'down' && active !== commentIds.last()) { - this.setState({ active: commentIds.get(commentIds.indexOf(active) + 1) }) + this.setState({active: commentIds.get(commentIds.indexOf(active) + 1)}); } // scroll to the position - const index = Math.max(commentIds.indexOf(this.state.active), 0) - this.base.childNodes[index] && this.base.childNodes[index].focus() + const index = Math.max(commentIds.indexOf(this.state.active), 0); + this.base.childNodes[index] && this.base.childNodes[index].focus(); } unbindKeyHandlers () { - key.deleteScope('commentList') + key.deleteScope('commentList'); } // If we are performing an action over a comment (aka removing from the list) we need to select a new active. @@ -101,26 +101,26 @@ export default class CommentList extends React.Component { // resolve since the content of the list could change externally. For now it works as expected onClickAction (action, id) { if (id === this.state.active) { - const { commentIds } = this.props + const {commentIds} = this.props; if (commentIds.last() === this.state.active) { - this.setState({ active: commentIds.get(commentIds.size - 2) }) + this.setState({active: commentIds.get(commentIds.size - 2)}); } else { - this.setState({ active: commentIds.get(Math.min(commentIds.indexOf(this.state.active) + 1, commentIds.size - 1)) }) + this.setState({active: commentIds.get(Math.min(commentIds.indexOf(this.state.active) + 1, commentIds.size - 1))}); } } - this.props.onClickAction(action, id) + this.props.onClickAction(action, id); } render () { - const {singleView, commentIds, comments, hideActive} = this.props - const {active} = this.state + const {singleView, commentIds, comments, hideActive} = this.props; + const {active} = this.state; return ( - ) + ); } } diff --git a/client/coral-admin/src/components/EmbedLink.js b/client/coral-admin/src/components/EmbedLink.js index 21fe52f3f..41cbdf170 100644 --- a/client/coral-admin/src/components/EmbedLink.js +++ b/client/coral-admin/src/components/EmbedLink.js @@ -1,22 +1,22 @@ -import React from 'react' -import styles from './EmbedLink.css' -import I18n from 'coral-framework/i18n/i18n' -import translations from '../translations' -import { Button } from 'react-mdl' +import React from 'react'; +import styles from './EmbedLink.css'; +import I18n from 'coral-framework/i18n/i18n'; +import translations from '../translations'; +import {Button} from 'react-mdl'; const embedText = -`
` +`
`; -const copyToClipBoard = event => { - const copyTextarea = document.querySelector('.' + styles.embedTextarea) - copyTextarea.select() +const copyToClipBoard = () => { + const copyTextarea = document.querySelector(`.${ styles.embedTextarea}`); + copyTextarea.select(); try { - document.execCommand('copy') + document.execCommand('copy'); } catch (err) { - console.error('Unable to copy') + console.error('Unable to copy'); } -} +}; const EmbedLink = () =>

Embed Comment Stream

@@ -30,8 +30,8 @@ const EmbedLink = () =>
{lang.t('embedlink.copy')}
-
+; -export default EmbedLink +export default EmbedLink; -const lang = new I18n(translations) +const lang = new I18n(translations); diff --git a/client/coral-admin/src/components/Header.js b/client/coral-admin/src/components/Header.js index ea268108e..1a89da513 100644 --- a/client/coral-admin/src/components/Header.js +++ b/client/coral-admin/src/components/Header.js @@ -1,24 +1,23 @@ -import React from 'react' -import { Layout, Navigation, Drawer, Header } from 'react-mdl' -import { Link } from 'react-router' -import styles from './Header.css' -import config from 'services/config' +import React from 'react'; +import {Layout, Navigation, Drawer, Header} from 'react-mdl'; +import {Link} from 'react-router'; +import styles from './Header.css'; // App header. If we add a navbar it should be here export default (props) => (
- Moderate - Configure + Moderate + Configure
- Moderate - Configure + Moderate + Configure {props.children}
-) +); diff --git a/client/coral-admin/src/components/Modal.js b/client/coral-admin/src/components/Modal.js index 44535eda7..99c27c3a1 100644 --- a/client/coral-admin/src/components/Modal.js +++ b/client/coral-admin/src/components/Modal.js @@ -1,13 +1,13 @@ -import React from 'react' -import { Button, Icon } from 'react-mdl' -import styles from './Modal.css' +import React from 'react'; +import {Button, Icon} from 'react-mdl'; +import styles from './Modal.css'; -export default ({ open, children, onClose }) => ( +export default ({open, children, onClose}) => (
{children}
-) +); diff --git a/client/coral-admin/src/components/ModerationKeysModal.js b/client/coral-admin/src/components/ModerationKeysModal.js index efe235df7..5cf9fe17e 100644 --- a/client/coral-admin/src/components/ModerationKeysModal.js +++ b/client/coral-admin/src/components/ModerationKeysModal.js @@ -1,9 +1,8 @@ -import I18n from 'coral-framework/i18n/i18n' -import translations from '../translations' -import React from 'react' -import Modal from 'components/Modal' -import styles from './ModerationKeysModal.css' -import { Map } from 'immutable' +import I18n from 'coral-framework/i18n/i18n'; +import translations from '../translations'; +import React from 'react'; +import Modal from 'components/Modal'; +import styles from './ModerationKeysModal.css'; const shortcuts = [ { @@ -22,9 +21,9 @@ const shortcuts = [ 'r': 'modqueue.reject' } } -] +]; -export default ({ open, onClose }) => ( +export default ({open, onClose}) => (

{lang.t('modqueue.shortcuts')}

@@ -37,7 +36,7 @@ export default ({ open, onClose }) => ( {Object.keys(shortcut.shortcuts).map(key => ( - + {key} {lang.t(shortcut.shortcuts[key])} @@ -47,6 +46,6 @@ export default ({ open, onClose }) => ( ))}
-) +); -const lang = new I18n(translations) +const lang = new I18n(translations); diff --git a/client/coral-admin/src/components/Page.js b/client/coral-admin/src/components/Page.js index 733cec677..845c10cb8 100644 --- a/client/coral-admin/src/components/Page.js +++ b/client/coral-admin/src/components/Page.js @@ -1,7 +1,7 @@ -import React from 'react' -import {Layout} from 'react-mdl' -import 'material-design-lite' -import Header from 'components/Header' +import React from 'react'; +import {Layout} from 'react-mdl'; +import 'material-design-lite'; +import Header from 'components/Header'; export default (props) => ( @@ -9,4 +9,4 @@ export default (props) => ( {props.children} -) +); diff --git a/client/coral-admin/src/containers/CommentStream.js b/client/coral-admin/src/containers/CommentStream.js index 4f0a03698..739ff2778 100644 --- a/client/coral-admin/src/containers/CommentStream.js +++ b/client/coral-admin/src/containers/CommentStream.js @@ -1,12 +1,12 @@ -import React from 'react' -import styles from './CommentStream.css' -import { Snackbar } from 'react-mdl' -import { connect } from 'react-redux' -import { createComment, flagComment } from 'actions/comments' -import CommentList from 'components/CommentList' -import CommentBox from 'components/CommentBox' -import Page from 'components/Page' +import React from 'react'; +import styles from './CommentStream.css'; +import {Snackbar} from 'react-mdl'; +import {connect} from 'react-redux'; +import {createComment, flagComment} from 'actions/comments'; +import CommentList from 'components/CommentList'; +import CommentBox from 'components/CommentBox'; +import Page from 'components/Page'; /** * Renders a comment stream using a CommentList component @@ -15,34 +15,34 @@ import Page from 'components/Page' class CommentStream extends React.Component { constructor (props) { - super(props) - this.state = { snackbar: false, snackbarMsg: '' } - this.onSubmit = this.onSubmit.bind(this) - this.onClickAction = this.onClickAction.bind(this) + super(props); + this.state = {snackbar: false, snackbarMsg: ''}; + this.onSubmit = this.onSubmit.bind(this); + this.onClickAction = this.onClickAction.bind(this); } // Fetch the comments before mounting componentWillMount () { - this.props.dispatch({ type: 'COMMENT_STREAM_FETCH' }) + this.props.dispatch({type: 'COMMENT_STREAM_FETCH'}); } // Submit the new comment onSubmit (comment) { - this.props.dispatch(createComment(comment.name, comment.body)) + this.props.dispatch(createComment(comment.name, comment.body)); } // The only action for now is flagging onClickAction (action, id) { if (action === 'flagged') { - this.props.dispatch(flagComment(id)) - clearTimeout(this._snackTimeout) - this.setState({ snackbar: true, snackbarMsg: 'Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.' }) - this._snackTimeout = setTimeout(() => this.setState({ snackbar: false }), 30000) + this.props.dispatch(flagComment(id)); + clearTimeout(this._snackTimeout); + this.setState({snackbar: true, snackbarMsg: 'Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.'}); + this._snackTimeout = setTimeout(() => this.setState({snackbar: false}), 30000); } } // Render the comment box along with the CommentList - render ({ comments }, { snackbar, snackbarMsg }) { + render ({comments}, {snackbar, snackbarMsg}) { return (
@@ -57,8 +57,8 @@ class CommentStream extends React.Component { {snackbarMsg}
- ) + ); } } -export default connect(({ comments }) => ({ comments }))(CommentStream) +export default connect(({comments}) => ({comments}))(CommentStream); diff --git a/client/coral-admin/src/containers/Configure.js b/client/coral-admin/src/containers/Configure.js index f90e8c747..f8ab0159e 100644 --- a/client/coral-admin/src/containers/Configure.js +++ b/client/coral-admin/src/containers/Configure.js @@ -1,5 +1,5 @@ -import React from 'react' -import {connect} from 'react-redux' +import React from 'react'; +import {connect} from 'react-redux'; import { List, ListItem, @@ -9,16 +9,16 @@ import { Checkbox, Button, Icon -} from 'react-mdl' -import Page from 'components/Page' -import styles from './Configure.css' -import I18n from 'coral-framework/i18n/i18n' -import translations from '../translations' +} from 'react-mdl'; +import Page from 'components/Page'; +import styles from './Configure.css'; +import I18n from 'coral-framework/i18n/i18n'; +import translations from '../translations'; class Configure extends React.Component { constructor (props) { - super(props) - this.state = {activeSection: 'comments'} + super(props); + this.state = {activeSection: 'comments'}; } getCommentSettings () { @@ -39,23 +39,23 @@ class Configure extends React.Component { error='Input is not a number!' label='Maximum Characters' /> - + ; } - copyToClipBoard (event) { - const copyTextarea = document.querySelector('.' + styles.embedInput) - copyTextarea.select() + copyToClipBoard () { + const copyTextarea = document.querySelector(`.${ styles.embedInput}`); + copyTextarea.select(); try { - document.execCommand('copy') + document.execCommand('copy'); } catch (err) { - console.error('Unable to copy') + console.error('Unable to copy'); } } getEmbed () { const embedText = - `
` + `
`; return @@ -65,17 +65,17 @@ class Configure extends React.Component { - + ; } changeSection (activeSection) { - this.setState({activeSection}) + this.setState({activeSection}); } render () { const pageTitle = this.state.activeSection === 'comments' ? 'Comment Settings' - : 'Embed Comment Stream' + : 'Embed Comment Stream'; return ( @@ -107,10 +107,10 @@ class Configure extends React.Component { - ) + ); } } -export default connect(x => x)(Configure) +export default connect(x => x)(Configure); -const lang = new I18n(translations) +const lang = new I18n(translations); diff --git a/client/coral-admin/src/containers/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue.js index 061786543..3728deb1e 100644 --- a/client/coral-admin/src/containers/ModerationQueue.js +++ b/client/coral-admin/src/containers/ModerationQueue.js @@ -1,14 +1,14 @@ -import React from 'react' -import { connect } from 'react-redux' -import ModerationKeysModal from 'components/ModerationKeysModal' -import Page from 'components/Page' -import CommentList from 'components/CommentList' -import { updateStatus } from 'actions/comments' -import styles from './ModerationQueue.css' -import key from 'keymaster' -import I18n from 'coral-framework/i18n/i18n' -import translations from '../translations' +import React from 'react'; +import {connect} from 'react-redux'; +import ModerationKeysModal from 'components/ModerationKeysModal'; +import Page from 'components/Page'; +import CommentList from 'components/CommentList'; +import {updateStatus} from 'actions/comments'; +import styles from './ModerationQueue.css'; +import key from 'keymaster'; +import I18n from 'coral-framework/i18n/i18n'; +import translations from '../translations'; /* * Renders the moderation queue as a tabbed layout with 3 moderation @@ -18,49 +18,50 @@ import translations from '../translations' class ModerationQueue extends React.Component { constructor (props) { - super(props) + super(props); - console.log('ModerationQueue', props) + console.log('ModerationQueue', props); - this.state = { activeTab: 'pending', singleView: false, modalOpen: false } + this.state = {activeTab: 'pending', singleView: false, modalOpen: false}; } // Fetch comments and bind singleView key before render componentWillMount () { - this.props.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH' }) - key('s', () => this.setState({ singleView: !this.state.singleView })) - key('shift+/', () => this.setState({ modalOpen: true })) - key('esc', () => this.setState({ modalOpen: false })) + this.props.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH'}); + key('s', () => this.setState({singleView: !this.state.singleView})); + key('shift+/', () => this.setState({modalOpen: true})); + key('esc', () => this.setState({modalOpen: false})); } // Unbind singleView key before unmount componentWillUnmount () { - key.unbind('s') - key.unbind('shift+/') - key.unbind('esc') + key.unbind('s'); + key.unbind('shift+/'); + key.unbind('esc'); } // Hack for dynamic mdl tabs componentDidMount () { if (typeof componentHandler !== 'undefined') { - componentHandler.upgradeAllRegistered() + // FIXME: fix this hack + componentHandler.upgradeAllRegistered(); // eslint-disable-line no-undef } } // Dispatch the update status action onCommentAction (status, id) { - this.props.dispatch(updateStatus(status, id)) + this.props.dispatch(updateStatus(status, id)); } onTabClick (activeTab) { - this.setState({ activeTab }) + this.setState({activeTab}); } // Render the tabbed lists moderation queues render () { - const { comments } = this.props - const { activeTab, singleView, modalOpen } = this.state - console.log('moderation queue', styles) + const {comments} = this.props; + const {activeTab, singleView, modalOpen} = this.state; + console.log('moderation queue', styles); return ( @@ -98,8 +99,8 @@ class ModerationQueue extends React.Component { isActive={activeTab === 'rejected'} singleView={singleView} commentIds={comments.get('ids').filter(id => { - const data = comments.get('byId').get(id) - return !data.get('status') && data.get('flagged') === true + const data = comments.get('byId').get(id); + return !data.get('status') && data.get('flagged') === true; })} comments={comments.get('byId')} onClickAction={(action, id) => this.onCommentAction(action, id)} @@ -107,13 +108,13 @@ class ModerationQueue extends React.Component { loading={comments.loading} /> this.setState({ modalOpen: false })} /> + onClose={() => this.setState({modalOpen: false})} /> - ) + ); } } -export default connect(({ comments }) => ({ comments }))(ModerationQueue) +export default connect(({comments}) => ({comments}))(ModerationQueue); -const lang = new I18n(translations) +const lang = new I18n(translations); diff --git a/client/coral-admin/src/index.js b/client/coral-admin/src/index.js index d15367dd0..aed9d5748 100644 --- a/client/coral-admin/src/index.js +++ b/client/coral-admin/src/index.js @@ -1,7 +1,7 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import App from './components/App' +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './components/App'; // Render the application into the DOM -ReactDOM.render(, document.querySelector('#root')) +ReactDOM.render(, document.querySelector('#root')); diff --git a/client/coral-admin/src/reducers/comments.js b/client/coral-admin/src/reducers/comments.js index 4fd14673a..2842e2289 100644 --- a/client/coral-admin/src/reducers/comments.js +++ b/client/coral-admin/src/reducers/comments.js @@ -1,5 +1,5 @@ -import { Map, List, fromJS } from 'immutable' +import {Map, List, fromJS} from 'immutable'; /** * Comments state is stored using 2 structures: @@ -12,48 +12,48 @@ const initialState = Map({ byId: Map(), ids: List(), loading: false -}) +}); // Handle the comment actions export default (state = initialState, action) => { switch (action.type) { - case 'COMMENTS_MODERATION_QUEUE_FETCH': return state.set('loading', true) - case 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceComments(action, state) - case 'COMMENTS_MODERATION_QUEUE_FAILED': return state.set('loading', false) - case 'COMMENT_STATUS_UPDATE': return updateStatus(state, action) - case 'COMMENT_FLAG': return flag(state, action) - case 'COMMENT_CREATE_SUCCESS': return addComment(state, action) - case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state) - default: return state + case 'COMMENTS_MODERATION_QUEUE_FETCH': return state.set('loading', true); + case 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceComments(action, state); + case 'COMMENTS_MODERATION_QUEUE_FAILED': return state.set('loading', false); + case 'COMMENT_STATUS_UPDATE': return updateStatus(state, action); + case 'COMMENT_FLAG': return flag(state, action); + case 'COMMENT_CREATE_SUCCESS': return addComment(state, action); + case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state); + default: return state; } -} +}; // Update a comment status const updateStatus = (state, action) => { - const byId = state.get('byId') - const data = byId.get(action.id).get('data').set('status', action.status) - const comment = byId.get(action.id).set('data', data) - return state.set('byId', byId.set(action.id, comment)) -} + const byId = state.get('byId'); + const data = byId.get(action.id).get('data').set('status', action.status); + const comment = byId.get(action.id).set('data', data); + return state.set('byId', byId.set(action.id, comment)); +}; // Flag a comment const flag = (state, action) => { - const byId = state.get('byId') - const data = byId.get(action.id).get('data').set('flagged', true) - const comment = byId.get(action.id).set('data', data) - return state.set('byId', byId.set(action.id, comment)) -} + const byId = state.get('byId'); + const data = byId.get(action.id).get('data').set('flagged', true); + const comment = byId.get(action.id).set('data', data); + return state.set('byId', byId.set(action.id, comment)); +}; // Replace the comment list with a new one const replaceComments = (action, state) => { - const comments = fromJS(action.comments.reduce((prev, curr) => { prev[curr._id] = curr; return prev }, {})) + const comments = fromJS(action.comments.reduce((prev, curr) => { prev[curr._id] = curr; return prev; }, {})); return state.set('byId', comments).set('loading', false) - .set('ids', List(comments.keys())) -} + .set('ids', List(comments.keys())); +}; // Add a new comment const addComment = (state, action) => { - const comment = fromJS(action.comment) + const comment = fromJS(action.comment); return state.set('byId', state.get('byId').set(comment.get('item_id'), comment)) - .set('ids', state.get('ids').unshift(comment.get('item_id'))) -} + .set('ids', state.get('ids').unshift(comment.get('item_id'))); +}; diff --git a/client/coral-admin/src/reducers/index.js b/client/coral-admin/src/reducers/index.js index 5c99e3bb2..3c0ddc924 100644 --- a/client/coral-admin/src/reducers/index.js +++ b/client/coral-admin/src/reducers/index.js @@ -1,8 +1,8 @@ -import { combineReducers } from 'redux' -import comments from 'reducers/comments' +import {combineReducers} from 'redux'; +import comments from 'reducers/comments'; // Combine all reducers into a main one export default combineReducers({ comments -}) +}); diff --git a/client/coral-admin/src/services/config.js b/client/coral-admin/src/services/config.js index 56e96222f..05cf0ecb8 100644 --- a/client/coral-admin/src/services/config.js +++ b/client/coral-admin/src/services/config.js @@ -5,10 +5,10 @@ */ try { - module.exports = require('../../config.json') + module.exports = require('../../config.json'); } catch (error) { const message = `The config.json file under the root directory is missing -or invalid Please add one to use this app. You can use config.sample.json as a guide.` - window.alert(message) - throw new Error(message) +or invalid Please add one to use this app. You can use config.sample.json as a guide.`; + window.alert(message); + throw new Error(message); } diff --git a/client/coral-admin/src/services/store.js b/client/coral-admin/src/services/store.js index c11728de0..88b2650e0 100644 --- a/client/coral-admin/src/services/store.js +++ b/client/coral-admin/src/services/store.js @@ -1,8 +1,8 @@ -import { createStore, applyMiddleware } from 'redux' -import thunk from 'redux-thunk' -import mainReducer from 'reducers' -import talkAdapter from 'services/talk-adapter' +import {createStore, applyMiddleware} from 'redux'; +import thunk from 'redux-thunk'; +import mainReducer from 'reducers'; +import talkAdapter from 'services/talk-adapter'; /** * Create the store by merging the app reducers with @@ -15,4 +15,4 @@ export default createStore( mainReducer, window.devToolsExtension && window.devToolsExtension(), applyMiddleware(thunk, talkAdapter) -) +); diff --git a/client/coral-admin/src/services/talk-adapter.js b/client/coral-admin/src/services/talk-adapter.js index 2336e0cfd..ce2e2692a 100644 --- a/client/coral-admin/src/services/talk-adapter.js +++ b/client/coral-admin/src/services/talk-adapter.js @@ -10,44 +10,44 @@ // Intercept redux actions and act over the ones we are interested export default store => next => action => { switch (action.type) { - case 'COMMENTS_MODERATION_QUEUE_FETCH': - fetchModerationQueueComments(store) - break - case 'COMMENT_STREAM_FETCH': - fetchCommentStream(store) - break - case 'COMMENT_UPDATE': - updateComment(store, action.comment) - break - case 'COMMENT_CREATE': - createComment(store, action.name, action.body) - break + case 'COMMENTS_MODERATION_QUEUE_FETCH': + fetchModerationQueueComments(store); + break; + // case 'COMMENT_STREAM_FETCH': + // fetchCommentStream(store); + // break; + case 'COMMENT_UPDATE': + updateComment(store, action.comment); + break; + case 'COMMENT_CREATE': + createComment(store, action.name, action.body); + break; } - next(action) -} + next(action); +}; // Get comments to fill each of the three lists on the mod queue const fetchModerationQueueComments = store => -fetch(`/api/v1/queue`) +fetch('/api/v1/queue') .then(res => res.json()) -.then(res => store.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS', - comments: res })) -.catch(error => store.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error })) +.then(res => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS', + comments: res})) +.catch(error => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error})); // Update a comment. Now to update a comment we need to send back the whole object const updateComment = (store, comment) => fetch(`/api/v1/comments/${comment._id}/status`, { method: 'POST', - body: JSON.stringify({ status: comment.status }) + body: JSON.stringify({status: comment.status}) }) .then(res => res.json()) -.then(res => store.dispatch({ type: 'COMMENT_UPDATE_SUCCESS', res })) -.catch(error => store.dispatch({ type: 'COMMENT_UPDATE_FAILED', error })) +.then(res => store.dispatch({type: 'COMMENT_UPDATE_SUCCESS', res})) +.catch(error => store.dispatch({type: 'COMMENT_UPDATE_FAILED', error})); // Create a new comment const createComment = (store, name, comment) => -fetch(`/api/v1/comments`, { +fetch('/api/v1/comments', { method: 'POST', body: JSON.stringify({ status: 'Untouched', @@ -56,5 +56,5 @@ fetch(`/api/v1/comments`, { createdAt: Date.now() }) }).then(res => res.json()) -.then(res => store.dispatch({ type: 'COMMENT_CREATE_SUCCESS', comment: res })) -.catch(error => store.dispatch({ type: 'COMMENT_CREATE_FAILED', error })) +.then(res => store.dispatch({type: 'COMMENT_CREATE_SUCCESS', comment: res})) +.catch(error => store.dispatch({type: 'COMMENT_CREATE_FAILED', error})); diff --git a/client/coral-admin/src/translations.js b/client/coral-admin/src/translations.js index ce5bf7718..5302c1221 100644 --- a/client/coral-admin/src/translations.js +++ b/client/coral-admin/src/translations.js @@ -1,39 +1,39 @@ export default { en: { - "modqueue": { - "pending": "pending", - "rejected": "rejected", - "flagged": "flagged", - "shortcuts": "Shortcuts", - "close": "Close", - "actions": "Actions", - "navigation": "Navigation", - "approve": "Approve comment", - "reject": "Reject comment", - "nextcomment": "Go to the next comment", - "prevcomment": "Go to the previous comment", - "singleview": "Toggle single comment edit view", - "thismenu": "Open this menu" + 'modqueue': { + 'pending': 'pending', + 'rejected': 'rejected', + 'flagged': 'flagged', + 'shortcuts': 'Shortcuts', + 'close': 'Close', + 'actions': 'Actions', + 'navigation': 'Navigation', + 'approve': 'Approve comment', + 'reject': 'Reject comment', + 'nextcomment': 'Go to the next comment', + 'prevcomment': 'Go to the previous comment', + 'singleview': 'Toggle single comment edit view', + 'thismenu': 'Open this menu' }, - "comment": { - "flagged": "flagged", - "anon": "Anonymous" + 'comment': { + 'flagged': 'flagged', + 'anon': 'Anonymous' }, - "embedlink": { - "copy": "Copy to Clipboard" + 'embedlink': { + 'copy': 'Copy to Clipboard' } }, es: { - "modqueue": { - "pending": "pendiente", - "rejected": "rechazado", - "flagged": "marcado", - "shortcuts": "Atajos de teclado", - "close": "Cerrar" + 'modqueue': { + 'pending': 'pendiente', + 'rejected': 'rechazado', + 'flagged': 'marcado', + 'shortcuts': 'Atajos de teclado', + 'close': 'Cerrar' }, - "comment": { - "flagged": "marcado", - "anon": "Anónimo" + 'comment': { + 'flagged': 'marcado', + 'anon': 'Anónimo' } } -} +}; diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js index cda7ffd57..76d5a0e9b 100644 --- a/client/coral-embed-stream/src/CommentStream.js +++ b/client/coral-embed-stream/src/CommentStream.js @@ -1,63 +1,62 @@ -import React, {Component, PropTypes} from 'react' +import React, {Component, PropTypes} from 'react'; import { itemActions, Notification, notificationActions, authActions -} from '../../coral-framework' -import {connect} from 'react-redux' -import CommentBox from '../../coral-plugin-commentbox/CommentBox' -import Content from '../../coral-plugin-commentcontent/CommentContent' -import PubDate from '../../coral-plugin-pubdate/PubDate' -import Count from '../../coral-plugin-comment-count/CommentCount' -import Flag from '../../coral-plugin-flags/FlagButton' -import AuthorName from '../../coral-plugin-author-name/AuthorName' -import {ReplyBox, ReplyButton} from '../../coral-plugin-replies' -import Pym from 'pym.js' +} from '../../coral-framework'; +import {connect} from 'react-redux'; +import CommentBox from '../../coral-plugin-commentbox/CommentBox'; +import Content from '../../coral-plugin-commentcontent/CommentContent'; +import PubDate from '../../coral-plugin-pubdate/PubDate'; +import Count from '../../coral-plugin-comment-count/CommentCount'; +import AuthorName from '../../coral-plugin-author-name/AuthorName'; +import {ReplyBox, ReplyButton} from '../../coral-plugin-replies'; +import Pym from 'pym.js'; -const {addItem, updateItem, postItem, getStream, postAction, appendItemArray} = itemActions -const {addNotification, clearNotification} = notificationActions -const {setLoggedInUser} = authActions +const {addItem, updateItem, postItem, getStream, postAction, appendItemArray} = itemActions; +const {addNotification, clearNotification} = notificationActions; +const {setLoggedInUser} = authActions; @connect( (state) => { - return { + return { config: state.config.toJS(), items: state.items.toJS(), notification: state.notification.toJS(), auth: state.auth.toJS() - } + }; }, (dispatch) => { return { addItem: (item) => { - return dispatch(addItem(item)) + return dispatch(addItem(item)); }, updateItem: (id, property, value) => { - return dispatch(updateItem(id, property, value)) + return dispatch(updateItem(id, property, value)); }, postItem: (data, type, id) => { - return dispatch(postItem(data, type, id)) + return dispatch(postItem(data, type, id)); }, getStream: (rootId) => { - return dispatch(getStream(rootId)) + return dispatch(getStream(rootId)); }, addNotification: (type, text) => { - return dispatch(addNotification(type, text)) + return dispatch(addNotification(type, text)); }, clearNotification: () => { - return dispatch(clearNotification()) + return dispatch(clearNotification()); }, setLoggedInUser: (user_id) => { - return dispatch(setLoggedInUser(user_id)) + return dispatch(setLoggedInUser(user_id)); }, postAction: (item, action, user) => { - return dispatch(postAction(item, action, user)) + return dispatch(postAction(item, action, user)); }, appendItemArray: (item, property, value, addToFront) => { - return dispatch(appendItemArray(item, property, value, addToFront)) + return dispatch(appendItemArray(item, property, value, addToFront)); } - } + }; } ) @@ -72,33 +71,30 @@ class CommentStream extends Component { componentDidMount () { // Set up messaging between embedded Iframe an parent component // Using recommended Pym init code which violates .eslint standards - new Pym.Child({ polling: 500 }) - this.props.getStream('assetTest') + new Pym.Child({polling: 500}); + this.props.getStream('assetTest'); } render () { - if (Object.keys(this.props.items).length === 0) { + if (Object.keys(this.props.items).length === 0) { // Loading mock asset - this.props.postItem({ - comments: [], - url: 'http://coralproject.net' - }, 'asset', 'assetTest') + this.props.postItem({ + comments: [], + url: 'http://coralproject.net' + }, 'asset', 'assetTest'); // Loading mock user - this.props.postItem({name: 'Ban Ki-Moon'}, 'user', 'user_8989') + this.props.postItem({name: 'Ban Ki-Moon'}, 'user', 'user_8989') .then((id) => { - this.props.setLoggedInUser(id) - }) - } - + this.props.setLoggedInUser(id); + }); + } // TODO: Replace teststream id with id from params - - - const rootItemId = 'assetTest' - const rootItem = this.props.items[rootItemId] - return
+ const rootItemId = 'assetTest'; + const rootItem = this.props.items[rootItemId]; + return
{ rootItem ?
@@ -116,7 +112,7 @@ class CommentStream extends Component {
{ rootItem.comments.map((commentId) => { - const comment = this.props.items[commentId] + const comment = this.props.items[commentId]; return

@@ -146,8 +142,8 @@ class CommentStream extends Component { { comment.children && comment.children.map((replyId) => { - let reply = this.props.items[replyId] - return
+ let reply = this.props.items[replyId]; + return

@@ -165,10 +161,10 @@ class CommentStream extends Component { updateItem={this.props.updateItem} parent_id={reply.parent_id}/>
-
- }) +
; + }) } -
+
; }) } - :'Loading' + : 'Loading' } - - + ; } } -export default CommentStream +export default CommentStream; diff --git a/client/coral-embed-stream/src/index.js b/client/coral-embed-stream/src/index.js index 189427e23..f2a584ed1 100644 --- a/client/coral-embed-stream/src/index.js +++ b/client/coral-embed-stream/src/index.js @@ -1,13 +1,13 @@ -import React from 'react' -import { render } from 'react-dom' -import CommentStream from './CommentStream' -import { Provider } from 'react-redux' -import { fetchConfig, store } from '../../coral-framework' +import React from 'react'; +import {render} from 'react-dom'; +import CommentStream from './CommentStream'; +import {Provider} from 'react-redux'; +import {fetchConfig, store} from '../../coral-framework'; -store.dispatch(fetchConfig()) +store.dispatch(fetchConfig()); render( - , document.querySelector('#coralStream')) + , document.querySelector('#coralStream')); diff --git a/client/coral-framework/__tests__/store/authReducer.js b/client/coral-framework/__tests__/store/authReducer.js index dd9f58501..90138f8f2 100644 --- a/client/coral-framework/__tests__/store/authReducer.js +++ b/client/coral-framework/__tests__/store/authReducer.js @@ -1,7 +1,7 @@ -import { Map } from 'immutable' -import {expect} from 'chai' -import authReducer from '../../store/reducers/auth' -import * as actions from '../../store/actions/auth' +import {Map} from 'immutable'; +import {expect} from 'chai'; +import authReducer from '../../store/reducers/auth'; +import * as actions from '../../store/actions/auth'; describe ('authReducer', () => { describe('SET_LOGGED_IN_USER', () => { @@ -9,23 +9,23 @@ describe ('authReducer', () => { const action = { type: actions.SET_LOGGED_IN_USER, user_id: '123' - } - const store = new Map({}) - const result = authReducer(store, action) - expect(result.get('user')).to.equal(action.user_id) - }) - }) + }; + const store = new Map({}); + const result = authReducer(store, action); + expect(result.get('user')).to.equal(action.user_id); + }); + }); describe('LOG_OUT_USER', () => { it('should clear the user store', () => { const action = { type: actions.LOG_OUT_USER - } + }; const store = new Map({ user: '123' - }) - const result = authReducer(store, action) - expect(result.get('user')).to.equal(undefined) - }) - }) -}) + }); + const result = authReducer(store, action); + expect(result.get('user')).to.equal(undefined); + }); + }); +}); diff --git a/client/coral-framework/__tests__/store/itemActions.spec.js b/client/coral-framework/__tests__/store/itemActions.spec.js index 948aee32d..14bdca790 100644 --- a/client/coral-framework/__tests__/store/itemActions.spec.js +++ b/client/coral-framework/__tests__/store/itemActions.spec.js @@ -1,70 +1,70 @@ -import 'react' -import 'redux' -import {expect} from 'chai' -import fetchMock from 'fetch-mock' -import * as actions from '../../store/actions/items' -import {Map} from 'immutable' +import 'react'; +import 'redux'; +import {expect} from 'chai'; +import fetchMock from 'fetch-mock'; +import * as actions from '../../store/actions/items'; +import {Map} from 'immutable'; -import configureStore from 'redux-mock-store' +import configureStore from 'redux-mock-store'; -const mockStore = configureStore() +const mockStore = configureStore(); describe('itemActions', () => { - let store - const host = 'http://test.host' + let store; + const host = 'http://test.host'; beforeEach(() => { - store = mockStore(new Map({})) - fetchMock.restore() - }) + store = mockStore(new Map({})); + fetchMock.restore(); + }); describe('getItemsQuery', () => { - const query = 'all' - const rootId = '1234' - const view = 'testView' + const query = 'all'; + const rootId = '1234'; + const view = 'testView'; const response = {results: [ {Docs: [ {type: 'comment', data: {content: 'stuff'}, item_id: '123'}, {type: 'comment', data: {content: 'morestuff'}, item_id: '456'} ]} - ]} + ]}; it('should get an item from a query and send the appropriate dispatches', () => { - fetchMock.get('*', JSON.stringify(response)) + fetchMock.get('*', JSON.stringify(response)); return actions.getItemsQuery(query, rootId, view, host)(store.dispatch) .then((res) => { - expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/exec/all/view/testView/1234') - expect(res).to.deep.equal(response.results[0].Docs) + expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/exec/all/view/testView/1234'); + expect(res).to.deep.equal(response.results[0].Docs); expect(store.getActions()[0]).to.deep.equal({ type: actions.ADD_ITEM, item: response.results[0].Docs[0], item_id: '123' - }) + }); expect(store.getActions()[1]).to.deep.equal({ type: actions.ADD_ITEM, item: response.results[0].Docs[1], item_id: '456' - }) - }) - }) + }); + }); + }); it('should handle an error', () => { - fetchMock.get('*', 404) + fetchMock.get('*', 404); return actions.getItemsQuery(query, rootId, view, host)(store.dispatch) .catch((err) => { - expect(err).to.be.truthy - }) - }) - }) + expect(err).to.be.truthy; + }); + }); + }); describe('getItemsArray', () => { - const response = {items: [{type: 'comment', item_id: '123'}, {type: 'comment', item_id: '456'}]} - const ids = [1, 2] + const response = {items: [{type: 'comment', item_id: '123'}, {type: 'comment', item_id: '456'}]}; + const ids = [1, 2]; it('should get an item from an array of ids and send the appropriate dispatches', () => { - fetchMock.get('*', JSON.stringify(response)) + fetchMock.get('*', JSON.stringify(response)); return actions.getItemsArray(ids, host)(store.dispatch) .then((res) => { - expect(res).to.deep.equal(response.items) + expect(res).to.deep.equal(response.items); expect(store.getActions()[0]).to.deep.equal({ type: actions.ADD_ITEM, item: { @@ -72,33 +72,33 @@ describe('itemActions', () => { item_id: '123' }, item_id: '123' - }) + }); expect(store.getActions()[1]).to.deep.equal({ type: actions.ADD_ITEM, item: { type: 'comment', item_id: '456' }, item_id: '456' - }) - }) - }) + }); + }); + }); it('should handle an error', () => { - fetchMock.get('*', 404) + fetchMock.get('*', 404); return actions.getItemsArray(ids, host)(store.dispatch) .catch((err) => { - expect(err).to.be.truthy - }) - }) - }) + expect(err).to.be.truthy; + }); + }); + }); describe('postItem', () => { const item = { type: 'comment', data:{content: 'stuff'} - } + }; it ('should post an item, return an id, then dispatch that item to the store', () => { - fetchMock.post('*', {item_id: '123', type: 'comment', data: {content: 'stuff'}}) + fetchMock.post('*', {item_id: '123', type: 'comment', data: {content: 'stuff'}}); return actions.postItem(item.data, item.type, undefined, host)(store.dispatch) .then((id) => { expect(fetchMock.calls().matched[0][1]).to.deep.equal( @@ -106,8 +106,8 @@ describe('itemActions', () => { method: 'POST', body: JSON.stringify({...item, version: 1}) } - ) - expect(id).to.equal('123') + ); + expect(id).to.equal('123'); expect(store.getActions()[0]).to.deep.equal({ type: actions.ADD_ITEM, item: { @@ -118,35 +118,35 @@ describe('itemActions', () => { item_id: '123' }, item_id: '123' - }) - }) - }) + }); + }); + }); it('should handle an error', () => { - fetchMock.post('*', 404) + fetchMock.post('*', 404); return actions.postItem(item, host)(store.dispatch) .catch((err) => { - expect(err).to.be.truthy - }) - }) - }) + expect(err).to.be.truthy; + }); + }); + }); describe('postAction', () => { it ('should post an action', () => { - fetchMock.post('*', 200) + fetchMock.post('*', 200); return actions.postAction('abc', 'flag', '123', host)(store.dispatch) .then(response => { - expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/action/flag/user/123/on/item/abc') - expect(response).to.equal('') - }) - }) + expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/action/flag/user/123/on/item/abc'); + expect(response).to.equal(''); + }); + }); it('should handle an error', () => { - fetchMock.post('*', 404) + fetchMock.post('*', 404); return actions.postItem('abc', 'flag', '123', host)(store.dispatch) .catch((err) => { - expect(err).to.be.truthy - }) - }) + expect(err).to.be.truthy; + }); + }); - }) -}) + }); +}); diff --git a/client/coral-framework/__tests__/store/itemReducer.spec.js b/client/coral-framework/__tests__/store/itemReducer.spec.js index 8a664ac8c..0e8106bae 100644 --- a/client/coral-framework/__tests__/store/itemReducer.spec.js +++ b/client/coral-framework/__tests__/store/itemReducer.spec.js @@ -1,7 +1,6 @@ -import { Map, fromJS } from 'immutable' -import {expect} from 'chai' -import itemsReducer from '../../store/reducers/items' -import * as actions from '../../store/actions/items' +import {Map, fromJS} from 'immutable'; +import {expect} from 'chai'; +import itemsReducer from '../../store/reducers/items'; describe ('itemsReducer', () => { describe('ADD_ITEM', () => { @@ -16,18 +15,18 @@ describe ('itemsReducer', () => { item_id: '123' }, item_id: '123' - } - const store = new Map({}) - const result = itemsReducer(store, action) + }; + const store = new Map({}); + const result = itemsReducer(store, action); expect(result.get('123').toJS()).to.deep.equal({ type: 'comment', data: { content: 'stuff' }, item_id: '123' - }) - }) - }) + }); + }); + }); describe ('UPDATE_ITEM', () => { it ('should update an item', () => { @@ -36,7 +35,7 @@ describe ('itemsReducer', () => { property: 'stuff', value: 'things', item_id: '123' - } + }; const store = fromJS({ '123': { item_id: '123', @@ -44,20 +43,20 @@ describe ('itemsReducer', () => { stuff: 'morestuff' } } - }) - const result = itemsReducer(store, action) + }); + const result = itemsReducer(store, action); expect(result.get('123').toJS()).to.deep.equal({ item_id: '123', data: { stuff: 'things' } - }) - }) - }) + }); + }); + }); describe('APPEND_ITEM_ARRAY', () => { - let action - let store + let action; + let store; beforeEach (() => { action = { @@ -65,7 +64,7 @@ describe ('itemsReducer', () => { property: 'stuff', value: 'things', item_id: '123' - } + }; store = fromJS({ '123': { item_id: '123', @@ -73,37 +72,37 @@ describe ('itemsReducer', () => { stuff: ['morestuff'] } } - }) - }) + }); + }); it ('should append to an existing array', () => { - const result = itemsReducer(store, action) + const result = itemsReducer(store, action); expect(result.get('123').toJS()).to.deep.equal({ item_id: '123', data: { stuff: ['morestuff', 'things'] } - }) - }) + }); + }); it ('should create a new array', () => { store = fromJS({ '123': { item_id: '123', data: {} } - }) - const result = itemsReducer(store, action) + }); + const result = itemsReducer(store, action); expect(result.get('123').toJS()).to.deep.equal({ item_id: '123', data: { stuff: ['things'] } - }) - }) - }) + }); + }); + }); describe('APPEND_ITEM_RELATED', () => { - let action - let store + let action; + let store; beforeEach (() => { action = { @@ -111,7 +110,7 @@ describe ('itemsReducer', () => { property: 'stuff', value: 'things', item_id: '123' - } + }; store = fromJS({ '123': { item_id: '123', @@ -119,31 +118,31 @@ describe ('itemsReducer', () => { stuff: ['morestuff'] } } - }) - }) + }); + }); it ('should append to an existing array', () => { - const result = itemsReducer(store, action) + const result = itemsReducer(store, action); expect(result.get('123').toJS()).to.deep.equal({ item_id: '123', related: { stuff: ['morestuff', 'things'] } - }) - }) + }); + }); it ('should create a new array', () => { store = fromJS({ '123': { item_id: '123', related: {} } - }) - const result = itemsReducer(store, action) + }); + const result = itemsReducer(store, action); expect(result.get('123').toJS()).to.deep.equal({ item_id: '123', related: { stuff: ['things'] } - }) - }) - }) -}) + }); + }); + }); +}); diff --git a/client/coral-framework/__tests__/store/notificationReducer.spec.js b/client/coral-framework/__tests__/store/notificationReducer.spec.js index 4f37034a6..974d2c627 100644 --- a/client/coral-framework/__tests__/store/notificationReducer.spec.js +++ b/client/coral-framework/__tests__/store/notificationReducer.spec.js @@ -1,7 +1,7 @@ -import { Map } from 'immutable' -import {expect} from 'chai' -import notificationReducer from '../../store/reducers/notification' -import * as actions from '../../store/actions/notification' +import {Map} from 'immutable'; +import {expect} from 'chai'; +import notificationReducer from '../../store/reducers/notification'; +import * as actions from '../../store/actions/notification'; describe ('notificationsReducer', () => { describe('ADD_NOTIFICATION', () => { @@ -10,26 +10,26 @@ describe ('notificationsReducer', () => { type: actions.ADD_NOTIFICATION, text: 'Test notification', notifType: 'test' - } - const store = new Map({}) - const result = notificationReducer(store, action) - expect(result.get('text')).to.equal(action.text) - expect(result.get('type')).to.equal(action.notifType) - }) - }) + }; + const store = new Map({}); + const result = notificationReducer(store, action); + expect(result.get('text')).to.equal(action.text); + expect(result.get('type')).to.equal(action.notifType); + }); + }); describe('CLEAR_NOTIFICATION', () => { it('should clear a notification', () => { const action = { type: actions.CLEAR_NOTIFICATION - } + }; const store = new Map({ text: 'Test notification', type: 'test' - }) - const result = notificationReducer(store, action) - expect(result.get('text')).to.equal(undefined) - expect(result.get('type')).to.equal(undefined) - }) - }) -}) + }); + const result = notificationReducer(store, action); + expect(result.get('text')).to.equal(undefined); + expect(result.get('type')).to.equal(undefined); + }); + }); +}); diff --git a/client/coral-framework/i18n/i18n.js b/client/coral-framework/i18n/i18n.js index d3e7d92b8..43144f3a6 100644 --- a/client/coral-framework/i18n/i18n.js +++ b/client/coral-framework/i18n/i18n.js @@ -1,5 +1,5 @@ -import timeago from 'timeago.js' -import esTA from 'timeago.js/locales/es' +import timeago from 'timeago.js'; +import esTA from 'timeago.js/locales/es'; /** * Default locales, this should be overriden by config file @@ -11,32 +11,34 @@ class i18n { * Register locales */ - this.locales = {'en': 'en', 'es': 'es'} - timeago.register('es_ES', esTA) - this.timeagoInstance = new timeago() + this.locales = {'en': 'en', 'es': 'es'}; + timeago.register('es_ES', esTA); + this.timeagoInstance = new timeago(); /** * Load translations */ - let trans = translations || { en: {} } + let trans = translations || {en: {}}; try { - const locale = localStorage.getItem('locale') || navigator.language - localStorage.setItem('locale', locale) - const lang = this.locales[locale.split('-')[0]] || 'en' - this.translations = trans[lang] + const locale = localStorage.getItem('locale') || navigator.language; + localStorage.setItem('locale', locale); + const lang = this.locales[locale.split('-')[0]] || 'en'; + this.translations = trans[lang]; } catch (err) { - this.translations = trans['en'] + this.translations = trans['en']; } this.setLocale = (locale) => { try { - localStorage.setItem('locale', locale) - } catch (err) {} - } + localStorage.setItem('locale', locale); + } catch (err) { + console.error(err); + } + }; this.getLocale = () => ( localStorage.getItem('locale') || navigator.locale || 'en-US' - ) + ); /** * Expose the translation function @@ -47,28 +49,28 @@ class i18n { */ this.t = (key) => { - const arr = key.split('.') - let translation = this.translations + const arr = key.split('.'); + let translation = this.translations; try { - for (var i = 0; i < arr.length; i++) translation = translation[arr[i]] + for (let i = 0; i < arr.length; i++) {translation = translation[arr[i]];} } catch (error) { - console.warn(`${key} language key not set`) - return key + console.warn(`${key} language key not set`); + return key; } - const val = String(translation) + const val = String(translation); if (val) { - return val + return val; } else { - console.warn(`${key} language key not set`) - return key + console.warn(`${key} language key not set`); + return key; } - } + }; this.timeago = (time) => { - return this.timeagoInstance.format(time) - } + return this.timeagoInstance.format(time); + }; } } -export default i18n +export default i18n; diff --git a/client/coral-framework/index.js b/client/coral-framework/index.js index 537693d97..118935c50 100644 --- a/client/coral-framework/index.js +++ b/client/coral-framework/index.js @@ -1,10 +1,10 @@ -import Notification from './notification/Notification' -import store from './store/store' -import {fetchConfig} from './store/actions/config' -import * as itemActions from './store/actions/items' -import I18n from './i18n/i18n' -import * as notificationActions from './store/actions/notification' -import * as authActions from './store/actions/auth' +import Notification from './notification/Notification'; +import store from './store/store'; +import {fetchConfig} from './store/actions/config'; +import * as itemActions from './store/actions/items'; +import I18n from './i18n/i18n'; +import * as notificationActions from './store/actions/notification'; +import * as authActions from './store/actions/auth'; export { Notification, @@ -14,4 +14,4 @@ export { I18n, notificationActions, authActions -} +}; diff --git a/client/coral-framework/notification/Notification.js b/client/coral-framework/notification/Notification.js index 5d26e3dbf..2a5e1d693 100644 --- a/client/coral-framework/notification/Notification.js +++ b/client/coral-framework/notification/Notification.js @@ -1,19 +1,19 @@ -import React from 'react' +import React from 'react'; const Notification = (props) => { if (props.notification.text) { setTimeout(() => { - props.clearNotification() - }, props.notifLength) + props.clearNotification(); + }, props.notifLength); } return
{ props.notification.text && - + {props.notification.text} } -
-} + ; +}; -export default Notification +export default Notification; diff --git a/client/coral-framework/store/actions/auth.js b/client/coral-framework/store/actions/auth.js index dfdf2c7cd..af1e3cb34 100644 --- a/client/coral-framework/store/actions/auth.js +++ b/client/coral-framework/store/actions/auth.js @@ -1,17 +1,17 @@ /* Auth Actions */ -export const SET_LOGGED_IN_USER = 'SET_LOGGED_IN_USER' -export const LOG_OUT_USER = 'LOG_OUT_USER' +export const SET_LOGGED_IN_USER = 'SET_LOGGED_IN_USER'; +export const LOG_OUT_USER = 'LOG_OUT_USER'; export const setLoggedInUser = (user_id) => { return { type: SET_LOGGED_IN_USER, user_id - } -} + }; +}; export const LogOutUser = () => { return { type: LOG_OUT_USER - } -} + }; +}; diff --git a/client/coral-framework/store/actions/config.js b/client/coral-framework/store/actions/config.js index 243cb9049..b529fc313 100644 --- a/client/coral-framework/store/actions/config.js +++ b/client/coral-framework/store/actions/config.js @@ -1,28 +1,28 @@ /* @flow */ -import { fromJS } from 'immutable' +import {fromJS} from 'immutable'; /** * Action name constants */ -export const FETCH_CONFIG_REQUEST = 'FETCH_CONFIG_REQUEST' -export const FETCH_CONFIG_FAILED = 'FETCH_CONFIG_FAILED' -export const FETCH_CONFIG_SUCCESS = 'FETCH_CONFIG_SUCCESS' +export const FETCH_CONFIG_REQUEST = 'FETCH_CONFIG_REQUEST'; +export const FETCH_CONFIG_FAILED = 'FETCH_CONFIG_FAILED'; +export const FETCH_CONFIG_SUCCESS = 'FETCH_CONFIG_SUCCESS'; /** * Action creators */ export const fetchConfig = () => async (dispatch) => { - dispatch({ type: FETCH_CONFIG_REQUEST }) + dispatch({type: FETCH_CONFIG_REQUEST}); try { //TODO: Replace with fetching config from backend // const response = await fetch(`./talk.config.json`) // const json = await response.json() - dispatch({ type: FETCH_CONFIG_SUCCESS, config: fromJS({}) }) + dispatch({type: FETCH_CONFIG_SUCCESS, config: fromJS({})}); } catch (error) { - dispatch({ type: FETCH_CONFIG_FAILED }) + dispatch({type: FETCH_CONFIG_FAILED}); } -} +}; diff --git a/client/coral-framework/store/actions/items.js b/client/coral-framework/store/actions/items.js index 8b30e2548..56e0aafc3 100644 --- a/client/coral-framework/store/actions/items.js +++ b/client/coral-framework/store/actions/items.js @@ -1,15 +1,12 @@ /* Item Actions */ -import { fromJS } from 'immutable' -import mocks from '../../mocks.json' - /** * Action name constants */ -export const ADD_ITEM = 'ADD_ITEM' -export const UPDATE_ITEM = 'UPDATE_ITEM' -export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY' +export const ADD_ITEM = 'ADD_ITEM'; +export const UPDATE_ITEM = 'UPDATE_ITEM'; +export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY'; /** * Action creators @@ -26,14 +23,14 @@ export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY' export const addItem = (item) => { if (!item.id) { - console.warn('addItem called without an item id.') + console.warn('addItem called without an item id.'); } return { type: ADD_ITEM, item: item, id: item.id - } -} + }; +}; /* * Updates an item in the local store without posting it to the server @@ -46,15 +43,14 @@ export const addItem = (item) => { * */ - export const updateItem = (id, property, value) => { return { type: UPDATE_ITEM, id, property, value - } -} + }; +}; export const appendItemArray = (id, property, value, addToFront) => { return { @@ -63,8 +59,8 @@ export const appendItemArray = (id, property, value, addToFront) => { property, value, addToFront - } -} + }; +}; /* * Get Items from Query @@ -81,47 +77,47 @@ export const appendItemArray = (id, property, value, addToFront) => { */ export function getStream (assetId) { return (dispatch) => { - return fetch('/api/v1/stream?asset_id='+assetId) + return fetch(`/api/v1/stream?asset_id=${assetId}`) .then( response => { - return response.ok ? response.json() : Promise.reject(response.status + ' ' + response.statusText) + return response.ok ? response.json() : Promise.reject(`${response.status } ${ response.statusText}`); } ) .then((json) => { /* Sort comments by date*/ - let rootComments = [] - let childComments = {} - json.sort((a,b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()) - json.reduce((prev, item) => { - dispatch(addItem(item)) + let rootComments = []; + let childComments = {}; + json.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime()); + json.forEach(item => { + dispatch(addItem(item)); /* Check for root and child comments. */ if ( item.asset_id === assetId && !item.parent_id) { - rootComments.push(item.id) + rootComments.push(item.id); } else if ( item.asset_id === assetId ) { - let children = childComments[item.parent_id] || [] - childComments[item.parent_id] = children.concat(item.id) + let children = childComments[item.parent_id] || []; + childComments[item.parent_id] = children.concat(item.id); } - }, {}) + }, {}); dispatch(addItem({ id: assetId, comments: rootComments - })) + })); - const keys = Object.keys(childComments) - for (var i=0; i < keys.length; i++ ) { - dispatch(updateItem(keys[i], 'children', childComments[keys[i]].reverse())) + const keys = Object.keys(childComments); + for (let i = 0; i < keys.length; i++ ) { + dispatch(updateItem(keys[i], 'children', childComments[keys[i]].reverse())); } - return (json) - }) - } + return (json); + }); + }; } /* @@ -140,20 +136,20 @@ export function getStream (assetId) { export function getItemsArray (ids) { return (dispatch) => { - return fetch('/v1/item/' + ids) + return fetch(`/v1/item/${ ids}`) .then( response => { return response.ok ? response.json() - : Promise.reject(response.status + ' ' + response.statusText) + : Promise.reject(`${response.status } ${ response.statusText}`); } ) .then((json) => { - for (var i = 0; i < json.items.length; i++) { - dispatch(addItem(json.items[i])) + for (let i = 0; i < json.items.length; i++) { + dispatch(addItem(json.items[i])); } - return json.items - }) - } + return json.items; + }); + }; } /* @@ -173,7 +169,7 @@ export function getItemsArray (ids) { export function postItem (item, type, id) { return (dispatch) => { if (id) { - item.id = id + item.id = id; } let options = { method: 'POST', @@ -181,20 +177,20 @@ export function postItem (item, type, id) { headers: { 'Content-Type':'application/json' } - } + }; console.log('postItem', options); - return fetch('/api/v1/' + type, options) + return fetch(`/api/v1/${ type}`, options) .then( response => { return response.ok ? response.json() - : Promise.reject(response.status + ' ' + response.statusText) + : Promise.reject(`${response.status } ${ response.statusText}`); } ) .then((json) => { - dispatch(addItem({...item, id:json.id})) - return json.id - }) - } + dispatch(addItem({...item, id:json.id})); + return json.id; + }); + }; } //http://localhost:16180/v1/action/flag/user/user_89654/on/item/87e418c5-aafb-4eb7-9ce4-78f28793782a @@ -219,19 +215,19 @@ export function postAction (id, type, user_id) { const action = { type, user_id - } + }; const options = { method: 'POST', body: JSON.stringify(action) - } + }; - dispatch(appendItemArray(id, type, user_id)) - return fetch('/api/v1/comments/' + id + '/actions', options) + dispatch(appendItemArray(id, type, user_id)); + return fetch(`/api/v1/comments/${ id }/actions`, options) .then( response => { return response.ok ? response.text() - : Promise.reject(response.status + ' ' + response.statusText) + : Promise.reject(`${response.status } ${ response.statusText}`); } - ) - } + ); + }; } diff --git a/client/coral-framework/store/actions/notification.js b/client/coral-framework/store/actions/notification.js index 0503c2a64..c34adc414 100644 --- a/client/coral-framework/store/actions/notification.js +++ b/client/coral-framework/store/actions/notification.js @@ -1,18 +1,18 @@ /* Notification Actions */ -export const ADD_NOTIFICATION = 'ADD_NOTIFICATION' -export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION' +export const ADD_NOTIFICATION = 'ADD_NOTIFICATION'; +export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION'; export const addNotification = (notifType, text) => { return { type: ADD_NOTIFICATION, notifType, text - } -} + }; +}; export const clearNotification = () => { return { type: CLEAR_NOTIFICATION - } -} + }; +}; diff --git a/client/coral-framework/store/reducers/auth.js b/client/coral-framework/store/reducers/auth.js index f25c88749..b79444cc9 100644 --- a/client/coral-framework/store/reducers/auth.js +++ b/client/coral-framework/store/reducers/auth.js @@ -1,17 +1,17 @@ /* Auth */ -import * as actions from '../actions/auth' -import { fromJS } from 'immutable' +import * as actions from '../actions/auth'; +import {fromJS} from 'immutable'; -const initialState = fromJS({}) +const initialState = fromJS({}); export default (state = initialState, action) => { switch (action.type) { - case actions.SET_LOGGED_IN_USER: - return state.set('user', action.user_id) - case actions.LOG_OUT_USER: - return initialState - default: - return state + case actions.SET_LOGGED_IN_USER: + return state.set('user', action.user_id); + case actions.LOG_OUT_USER: + return initialState; + default: + return state; } -} +}; diff --git a/client/coral-framework/store/reducers/config.js b/client/coral-framework/store/reducers/config.js index d9ee5e763..cbc131fe6 100644 --- a/client/coral-framework/store/reducers/config.js +++ b/client/coral-framework/store/reducers/config.js @@ -1,25 +1,25 @@ /* @flow */ -import { Map, fromJS } from 'immutable' -import * as actions from '../actions/config' +import {Map} from 'immutable'; +import * as actions from '../actions/config'; const initialState = Map({ features: Map({}) -}) +}); export default (state = initialState, action) => { switch(action.type) { - case actions.FETCH_CONFIG_REQUEST: - return state.set('loading', true) + case actions.FETCH_CONFIG_REQUEST: + return state.set('loading', true); - case actions.FETCH_CONFIG_FAILED: - return state.set('loading', false) + case actions.FETCH_CONFIG_FAILED: + return state.set('loading', false); // Override config if worked - case actions.FETCH_CONFIG_SUCCESS: - return action.config.set('loading', false) + case actions.FETCH_CONFIG_SUCCESS: + return action.config.set('loading', false); - default: - return state + default: + return state; } -} +}; diff --git a/client/coral-framework/store/reducers/index.js b/client/coral-framework/store/reducers/index.js index 5774a4d9d..b38de61ae 100644 --- a/client/coral-framework/store/reducers/index.js +++ b/client/coral-framework/store/reducers/index.js @@ -1,10 +1,10 @@ /* @flow */ -import { combineReducers } from 'redux' -import config from './config' -import items from './items' -import notification from './notification' -import auth from './auth' +import {combineReducers} from 'redux'; +import config from './config'; +import items from './items'; +import notification from './notification'; +import auth from './auth'; /** * Expose the combined main reducer @@ -15,4 +15,4 @@ export default combineReducers({ items, notification, auth -}) +}); diff --git a/client/coral-framework/store/reducers/items.js b/client/coral-framework/store/reducers/items.js index d3eb4d3af..77ee44130 100644 --- a/client/coral-framework/store/reducers/items.js +++ b/client/coral-framework/store/reducers/items.js @@ -1,29 +1,29 @@ /* Items Reducer */ -import { Map, fromJS } from 'immutable' -import * as actions from '../actions/items' +import {fromJS} from 'immutable'; +import * as actions from '../actions/items'; -const initialState = fromJS({}) +const initialState = fromJS({}); export default (state = initialState, action) => { switch (action.type) { - case actions.ADD_ITEM: - return state.set(action.id, fromJS(action.item)) - case actions.UPDATE_ITEM: - return state.updateIn([action.id, action.property], () => + case actions.ADD_ITEM: + return state.set(action.id, fromJS(action.item)); + case actions.UPDATE_ITEM: + return state.updateIn([action.id, action.property], () => fromJS(action.value) - ) - case actions.APPEND_ITEM_ARRAY: - return state.updateIn([action.id, action.property], (prop) => { - if (action.addToFront) { - return prop ? prop.unshift(action.value) : fromJS([action.value]) - } else { - return prop ? prop.push(action.value) : fromJS([action.value]) - } - + ); + case actions.APPEND_ITEM_ARRAY: + return state.updateIn([action.id, action.property], (prop) => { + if (action.addToFront) { + return prop ? prop.unshift(action.value) : fromJS([action.value]); + } else { + return prop ? prop.push(action.value) : fromJS([action.value]); } - ) - default: - return state + + } + ); + default: + return state; } -} +}; diff --git a/client/coral-framework/store/reducers/notification.js b/client/coral-framework/store/reducers/notification.js index 86c65c9e7..ea8b4889d 100644 --- a/client/coral-framework/store/reducers/notification.js +++ b/client/coral-framework/store/reducers/notification.js @@ -1,17 +1,17 @@ /* Items Notifications */ -import * as actions from '../actions/notification' -import { fromJS } from 'immutable' +import * as actions from '../actions/notification'; +import {fromJS} from 'immutable'; -const initialState = fromJS({}) +const initialState = fromJS({}); export default (state = initialState, action) => { switch (action.type) { - case actions.ADD_NOTIFICATION: - return state.set('text', action.text).set('type', action.notifType) - case actions.CLEAR_NOTIFICATION: - return initialState - default: - return state + case actions.ADD_NOTIFICATION: + return state.set('text', action.text).set('type', action.notifType); + case actions.CLEAR_NOTIFICATION: + return initialState; + default: + return state; } -} +}; diff --git a/client/coral-framework/store/store.js b/client/coral-framework/store/store.js index 42678cddd..33cc9efb5 100644 --- a/client/coral-framework/store/store.js +++ b/client/coral-framework/store/store.js @@ -1,10 +1,10 @@ -import { createStore, applyMiddleware } from 'redux' -import thunk from 'redux-thunk' -import mainReducer from './reducers' +import {createStore, applyMiddleware} from 'redux'; +import thunk from 'redux-thunk'; +import mainReducer from './reducers'; export default createStore( mainReducer, window.devToolsExtension && window.devToolsExtension(), applyMiddleware(thunk) -) +); diff --git a/client/coral-plugin-author-name/AuthorName.js b/client/coral-plugin-author-name/AuthorName.js index 04817da1c..ddfd40ccf 100644 --- a/client/coral-plugin-author-name/AuthorName.js +++ b/client/coral-plugin-author-name/AuthorName.js @@ -1,9 +1,9 @@ -import React from 'react' -const packagename = 'coral-plugin-author-name' +import React from 'react'; +const packagename = 'coral-plugin-author-name'; const AuthorName = ({name}) => -
+
{name} -
+
; -export default AuthorName +export default AuthorName; diff --git a/client/coral-plugin-comment-count/CommentCount.js b/client/coral-plugin-comment-count/CommentCount.js index 01a5c602b..b0d7312e2 100644 --- a/client/coral-plugin-comment-count/CommentCount.js +++ b/client/coral-plugin-comment-count/CommentCount.js @@ -1,23 +1,23 @@ -import React from 'react' +import React from 'react'; -const name = 'coral-plugin-comment-count' +const name = 'coral-plugin-comment-count'; const CommentCount = ({items, id}) => { - let count = 0 + let count = 0; if (items[id]) { - count += items[id].comments.length + count += items[id].comments.length; } - const itemKeys = Object.keys(items) - for (var i=0; i < itemKeys.length; i++) { - const item = items[itemKeys[i]] + const itemKeys = Object.keys(items); + for (let i = 0; i < itemKeys.length; i++) { + const item = items[itemKeys[i]]; if (item.children) { - count += item.children.length + count += item.children.length; } } - return
- {count + ' ' + (count === 1 ? 'Comment':'Comments')} -
-} + return
+ {`${count } ${ count === 1 ? 'Comment' : 'Comments'}`} +
; +}; -export default CommentCount +export default CommentCount; diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js index 0f1578859..cf428fac2 100644 --- a/client/coral-plugin-commentbox/CommentBox.js +++ b/client/coral-plugin-commentbox/CommentBox.js @@ -1,7 +1,7 @@ -import React, {Component, PropTypes} from 'react' -import {I18n} from '../coral-framework' +import React, {Component, PropTypes} from 'react'; +import {I18n} from '../coral-framework'; -const name='coral-plugin-commentbox' +const name = 'coral-plugin-commentbox'; class CommentBox extends Component { @@ -19,35 +19,35 @@ class CommentBox extends Component { } postComment = () => { - const {postItem, updateItem, id, parent_id, addNotification, appendItemArray} = this.props + const {postItem, updateItem, id, parent_id, addNotification, appendItemArray} = this.props; let comment = { body: this.state.body, asset_id: id, username: this.state.username - } - let related + }; + let related; if (parent_id) { - comment.parent_id = parent_id - related = 'children' + comment.parent_id = parent_id; + related = 'children'; } else { - related = 'comments' + related = 'comments'; } - updateItem(parent_id, 'showReply', false) + updateItem(parent_id, 'showReply', false); postItem(comment, 'comments') .then((comment_id) => { - appendItemArray(parent_id || id, related, comment_id, parent_id ? false : true) - addNotification('success', 'Your comment has been posted.') - }).catch((err) => console.error(err)) - this.setState({body: ''}) + appendItemArray((parent_id || id, related, comment_id, parent_id)); + addNotification('success', 'Your comment has been posted.'); + }).catch((err) => console.error(err)); + this.setState({body: ''}); } render () { - const {styles, reply} = this.props + const {styles, reply} = this.props; // How to handle language in plugins? Should we have a dependency on our central translation file? return
-
+
this.setState({username: e.target.value})}/>
+ className={`${name }-container`}> - +