load user via HOC UserDetail

This commit is contained in:
riley
2017-05-03 12:54:02 -06:00
parent 9e1b470cb5
commit 4a42436b7b
11 changed files with 97 additions and 72 deletions
@@ -18,3 +18,5 @@ export const hideShortcutsNote = () => {
return {type: actions.HIDE_SHORTCUTS_NOTE};
};
export const viewUserDetail = userId => ({type: actions.VIEW_USER_DETAIL, userId});
@@ -1,39 +0,0 @@
import React, {PropTypes} from 'react';
import {Button, Drawer} from 'coral-ui';
import styles from './UserDetail.js';
const UserDetail = ({user}) => {
const localProfile = user.profiles.find(p => p.provider === 'local');
const facebookProfile = user.profiles.find(p => p.provider === 'facebook');
let profile;
if (localProfile) {
profile = profile.id;
} else if (facebookProfile) {
profile = <a href={`https://facebook.com/${facebookProfile.id}`}>{facebookProfile.id}</a>;
}
return (
<Drawer>
<h3>{user.username}</h3>
<p>{profile}</p> <Button>Copy</Button>
<strong>Member since</strong> {user.created_at}
<hr/>
<strong>Account summary</strong>
<br/><span className={styles.small}>Data represents the last six months of activity</span>
<div className={styles.stats}>
</div>
</Drawer>
);
};
UserDetail.propTypes = {
user: PropTypes.shape({
username: PropTypes.string.isRequired,
profiles: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string,
provider: PropTypes.string
}))
})
};
export default UserDetail;
@@ -3,3 +3,5 @@ export const SINGLE_VIEW = 'SINGLE_VIEW';
export const SHOW_BANUSER_DIALOG = 'SHOW_BANUSER_DIALOG';
export const HIDE_BANUSER_DIALOG = 'HIDE_BANUSER_DIALOG';
export const HIDE_SHORTCUTS_NOTE = 'HIDE_SHORTCUTS_NOTE';
export const VIEW_USER_DETAIL = 'VIEW_USER_DETAIL';
export const HIDE_USER_DETAIL = 'HIDE_USER_DETAIL';
@@ -5,12 +5,19 @@ import key from 'keymaster';
import isEqual from 'lodash/isEqual';
import styles from './components/styles.css';
import {modQueueQuery, getUserDetail} from '../../graphql/queries';
import {modQueueQuery} from '../../graphql/queries';
import {banUser, setCommentStatus} from '../../graphql/mutations';
import {fetchSettings} from 'actions/settings';
import {updateAssets} from 'actions/assets';
import {toggleModal, singleView, showBanUserDialog, hideBanUserDialog, hideShortcutsNote} from 'actions/moderation';
import {
toggleModal,
singleView,
showBanUserDialog,
hideBanUserDialog,
hideShortcutsNote,
viewUserDetail
} from 'actions/moderation';
import {Spinner} from 'coral-ui';
import BanUserDialog from '../../components/BanUserDialog';
@@ -19,7 +26,7 @@ import ModerationMenu from './components/ModerationMenu';
import ModerationHeader from './components/ModerationHeader';
import NotFoundAsset from './components/NotFoundAsset';
import ModerationKeysModal from '../../components/ModerationKeysModal';
import UserDetail from '../../components/UserDetail';
import UserDetail from './UserDetail';
class ModerationContainer extends Component {
state = {
@@ -77,15 +84,6 @@ class ModerationContainer extends Component {
}
}
viewUserDetail = (id) => {
console.log('getting user detail', id, typeof getUserDetail);
try {
getUserDetail({id});
} catch (e) {
console.log(e);
}
}
selectSort = (sort) => {
this.setState({sort});
this.props.modQueueResort(sort);
@@ -120,7 +118,7 @@ class ModerationContainer extends Component {
}
render () {
const {data, moderation, settings, assets, onClose, ...props} = this.props;
const {data, moderation, settings, assets, onClose, viewUserDetail, ...props} = this.props;
const providedAssetId = this.props.params.id;
const activeTab = this.props.route.path === ':id' ? 'premod' : this.props.route.path;
@@ -190,7 +188,7 @@ class ModerationContainer extends Component {
assetId={providedAssetId}
sort={this.state.sort}
commentCount={activeTabCount}
viewUserDetail={this.viewUserDetail}
viewUserDetail={viewUserDetail}
/>
<BanUserDialog
open={moderation.banDialog}
@@ -206,7 +204,7 @@ class ModerationContainer extends Component {
shortcutsNoteVisible={moderation.shortcutsNoteVisible}
open={moderation.modalOpen}
onClose={onClose}/>
{data.user && <UserDetail user={data.user} />}
{moderation.userDetailId && <UserDetail id={moderation.userDetailId} />}
</div>
);
}
@@ -224,6 +222,7 @@ const mapDispatchToProps = dispatch => ({
singleView: () => dispatch(singleView()),
updateAssets: assets => dispatch(updateAssets(assets)),
fetchSettings: () => dispatch(fetchSettings()),
viewUserDetail: id => dispatch(viewUserDetail(id)),
showBanUserDialog: (user, commentId, showRejectedNote) => dispatch(showBanUserDialog(user, commentId, showRejectedNote)),
hideBanUserDialog: () => dispatch(hideBanUserDialog(false)),
hideShortcutsNote: () => dispatch(hideShortcutsNote()),
@@ -0,0 +1,46 @@
import React, {PropTypes} from 'react';
import {Button, Drawer} from 'coral-ui';
import styles from './UserDetail.js';
import {compose} from 'react-apollo';
import {getUserDetail} from 'coral-admin/src/graphql/queries';
class UserDetail extends React.Component {
static propTypes = {
id: PropTypes.string.isRequired
}
render () {
const {data} = this.props;
if (!('user' in data)) {
return null;
}
const {user} = data;
const localProfile = user.profiles.find(p => p.provider === 'local');
const facebookProfile = user.profiles.find(p => p.provider === 'facebook');
let profile;
if (localProfile) {
profile = localProfile.id;
} else if (facebookProfile) {
profile = <a href={`https://facebook.com/${facebookProfile.id}`}>{facebookProfile.id}</a>;
}
return (
<Drawer>
<h3>{user.username}</h3>
<p>{profile}</p> <Button>Copy</Button>
<strong>Member since</strong> {user.created_at}
<hr/>
<strong>Account summary</strong>
<br/><span className={styles.small}>Data represents the last six months of activity</span>
<div className={styles.stats}>
</div>
</Drawer>
);
}
}
export default compose(
getUserDetail
)(UserDetail);
@@ -35,10 +35,7 @@ const Comment = ({actions = [], comment, viewUserDetail, ...props}) => {
<div className={styles.container}>
<div className={styles.itemHeader}>
<div className={styles.author}>
<span className={styles.username} onClick={() => {
console.log('clickt', comment.user.id);
viewUserDetail(comment.user.id);
}}>
<span className={styles.username} onClick={() => viewUserDetail(comment.user.id)}>
{comment.user.name}
</span>
<span className={styles.created}>
@@ -95,16 +95,10 @@ export const modQueueResort = (id, fetchMore) => (sort) => {
});
};
export const getUserDetail = ({id}) => {
console.log('close', id);
return graphql(USER_DETAIL, {
options: () => {
console.log('so close!', id);
return {
variables: {
id
}
};
}
});
};
export const getUserDetail = graphql(USER_DETAIL, {
options: ({id}) => {
return {
variables: {id}
};
}
});
@@ -6,6 +6,7 @@ const initialState = Map({
modalOpen: false,
user: Map({}),
commentId: null,
userDetailId: null,
banDialog: false,
shortcutsNoteVisible: window.localStorage.getItem('coral:shortcutsNote') || 'show'
});
@@ -35,6 +36,10 @@ export default function moderation (state = initialState, action) {
case actions.HIDE_SHORTCUTS_NOTE:
return state
.set('shortcutsNoteVisible', 'hide');
case actions.VIEW_USER_DETAIL:
return state.set('userDetailId', action.userId);
case actions.HIDE_USER_DETAIL:
return state.set('userDetailId', null);
default :
return state;
}
-1
View File
@@ -98,7 +98,6 @@ const RootQuery = {
// this returns an arbitrary user
user(_, {id}, {user, loaders: {Users}}) {
console.log("user id!", id);
if (user == null || !user.hasRoles('ADMIN')) {
return null;
}
+9
View File
@@ -20,6 +20,15 @@ const User = {
return null;
},
profiles({id, profiles}, _, {user}) {
// if the user is not an admin, do not return the profiles
if (user && (user.hasRoles('ADMIN') || user.id === id)) {
return profiles;
}
return null;
},
roles({id, roles}, _, {user}) {
// If the user is not an admin, only return the current user's roles.
+11
View File
@@ -20,6 +20,14 @@ enum USER_ROLES {
MODERATOR
}
type UserProfile {
# the id is an identifier for the user profile (email, facebook id, etc)
id: String!
# name of the provider attached to the authentication mode
provider: String!
}
# Any person who can author comments, create actions, and view comments on a
# stream.
type User {
@@ -39,6 +47,9 @@ type User {
# the current roles of the user.
roles: [USER_ROLES]
# the current profiles of the user.
profiles: [UserProfile]
# determines whether the user can edit their username
canEditName: Boolean