Merge pull request #314 from coralproject/sory-139595043-qbox

Story 139595043 Question Box to Comment Stream
This commit is contained in:
David Erwin
2017-02-16 11:31:17 -05:00
committed by GitHub
23 changed files with 148 additions and 71 deletions
@@ -22,17 +22,17 @@
}
}
.formField {
.textField {
margin-top: 15px;
}
.formField label {
.textField label {
font-size: 1.08em;
font-weight: bold;
margin-bottom: 5px;
}
.formField input {
.textField input {
width: 100%;
display: block;
border: none;
@@ -1,6 +1,6 @@
import React from 'react';
import styles from './style.css';
import {FormField, Button} from 'coral-ui';
import {TextField, Button} from 'coral-ui';
const AddOrganizationName = props => {
const {handleSettingsChange, handleSettingsSubmit, install} = props;
@@ -12,8 +12,8 @@ const AddOrganizationName = props => {
</p>
<div className={styles.form}>
<form onSubmit={handleSettingsSubmit}>
<FormField
className={styles.FormField}
<TextField
className={styles.TextField}
id="organizationName"
type="text"
label='Organization name'
@@ -1,6 +1,6 @@
import React from 'react';
import styles from './style.css';
import {FormField, Button, Spinner} from 'coral-ui';
import {TextField, Button, Spinner} from 'coral-ui';
const InitialStep = props => {
const {handleUserChange, handleUserSubmit, install} = props;
@@ -8,8 +8,8 @@ const InitialStep = props => {
<div className={styles.step}>
<div className={styles.form}>
<form onSubmit={handleUserSubmit}>
<FormField
className={styles.formField}
<TextField
className={styles.textField}
id="email"
type="email"
label='Email address'
@@ -19,8 +19,8 @@ const InitialStep = props => {
noValidate
/>
<FormField
className={styles.formField}
<TextField
className={styles.textField}
id="username"
type="text"
label='Username'
@@ -29,8 +29,8 @@ const InitialStep = props => {
errorMsg={install.errors.username}
/>
<FormField
className={styles.formField}
<TextField
className={styles.textField}
id="password"
type="password"
label='Password'
@@ -39,8 +39,8 @@ const InitialStep = props => {
errorMsg={install.errors.password}
/>
<FormField
className={styles.formField}
<TextField
className={styles.textField}
id="confirmPassword"
type="password"
label='Confirm Password'
@@ -1,6 +1,6 @@
import React from 'react';
import styles from './style.css';
import {Button, Select, Option, FormField} from 'coral-ui';
import {Button, Select, Option, TextField} from 'coral-ui';
const InviteTeamMembers = props => {
const {nextStep} = props;
@@ -14,19 +14,19 @@ const InviteTeamMembers = props => {
<div className={styles.form}>
<form>
<FormField
className={styles.formField}
<TextField
className={styles.textField}
id="email"
type="email"
label='Email address' required/>
<FormField
className={styles.formField}
<TextField
className={styles.textField}
id="username"
type="text"
label='Username' required/>
<div className={styles.formField}>
<div className={styles.textField}>
<label htmlFor='role'>Assing a role</label>
<Select id='role' label='Select Role'>
<Option>Admin</Option>
@@ -33,7 +33,7 @@
margin: 30px 0;
}
.formField {
.textField {
text-align: left;
label {
@@ -35,3 +35,7 @@ p {
.wrapper {
margin-bottom: 20px;
}
.hidden {
display: none;
}
@@ -1,12 +1,13 @@
import React from 'react';
import {Button, Checkbox} from 'coral-ui';
import {Button, Checkbox, TextField} from 'coral-ui';
import styles from './ConfigureCommentStream.css';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations.json';
const lang = new I18n(translations);
export default ({handleChange, handleApply, changed, ...props}) => (
export default ({handleChange, handleApply, changed, updateQuestionBoxContent, ...props}) => (
<form onSubmit={handleApply}>
<div className={styles.wrapper}>
<div className={styles.container}>
@@ -32,25 +33,31 @@ export default ({handleChange, handleApply, changed, ...props}) => (
title: lang.t('configureCommentStream.enablePremod'),
description: lang.t('configureCommentStream.enablePremodDescription')
}} />
{/* To be implimented
<ul>
<li>
<Checkbox
className={styles.checkbox}
cStyle={changed ? 'green' : 'darkGrey'}
name="premodLinks"
onChange={handleChange}
defaultChecked={props.premodLinks}
info={{
title: lang.t('configureCommentStream.enablePremodLinks'),
description: lang.t('configureCommentStream.enablePremodDescription')
}} />
</li>
</ul>
*/}
</li>
<li>
<Checkbox
className={styles.checkbox}
cStyle={changed ? 'green' : 'darkGrey'}
name="qboxenable"
onChange={handleChange}
defaultChecked={props.questionBoxEnable}
info={{
title: lang.t('configureCommentStream.enableQuestionBox'),
description: lang.t('configureCommentStream.enableQuestionBoxDescription')
}} />
<div className={`${props.questionBoxEnable ? null : styles.hidden}`} >
<TextField
id="qboxcontent"
onChange={updateQuestionBoxContent}
rows={3}
value={props.questionBoxContent}
label={lang.t('configureCommentStream.includeQuestionHere')}
/>
</div>
</li>
</ul>
</div>
</form>
);
@@ -21,18 +21,23 @@ class ConfigureStreamContainer extends Component {
this.toggleStatus = this.toggleStatus.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleApply = this.handleApply.bind(this);
this.updateQuestionBoxContent = this.updateQuestionBoxContent.bind(this);
}
handleApply (e) {
e.preventDefault();
const {elements} = e.target;
const premod = elements.premod.checked;
const questionBoxEnable = elements.qboxenable.checked;
const questionBoxContent = elements.qboxcontent.value;
// const premodLinks = elements.premodLinks.checked;
const {changed} = this.state;
const newConfig = {
moderation: premod ? 'PRE' : 'POST'
moderation: premod ? 'PRE' : 'POST',
questionBoxEnable,
questionBoxContent
};
if (changed) {
@@ -45,12 +50,20 @@ class ConfigureStreamContainer extends Component {
}
}
handleChange () {
handleChange (e) {
if (e.target && e.target.id === 'qboxenable') {
this.props.asset.settings.questionBoxEnable = e.target.checked;
}
this.setState({
changed: true
});
}
updateQuestionBoxContent(e) {
this.props.asset.settings.questionBoxContent = e.target.value;
this.handleChange(e);
}
toggleStatus () {
this.props.updateStatus(
this.props.asset.closedAt === null ? 'closed' : 'open'
@@ -66,6 +79,8 @@ class ConfigureStreamContainer extends Component {
render () {
const status = this.props.asset.closedAt === null ? 'open' : 'closed';
const premod = this.props.asset.settings.moderation === 'PRE';
const questionBoxEnable = this.props.asset.settings.questionBoxEnable;
const questionBoxContent = this.props.asset.settings.questionBoxContent;
return (
<div>
@@ -75,6 +90,9 @@ class ConfigureStreamContainer extends Component {
changed={this.state.changed}
premodLinks={false}
premod={premod}
updateQuestionBoxContent={this.updateQuestionBoxContent}
questionBoxEnable={questionBoxEnable}
questionBoxContent={questionBoxContent}
/>
<hr />
<h3>{status === 'open' ? 'Close' : 'Open'} Comment Stream</h3>
@@ -94,7 +112,7 @@ const mapStateToProps = (state) => ({
const mapDispatchToProps = dispatch => ({
updateStatus: status => dispatch(updateOpenStatus(status)),
updateConfiguration: newConfig => dispatch(updateConfiguration(newConfig))
updateConfiguration: newConfig => dispatch(updateConfiguration(newConfig)),
});
export default compose(
+10 -4
View File
@@ -7,18 +7,24 @@
"enablePremod": "Enable Premoderation",
"enablePremodDescription": "Moderators must approve any comment before its published.",
"enablePremodLinks": "Pre-Moderate Comments Containing Links",
"enablePremodLinksDescription": "Moderators must approve any comment containing a link before its published."
"enablePremodLinksDescription": "Moderators must approve any comment containing a link before its published.",
"enableQuestionBox": "Ask readers a question",
"enableQuestionBoxDescription": "This question will appear at the top of this comment stram. Ask readers about a certain issue in the article or pose discussion questions, etc.",
"includeQuestionHere": "Write your question here."
}
},
"es": {
"configureCommentStream": {
"apply": "Aplicar",
"title": "Configurar los comentarios",
"description": "Como Administrador puedes modificar las opciones de los comentarios en este artículo",
"description": "Como Administrador/a puedes modificar las opciones de los comentarios en este artículo",
"enablePremod": "Activar Pre Moderación",
"enablePremodDescription": "Los Moderadores deben aprobar cualquier comentario antes de su publicación",
"enablePremodDescription": "Los y las Moderadoras deben aprobar cualquier comentario antes de su publicación",
"enablePremodLinks": "Pre-Moderar Commentarios que contienen Links",
"enablePremodLinksDescription": "Los Moderadores deben probar cualquier comentario que contengan links antes de su publicación."
"enablePremodLinksDescription": "Los y las Moderadoras deben probar cualquier comentario que contengan links antes de su publicación.",
"enableQuestionBox": "Hacer una pregunta a los y las lectoras.",
"enableQuestionBoxDescription": "Esta pregunta aparecera en la parte de arriba del hilo de comentarios.",
"includeQuestionHere": "Escribir la pregunta aquí."
}
}
}
+5
View File
@@ -16,6 +16,7 @@ import {Notification, notificationActions, authActions, assetActions, pym} from
import Stream from './Stream';
import InfoBox from 'coral-plugin-infobox/InfoBox';
import QuestionBox from 'coral-plugin-questionbox/QuestionBox';
import {ModerationLink} from 'coral-plugin-moderation';
import Count from 'coral-plugin-comment-count/CommentCount';
import CommentBox from 'coral-plugin-commentbox/CommentBox';
@@ -114,6 +115,10 @@ class Embed extends Component {
content={asset.settings.infoBoxContent}
enable={asset.settings.infoBoxEnable}
/>
<QuestionBox
content={asset.settings.questionBoxContent}
enable={asset.settings.questionBoxEnable}
/>
<RestrictedContent restricted={banned} restrictedComp={
<SuspendedAccount
canEditName={user && user.canEditName}
+16 -1
View File
@@ -62,7 +62,7 @@ hr {
.coral-plugin-infobox-info {
top: 0;
border: 0;
background: rgb(105,105,105);
background: rgb(35,118,216);
color: white;
width: 100%;
text-align: center;
@@ -72,6 +72,21 @@ hr {
display: block;
}
/* Question Box Styles */
.coral-plugin-questionbox-info {
top: 0;
border: 0;
background: rgb(105,105,105);
color: white;
width: 100%;
text-align: center;
padding: 10px;
margin-bottom: 0px;
font-weight: bold;
display: block;
}
.hidden {
visibility: hidden;
display: none;
@@ -11,6 +11,8 @@ query AssetQuery($asset_url: String!) {
moderation
infoBoxEnable
infoBoxContent
questionBoxEnable
questionBoxContent
closeTimeout
closedMessage
charCountEnable
@@ -0,0 +1,10 @@
import React from 'react';
const packagename = 'coral-plugin-questionbox';
const QuestionBox = ({enable, content}) =>
<div
className={`${packagename}-info ${enable ? null : 'hidden'}` }>
{content}
</div>;
export default QuestionBox;
+1 -1
View File
@@ -50,7 +50,7 @@ class Stream extends Component {
}
}
// Initialize GraphQL queries or mutations with the `gql` tag
// Initialize GraphQL queries or mutations with the gql tag
const StreamQuery = gql`fragment commentView on Comment {
id
body
@@ -1,5 +1,5 @@
import React from 'react';
import FormField from 'coral-ui/components/FormField';
import TextField from 'coral-ui/components/TextField';
import Alert from './Alert';
import Button from 'coral-ui/components/Button';
import {Dialog} from 'coral-ui';
@@ -28,7 +28,7 @@ const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSub
<label htmlFor="username">{lang.t('createdisplay.yourusername')}</label>
{ props.auth.error && <Alert>{props.auth.error}</Alert> }
<form id="saveDisplayName" onSubmit={handleSubmitDisplayName}>
<FormField
<TextField
id="username"
type="string"
label={lang.t('createdisplay.username')}
@@ -26,7 +26,7 @@ class ForgotContent extends React.Component {
<h1>{lang.t('signIn.recoverPassword')}</h1>
</div>
<form onSubmit={this.handleSubmit}>
<div className={styles.formField}>
<div className={styles.textField}>
<label htmlFor="email">{lang.t('signIn.email')}</label>
<input
ref={input => this.emailInput = input}
@@ -1,6 +1,6 @@
import React, {PropTypes} from 'react';
import Alert from './Alert';
import {Button, FormField, Spinner, Success} from 'coral-ui';
import {Button, TextField, Spinner, Success} from 'coral-ui';
import styles from './styles.css';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
@@ -32,7 +32,7 @@ const SignInContent = ({
auth.emailVerificationFailure
? <form onSubmit={handleResendVerification}>
<p>{lang.t('signIn.requestNewVerifyEmail')}</p>
<FormField
<TextField
id="confirm-email"
type="email"
label={lang.t('signIn.email')}
@@ -54,14 +54,14 @@ const SignInContent = ({
</h1>
</div>
<form onSubmit={handleSignIn}>
<FormField
<TextField
id="email"
type="email"
label={lang.t('signIn.email')}
value={formData.email}
onChange={handleChange}
/>
<FormField
<TextField
id="password"
type="password"
label={lang.t('signIn.password')}
@@ -1,6 +1,6 @@
import React, {PropTypes} from 'react';
import Alert from './Alert';
import {Button, FormField, Spinner, Success} from 'coral-ui';
import {Button, TextField, Spinner, Success} from 'coral-ui';
import styles from './styles.css';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
@@ -79,7 +79,7 @@ class SignUpContent extends React.Component {
</h1>
</div>
<form onSubmit={handleSignUp}>
<FormField
<TextField
id="email"
type="email"
label={lang.t('signIn.email')}
@@ -88,7 +88,7 @@ class SignUpContent extends React.Component {
errorMsg={errors.email}
onChange={handleChange}
/>
<FormField
<TextField
id="username"
type="text"
label={lang.t('signIn.username')}
@@ -97,7 +97,7 @@ class SignUpContent extends React.Component {
errorMsg={errors.username}
onChange={handleChange}
/>
<FormField
<TextField
id="password"
type="password"
label={lang.t('signIn.password')}
@@ -108,7 +108,7 @@ class SignUpContent extends React.Component {
minLength="8"
/>
{ errors.password && <span className={styles.hint}> Password must be at least 8 characters. </span> }
<FormField
<TextField
id="confirmPassword"
type="password"
label={lang.t('signIn.confirmPassword')}
@@ -1,14 +1,14 @@
.formField {
.textField {
margin-top: 15px;
}
.formField label {
.textField label {
font-size: 1.08em;
font-weight: bold;
margin-bottom: 5px;
}
.formField input {
.textField input {
width: 100%;
display: block;
border: none;
@@ -1,8 +1,8 @@
import React, {PropTypes} from 'react';
import styles from './FormField.css';
import styles from './TextField.css';
const FormField = ({className, showErrors = false, errorMsg, label, ...props}) => (
<div className={`${styles.formField} ${className ? className : ''}`}>
const TextField = ({className, showErrors = false, errorMsg, label, ...props}) => (
<div className={`${styles.textField} ${className ? className : ''}`}>
<label htmlFor={props.id}>
{label}
</label>
@@ -15,7 +15,7 @@ const FormField = ({className, showErrors = false, errorMsg, label, ...props}) =
</div>
);
FormField.propTypes = {
TextField.propTypes = {
label: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,
@@ -23,4 +23,4 @@ FormField.propTypes = {
type: PropTypes.string
};
export default FormField;
export default TextField;
+1 -1
View File
@@ -13,7 +13,7 @@ export {default as Icon} from './components/Icon';
export {default as List} from './components/List';
export {default as Item} from './components/Item';
export {default as Card} from './components/Card';
export {default as FormField} from './components/FormField';
export {default as TextField} from './components/TextField';
export {default as Success} from './components/Success';
export {default as Pager} from './components/Pager';
export {default as Wizard} from './components/Wizard';
+2
View File
@@ -308,6 +308,8 @@ type Settings {
infoBoxEnable: Boolean
infoBoxContent: String
questionBoxEnable: Boolean
questionBoxContent: String
closeTimeout: Int
closedMessage: String
charCountEnable: Boolean
+8
View File
@@ -32,6 +32,14 @@ const SettingSchema = new Schema({
type: String,
default: ''
},
questionBoxEnable: {
type: Boolean,
default: false
},
questionBoxContent: {
type: String,
default: ''
},
organizationName: {
type: String
},