Merge branch 'master' into refactor-graph

This commit is contained in:
Chi Vinh Le
2018-03-09 19:27:35 +01:00
59 changed files with 1060 additions and 289 deletions
@@ -130,3 +130,12 @@ th.header:nth-child(2), th.header:nth-child(3) {
.loadMore {
margin-top: 24px;
}
.roleDropdown {
width: 150px;
}
.roleOption {
min-width: 100px;
}
@@ -200,24 +200,31 @@ class People extends React.Component {
</td>
<td className="mdl-data-table__cell--non-numeric">
<Dropdown
containerClassName="talk-admin-community-people-dd-role"
className={cn(
'talk-admin-community-people-dd-role',
styles.roleDropdown
)}
value={user.role}
placeholder={t('community.role')}
onChange={role => setUserRole(user.id, role)}
>
<Option
className={styles.roleOption}
value={COMMENTER}
label={t('community.commenter')}
/>
<Option
className={styles.roleOption}
value={STAFF}
label={t('community.staff')}
/>
<Option
className={styles.roleOption}
value={MODERATOR}
label={t('community.moderator')}
/>
<Option
className={styles.roleOption}
value={ADMIN}
label={t('community.admin')}
/>
@@ -89,3 +89,12 @@
display: inline-block;
}
}
.statusDropdown {
width: 150px;
}
.statusDropdownOption {
min-width: 100px;
}
@@ -22,11 +22,20 @@ class Stories extends Component {
const closed = !!(closedAt && new Date(closedAt).getTime() < Date.now());
return (
<Dropdown
className={styles.statusDropdown}
value={closed}
onChange={value => this.props.onStatusChange(value, id)}
>
<Option value={false} label={t('streams.open')} />
<Option value={true} label={t('streams.closed')} />
<Option
value={false}
label={t('streams.open')}
className={styles.statusDropdownOption}
/>
<Option
value={true}
label={t('streams.closed')}
className={styles.statusDropdownOption}
/>
</Dropdown>
);
};
@@ -0,0 +1,20 @@
.root {
text-align: center;
padding-top: 24px;
}
.icon {
font-size: 64px;
color: #3a4a52;
}
.title {
font-size: 18px;
margin-bottom: 8px;
}
.info {
margin-top: 0px;
font-size: 14px;
color: #7d8285;
}
@@ -0,0 +1,14 @@
import React from 'react';
import styles from './BlankCommentHistory.css';
import { Icon } from 'coral-ui';
import cn from 'classnames';
import t from 'coral-framework/services/i18n';
export default () => (
<section className={cn(styles.root, 'talk-my-profile-comment-history-blank')}>
<Icon name="chat" className={styles.icon} />
<h1 className={styles.title}>{t('comment_history_blank.title')}</h1>
<p className={styles.info}>{t('comment_history_blank.info')}</p>
</section>
);
@@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import Comment from '../containers/Comment';
import LoadMore from './LoadMore';
import BlankCommentHistory from './BlankCommentHistory';
class CommentHistory extends React.Component {
state = {
@@ -22,6 +23,9 @@ class CommentHistory extends React.Component {
render() {
const { navigate, comments, data, root } = this.props;
if (!comments.nodes.length) {
return <BlankCommentHistory />;
}
return (
<div className="talk-my-profile-comment-history">
<div className="commentHistory__list">
@@ -10,6 +10,7 @@ class TalkProvider extends React.Component {
plugins: this.props.plugins,
rest: this.props.rest,
graphql: this.props.graphql,
introspection: this.props.introspection,
notification: this.props.notification,
localStorage: this.props.localStorage,
sessionStorage: this.props.sessionStorage,
@@ -29,6 +30,7 @@ class TalkProvider extends React.Component {
TalkProvider.childContextTypes = {
pym: PropTypes.object,
introspection: PropTypes.object,
eventEmitter: PropTypes.object,
plugins: PropTypes.object,
rest: PropTypes.func,
+1
View File
@@ -11,6 +11,7 @@ export { default as withSignUp } from './withSignUp';
export { default as withForgotPassword } from './withForgotPassword';
export { default as withSetUsername } from './withSetUsername';
export { default as withPopupAuthHandler } from './withPopupAuthHandler';
export { default as withEnumValues } from './withEnumValues';
export {
default as withResendEmailConfirmation,
} from './withResendEmailConfirmation';
@@ -0,0 +1,24 @@
import React from 'react';
import hoistStatics from 'recompose/hoistStatics';
import PropTypes from 'prop-types';
/**
* WithEnumValues inject given property name for given enum.
*/
export default (enumName, propName) =>
hoistStatics(WrappedComponent => {
class WithEnumValues extends React.Component {
static contextTypes = {
introspection: PropTypes.object,
};
render() {
const inject = {
[propName]: this.context.introspection.getEnumValues(enumName),
};
return <WrappedComponent {...this.props} {...inject} />;
}
}
return WithEnumValues;
});
@@ -19,6 +19,16 @@ class Introspection {
isValidEnumValue(name, value) {
return this._enums[name] && this._enums[name].indexOf(value) >= 0;
}
/**
* getEnumValues returns array of possible values.
* @param {string} name
* @param {string} value
* @return {array}
*/
getEnumValues(name) {
return this._enums[name];
}
}
/**
+10 -5
View File
@@ -1,20 +1,27 @@
.dropdown {
position: relative;
width: 150px;
height: 34px;
background: #2c2c2c;
box-sizing: border-box;
color: white;
border-radius: 3px;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
line-height: 20px;
font-size: 0.98em;
border-radius: 3px;
cursor: pointer;
&.disabled {
color: #e5e5e5;
background: #888;
cursor: default;
pointer-events: none;
}
}
.toggle {
padding: 8px 15px;
cursor: pointer;
padding: 8px 45px 8px 15px;
outline: none;
&:focus {
@@ -27,7 +34,6 @@
}
.label {
text-transform: capitalize;
}
.list {
@@ -38,7 +44,6 @@
border-radius: 2px;
background: white;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12);
width: 100%;
list-style: none;
padding: 0;
margin: 0;
+24 -2
View File
@@ -13,6 +13,12 @@ class Dropdown extends React.Component {
isOpen: false,
};
componentWillReceiveProps(nextProps) {
if (this.state.isOpen && nextProps.disabled) {
this.toggle();
}
}
componentDidUpdate(_, prevState) {
if (!this.state.isOpen && prevState.isOpen) {
// Refocus on the toggle element when menu closes.
@@ -69,6 +75,10 @@ class Dropdown extends React.Component {
};
toggle = () => {
if (this.props.disabled) {
return false;
}
this.setState({
isOpen: !this.state.isOpen,
});
@@ -135,11 +145,21 @@ class Dropdown extends React.Component {
containerClassName,
toggleClassName,
toggleOpenClassName,
disabled,
className,
} = this.props;
return (
<ClickOutside onClickOutside={this.hideMenu}>
<div
className={cn(styles.dropdown, containerClassName, 'dd dd-container')}
className={cn(
styles.dropdown,
className,
containerClassName,
'dd dd-container',
{
[styles.disabled]: disabled,
}
)}
>
<div
className={cn(styles.toggle, toggleClassName, {
@@ -150,7 +170,7 @@ class Dropdown extends React.Component {
role="button"
aria-pressed={this.state.isOpen}
aria-haspopup="true"
tabIndex="0"
tabIndex={disabled ? '-1' : '0'}
ref={this.handleToggleRef}
>
{this.props.icon && (
@@ -206,6 +226,7 @@ class Dropdown extends React.Component {
}
Dropdown.propTypes = {
className: PropTypes.string,
containerClassName: PropTypes.string,
toggleClassName: PropTypes.string,
toggleOpenClassName: PropTypes.string,
@@ -213,6 +234,7 @@ Dropdown.propTypes = {
icon: PropTypes.string,
onChange: PropTypes.func.isRequired,
children: PropTypes.node.isRequired,
disabled: PropTypes.bool,
value: PropTypes.oneOfType([
PropTypes.number,
PropTypes.string,
+1 -1
View File
@@ -1,7 +1,7 @@
.option {
padding: 10px;
text-transform: capitalize;
outline: none;
white-space: nowrap;
&:focus, &:hover {
background-color: #ccc;