Merge branch 'all-flag'

t push origin master
This commit is contained in:
David Erwin
2017-02-14 16:31:01 -05:00
15 changed files with 97 additions and 72 deletions
+18 -3
View File
@@ -1,5 +1,5 @@
import React from 'react';
import {Router, Route, IndexRoute, browserHistory} from 'react-router';
import {Router, Route, IndexRoute, IndexRedirect, browserHistory} from 'react-router';
import Streams from 'containers/Streams/Streams';
import Configure from 'containers/Configure/Configure';
@@ -7,6 +7,8 @@ import LayoutContainer from 'containers/LayoutContainer';
import CommentStream from 'containers/CommentStream/CommentStream';
import InstallContainer from 'containers/Install/InstallContainer';
import CommunityContainer from 'containers/Community/CommunityContainer';
import ModerationLayout from 'containers/ModerationQueue/ModerationLayout';
import ModerationContainer from 'containers/ModerationQueue/ModerationContainer';
const routes = (
@@ -19,8 +21,21 @@ const routes = (
<Route path='configure' component={Configure} />
<Route path='streams' component={Streams} />
<Route path='moderate' component={ModerationContainer} />
<Route path='moderate/:id' component={ModerationContainer} />
{/* Moderation Routes */}
<Route path='moderate' component={ModerationLayout}>
<Route path='premod' components={ModerationContainer}>
<Route path=':id' components={ModerationContainer} />
</Route>
<Route path='rejected' components={ModerationContainer}>
<Route path=':id' components={ModerationContainer} />
</Route>
<Route path='flagged' components={ModerationContainer}>
<Route path=':id' components={ModerationContainer} />
</Route>
<Route path=':id' components={ModerationContainer} />
<IndexRedirect to='premod' />
</Route>
</Route>
</div>
);
@@ -1,6 +1,5 @@
import * as actions from 'constants/moderation';
export const setActiveTab = activeTab => ({type: actions.SET_ACTIVE_TAB, activeTab});
export const toggleModal = open => ({type: actions.TOGGLE_MODAL, open});
export const singleView = () => ({type: actions.SINGLE_VIEW});
@@ -1,4 +1,3 @@
export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB';
export const TOGGLE_MODAL = 'TOGGLE_MODAL';
export const SINGLE_VIEW = 'SINGLE_VIEW';
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
@@ -51,6 +51,12 @@ const updateClosedMessage = (updateSettings) => (event) => {
updateSettings({closedMessage});
};
const updateCustomCssUrl = (updateSettings) => (event) => {
console.log('updateCustomCssUrl', event.target.value);
const customCssUrl = event.target.value;
updateSettings({customCssUrl});
};
// If we are changing the measure we need to recalculate using the old amount
// Same thing if we are just changing the amount
const updateClosedTimeout = (updateSettings, ts, isMeasure) => (event) => {
@@ -165,7 +171,7 @@ const CommentSettings = ({fetchingSettings, title, updateSettings, settingsError
</div>
</div>
</Card>
<Card className={`${styles.configSettingInfoBox}`}>
<Card className={styles.configSettingInfoBox}>
<div className={styles.content}>
{lang.t('configure.close-after')}
<br />
@@ -188,6 +194,18 @@ const CommentSettings = ({fetchingSettings, title, updateSettings, settingsError
</div>
</div>
</Card>
<Card className={styles.configSettingInfoBox}>
<div className={styles.content}>
{lang.t('configure.custom-css-url')}
<p>{lang.t('configure.custom-css-url-desc')}</p>
<br />
<Textfield
style={{width: '100%'}}
label={lang.t('configure.custom-css-url')}
value={settings.customCssUrl}
onChange={updateCustomCssUrl(updateSettings)} />
</div>
</Card>
</div>
);
};
@@ -9,7 +9,7 @@ import {banUser, setCommentStatus} from '../../graphql/mutations';
import {fetchSettings} from 'actions/settings';
import {updateAssets} from 'actions/assets';
import {setActiveTab, toggleModal, singleView, showBanUserDialog, hideBanUserDialog} from 'actions/moderation';
import {toggleModal, singleView, showBanUserDialog, hideBanUserDialog} from 'actions/moderation';
import {Spinner} from 'coral-ui';
import BanUserDialog from '../../components/BanUserDialog';
@@ -19,7 +19,6 @@ import ModerationHeader from './components/ModerationHeader';
import NotFoundAsset from './components/NotFoundAsset';
class ModerationContainer extends Component {
componentWillMount() {
const {toggleModal, singleView} = this.props;
@@ -46,6 +45,8 @@ class ModerationContainer extends Component {
render () {
const {data, moderation, settings, assets, ...props} = this.props;
const providedAssetId = this.props.params.id;
const activeTab = this.props.route.path === ':id' ? 'premod' : this.props.route.path;
let asset;
if (data.loading) {
@@ -65,20 +66,17 @@ class ModerationContainer extends Component {
}
}
const enablePremodTab = !!data.premod.length;
return (
<div>
<ModerationHeader asset={asset} />
<ModerationMenu
onTabClick={props.onTabClick}
enablePremodTab={enablePremodTab}
activeTab={moderation.activeTab}
activeTab={activeTab}
asset={asset}
/>
<ModerationQueue
data={data}
currentAsset={asset}
activeTab={moderation.activeTab}
enablePremodTab={enablePremodTab}
activeTab={activeTab}
suspectWords={settings.wordlist.suspect}
showBanUserDialog={props.showBanUserDialog}
acceptComment={props.acceptComment}
@@ -102,7 +100,6 @@ const mapStateToProps = state => ({
});
const mapDispatchToProps = dispatch => ({
onTabClick: activeTab => dispatch(setActiveTab(activeTab)),
toggleModal: toggle => dispatch(toggleModal(toggle)),
onClose: () => dispatch(toggleModal(false)),
singleView: () => dispatch(singleView()),
@@ -0,0 +1,9 @@
import React from 'react';
const ModerationLayout = props => (
<div>
{props.children}
</div>
);
export default ModerationLayout;
@@ -3,12 +3,12 @@ import React, {PropTypes} from 'react';
import Comment from './components/Comment';
import {actionsMap} from './helpers/moderationQueueActionsMap';
const ModerationQueue = props => {
const ModerationQueue = ({activeTab = 'premod', ...props}) => {
return (
<div id="moderationList">
<ul>
{
props.data[props.activeTab].map((comment, i) => {
props.data[activeTab].map((comment, i) => {
return <Comment
key={i}
index={i}
@@ -63,10 +63,6 @@ const Comment = ({actions = [], ...props}) => {
</p>
</div>
{actionSumaries && <FlagBox actionSumaries={actionSumaries} />}
{/* <span className={styles.context}>*/}
{/* <a>View context</a>*/}
{/* </span>*/}
</li>
);
};
@@ -1,59 +1,43 @@
import React, {PropTypes} from 'react';
import React from 'react';
import styles from './styles.css';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from 'coral-admin/src/translations.json';
import {Link} from 'react-router';
const lang = new I18n(translations);
const ModerationMenu = (props) => (
<div className='mdl-tabs'>
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
<a href='#all'
onClick={(e) => {
e.preventDefault();
props.onTabClick('all');
}}
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'all' ? styles.active : ''}`}
>
{lang.t('modqueue.all')}
</a>
{
props.enablePremodTab
? <a href='#premod'
onClick={(e) => {
e.preventDefault();
props.onTabClick('premod');
}}
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'premod' ? styles.active : ''}`}>
{lang.t('modqueue.premod')}
</a>
: null
props.asset ? (
<div>
<Link to={`/admin/moderate/premod/${props.asset.id}`} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('modqueue.premod')}
</Link>
<Link to={`/admin/moderate/rejected/${props.asset.id}`} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('modqueue.rejected')}
</Link>
<Link to={`/admin/moderate/flagged/${props.asset.id}`} className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('modqueue.flagged')}
</Link>
</div>
) : (
<div>
<Link to='/admin/moderate/premod' className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('modqueue.premod')}
</Link>
<Link to='/admin/moderate/rejected' className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('modqueue.rejected')}
</Link>
<Link to='/admin/moderate/flagged' className={`mdl-tabs__tab ${styles.tab}`} activeClassName={styles.active}>
{lang.t('modqueue.flagged')}
</Link>
</div>
)
}
<a href='#rejected'
onClick={(e) => {
e.preventDefault();
props.onTabClick('rejected');
}}
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'rejected' ? styles.active : ''}`}
>
{lang.t('modqueue.rejected')}
</a>
<a href='#flagged'
onClick={(e) => {
e.preventDefault();
props.onTabClick('flagged');
}}
className={`mdl-tabs__tab ${styles.tab} ${props.activeTab === 'flagged' ? styles.active : ''}`}
>
{lang.t('modqueue.flagged')}
</a>
</div>
</div>
);
ModerationMenu.propTypes = {
activeTab: PropTypes.string.isRequired,
enablePremodTab: PropTypes.bool
};
export default ModerationMenu;
@@ -1,12 +1,6 @@
#import "../fragments/commentView.graphql"
query ModQueue ($asset_id: ID!) {
all: comments(query: {
statuses: [REJECTED, PREMOD],
asset_id: $asset_id
}) {
...commentView
}
premod: comments(query: {
statuses: [PREMOD],
asset_id: $asset_id
@@ -2,7 +2,6 @@ import {Map} from 'immutable';
import * as actions from '../constants/moderation';
const initialState = Map({
activeTab: 'all',
singleView: false,
modalOpen: false,
user: Map({}),
+4
View File
@@ -48,6 +48,8 @@
"copy": "Copy to Clipboard"
},
"configure": {
"custom-css-url": "Custom CSS URL",
"custom-css-url-desc": "URL of a CSS stylesheet that will override default Embed Stream styles. Can be internal or external.",
"enable-pre-moderation": "Enable pre-moderation",
"enable-pre-moderation-text": "Moderators must approve any comment before it is published.",
"require-email-verification": "Require Email Verification",
@@ -157,6 +159,8 @@
"username_flags": ""
},
"configure": {
"custom-css-url": "URL CSS a medida",
"custom-css-url-desc": "URL de una hoja de estilo que va a sobrescribir los estilos por defecto de Embed Stream. Puede ser interna o externa.",
"enable-pre-moderation": "Habilitar pre-moderación",
"enable-pre-moderation-text": "Los moderadores deben aprobar cada comentario antes de que sea publicado.",
"require-email-verification": "Necesita confirmación de correo",
+4
View File
@@ -24,6 +24,10 @@ const SettingSchema = new Schema({
type: Boolean,
default: false
},
customCssUrl: {
type: String,
default: ''
},
infoBoxContent: {
type: String,
default: ''
+5 -1
View File
@@ -1,10 +1,14 @@
const express = require('express');
const router = express.Router();
const SettingsService = require('../../services/settings');
router.use('/:embed', (req, res, next) => {
switch (req.params.embed) {
case 'stream':
return res.render('embed/stream', {});
return SettingsService.retrieve()
.then(({customCssUrl}) => {
return res.render('embed/stream', {customCssUrl});
});
default:
// will return a 404.
+3
View File
@@ -5,6 +5,9 @@
<link rel="stylesheet" type="text/css" href="/client/embed/stream/default.css">
<link href="https://fonts.googleapis.com/css?family=Lato|Open+Sans" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<% if (locals.customCssUrl) { %>
<link href="<%= customCssUrl %>" rel="stylesheet" type="text/css">
<% } %>
</head>
<body>
<div id="coralStream"></div>