Only shw user flags in detail

This commit is contained in:
Chi Vinh Le
2017-09-28 22:02:06 +07:00
parent 219399a231
commit 5d718f6dd4
8 changed files with 148 additions and 126 deletions
@@ -0,0 +1,18 @@
.root {
margin-top: 10px;
padding-top: 10px;
}
.moreDetail {
position: absolute;
font-size: 12px;
font-weight: 500;
color: black;
right: 16px;
&:hover {
opacity: 0.9;
cursor: pointer;
}
}
@@ -0,0 +1,50 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import styles from './CommentDetails.css';
import t from 'coral-framework/services/i18n';
import FlagDetails from './FlagDetails';
class CommentDetails extends Component {
state = {
showDetail: false
};
constructor () {
super();
this.state = {
showDetail: false
};
}
toggleDetail = () => {
this.setState((state) => ({
showDetail: !state.showDetail
}));
}
render() {
const {actions, viewUserDetail} = this.props;
const {showDetail} = this.state;
return (
<div className={styles.root}>
<a onClick={this.toggleDetail} className={styles.moreDetail}>{showDetail ? t('modqueue.less_detail') : t('modqueue.more_detail')}</a>
<FlagDetails
actions={actions}
viewUserDetail={viewUserDetail}
more={showDetail}
/>
</div>
);
}
}
CommentDetails.propTypes = {
actions: PropTypes.arrayOf(PropTypes.shape({
message: PropTypes.string,
user: PropTypes.shape({username: PropTypes.string})
})).isRequired,
viewUserDetail: PropTypes.func.isRequired,
};
export default CommentDetails;
@@ -1,94 +0,0 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import styles from './FlagBox.css';
import t from 'coral-framework/services/i18n';
import CommentDetail from './CommentDetail';
const shortReasons = {
'This comment is offensive': t('modqueue.offensive'),
'This looks like an ad/marketing': t('modqueue.spam_ads'),
'This user is impersonating': t('modqueue.impersonating'),
'I don\'t like this username': t('modqueue.dont_like_username'),
'Other': t('modqueue.other')
};
class FlagBox extends Component {
constructor () {
super();
this.state = {
showDetail: false
};
}
toggleDetail = () => {
this.setState((state) => ({
showDetail: !state.showDetail
}));
}
reasonMap = (reason) => {
const shortReason = shortReasons[reason];
// if the short reason isn't found, just return the long one.
return shortReason ? shortReason : reason;
}
render() {
const {actionSummaries, actions, viewUserDetail} = this.props;
const {showDetail} = this.state;
return (
<div className={styles.flagBox}>
<a onClick={this.toggleDetail} className={styles.moreDetail}>{showDetail ? t('modqueue.less_detail') : t('modqueue.more_detail')}</a>
<CommentDetail
icon={'flag'}
header={`${t('community.flags')} (${actionSummaries.length})`}
info={
<ul className={styles.info}>
{actionSummaries.map((action, i) =>
<li key={i} className={styles.lessDetail}> {this.reasonMap(action.reason)} (<strong>{action.count}</strong>)</li>
)}
</ul>
}>
{showDetail && (
<ul className={styles.detail}>
{actionSummaries.map((summary, i) => {
const actionList = actions.filter((a) => a.reason === summary.reason);
return (
<li key={i}>
{this.reasonMap(summary.reason)} (<strong>{summary.count}</strong>)
<ul>
{actionList.map((action, j) =>
<li key={`${i}_${j}`} className={styles.subDetail}>
{action.user &&
<a className={styles.username} onClick={() => viewUserDetail(action.user.id)}>
{action.user.username}
</a>
}
{action.message}
</li>
)}
</ul>
</li>
);
})}
</ul>
)}
</CommentDetail>
</div>
);
}
}
FlagBox.propTypes = {
actionSummaries: PropTypes.arrayOf(PropTypes.shape({
reason: PropTypes.string,
count: PropTypes.number
})).isRequired,
actions: PropTypes.arrayOf(PropTypes.shape({
message: PropTypes.string,
user: PropTypes.shape({username: PropTypes.string})
})).isRequired
};
export default FlagBox;
@@ -1,8 +1,3 @@
.flagBox {
border-top: 1px solid rgba(66, 66, 66, 0.12);
margin-top: 10px;
padding-top: 10px;
}
.info {
vertical-align: middle;
@@ -20,6 +15,7 @@
}
.subDetail {
margin-left:10px;
padding: 0;
list-style: none;
font-size: 12px;
@@ -27,19 +23,6 @@
color: #888;
}
.moreDetail {
position: absolute;
font-size: 12px;
font-weight: 500;
color: black;
right: 16px;
&:hover {
opacity: 0.9;
cursor: pointer;
}
}
.lessDetail {
display: inline-block;
margin-right: 10px;
@@ -0,0 +1,75 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';
import styles from './FlagDetails.css';
import t from 'coral-framework/services/i18n';
import CommentDetail from './CommentDetail';
class FlagDetails extends Component {
render() {
const {actions, viewUserDetail, more} = this.props;
const summaries = actions.reduce((sum, action) => {
if (!(action.reason in sum)) {
sum[action.reason] = {count: 0, userFlagged: false, actions: []};
}
sum[action.reason].count++;
if (action.user) {
sum[action.reason].userFlagged = true;
}
sum[action.reason].actions.push(action);
return sum;
}, {});
const userFlagReasons = Object.keys(summaries).filter((reason) => summaries[reason].userFlagged);
return (
<CommentDetail
icon={'flag'}
header={`${t('community.flags')} (${Object.keys(summaries).length})`}
info={
<ul className={styles.info}>
{Object.keys(summaries).map((reason) =>
<li key={reason} className={styles.lessDetail}>
{reason} {summaries[reason].userFlagged && `(${summaries[reason].count})`}
</li>
)}
</ul>
}>
{more && userFlagReasons.length > 0 && (
<ul className={styles.detail}>
{userFlagReasons
.map((reason) => (
<li key={reason}>
{reason} ({summaries[reason].count})
<ul className={styles.subDetail}>
{summaries[reason].actions.map((action) =>
<li key={action.user.id}>
{action.user &&
<a className={styles.username} onClick={() => viewUserDetail(action.user.id)}>
{action.user.username}
</a>
}
{action.message}
</li>
)}
</ul>
</li>
))
}
</ul>
)}
</CommentDetail>
);
}
}
FlagDetails.propTypes = {
more: PropTypes.bool,
actions: PropTypes.arrayOf(PropTypes.shape({
message: PropTypes.string,
user: PropTypes.shape({username: PropTypes.string})
})).isRequired,
viewUserDetail: PropTypes.func.isRequired,
};
export default FlagDetails;
@@ -3,9 +3,8 @@ import PropTypes from 'prop-types';
import {Link} from 'react-router';
import {Icon} from 'coral-ui';
import FlagBox from './FlagBox';
import CommentDetails from './CommentDetails';
import styles from './UserDetailComment.css';
import {getActionSummary} from 'coral-framework/utils';
import ActionButton from 'coral-admin/src/components/ActionButton';
import CommentBodyHighlighter from 'coral-admin/src/components/CommentBodyHighlighter';
import IfHasLink from 'coral-admin/src/components/IfHasLink';
@@ -31,7 +30,6 @@ class UserDetailComment extends React.Component {
...props
} = this.props;
const flagActionSummaries = getActionSummary('FlagActionSummary', comment);
const flagActions = comment.actions && comment.actions.filter((a) => a.__typename === 'FlagAction');
return (
@@ -117,9 +115,8 @@ class UserDetailComment extends React.Component {
</CommentAnimatedEdit>
</div>
{flagActions && flagActions.length
? <FlagBox
? <CommentDetails
actions={flagActions}
actionSummaries={flagActionSummaries}
viewUserDetail={viewUserDetail}
/>
: null}
@@ -139,7 +136,6 @@ UserDetailComment.propTypes = {
toggleSelect: PropTypes.func,
comment: PropTypes.shape({
body: PropTypes.string.isRequired,
action_summaries: PropTypes.array,
actions: PropTypes.array,
created_at: PropTypes.string.isRequired,
asset: PropTypes.shape({
@@ -17,12 +17,6 @@ export default withFragments({
title
url
}
action_summaries {
count
... on FlagActionSummary {
reason
}
}
actions {
... on FlagAction {
id
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import {Link} from 'react-router';
import {Icon} from 'coral-ui';
import FlagBox from 'coral-admin/src/components/FlagBox';
import CommentDetails from 'coral-admin/src/components/CommentDetails';
import styles from './Comment.css';
import CommentLabels from 'coral-admin/src/components/CommentLabels';
import CommentAnimatedEdit from 'coral-admin/src/components/CommentAnimatedEdit';
@@ -186,7 +186,7 @@ class Comment extends React.Component {
</CommentAnimatedEdit>
</div>
{flagActions && flagActions.length
? <FlagBox
? <CommentDetails
actions={flagActions}
actionSummaries={flagActionSummaries}
viewUserDetail={viewUserDetail}