mirror of
https://github.com/wassname/talk.git
synced 2026-08-18 12:30:39 +08:00
Merge branch 'master' into provide-valid-optimistic-status
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Router, Route, IndexRedirect, Redirect} from 'react-router';
|
import {Router, Route, IndexRedirect, IndexRoute} from 'react-router';
|
||||||
import {history} from 'coral-framework/helpers/router';
|
import {history} from 'coral-framework/helpers/router';
|
||||||
|
|
||||||
import Configure from 'routes/Configure';
|
import Configure from 'routes/Configure';
|
||||||
@@ -15,7 +15,7 @@ const routes = (
|
|||||||
<div>
|
<div>
|
||||||
<Route exact path="/admin/install" component={Install}/>
|
<Route exact path="/admin/install" component={Install}/>
|
||||||
<Route path='/admin' component={Layout}>
|
<Route path='/admin' component={Layout}>
|
||||||
<IndexRedirect to='/admin/moderate/all' />
|
<IndexRedirect to='/admin/moderate' />
|
||||||
<Route path='configure' component={Configure} />
|
<Route path='configure' component={Configure} />
|
||||||
<Route path='stories' component={Stories} />
|
<Route path='stories' component={Stories} />
|
||||||
<Route path='dashboard' component={Dashboard} />
|
<Route path='dashboard' component={Dashboard} />
|
||||||
@@ -35,10 +35,15 @@ const routes = (
|
|||||||
{/* Moderation Routes */}
|
{/* Moderation Routes */}
|
||||||
|
|
||||||
<Route path='moderate' component={ModerationLayout}>
|
<Route path='moderate' component={ModerationLayout}>
|
||||||
|
<IndexRoute components={Moderation} />
|
||||||
|
|
||||||
<Route path='all' components={Moderation}>
|
<Route path='all' components={Moderation}>
|
||||||
<Route path=':id' components={Moderation} />
|
<Route path=':id' components={Moderation} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='accepted' components={Moderation}>
|
<Route path='new' components={Moderation}>
|
||||||
|
<Route path=':id' components={Moderation} />
|
||||||
|
</Route>
|
||||||
|
<Route path='approved' components={Moderation}>
|
||||||
<Route path=':id' components={Moderation} />
|
<Route path=':id' components={Moderation} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='premod' components={Moderation}>
|
<Route path='premod' components={Moderation}>
|
||||||
@@ -47,11 +52,12 @@ const routes = (
|
|||||||
<Route path='rejected' components={Moderation}>
|
<Route path='rejected' components={Moderation}>
|
||||||
<Route path=':id' components={Moderation} />
|
<Route path=':id' components={Moderation} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='flagged' components={Moderation}>
|
<Route path='reported' components={Moderation}>
|
||||||
<Route path=':id' components={Moderation} />
|
<Route path=':id' components={Moderation} />
|
||||||
</Route>
|
</Route>
|
||||||
<Redirect from=':id' to='all/:id' />
|
|
||||||
<IndexRedirect to='all' />
|
<Route path=':id' components={Moderation} />
|
||||||
|
|
||||||
</Route>
|
</Route>
|
||||||
</Route>
|
</Route>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class UserDetailComment extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.story}>
|
<div className={styles.story}>
|
||||||
Story: {comment.asset.title}
|
Story: {comment.asset.title}
|
||||||
{<Link to={`/admin/moderate/all/${comment.asset.id}`}>{t('modqueue.moderate')}</Link>}
|
{<Link to={`/admin/moderate/${comment.asset.id}`}>{t('modqueue.moderate')}</Link>}
|
||||||
</div>
|
</div>
|
||||||
<CommentAnimatedEdit body={comment.body}>
|
<CommentAnimatedEdit body={comment.body}>
|
||||||
<div className={styles.bodyContainer}>
|
<div className={styles.bodyContainer}>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import update from 'immutability-helper';
|
import update from 'immutability-helper';
|
||||||
import * as notification from 'coral-admin/src/services/notification';
|
import * as notification from 'coral-admin/src/services/notification';
|
||||||
|
|
||||||
const queues = ['all', 'premod', 'flagged', 'accepted', 'rejected'];
|
const queues = ['all', 'premod', 'reported', 'approved', 'rejected', 'new'];
|
||||||
const limit = 10;
|
const limit = 10;
|
||||||
|
|
||||||
const ascending = (a, b) => {
|
const ascending = (a, b) => {
|
||||||
@@ -64,23 +64,35 @@ function addCommentToQueue(root, queue, comment, sort) {
|
|||||||
return update(root, changes);
|
return update(root, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getCommentQueues determines in which queues a comment should be placed.
|
||||||
|
*/
|
||||||
function getCommentQueues(comment) {
|
function getCommentQueues(comment) {
|
||||||
const queues = ['all'];
|
const queues = ['all'];
|
||||||
if (comment.status === 'ACCEPTED') {
|
const isFlagged = comment.actions && comment.actions.some((a) => a.__typename === 'FlagAction');
|
||||||
queues.push('accepted');
|
|
||||||
}
|
switch(comment.status) {
|
||||||
else if (comment.status === 'REJECTED') {
|
case 'ACCEPTED':
|
||||||
|
queues.push('approved');
|
||||||
|
break;
|
||||||
|
case 'REJECTED':
|
||||||
queues.push('rejected');
|
queues.push('rejected');
|
||||||
}
|
break;
|
||||||
else if (comment.status === 'PREMOD') {
|
case 'PREMOD':
|
||||||
queues.push('premod');
|
queues.push('premod');
|
||||||
|
queues.push('new');
|
||||||
|
if (isFlagged) {
|
||||||
|
queues.push('reported');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'NONE':
|
||||||
|
queues.push('new');
|
||||||
|
if (isFlagged) {
|
||||||
|
queues.push('reported');
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
['NONE', 'PREMOD'].indexOf(comment.status) >= 0
|
|
||||||
&& comment.actions && comment.actions.some((a) => a.__typename === 'FlagAction')
|
|
||||||
) {
|
|
||||||
queues.push('flagged');
|
|
||||||
}
|
|
||||||
return queues;
|
return queues;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +110,7 @@ function getCommentQueues(comment) {
|
|||||||
*/
|
*/
|
||||||
export function handleCommentChange(root, comment, sort, notify) {
|
export function handleCommentChange(root, comment, sort, notify) {
|
||||||
let next = root;
|
let next = root;
|
||||||
|
|
||||||
const nextQueues = getCommentQueues(comment);
|
const nextQueues = getCommentQueues(comment);
|
||||||
|
|
||||||
let notificationShown = false;
|
let notificationShown = false;
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class Comment extends React.Component {
|
|||||||
<div className={styles.moderateArticle}>
|
<div className={styles.moderateArticle}>
|
||||||
Story: {comment.asset.title}
|
Story: {comment.asset.title}
|
||||||
{!props.currentAsset &&
|
{!props.currentAsset &&
|
||||||
<Link to={`/admin/moderate/all/${comment.asset.id}`}>{t('modqueue.moderate')}</Link>}
|
<Link to={`/admin/moderate/${comment.asset.id}`}>{t('modqueue.moderate')}</Link>}
|
||||||
</div>
|
</div>
|
||||||
<CommentAnimatedEdit body={comment.body}>
|
<CommentAnimatedEdit body={comment.body}>
|
||||||
<div className={styles.itemBody}>
|
<div className={styles.itemBody}>
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ export default class Moderation extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getComments = () => {
|
getComments = () => {
|
||||||
const {root, route} = this.props;
|
const {root, activeTab} = this.props;
|
||||||
const activeTab = route.path === ':id' ? 'premod' : route.path;
|
|
||||||
return root[activeTab].nodes;
|
return root[activeTab].nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,25 +100,28 @@ export default class Moderation extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
const {root, moderation, settings, viewUserDetail, hideUserDetail, activeTab, getModPath, premodEnabled, ...props} = this.props;
|
||||||
const {root, moderation, settings, viewUserDetail, hideUserDetail, activeTab, ...props} = this.props;
|
|
||||||
const assetId = this.props.params.id;
|
const assetId = this.props.params.id;
|
||||||
const {asset} = root;
|
const {asset} = root;
|
||||||
|
|
||||||
const comments = root[activeTab];
|
const comments = root[activeTab];
|
||||||
|
|
||||||
let activeTabCount;
|
let activeTabCount;
|
||||||
switch(activeTab) {
|
switch(activeTab) {
|
||||||
case 'all':
|
case 'all':
|
||||||
activeTabCount = root.allCount;
|
activeTabCount = root.allCount;
|
||||||
break;
|
break;
|
||||||
case 'accepted':
|
case 'new':
|
||||||
activeTabCount = root.acceptedCount;
|
activeTabCount = root.newCount;
|
||||||
|
break;
|
||||||
|
case 'approved':
|
||||||
|
activeTabCount = root.approvedCount;
|
||||||
break;
|
break;
|
||||||
case 'premod':
|
case 'premod':
|
||||||
activeTabCount = root.premodCount;
|
activeTabCount = root.premodCount;
|
||||||
break;
|
break;
|
||||||
case 'flagged':
|
case 'reported':
|
||||||
activeTabCount = root.flaggedCount;
|
activeTabCount = root.reportedCount;
|
||||||
break;
|
break;
|
||||||
case 'rejected':
|
case 'rejected':
|
||||||
activeTabCount = root.rejectedCount;
|
activeTabCount = root.rejectedCount;
|
||||||
@@ -137,12 +139,16 @@ export default class Moderation extends Component {
|
|||||||
<ModerationMenu
|
<ModerationMenu
|
||||||
asset={asset}
|
asset={asset}
|
||||||
allCount={root.allCount}
|
allCount={root.allCount}
|
||||||
acceptedCount={root.acceptedCount}
|
newCount={root.newCount}
|
||||||
|
getModPath={getModPath}
|
||||||
|
approvedCount={root.approvedCount}
|
||||||
premodCount={root.premodCount}
|
premodCount={root.premodCount}
|
||||||
rejectedCount={root.rejectedCount}
|
rejectedCount={root.rejectedCount}
|
||||||
flaggedCount={root.flaggedCount}
|
reportedCount={root.reportedCount}
|
||||||
selectSort={this.props.setSortOrder}
|
selectSort={this.props.setSortOrder}
|
||||||
sort={this.props.moderation.sortOrder}
|
sort={this.props.moderation.sortOrder}
|
||||||
|
premodEnabled={premodEnabled}
|
||||||
|
activeTab={activeTab}
|
||||||
/>
|
/>
|
||||||
<ModerationQueue
|
<ModerationQueue
|
||||||
data={this.props.data}
|
data={this.props.data}
|
||||||
|
|||||||
@@ -4,52 +4,72 @@ import styles from './styles.css';
|
|||||||
import {SelectField, Option} from 'react-mdl-selectfield';
|
import {SelectField, Option} from 'react-mdl-selectfield';
|
||||||
import {Icon} from 'coral-ui';
|
import {Icon} from 'coral-ui';
|
||||||
import {Link} from 'react-router';
|
import {Link} from 'react-router';
|
||||||
|
import cn from 'classnames';
|
||||||
|
|
||||||
import t from 'coral-framework/services/i18n';
|
import t from 'coral-framework/services/i18n';
|
||||||
|
|
||||||
const ModerationMenu = (
|
const ModerationMenu = ({
|
||||||
{asset, allCount, acceptedCount, premodCount, rejectedCount, flaggedCount, selectSort, sort}
|
asset = {},
|
||||||
) => {
|
allCount,
|
||||||
|
approvedCount,
|
||||||
function getPath (type) {
|
premodCount,
|
||||||
return asset ? `/admin/moderate/${type}/${asset.id}` : `/admin/moderate/${type}`;
|
newCount,
|
||||||
}
|
rejectedCount,
|
||||||
|
reportedCount,
|
||||||
|
selectSort,
|
||||||
|
sort,
|
||||||
|
premodEnabled,
|
||||||
|
getModPath,
|
||||||
|
activeTab
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="mdl-tabs">
|
<div className="mdl-tabs">
|
||||||
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
|
<div className={`mdl-tabs__tab-bar ${styles.tabBar}`}>
|
||||||
<div className={styles.tabBarPadding} />
|
<div className={styles.tabBarPadding} />
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
{
|
||||||
|
premodEnabled ? (
|
||||||
|
<Link
|
||||||
|
to={getModPath('premod', asset.id)}
|
||||||
|
className={cn('mdl-tabs__tab', styles.tab, {[styles.active]: activeTab === 'premod'})}
|
||||||
|
activeClassName={styles.active}>
|
||||||
|
<Icon name='access_time' className={styles.tabIcon} /> {t('modqueue.premod')} <CommentCount count={premodCount} />
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<Link
|
||||||
|
to={getModPath('new', asset.id)}
|
||||||
|
className={cn('mdl-tabs__tab', styles.tab, {[styles.active]: activeTab === 'new'})}
|
||||||
|
activeClassName={styles.active}>
|
||||||
|
<Icon name='question_answer' className={styles.tabIcon} /> {t('modqueue.new')} <CommentCount count={newCount} />
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
to={getPath('all')}
|
to={getModPath('reported', asset.id)}
|
||||||
className={`mdl-tabs__tab ${styles.tab}`}
|
className={cn('mdl-tabs__tab', styles.tab, {[styles.active]: activeTab === 'reported'})}
|
||||||
activeClassName={styles.active}>
|
activeClassName={styles.active}>
|
||||||
<Icon name='question_answer' className={styles.tabIcon} /> {t('modqueue.all')} <CommentCount count={allCount} />
|
<Icon name='flag' className={styles.tabIcon} /> {t('modqueue.reported')} <CommentCount count={reportedCount} />
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to={getPath('premod')}
|
to={getModPath('approved', asset.id)}
|
||||||
className={`mdl-tabs__tab ${styles.tab}`}
|
className={cn('mdl-tabs__tab', styles.tab, {[styles.active]: activeTab === 'approved'})}
|
||||||
activeClassName={styles.active}>
|
activeClassName={styles.active}>
|
||||||
<Icon name='access_time' className={styles.tabIcon} /> {t('modqueue.premod')} <CommentCount count={premodCount} />
|
<Icon name='check' className={styles.tabIcon} /> {t('modqueue.approved')} <CommentCount count={approvedCount} />
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to={getPath('flagged')}
|
to={getModPath('rejected', asset.id)}
|
||||||
className={`mdl-tabs__tab ${styles.tab}`}
|
className={cn('mdl-tabs__tab', styles.tab, {[styles.active]: activeTab === 'rejected'})}
|
||||||
activeClassName={styles.active}>
|
|
||||||
<Icon name='flag' className={styles.tabIcon} /> {t('modqueue.flagged')} <CommentCount count={flaggedCount} />
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
to={getPath('accepted')}
|
|
||||||
className={`mdl-tabs__tab ${styles.tab}`}
|
|
||||||
activeClassName={styles.active}>
|
|
||||||
<Icon name='check' className={styles.tabIcon} /> {t('modqueue.approved')} <CommentCount count={acceptedCount} />
|
|
||||||
</Link>
|
|
||||||
<Link
|
|
||||||
to={getPath('rejected')}
|
|
||||||
className={`mdl-tabs__tab ${styles.tab}`}
|
|
||||||
activeClassName={styles.active}>
|
activeClassName={styles.active}>
|
||||||
<Icon name='close' className={styles.tabIcon} /> {t('modqueue.rejected')} <CommentCount count={rejectedCount} />
|
<Icon name='close' className={styles.tabIcon} /> {t('modqueue.rejected')} <CommentCount count={rejectedCount} />
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link
|
||||||
|
to={getModPath('all', asset.id)}
|
||||||
|
className={cn('mdl-tabs__tab', styles.tab, {[styles.active]: activeTab === 'all'})}
|
||||||
|
activeClassName={styles.active}>
|
||||||
|
<Icon name='question_answer' className={styles.tabIcon} /> {t('modqueue.all')} <CommentCount count={allCount} />
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<SelectField
|
<SelectField
|
||||||
className={styles.selectField}
|
className={styles.selectField}
|
||||||
@@ -68,7 +88,7 @@ ModerationMenu.propTypes = {
|
|||||||
allCount: PropTypes.number.isRequired,
|
allCount: PropTypes.number.isRequired,
|
||||||
premodCount: PropTypes.number.isRequired,
|
premodCount: PropTypes.number.isRequired,
|
||||||
rejectedCount: PropTypes.number.isRequired,
|
rejectedCount: PropTypes.number.isRequired,
|
||||||
flaggedCount: PropTypes.number.isRequired,
|
reportedCount: PropTypes.number.isRequired,
|
||||||
asset: PropTypes.shape({
|
asset: PropTypes.shape({
|
||||||
id: PropTypes.string
|
id: PropTypes.string
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ const StorySearch = (props) => {
|
|||||||
? <Spinner />
|
? <Spinner />
|
||||||
: assets.map((story, i) => {
|
: assets.map((story, i) => {
|
||||||
const storyOpen = story.closedAt === null || new Date(story.closedAt) > new Date();
|
const storyOpen = story.closedAt === null || new Date(story.closedAt) > new Date();
|
||||||
|
|
||||||
return <Story
|
return <Story
|
||||||
key={i}
|
key={i}
|
||||||
id={story.id}
|
id={story.id}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import t from 'coral-framework/services/i18n';
|
|||||||
import update from 'immutability-helper';
|
import update from 'immutability-helper';
|
||||||
import truncate from 'lodash/truncate';
|
import truncate from 'lodash/truncate';
|
||||||
import NotFoundAsset from '../components/NotFoundAsset';
|
import NotFoundAsset from '../components/NotFoundAsset';
|
||||||
|
import {isPremod, getModPath} from '../../../utils';
|
||||||
|
|
||||||
import {withSetCommentStatus} from 'coral-framework/graphql/mutations';
|
import {withSetCommentStatus} from 'coral-framework/graphql/mutations';
|
||||||
import {handleCommentChange} from '../../../graphql/utils';
|
import {handleCommentChange} from '../../../graphql/utils';
|
||||||
@@ -37,7 +38,18 @@ function prepareNotificationText(text) {
|
|||||||
class ModerationContainer extends Component {
|
class ModerationContainer extends Component {
|
||||||
subscriptions = [];
|
subscriptions = [];
|
||||||
|
|
||||||
get activeTab() { return this.props.route.path; }
|
get activeTab() {
|
||||||
|
|
||||||
|
const {root: {asset, settings}, router, route} = this.props;
|
||||||
|
|
||||||
|
// Grab premod from asset or from settings
|
||||||
|
const premod = !router.params.id ? settings.moderation : asset.settings.moderation;
|
||||||
|
|
||||||
|
const queue = isPremod(premod) ? 'premod' : 'new';
|
||||||
|
const activeTab = route.path && route.path !== ':id' ? route.path : queue;
|
||||||
|
|
||||||
|
return activeTab;
|
||||||
|
}
|
||||||
|
|
||||||
subscribeToUpdates(variables = this.props.data.variables) {
|
subscribeToUpdates(variables = this.props.data.variables) {
|
||||||
const sub1 = this.props.data.subscribeToMore({
|
const sub1 = this.props.data.subscribeToMore({
|
||||||
@@ -153,13 +165,16 @@ class ModerationContainer extends Component {
|
|||||||
case 'all':
|
case 'all':
|
||||||
variables.statuses = null;
|
variables.statuses = null;
|
||||||
break;
|
break;
|
||||||
case 'accepted':
|
case 'new':
|
||||||
|
variables.statuses = ['NONE', 'PREMOD'];
|
||||||
|
break;
|
||||||
|
case 'approved':
|
||||||
variables.statuses = ['ACCEPTED'];
|
variables.statuses = ['ACCEPTED'];
|
||||||
break;
|
break;
|
||||||
case 'premod':
|
case 'premod':
|
||||||
variables.statuses = ['PREMOD'];
|
variables.statuses = ['PREMOD'];
|
||||||
break;
|
break;
|
||||||
case 'flagged':
|
case 'reported':
|
||||||
variables.statuses = ['NONE', 'PREMOD'];
|
variables.statuses = ['NONE', 'PREMOD'];
|
||||||
variables.action_type = 'FLAG';
|
variables.action_type = 'FLAG';
|
||||||
break;
|
break;
|
||||||
@@ -184,7 +199,7 @@ class ModerationContainer extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {root, root: {asset}, data, params: {id: assetId}} = this.props;
|
const {root, root: {asset, settings}, data, params: {id: assetId}} = this.props;
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
return <div>Error</div>;
|
return <div>Error</div>;
|
||||||
@@ -209,10 +224,12 @@ class ModerationContainer extends Component {
|
|||||||
|
|
||||||
return <Moderation
|
return <Moderation
|
||||||
{...this.props}
|
{...this.props}
|
||||||
|
getModPath={getModPath}
|
||||||
loadMore={this.loadMore}
|
loadMore={this.loadMore}
|
||||||
acceptComment={this.acceptComment}
|
acceptComment={this.acceptComment}
|
||||||
rejectComment={this.rejectComment}
|
rejectComment={this.rejectComment}
|
||||||
activeTab={this.activeTab}
|
activeTab={this.activeTab}
|
||||||
|
premodEnabled={assetId ? isPremod(asset.settings.moderation) : isPremod(settings.moderation)}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,7 +321,14 @@ const withModQueueQuery = withQuery(gql`
|
|||||||
}) {
|
}) {
|
||||||
...CoralAdmin_Moderation_CommentConnection
|
...CoralAdmin_Moderation_CommentConnection
|
||||||
}
|
}
|
||||||
accepted: comments(query: {
|
new: comments(query: {
|
||||||
|
statuses: [NONE, PREMOD],
|
||||||
|
asset_id: $asset_id,
|
||||||
|
sort: $sort
|
||||||
|
}) {
|
||||||
|
...CoralAdmin_Moderation_CommentConnection
|
||||||
|
}
|
||||||
|
approved: comments(query: {
|
||||||
statuses: [ACCEPTED],
|
statuses: [ACCEPTED],
|
||||||
asset_id: $asset_id,
|
asset_id: $asset_id,
|
||||||
sort: $sort
|
sort: $sort
|
||||||
@@ -318,7 +342,7 @@ const withModQueueQuery = withQuery(gql`
|
|||||||
}) {
|
}) {
|
||||||
...CoralAdmin_Moderation_CommentConnection
|
...CoralAdmin_Moderation_CommentConnection
|
||||||
}
|
}
|
||||||
flagged: comments(query: {
|
reported: comments(query: {
|
||||||
action_type: FLAG,
|
action_type: FLAG,
|
||||||
asset_id: $asset_id,
|
asset_id: $asset_id,
|
||||||
statuses: [NONE, PREMOD],
|
statuses: [NONE, PREMOD],
|
||||||
@@ -337,11 +361,18 @@ const withModQueueQuery = withQuery(gql`
|
|||||||
id
|
id
|
||||||
title
|
title
|
||||||
url
|
url
|
||||||
|
settings {
|
||||||
|
moderation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
allCount: commentCount(query: {
|
allCount: commentCount(query: {
|
||||||
asset_id: $asset_id
|
asset_id: $asset_id
|
||||||
})
|
})
|
||||||
acceptedCount: commentCount(query: {
|
newCount: commentCount(query: {
|
||||||
|
statuses: [NONE, PREMOD],
|
||||||
|
asset_id: $asset_id
|
||||||
|
})
|
||||||
|
approvedCount: commentCount(query: {
|
||||||
statuses: [ACCEPTED],
|
statuses: [ACCEPTED],
|
||||||
asset_id: $asset_id
|
asset_id: $asset_id
|
||||||
})
|
})
|
||||||
@@ -353,13 +384,14 @@ const withModQueueQuery = withQuery(gql`
|
|||||||
statuses: [REJECTED],
|
statuses: [REJECTED],
|
||||||
asset_id: $asset_id
|
asset_id: $asset_id
|
||||||
})
|
})
|
||||||
flaggedCount: commentCount(query: {
|
reportedCount: commentCount(query: {
|
||||||
action_type: FLAG,
|
action_type: FLAG,
|
||||||
asset_id: $asset_id,
|
asset_id: $asset_id,
|
||||||
statuses: [NONE, PREMOD]
|
statuses: [NONE, PREMOD]
|
||||||
})
|
})
|
||||||
settings {
|
settings {
|
||||||
organizationName
|
organizationName
|
||||||
|
moderation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
${commentConnectionFragment}
|
${commentConnectionFragment}
|
||||||
@@ -380,7 +412,11 @@ const withQueueCountPolling = withQuery(gql`
|
|||||||
allCount: commentCount(query: {
|
allCount: commentCount(query: {
|
||||||
asset_id: $asset_id
|
asset_id: $asset_id
|
||||||
})
|
})
|
||||||
acceptedCount: commentCount(query: {
|
newCount: commentCount(query: {
|
||||||
|
statuses: [NONE, PREMOD],
|
||||||
|
asset_id: $asset_id
|
||||||
|
})
|
||||||
|
approvedCount: commentCount(query: {
|
||||||
statuses: [ACCEPTED],
|
statuses: [ACCEPTED],
|
||||||
asset_id: $asset_id
|
asset_id: $asset_id
|
||||||
})
|
})
|
||||||
@@ -392,7 +428,7 @@ const withQueueCountPolling = withQuery(gql`
|
|||||||
statuses: [REJECTED],
|
statuses: [REJECTED],
|
||||||
asset_id: $asset_id
|
asset_id: $asset_id
|
||||||
})
|
})
|
||||||
flaggedCount: commentCount(query: {
|
reportedCount: commentCount(query: {
|
||||||
action_type: FLAG,
|
action_type: FLAG,
|
||||||
asset_id: $asset_id,
|
asset_id: $asset_id,
|
||||||
statuses: [NONE, PREMOD]
|
statuses: [NONE, PREMOD]
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ class StorySearchContainer extends React.Component {
|
|||||||
|
|
||||||
goToStory = (id) => {
|
goToStory = (id) => {
|
||||||
const {router} = this.props;
|
const {router} = this.props;
|
||||||
router.push(`/admin/moderate/all/${id}`);
|
router.push(`/admin/moderate/${id}`);
|
||||||
this.clearAndCloseSearch();
|
this.clearAndCloseSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
goToModerateAll = () => {
|
goToModerateAll = () => {
|
||||||
const {router} = this.props;
|
const {router} = this.props;
|
||||||
router.push('/admin/moderate/all');
|
router.push('/admin/moderate');
|
||||||
this.clearAndCloseSearch();
|
this.clearAndCloseSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export const isPremod = (mod) => mod === 'PRE';
|
||||||
|
|
||||||
|
export const getModPath = (type = 'all', assetId) =>
|
||||||
|
assetId ? `/admin/moderate/${type}/${assetId}` : `/admin/moderate/${type}`;
|
||||||
@@ -42,14 +42,14 @@ export default class Popup extends Component {
|
|||||||
this.onUnload();
|
this.onUnload();
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
const interval = setInterval(() => {
|
||||||
if (this.ref.onload === null) {
|
if (this.ref && this.ref.onload === null) {
|
||||||
this.setCallbacks();
|
this.setCallbacks();
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
||||||
this.detectCloseInterval = setInterval(() => {
|
this.detectCloseInterval = setInterval(() => {
|
||||||
if (this.ref.closed) {
|
if (!this.ref || this.ref.closed) {
|
||||||
clearInterval(this.detectCloseInterval);
|
clearInterval(this.detectCloseInterval);
|
||||||
this.onClose();
|
this.onClose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import t from 'coral-framework/services/i18n';
|
|||||||
|
|
||||||
const ModerationLink = (props) => props.isAdmin ? (
|
const ModerationLink = (props) => props.isAdmin ? (
|
||||||
<div className={styles.moderationLink}>
|
<div className={styles.moderationLink}>
|
||||||
<a href={`/admin/moderate/all/${props.assetId}`} target="_blank">
|
<a href={`/admin/moderate/${props.assetId}`} target="_blank">
|
||||||
{t('moderate_this_stream')}
|
{t('moderate_this_stream')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ en:
|
|||||||
dont_like_username: "Don't like username"
|
dont_like_username: "Don't like username"
|
||||||
empty_queue: "No more comments to moderate! You're all caught up. Go have some ☕️"
|
empty_queue: "No more comments to moderate! You're all caught up. Go have some ☕️"
|
||||||
flagged: flagged
|
flagged: flagged
|
||||||
|
reported: reported
|
||||||
impersonating: Impersonating
|
impersonating: Impersonating
|
||||||
less_detail: "Less detail"
|
less_detail: "Less detail"
|
||||||
likes: likes
|
likes: likes
|
||||||
@@ -269,6 +270,7 @@ en:
|
|||||||
mod_faster: "Moderate faster with keyboard shortcuts"
|
mod_faster: "Moderate faster with keyboard shortcuts"
|
||||||
moderate: "Moderate →"
|
moderate: "Moderate →"
|
||||||
more_detail: "More detail"
|
more_detail: "More detail"
|
||||||
|
new: New
|
||||||
newest_first: "Newest First"
|
newest_first: "Newest First"
|
||||||
navigation: Navigation
|
navigation: Navigation
|
||||||
next_comment: "Go to the next comment"
|
next_comment: "Go to the next comment"
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ es:
|
|||||||
mod_faster: "Moderar más rápido con atajos de teclado"
|
mod_faster: "Moderar más rápido con atajos de teclado"
|
||||||
moderate: "Moderar →"
|
moderate: "Moderar →"
|
||||||
more_detail: "Más detalles"
|
more_detail: "Más detalles"
|
||||||
|
new: Nuevo
|
||||||
newest_first: "Primero el más nuevo"
|
newest_first: "Primero el más nuevo"
|
||||||
navigation: Navegación
|
navigation: Navegación
|
||||||
next_comment: "Ir al siguiente comentario"
|
next_comment: "Ir al siguiente comentario"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ export default class Tag extends React.Component {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showTooltip = e => {
|
showTooltip = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.setState({
|
this.setState({
|
||||||
tooltip: true
|
tooltip: true
|
||||||
|
|||||||
Reference in New Issue
Block a user