From e803593fc7fb204b2a2bcd5a598e38772662f259 Mon Sep 17 00:00:00 2001
From: gaba
Date: Mon, 30 Jan 2017 11:34:04 -0800
Subject: [PATCH 01/77] Move stuff around.
---
client/coral-embed-stream/src/Embed.js | 11 +-
client/coral-framework/actions/auth.js | 14 ++
.../components/CreateDisplayNameDialog.js | 44 ++++++
client/coral-framework/components/styles.css | 140 ++++++++++++++++++
client/coral-framework/constants/auth.js | 3 +
.../containers/ChangeDisplayNameContainer.js | 140 ++++++++++++++++++
client/coral-framework/reducers/auth.js | 8 +
client/coral-framework/translations.json | 15 ++
services/users.js | 12 ++
9 files changed, 378 insertions(+), 9 deletions(-)
create mode 100644 client/coral-framework/components/CreateDisplayNameDialog.js
create mode 100644 client/coral-framework/components/styles.css
create mode 100644 client/coral-framework/containers/ChangeDisplayNameContainer.js
diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index 5922266fa..b6fee1184 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -19,6 +19,7 @@ import Count from 'coral-plugin-comment-count/CommentCount';
import CommentBox from 'coral-plugin-commentbox/CommentBox';
import UserBox from '../../coral-sign-in/components/UserBox';
import SignInContainer from '../../coral-sign-in/containers/SignInContainer';
+import ChangeDisplayNameContainer from '../../coral-framework/containers/ChangeDisplayNameContainer';
import SuspendedAccount from '../../coral-framework/components/SuspendedAccount';
import SettingsContainer from '../../coral-settings/containers/SettingsContainer';
import RestrictedContent from '../../coral-framework/components/RestrictedContent';
@@ -51,15 +52,6 @@ class Embed extends Component {
}
componentDidMount () {
-
- // stream id, logged in user, settings
-
- // Set up messaging between embedded Iframe an parent component
-
- // this.props.getStream(path || window.location);
- // this.path = window.location.href.split('#')[0];
- //
-
pym.sendMessage('childReady');
pym.onMessage('DOMContentLoaded', hash => {
@@ -138,6 +130,7 @@ class Embed extends Component {
: {asset.settings.closedMessage}
}
{!loggedIn && }
+ {loggedIn && }
({type: actions.SHOW_SIGNIN_DIALOG, offset});
export const hideSignInDialog = () => ({type: actions.HIDE_SIGNIN_DIALOG});
+export const showCreateDisplayNameDialog = () => ({type: actions.SHOW_CREATEDISPLAYNAME_DIALOG});
+export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISPLAYNAME_DIALOG});
+export const createDisplayName = (formData) => (dispatch) => {
+ coralApi('/users', {method: 'POST', body: formData})
+ .then(() => {
+ dispatch(createDisplayNameSuccess());
+ dispatch(hideCreateDisplayNameDialog());
+ })
+ .catch(() => dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate'))));
+};
+const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS});
+const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error});
+
export const changeView = view => dispatch =>
dispatch({
type: actions.CHANGE_VIEW,
@@ -59,6 +72,7 @@ export const facebookCallback = (err, data) => dispatch => {
const user = JSON.parse(data);
dispatch(signInFacebookSuccess(user));
dispatch(hideSignInDialog());
+ dispatch(showCreateDisplayNameDialog());
dispatch(addItem(user, 'users'));
} catch (err) {
dispatch(signInFacebookFailure(err));
diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js
new file mode 100644
index 000000000..8b61989aa
--- /dev/null
+++ b/client/coral-framework/components/CreateDisplayNameDialog.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import {Dialog} from 'coral-ui';
+import styles from './styles.css';
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from '../translations';
+const lang = new I18n(translations);
+
+const CreateDisplayNameDialog = ({open, handleClose, offset, loggedIn}) => (
+
+ ×
+
+
+
+ {lang.t('createdisplay.writeyourusername')}
+
+ Logged {loggedIn}
+
+
+
+);
+
+//
+
+export default CreateDisplayNameDialog;
diff --git a/client/coral-framework/components/styles.css b/client/coral-framework/components/styles.css
new file mode 100644
index 000000000..f9d0aec6d
--- /dev/null
+++ b/client/coral-framework/components/styles.css
@@ -0,0 +1,140 @@
+.dialog {
+ border: none;
+ box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
+ width: 280px;
+ top: 10px;
+}
+
+.header {
+ margin-bottom: 20px;
+}
+
+.header h1, .separator h1{
+ text-align: center;
+ font-size: 1.2em;
+}
+
+.formField {
+ margin-top: 15px;
+}
+
+.formField label {
+ font-size: 1.08em;
+ font-weight: bold;
+ margin-bottom: 5px;
+}
+
+.formField input {
+ width: 100%;
+ display: block;
+ border: none;
+ outline: none;
+ border: 1px solid rgba(0,0,0,.12);
+ padding: 10px 6px;
+ box-sizing: border-box;
+ border-radius: 2px;
+ margin: 5px auto;
+}
+
+.footer {
+ margin: 20px auto 10px;
+ text-align: center;
+}
+
+.footer span {
+ display: block;
+ margin-bottom: 5px;
+}
+
+.footer a {
+ color: #2c69b6;
+ cursor: pointer;
+ margin: 0 5px;
+}
+
+.socialConnections {
+ margin-bottom: 20px;
+}
+
+.signInButton {
+ margin-top: 10px;
+}
+
+.close {
+ font-size: 20px;
+ line-height: 14px;
+ top: 10px;
+ right: 10px;
+ position: absolute;
+ display: block;
+ font-weight: bold;
+ color: #363636;
+ cursor: pointer;
+}
+
+.close:hover {
+ color: #6b6b6b;
+}
+
+input.error{
+ border: solid 2px #f44336;
+}
+
+.errorMsg, .hint {
+ color: grey;
+ font-weight: 600;
+ padding: 3px 0 16px;
+}
+
+.alert {
+ padding: 10px;
+ margin-bottom: 20px;
+ border-radius: 2px;
+}
+
+.alert--success {
+ border: solid 1px #1ec00e;
+ background: #cbf1b8;
+ color: #006900;
+}
+
+.alert--error {
+ background: #FFEBEE;
+ color: #B71C1C;
+}
+
+.userBox {
+ padding: 10px 0 20px;
+ letter-spacing: 0.1px;
+}
+
+.userBox a {
+ color: black;
+ font-weight: bold;
+ cursor: pointer;
+ margin: 0px;
+ margin-left: 4px;
+ padding-bottom: 2px;
+ border-bottom: solid 1px black;
+}
+
+.attention {
+ display: inline-block;
+ width: 15px;
+ height: 15px;
+ background: #B71C1C;
+ color: #FFEBEE;
+ font-weight: bolder;
+ padding: 4px;
+ vertical-align: middle;
+ border-radius: 20px;
+ box-sizing: border-box;
+ font-size: 9px;
+ line-height: 7px;
+ text-align: center;
+ margin-right: 5px;
+}
+
+.action {
+ margin-top: 15px;
+}
diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js
index 5742adf75..27fa8890f 100644
--- a/client/coral-framework/constants/auth.js
+++ b/client/coral-framework/constants/auth.js
@@ -4,6 +4,9 @@ export const CLEAN_STATE = 'CLEAN_STATE';
export const SHOW_SIGNIN_DIALOG = 'SHOW_SIGNIN_DIALOG';
export const HIDE_SIGNIN_DIALOG = 'HIDE_SIGNIN_DIALOG';
+export const SHOW_CREATEDISPLAYNAME_DIALOG = 'SHOW_CREATEDISPLAYNAME_DIALOG';
+export const HIDE_CREATEDISPLAYNAME_DIALOG = 'HIDE_CREATEDISPLAYNAME_DIALOG';
+
export const FETCH_SIGNUP_REQUEST = 'FETCH_SIGNUP_REQUEST';
export const FETCH_SIGNUP_FAILURE = 'FETCH_SIGNUP_FAILURE';
export const FETCH_SIGNUP_SUCCESS = 'FETCH_SIGNUP_SUCCESS';
diff --git a/client/coral-framework/containers/ChangeDisplayNameContainer.js b/client/coral-framework/containers/ChangeDisplayNameContainer.js
new file mode 100644
index 000000000..17e681388
--- /dev/null
+++ b/client/coral-framework/containers/ChangeDisplayNameContainer.js
@@ -0,0 +1,140 @@
+import React, {Component} from 'react';
+import {connect} from 'react-redux';
+
+import CreateDisplayNameDialog from '../components/CreateDisplayNameDialog';
+
+// import validate from 'coral-framework/helpers/validate';
+// import errorMsj from 'coral-framework/helpers/error';
+import I18n from 'coral-framework/modules/i18n/i18n';
+import translations from '../translations';
+const lang = new I18n(translations);
+
+import {
+ showCreateDisplayNameDialog,
+ hideCreateDisplayNameDialog,
+ invalidForm,
+ validForm,
+ createDisplayName
+} from '../../coral-framework/actions/auth';
+
+class ChangeDisplayNameContainer extends Component {
+ initialState = {
+ formData: {
+ displayName: '',
+ },
+ errors: {},
+ showErrors: false
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = this.initialState;
+ this.handleChange = this.handleChange.bind(this);
+ this.handleSubmitForm = this.handleSubmitForm.bind(this);
+ this.handleClose = this.handleClose.bind(this);
+ this.addError = this.addError.bind(this);
+ }
+
+ componentDidMount() {
+ const {formData} = this.state;
+ const errors = Object.keys(formData).reduce((map, prop) => {
+ map[prop] = lang.t('createdisplay.requiredField');
+ return map;
+ }, {});
+ this.setState({errors});
+ }
+
+ handleChange(e) {
+ const {name, value} = e.target;
+ this.setState(state => ({
+ ...state,
+ formData: {
+ ...state.formData,
+ [name]: value
+ }
+ }), () => {
+ this.validation(name, value);
+ });
+ }
+
+ addError(name, error) {
+ return this.setState(state => ({
+ errors: {
+ ...state.errors,
+ [name]: error
+ }
+ }));
+ }
+
+ validation(name, value) {
+ const {addError} = this;
+
+ if (!value.length) {
+ addError(name, lang.t('displayName.requiredField'));
+ } else {
+ const { [name]: prop, ...errors } = this.state.errors; // eslint-disable-line
+ // Removes Error
+ this.setState(state => ({...state, errors}));
+ }
+ }
+
+ isCompleted() {
+ const {formData} = this.state;
+ return !Object.keys(formData).filter(prop => !formData[prop].length).length;
+ }
+
+ displayErrors(show = true) {
+ this.setState({showErrors: show});
+ }
+
+ handleSubmitForm(e) {
+ e.preventDefault();
+ const {errors} = this.state;
+ const {validForm, invalidForm} = this.props;
+ this.displayErrors();
+ if (this.isCompleted() && !Object.keys(errors).length) {
+ createDisplayName(this.state.formData);
+ validForm();
+ } else {
+ invalidForm(lang.t('signIn.checkTheForm'));
+ }
+ }
+
+ handleClose() {
+ this.props.hideCreateDisplayNameDialog();
+ }
+
+ render() {
+ const {loggedIn, auth, offset, user} = this.props;
+ return (
+
+
+
+ );
+ }
+}
+
+const mapStateToProps = state => ({
+ auth: state.auth.toJS()
+});
+
+const mapDispatchToProps = dispatch => ({
+ createDisplayName: formData => dispatch(createDisplayName(formData)),
+ showCreateDisplayNameDialog: () => dispatch(showCreateDisplayNameDialog()),
+ hideCreateDisplayNameDialog: () => dispatch(hideCreateDisplayNameDialog()),
+ invalidForm: error => dispatch(invalidForm(error)),
+ validForm: () => dispatch(validForm())
+});
+
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ChangeDisplayNameContainer);
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index 36f8e0764..ff0f72b4a 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -7,6 +7,7 @@ const initialState = Map({
isAdmin: false,
user: null,
showSignInDialog: false,
+ showCreateDisplayNameDialog: false,
view: 'SIGNIN',
error: '',
passwordRequestSuccess: null,
@@ -35,6 +36,13 @@ export default function auth (state = initialState, action) {
passwordRequestSuccess: null,
successSignUp: false
}));
+ case actions.SHOW_CREATEDISPLAYNAME_DIALOG :
+ return state
+ .set('showCreateDisplayNameDialog', true);
+ case actions.HIDE_CREATEDISPLAYNAME_DIALOG :
+ return state.merge(Map({
+ showCreateDisplayNameDialog: false
+ }));
case actions.CHANGE_VIEW :
return state
.set('error', '')
diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json
index 5bf9b40a9..5900aad3e 100644
--- a/client/coral-framework/translations.json
+++ b/client/coral-framework/translations.json
@@ -4,6 +4,14 @@
"successBioUpdate": "Your Bio has been updated",
"contentNotAvailable": "This content is not available",
"suspendedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
+ "createdisplay": {
+ "writeyourusername": "Write your username",
+ "yourusername": "Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.",
+ "displayName": "Display Name",
+ "save": "Save",
+ "requiredField": "Required field",
+ "errorCreate": "Error when changing display name"
+ },
"error": {
"email": "Not a valid E-Mail",
"password": "Password must be at least 8 characters",
@@ -26,6 +34,13 @@
"successBioUpdate": "Tu bio fue actualizada",
"contentNotAvailable": "El contenido no se encuentra disponible",
"suspendedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information",
+ "createdisplay": {
+ "writeyourusername": "Escribe tu nombre",
+ "yourusername": "Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.",
+ "displayName": "Nombre",
+ "save": "Guardar",
+ "requiredField": "Campo necesario"
+ },
"error": {
"email": "No es un email válido",
"password": "La contraseña debe tener por lo menos 8 caracteres",
diff --git a/services/users.js b/services/users.js
index 0bf22e9e0..d1e7dce05 100644
--- a/services/users.js
+++ b/services/users.js
@@ -156,6 +156,18 @@ module.exports = class UsersService {
});
}
+ static changeDisplayName(id, displayName) {
+ return UsersService.isValidDisplayName(displayName)
+ .then((displayName) => { // displayName is valid
+ return UserModel.update({id}, {
+ $inc: {__v: 1},
+ $set: {
+ displayName: displayName
+ }
+ });
+ });
+ }
+
/**
* Creates local users.
* @param {Array} users Users to create
From 890da0400f8657cfa55a3681aee00c96ad3cbbc9 Mon Sep 17 00:00:00 2001
From: Belen Curcio
Date: Tue, 31 Jan 2017 16:31:29 -0300
Subject: [PATCH 02/77] Steps
---
client/coral-admin/src/AppRouter.js | 2 ++
client/coral-admin/src/actions/install.js | 4 +++
client/coral-admin/src/constants/install.js | 2 ++
.../containers/Install/InstallContainer.js | 30 +++++++++++++++++++
.../src/containers/Install/index.js | 0
.../src/containers/Install/style.css | 0
client/coral-admin/src/reducers/index.js | 4 ++-
client/coral-admin/src/reducers/install.js | 21 +++++++++++++
8 files changed, 62 insertions(+), 1 deletion(-)
create mode 100644 client/coral-admin/src/actions/install.js
create mode 100644 client/coral-admin/src/constants/install.js
create mode 100644 client/coral-admin/src/containers/Install/InstallContainer.js
create mode 100644 client/coral-admin/src/containers/Install/index.js
create mode 100644 client/coral-admin/src/containers/Install/style.css
create mode 100644 client/coral-admin/src/reducers/install.js
diff --git a/client/coral-admin/src/AppRouter.js b/client/coral-admin/src/AppRouter.js
index 9c0f271cc..ebb79b4e1 100644
--- a/client/coral-admin/src/AppRouter.js
+++ b/client/coral-admin/src/AppRouter.js
@@ -7,6 +7,7 @@ import Configure from 'containers/Configure/Configure';
import Streams from 'containers/Streams/Streams';
import CommunityContainer from 'containers/Community/CommunityContainer';
import LayoutContainer from 'containers/LayoutContainer';
+import InstallContainer from 'containers/Install/InstallContainer';
const routes = (
@@ -15,6 +16,7 @@ const routes = (
+
);
diff --git a/client/coral-admin/src/actions/install.js b/client/coral-admin/src/actions/install.js
new file mode 100644
index 000000000..460a36e23
--- /dev/null
+++ b/client/coral-admin/src/actions/install.js
@@ -0,0 +1,4 @@
+import * as actions from '../constants/install';
+
+export const nextStep = () => ({type: actions.NEXT_STEP});
+export const previousStep = () => ({type: actions.PREVIOUS_STEP});
diff --git a/client/coral-admin/src/constants/install.js b/client/coral-admin/src/constants/install.js
new file mode 100644
index 000000000..f15a39ed4
--- /dev/null
+++ b/client/coral-admin/src/constants/install.js
@@ -0,0 +1,2 @@
+export const NEXT_STEP = 'NEXT_STEP';
+export const PREVIOUS_STEP = 'PREVIOUS_STEP';
diff --git a/client/coral-admin/src/containers/Install/InstallContainer.js b/client/coral-admin/src/containers/Install/InstallContainer.js
new file mode 100644
index 000000000..de296acc0
--- /dev/null
+++ b/client/coral-admin/src/containers/Install/InstallContainer.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import {connect} from 'react-redux';
+import styles from './style.css';
+import {nextStep, previousStep} from '../../actions/install'
+
+const InstallContainer = props => {
+ const {nextStep, previousStep, install} = props;
+
+ return (
+
+ Install:
+
+ {install.step}
+
+ Previous Step
+ Next Step
+
+ );
+};
+
+const mapStateToProps = state => ({
+ install: state.install.toJS()
+});
+
+const mapDispatchToProps = dispatch => ({
+ nextStep: () => dispatch(nextStep()),
+ previousStep: () => dispatch(previousStep())
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(InstallContainer);
diff --git a/client/coral-admin/src/containers/Install/index.js b/client/coral-admin/src/containers/Install/index.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/client/coral-admin/src/containers/Install/style.css b/client/coral-admin/src/containers/Install/style.css
new file mode 100644
index 000000000..e69de29bb
diff --git a/client/coral-admin/src/reducers/index.js b/client/coral-admin/src/reducers/index.js
index a19a5a087..1943e5976 100644
--- a/client/coral-admin/src/reducers/index.js
+++ b/client/coral-admin/src/reducers/index.js
@@ -6,6 +6,7 @@ import users from 'reducers/users';
import auth from 'reducers/auth';
import actions from 'reducers/actions';
import assets from 'reducers/assets';
+import install from 'reducers/install';
// Combine all reducers into a main one
export default combineReducers({
@@ -15,5 +16,6 @@ export default combineReducers({
auth,
actions,
assets,
- users
+ users,
+ install
});
diff --git a/client/coral-admin/src/reducers/install.js b/client/coral-admin/src/reducers/install.js
new file mode 100644
index 000000000..1b9ae5b28
--- /dev/null
+++ b/client/coral-admin/src/reducers/install.js
@@ -0,0 +1,21 @@
+import {Map} from 'immutable';
+
+import * as actions from '../constants/install';
+
+const initialState = Map({
+ step: 0
+});
+
+export default function auth (state = initialState, action) {
+ switch (action.type) {
+ case actions.NEXT_STEP:
+ console.log(state)
+ return state
+ .set('step', state.get('step') + 1);
+ case actions.PREVIOUS_STEP:
+ return state
+ .set('step', state.get('step') - 1);
+ default :
+ return state;
+ }
+}
From 80122dfdceb3cd190f1c3de82391efc8d4a9fc0f Mon Sep 17 00:00:00 2001
From: gaba
Date: Tue, 31 Jan 2017 13:48:45 -0800
Subject: [PATCH 03/77] Adds formfield to components.
---
client/coral-framework/components/FormField.js | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
create mode 100644 client/coral-framework/components/FormField.js
diff --git a/client/coral-framework/components/FormField.js b/client/coral-framework/components/FormField.js
new file mode 100644
index 000000000..ceb2d939e
--- /dev/null
+++ b/client/coral-framework/components/FormField.js
@@ -0,0 +1,18 @@
+import React from 'react';
+import styles from './styles.css';
+
+const FormField = ({className, showErrors = false, errorMsg, label, ...props}) => (
+
+
+ {label}
+
+
+ {showErrors && errorMsg && ! {errorMsg} }
+
+);
+
+export default FormField;
From a377f61bddf12e8ac4c905560eadf419951ab190 Mon Sep 17 00:00:00 2001
From: gaba
Date: Tue, 31 Jan 2017 13:51:36 -0800
Subject: [PATCH 04/77] Adds service and endpoint to change displayname.
---
routes/api/users/index.js | 9 +++++++++
services/users.js | 18 ++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/routes/api/users/index.js b/routes/api/users/index.js
index 3ea3f3213..50e09aba7 100644
--- a/routes/api/users/index.js
+++ b/routes/api/users/index.js
@@ -57,6 +57,15 @@ router.post('/:user_id/status', authorization.needed('ADMIN'), (req, res, next)
.catch(next);
});
+router.post('/:user_id/displayname', authorization.needed(), (req, res, next) => {
+ UsersService
+ .setDisplayName(req.params.user_id, req.body.displayName)
+ .then((status) => {
+ res.status(201).json(status);
+ })
+ .catch(next);
+});
+
// /**
// * SendEmailConfirmation sends a confirmation email to the user.
// * @param {Request} req express request object
diff --git a/services/users.js b/services/users.js
index d1e7dce05..bc46c5e62 100644
--- a/services/users.js
+++ b/services/users.js
@@ -358,6 +358,24 @@ module.exports = class UsersService {
return UserModel.update({id}, {$set: {status}});
}
+ /**
+ * Set the display name of a user.
+ * @param {String} id id of a user
+ * @param {String} displayName display name to set
+ * @param {Function} done callback after the operation is complete
+ */
+ static setDisplayName(id, displayName) {
+
+ // Check to see if that the displayName is not empty.
+ if (displayName.length < 1) {
+
+ // User displayName is required! Error out here.
+ return Promise.reject(new Error('display name should not be empty'));
+ }
+
+ return UserModel.update({id}, {$set: {'displayName': displayName}});
+ }
+
/**
* Finds a user with the id.
* @param {String} id user id (uuid)
From 37eae516416edd9cf51554fbaba535baee5cc095 Mon Sep 17 00:00:00 2001
From: gaba
Date: Tue, 31 Jan 2017 13:52:40 -0800
Subject: [PATCH 05/77] Adds component to coral-framework to deal with the
change of displayname.
---
client/coral-framework/actions/auth.js | 18 +++++++---
client/coral-framework/actions/items.js | 1 -
.../components/CreateDisplayNameDialog.js | 33 +++++++++----------
client/coral-framework/constants/auth.js | 6 ++++
client/coral-framework/constants/user.js | 1 +
.../containers/ChangeDisplayNameContainer.js | 18 +++++-----
client/coral-framework/reducers/auth.js | 11 +++++++
client/coral-framework/translations.json | 8 +++--
8 files changed, 63 insertions(+), 33 deletions(-)
diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js
index ee6f6a817..f99450901 100644
--- a/client/coral-framework/actions/auth.js
+++ b/client/coral-framework/actions/auth.js
@@ -3,22 +3,32 @@ import translations from './../translations';
const lang = new I18n(translations);
import * as actions from '../constants/auth';
import coralApi, {base} from '../helpers/response';
-import {addItem} from './items';
+import {addItem, updateItem} from './items';
// Dialog Actions
export const showSignInDialog = (offset = 0) => ({type: actions.SHOW_SIGNIN_DIALOG, offset});
export const hideSignInDialog = () => ({type: actions.HIDE_SIGNIN_DIALOG});
+export const createDisplayNameRequest = () => ({type: actions.CREATE_DISPLAYNAME_REQUEST});
export const showCreateDisplayNameDialog = () => ({type: actions.SHOW_CREATEDISPLAYNAME_DIALOG});
export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISPLAYNAME_DIALOG});
-export const createDisplayName = (formData) => (dispatch) => {
- coralApi('/users', {method: 'POST', body: formData})
+
+export const updateDisplayName = displayName => ({type: actions.UPDATE_DISPLAYNAME, displayName});
+
+export const createDisplayName = (userId, formData) => dispatch => {
+ dispatch(createDisplayNameRequest());
+ coralApi(`/users/${userId}/displayname`, {method: 'POST', body: formData})
.then(() => {
dispatch(createDisplayNameSuccess());
dispatch(hideCreateDisplayNameDialog());
+ dispatch(updateItem(userId, 'displayName', formData.displayName, 'users'));
+ dispatch(updateDisplayName(formData.displayName));
})
- .catch(() => dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate'))));
+ .catch(() => {
+ dispatch(createDisplayNameFailure(lang.t('createdisplay.errorCreate')));
+ });
};
+
const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS});
const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error});
diff --git a/client/coral-framework/actions/items.js b/client/coral-framework/actions/items.js
index e289e9f60..692ec5648 100644
--- a/client/coral-framework/actions/items.js
+++ b/client/coral-framework/actions/items.js
@@ -203,7 +203,6 @@ export function postItem (item, type, id, mutate) {
parent_id: null
}
}).then(({data}) => {
- console.log('it workt');
console.log(data);
});
diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-framework/components/CreateDisplayNameDialog.js
index 8b61989aa..02c6eae4d 100644
--- a/client/coral-framework/components/CreateDisplayNameDialog.js
+++ b/client/coral-framework/components/CreateDisplayNameDialog.js
@@ -1,11 +1,13 @@
import React from 'react';
+import FormField from './FormField';
+import Button from 'coral-ui/components/Button';
import {Dialog} from 'coral-ui';
import styles from './styles.css';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../translations';
const lang = new I18n(translations);
-const CreateDisplayNameDialog = ({open, handleClose, offset, loggedIn}) => (
+const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSubmitDisplayName, handleChange}) => (
(
{lang.t('createdisplay.writeyourusername')}
- Logged {loggedIn}
+
+
+
{lang.t('createdisplay.yourusername')}
+
);
-//
-
export default CreateDisplayNameDialog;
diff --git a/client/coral-framework/constants/auth.js b/client/coral-framework/constants/auth.js
index 27fa8890f..a61975420 100644
--- a/client/coral-framework/constants/auth.js
+++ b/client/coral-framework/constants/auth.js
@@ -4,6 +4,10 @@ export const CLEAN_STATE = 'CLEAN_STATE';
export const SHOW_SIGNIN_DIALOG = 'SHOW_SIGNIN_DIALOG';
export const HIDE_SIGNIN_DIALOG = 'HIDE_SIGNIN_DIALOG';
+export const CREATE_DISPLAYNAME_REQUEST = 'CREATE_DISPLAYNAME_REQUEST';
+export const CREATEDISPLAYNAME_SUCCESS = 'CREATEDISPLAYNAME_SUCCESS';
+export const CREATEDISPLAYNAME_FAILURE = 'CREATEDISPLAYNAME_FAILURE';
+export const CREATE_DISPLAYNAME = 'CREATE_DISPLAYNAME';
export const SHOW_CREATEDISPLAYNAME_DIALOG = 'SHOW_CREATEDISPLAYNAME_DIALOG';
export const HIDE_CREATEDISPLAYNAME_DIALOG = 'HIDE_CREATEDISPLAYNAME_DIALOG';
@@ -35,3 +39,5 @@ export const CHECK_LOGIN_SUCCESS = 'CHECK_LOGIN_SUCCESS';
export const CHECK_LOGIN_FAILURE = 'CHECK_LOGIN_FAILURE';
export const CHECK_CSRF_TOKEN = 'CHECK_CSRF_TOKEN';
+
+export const UPDATE_DISPLAYNAME = 'UPDATE_DISPLAYNAME';
diff --git a/client/coral-framework/constants/user.js b/client/coral-framework/constants/user.js
index 9c6f508fe..57f4e706b 100644
--- a/client/coral-framework/constants/user.js
+++ b/client/coral-framework/constants/user.js
@@ -5,3 +5,4 @@ export const COMMENTS_BY_USER_REQUEST = 'COMMENTS_BY_USER_REQUEST';
export const COMMENTS_BY_USER_SUCCESS = 'COMMENTS_BY_USER_SUCCESS';
export const COMMENTS_BY_USER_FAILURE = 'COMMENTS_BY_USER_FAILURE';
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
+export const UPDATE_DISPLAYNAME = 'UPDATE_DISPLAYNAME';
diff --git a/client/coral-framework/containers/ChangeDisplayNameContainer.js b/client/coral-framework/containers/ChangeDisplayNameContainer.js
index 17e681388..e252119de 100644
--- a/client/coral-framework/containers/ChangeDisplayNameContainer.js
+++ b/client/coral-framework/containers/ChangeDisplayNameContainer.js
@@ -30,12 +30,13 @@ class ChangeDisplayNameContainer extends Component {
super(props);
this.state = this.initialState;
this.handleChange = this.handleChange.bind(this);
- this.handleSubmitForm = this.handleSubmitForm.bind(this);
+ this.handleSubmitDisplayName = this.handleSubmitDisplayName.bind(this);
this.handleClose = this.handleClose.bind(this);
this.addError = this.addError.bind(this);
}
componentDidMount() {
+ window.authCallback = this.props.facebookCallback;
const {formData} = this.state;
const errors = Object.keys(formData).reduce((map, prop) => {
map[prop] = lang.t('createdisplay.requiredField');
@@ -70,7 +71,7 @@ class ChangeDisplayNameContainer extends Component {
const {addError} = this;
if (!value.length) {
- addError(name, lang.t('displayName.requiredField'));
+ addError(name, lang.t('createdisplay.requiredField'));
} else {
const { [name]: prop, ...errors } = this.state.errors; // eslint-disable-line
// Removes Error
@@ -87,16 +88,16 @@ class ChangeDisplayNameContainer extends Component {
this.setState({showErrors: show});
}
- handleSubmitForm(e) {
+ handleSubmitDisplayName(e) {
e.preventDefault();
const {errors} = this.state;
const {validForm, invalidForm} = this.props;
this.displayErrors();
if (this.isCompleted() && !Object.keys(errors).length) {
- createDisplayName(this.state.formData);
+ this.props.createDisplayName(this.props.user.id, this.state.formData);
validForm();
} else {
- invalidForm(lang.t('signIn.checkTheForm'));
+ invalidForm(lang.t('createdisplay.checkTheForm'));
}
}
@@ -105,15 +106,16 @@ class ChangeDisplayNameContainer extends Component {
}
render() {
- const {loggedIn, auth, offset, user} = this.props;
+ const {loggedIn, auth, offset} = this.props;
return (
@@ -127,7 +129,7 @@ const mapStateToProps = state => ({
});
const mapDispatchToProps = dispatch => ({
- createDisplayName: formData => dispatch(createDisplayName(formData)),
+ createDisplayName: (userid, formData) => dispatch(createDisplayName(userid, formData)),
showCreateDisplayNameDialog: () => dispatch(showCreateDisplayNameDialog()),
hideCreateDisplayNameDialog: () => dispatch(hideCreateDisplayNameDialog()),
invalidForm: error => dispatch(invalidForm(error)),
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index ff0f72b4a..cb7b102df 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -43,6 +43,14 @@ export default function auth (state = initialState, action) {
return state.merge(Map({
showCreateDisplayNameDialog: false
}));
+ case actions.CREATEDISPLAYNAME_SUCCESS :
+ return state.merge(Map({
+ showCreateDisplayNameDialog: false,
+ error: ''
+ }));
+ case actions.CREATEDISPLAYNAME_FAILURE :
+ return state
+ .set('error', action.error);
case actions.CHANGE_VIEW :
return state
.set('error', '')
@@ -109,6 +117,9 @@ export default function auth (state = initialState, action) {
return state
.set('passwordRequestFailure', 'There was an error sending your password reset email. Please try again soon!')
.set('passwordRequestSuccess', null);
+ case actions.UPDATE_DISPLAYNAME:
+ return state
+ .merge({'user': {'displayName': action.displayName}});
default :
return state;
}
diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json
index 5900aad3e..0e191d89d 100644
--- a/client/coral-framework/translations.json
+++ b/client/coral-framework/translations.json
@@ -10,7 +10,8 @@
"displayName": "Display Name",
"save": "Save",
"requiredField": "Required field",
- "errorCreate": "Error when changing display name"
+ "errorCreate": "Error when changing display name",
+ "checkTheForm": "Invalid Form. Please, check the fields"
},
"error": {
"email": "Not a valid E-Mail",
@@ -37,9 +38,10 @@
"createdisplay": {
"writeyourusername": "Escribe tu nombre",
"yourusername": "Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.",
- "displayName": "Nombre",
+ "displayName": "Nombre a mostrar",
"save": "Guardar",
- "requiredField": "Campo necesario"
+ "requiredField": "Campo necesario",
+ "checkTheForm": "Formulario Invalido. Por favor, verifica los campos"
},
"error": {
"email": "No es un email válido",
From 282c7dc4f5ff861e46fa29173b8d00e1ce2632bd Mon Sep 17 00:00:00 2001
From: gaba
Date: Tue, 31 Jan 2017 14:04:31 -0800
Subject: [PATCH 06/77] Removes duplicate func and adds tests.
---
client/coral-embed-stream/src/Embed.js | 4 ++--
services/users.js | 26 ++++++--------------------
test/services/users.js | 19 +++++++++++++++++++
3 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index b6fee1184..1eec07213 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -98,7 +98,7 @@ class Embed extends Component {
Settings
Configure Stream
- {loggedIn && }
+ {loggedIn && user && }
{
asset.closedAt === null
@@ -130,7 +130,7 @@ class Embed extends Component {
: {asset.settings.closedMessage}
}
{!loggedIn && }
- {loggedIn && }
+ {loggedIn && user && }
{ // displayName is valid
- return UserModel.update({id}, {
- $inc: {__v: 1},
- $set: {
- displayName: displayName
- }
- });
- });
- }
-
/**
* Creates local users.
* @param {Array} users Users to create
@@ -366,14 +354,12 @@ module.exports = class UsersService {
*/
static setDisplayName(id, displayName) {
- // Check to see if that the displayName is not empty.
- if (displayName.length < 1) {
-
- // User displayName is required! Error out here.
- return Promise.reject(new Error('display name should not be empty'));
- }
-
- return UserModel.update({id}, {$set: {'displayName': displayName}});
+ return UsersService.isValidDisplayName(displayName)
+ .then((displayName) => { // displayName is valid
+ return UserModel.update(
+ {id},
+ {$set: {'displayName': displayName}});
+ });
}
/**
diff --git a/test/services/users.js b/test/services/users.js
index e2e5655e4..ba2bedcc3 100644
--- a/test/services/users.js
+++ b/test/services/users.js
@@ -178,6 +178,25 @@ describe('services.UsersService', () => {
});
});
+ describe('#setDisplayName', () => {
+ it('should set the display name to a new unique one', () => {
+ return UsersService
+ .setDisplayName(mockUsers[0].id, 'maria')
+ .then(() => UsersService.findById(mockUsers[0].id))
+ .then((user) => {
+ expect(user).to.have.property('displayName', 'maria');
+ });
+ });
+
+ it('should return an error when the displayName is not unique', () => {
+ return UsersService
+ .setDisplayName(mockUsers[0].id, 'marvel')
+ .catch((error) => {
+ expect(error).to.not.be.null;
+ });
+ });
+ });
+
describe('#ban', () => {
it('should set the status to banned', () => {
return UsersService
From 6a4315d60826fd0f2bfd4a884656cac0f1dd5fa3 Mon Sep 17 00:00:00 2001
From: Belen Curcio
Date: Wed, 1 Feb 2017 10:49:16 -0300
Subject: [PATCH 07/77] Working Install Wizard
---
client/coral-admin/src/actions/install.js | 1 +
client/coral-admin/src/constants/install.js | 1 +
.../containers/Install/InstallContainer.js | 29 +++++++++++++------
.../components/Steps/AddOrganizationName.js | 19 ++++++++++++
.../Install/components/Steps/InitialStep.js | 20 +++++++++++++
client/coral-admin/src/reducers/install.js | 3 ++
client/coral-ui/components/Wizard.js | 29 +++++++++++++++++++
client/coral-ui/index.js | 1 +
8 files changed, 94 insertions(+), 9 deletions(-)
create mode 100644 client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js
create mode 100644 client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
create mode 100644 client/coral-ui/components/Wizard.js
diff --git a/client/coral-admin/src/actions/install.js b/client/coral-admin/src/actions/install.js
index 460a36e23..abaaeceb7 100644
--- a/client/coral-admin/src/actions/install.js
+++ b/client/coral-admin/src/actions/install.js
@@ -2,3 +2,4 @@ import * as actions from '../constants/install';
export const nextStep = () => ({type: actions.NEXT_STEP});
export const previousStep = () => ({type: actions.PREVIOUS_STEP});
+export const goToStep = step => ({type: actions.GO_TO_STEP, step});
diff --git a/client/coral-admin/src/constants/install.js b/client/coral-admin/src/constants/install.js
index f15a39ed4..d33ec4657 100644
--- a/client/coral-admin/src/constants/install.js
+++ b/client/coral-admin/src/constants/install.js
@@ -1,2 +1,3 @@
export const NEXT_STEP = 'NEXT_STEP';
export const PREVIOUS_STEP = 'PREVIOUS_STEP';
+export const GO_TO_STEP = 'GO_TO_STEP';
diff --git a/client/coral-admin/src/containers/Install/InstallContainer.js b/client/coral-admin/src/containers/Install/InstallContainer.js
index de296acc0..bda32bde2 100644
--- a/client/coral-admin/src/containers/Install/InstallContainer.js
+++ b/client/coral-admin/src/containers/Install/InstallContainer.js
@@ -1,19 +1,29 @@
import React from 'react';
import {connect} from 'react-redux';
import styles from './style.css';
-import {nextStep, previousStep} from '../../actions/install'
+import {nextStep, previousStep, goToStep} from '../../actions/install';
+import {Button, Wizard} from 'coral-ui';
+
+import InitialStep from './components/Steps/InitialStep'
+import AddOrganizationName from './components/Steps/AddOrganizationName'
const InstallContainer = props => {
- const {nextStep, previousStep, install} = props;
+ const {nextStep, previousStep, goToStep, install} = props;
return (
- Install:
-
- {install.step}
-
-
Previous Step
-
Next Step
+
{install.step}
+
+
+ goToStep(0)}>Add Organization Name
+ goToStep(1)}>Create your account
+ goToStep(2)}>Invite team members
+
+
+
+
+
+
);
};
@@ -24,7 +34,8 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
nextStep: () => dispatch(nextStep()),
- previousStep: () => dispatch(previousStep())
+ previousStep: () => dispatch(previousStep()),
+ goToStep: step => dispatch(goToStep(step))
});
export default connect(mapStateToProps, mapDispatchToProps)(InstallContainer);
diff --git a/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js b/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js
new file mode 100644
index 000000000..1af4b9839
--- /dev/null
+++ b/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js
@@ -0,0 +1,19 @@
+import React from 'react';
+// import styles from './style.css';
+import {Button} from 'coral-ui';
+
+const InitialStep = props => {
+ const {nextStep, previousStep} = props;
+ return (
+
+
Welcome to the Coral Project
+
+ Please tell us the name of your organization. This will appear in emails when
+ inviting new team members
+
+
Go back
+
+ );
+};
+
+export default InitialStep;
diff --git a/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js b/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
new file mode 100644
index 000000000..9efdf4ad0
--- /dev/null
+++ b/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
@@ -0,0 +1,20 @@
+import React from 'react';
+// import styles from './style.css';
+import {Button} from 'coral-ui';
+
+const InitialStep = props => {
+ const {nextStep} = props;
+ return (
+
+
Welcome to the Coral Project
+
+ The remainder of the Talk installation will take about ten minutes.
+ Once you complete the following three steps, you will have a free
+ installation and provision of Mongo and Redis.
+
+
Get Started
+
+ );
+};
+
+export default InitialStep;
diff --git a/client/coral-admin/src/reducers/install.js b/client/coral-admin/src/reducers/install.js
index 1b9ae5b28..95febb887 100644
--- a/client/coral-admin/src/reducers/install.js
+++ b/client/coral-admin/src/reducers/install.js
@@ -15,6 +15,9 @@ export default function auth (state = initialState, action) {
case actions.PREVIOUS_STEP:
return state
.set('step', state.get('step') - 1);
+ case actions.GO_TO_STEP:
+ return state
+ .set('step', action.step);
default :
return state;
}
diff --git a/client/coral-ui/components/Wizard.js b/client/coral-ui/components/Wizard.js
new file mode 100644
index 000000000..1ba6e56a6
--- /dev/null
+++ b/client/coral-ui/components/Wizard.js
@@ -0,0 +1,29 @@
+import React, {PropTypes} from 'react';
+
+const Wizard = (props) => {
+ const {children, currentStep, nextStep, previousStep, goToStep, className = ''} = props;
+ return (
+
+ {React.Children.toArray(children)
+ .filter((child, i) => i === currentStep)
+ .map((child, i) =>
+ React.cloneElement(child, {
+ i,
+ currentStep,
+ nextStep,
+ previousStep,
+ goToStep
+ })
+ )}
+
+ );
+};
+
+Wizard.propTypes = {
+ currentStep: PropTypes.number.isRequired,
+ nextStep: PropTypes.func.isRequired,
+ previousStep: PropTypes.func.isRequired,
+ goToStep: PropTypes.func.isRequired
+}
+
+export default Wizard;
diff --git a/client/coral-ui/index.js b/client/coral-ui/index.js
index 23d5d876a..b58c2a74a 100644
--- a/client/coral-ui/index.js
+++ b/client/coral-ui/index.js
@@ -14,3 +14,4 @@ export {default as List} from './components/List';
export {default as Item} from './components/Item';
export {default as Card} from './components/Card';
export {default as Pager} from './components/Pager';
+export {default as Wizard} from './components/Wizard';
From 12070309d6bd5db9fdf5e26e702c4fb90327b559 Mon Sep 17 00:00:00 2001
From: Belen Curcio
Date: Wed, 1 Feb 2017 12:11:15 -0300
Subject: [PATCH 08/77] Wizard Nav
---
.../containers/Install/InstallContainer.js | 29 +++--
.../components/Steps/AddOrganizationName.js | 13 ++-
.../Install/components/Steps/InitialStep.js | 13 +--
.../Install/components/Steps/style.css | 30 +++++
.../src/containers/Install/style.css | 12 ++
client/coral-admin/src/reducers/install.js | 1 -
client/coral-ui/components/Wizard.js | 4 +-
client/coral-ui/components/WizardNav.css | 109 ++++++++++++++++++
client/coral-ui/components/WizardNav.js | 29 +++++
client/coral-ui/index.js | 1 +
10 files changed, 215 insertions(+), 26 deletions(-)
create mode 100644 client/coral-admin/src/containers/Install/components/Steps/style.css
create mode 100644 client/coral-ui/components/WizardNav.css
create mode 100644 client/coral-ui/components/WizardNav.js
diff --git a/client/coral-admin/src/containers/Install/InstallContainer.js b/client/coral-admin/src/containers/Install/InstallContainer.js
index bda32bde2..8ed0bbf69 100644
--- a/client/coral-admin/src/containers/Install/InstallContainer.js
+++ b/client/coral-admin/src/containers/Install/InstallContainer.js
@@ -2,24 +2,18 @@ import React from 'react';
import {connect} from 'react-redux';
import styles from './style.css';
import {nextStep, previousStep, goToStep} from '../../actions/install';
-import {Button, Wizard} from 'coral-ui';
+import {Wizard, WizardNav} from 'coral-ui';
-import InitialStep from './components/Steps/InitialStep'
-import AddOrganizationName from './components/Steps/AddOrganizationName'
+import InitialStep from './components/Steps/InitialStep';
+import AddOrganizationName from './components/Steps/AddOrganizationName';
const InstallContainer = props => {
const {nextStep, previousStep, goToStep, install} = props;
return (
-
{install.step}
-
-
- goToStep(0)}>Add Organization Name
- goToStep(1)}>Create your account
- goToStep(2)}>Invite team members
-
-
+
Welcome to the Coral Project
+ { install.step !== 0 ?
: null }
@@ -28,6 +22,19 @@ const InstallContainer = props => {
);
};
+const wizardNavitems = [{
+ text: '1. Add Organization Name',
+ step: 1
+},
+{
+ text: '2. Create your account',
+ step: 2
+},
+{
+ text: '3. Invite team members',
+ step: 3
+}];
+
const mapStateToProps = state => ({
install: state.install.toJS()
});
diff --git a/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js b/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js
index 1af4b9839..74f2c3016 100644
--- a/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js
+++ b/client/coral-admin/src/containers/Install/components/Steps/AddOrganizationName.js
@@ -1,17 +1,20 @@
import React from 'react';
-// import styles from './style.css';
+import styles from './style.css';
import {Button} from 'coral-ui';
const InitialStep = props => {
- const {nextStep, previousStep} = props;
+ const {nextStep} = props;
return (
-
-
Welcome to the Coral Project
+
Please tell us the name of your organization. This will appear in emails when
inviting new team members
-
Go back
+
);
};
diff --git a/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js b/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
index 9efdf4ad0..95043b515 100644
--- a/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
+++ b/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
@@ -1,18 +1,17 @@
import React from 'react';
-// import styles from './style.css';
+import styles from './style.css';
import {Button} from 'coral-ui';
const InitialStep = props => {
const {nextStep} = props;
return (
-
-
Welcome to the Coral Project
+
- The remainder of the Talk installation will take about ten minutes.
- Once you complete the following three steps, you will have a free
- installation and provision of Mongo and Redis.
+ The remainder of the Talk installation will take about ten minutes.
+ Once you complete the following three steps, you will have a free
+ installation and provision of Mongo and Redis.
-
Get Started
+
Get Started
);
};
diff --git a/client/coral-admin/src/containers/Install/components/Steps/style.css b/client/coral-admin/src/containers/Install/components/Steps/style.css
new file mode 100644
index 000000000..5284b3470
--- /dev/null
+++ b/client/coral-admin/src/containers/Install/components/Steps/style.css
@@ -0,0 +1,30 @@
+.step {
+
+ p {
+ max-width: 450px;
+ margin: 10px auto 30px;
+ }
+
+ > button {
+ min-width: 140px;
+ }
+
+ form {
+ max-width: 300px;
+ margin: 30px auto;
+
+ label {
+ text-align: left;
+ display: block;
+ }
+
+ input {
+ border: solid 1px rgba(0, 0, 0, 0.23);
+ padding: 10px 2px;
+ border-radius: 3px;
+ width: 100%;
+ box-sizing: border-box;
+ margin: 10px 0;
+ }
+ }
+}
diff --git a/client/coral-admin/src/containers/Install/style.css b/client/coral-admin/src/containers/Install/style.css
index e69de29bb..90c62c20e 100644
--- a/client/coral-admin/src/containers/Install/style.css
+++ b/client/coral-admin/src/containers/Install/style.css
@@ -0,0 +1,12 @@
+.Install {
+ max-width: 900px;
+ margin: 0 auto;
+ text-align: center;
+ padding: 40px 0;
+
+ h2 {
+ font-size: 2em;
+ font-weight: 500;
+ margin: 0;
+ }
+}
diff --git a/client/coral-admin/src/reducers/install.js b/client/coral-admin/src/reducers/install.js
index 95febb887..d97c7f236 100644
--- a/client/coral-admin/src/reducers/install.js
+++ b/client/coral-admin/src/reducers/install.js
@@ -9,7 +9,6 @@ const initialState = Map({
export default function auth (state = initialState, action) {
switch (action.type) {
case actions.NEXT_STEP:
- console.log(state)
return state
.set('step', state.get('step') + 1);
case actions.PREVIOUS_STEP:
diff --git a/client/coral-ui/components/Wizard.js b/client/coral-ui/components/Wizard.js
index 1ba6e56a6..e598b3c30 100644
--- a/client/coral-ui/components/Wizard.js
+++ b/client/coral-ui/components/Wizard.js
@@ -3,7 +3,7 @@ import React, {PropTypes} from 'react';
const Wizard = (props) => {
const {children, currentStep, nextStep, previousStep, goToStep, className = ''} = props;
return (
-
+
{React.Children.toArray(children)
.filter((child, i) => i === currentStep)
.map((child, i) =>
@@ -15,7 +15,7 @@ const Wizard = (props) => {
goToStep
})
)}
-
+
);
};
diff --git a/client/coral-ui/components/WizardNav.css b/client/coral-ui/components/WizardNav.css
new file mode 100644
index 000000000..12b9b3841
--- /dev/null
+++ b/client/coral-ui/components/WizardNav.css
@@ -0,0 +1,109 @@
+.WizardNav {
+ ul {
+ list-style: none;
+ }
+
+ li {
+ border: solid 1px #DFDFDF;
+ background-color: #F0F0F0;
+ display: inline-block;
+ padding: 10px;
+ margin-right: 10px;
+ color: #A7A7A7;
+ position: relative;
+ padding-left: 40px;
+
+ &:hover {
+ cursor: pointer;
+ }
+
+ &.active {
+ background-color: #FFFFFF;
+ color: #636363;
+ font-weight: 500;
+
+ span {
+ &::after {
+ border-color: transparent transparent transparent #FFFFFF;
+ }
+ }
+ }
+
+ span {
+ padding: 10px 20px;
+ margin-right: 10px;
+ position: absolute;
+ top: -1px;
+ right: -51px;
+ z-index: 10;
+
+ &::before {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ border: 23px solid #DFDFDF;
+ border-color: transparent transparent transparent #DFDFDF;
+ top: 0;
+ left: 0;
+ }
+
+ &::after {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ border: 23px solid white;
+ border-color: transparent transparent transparent #f0f0f0;
+ top: 0;
+ left: -1px;
+ }
+ }
+
+ &::before {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ border: 23px solid #DFDFDF;
+ border-color: transparent transparent transparent #DFDFDF;
+ top: 0;
+ left: 0;
+ }
+
+ &::after {
+ content: "";
+ display: inline-block;
+ position: absolute;
+ border: 23px solid white;
+ border-color: transparent transparent transparent #fafafa;
+ top: 0;
+ left: -1px;
+ }
+/*
+ &::before {
+ position: absolute;
+ top: 0;
+ left: -1px;
+ display: block;
+ border-left: 23px solid white;
+ border-top: 23px solid transparent;
+ border-bottom: 23px solid transparent;
+ width: 0;
+ height: 0;
+ content: " ";
+ }
+
+ &::after{
+ z-index: 1;
+ position: absolute;
+ top: 0;
+ right: -23px;
+ display: block;
+ border-left: 23px solid #f0f0f0;
+ border-top: 23px solid transparent;
+ border-bottom: 23px solid transparent;
+ width: 0;
+ height: 0;
+ content: " ";
+ }*/
+
+ }
+}
diff --git a/client/coral-ui/components/WizardNav.js b/client/coral-ui/components/WizardNav.js
new file mode 100644
index 000000000..200adb216
--- /dev/null
+++ b/client/coral-ui/components/WizardNav.js
@@ -0,0 +1,29 @@
+import React, {PropTypes} from 'react';
+import styles from './WizardNav.css';
+
+const WizardNav = props => {
+ const {goToStep, currentStep, items} = props;
+ return (
+
+
+ {
+ items.map((item, i) => (
+ goToStep(item.step)}>
+ {item.text}
+
+ ))
+ }
+
+
+ );
+};
+
+WizardNav.propTypes = {
+ goToStep: PropTypes.func.isRequired,
+ currentStep: PropTypes.number.isRequired
+};
+
+export default WizardNav;
diff --git a/client/coral-ui/index.js b/client/coral-ui/index.js
index b58c2a74a..69f63e397 100644
--- a/client/coral-ui/index.js
+++ b/client/coral-ui/index.js
@@ -15,3 +15,4 @@ export {default as Item} from './components/Item';
export {default as Card} from './components/Card';
export {default as Pager} from './components/Pager';
export {default as Wizard} from './components/Wizard';
+export {default as WizardNav} from './components/WizardNav';
From caa04de09df4c41b47c8e58301ce37889c5ab351 Mon Sep 17 00:00:00 2001
From: Belen Curcio
Date: Wed, 1 Feb 2017 12:12:28 -0300
Subject: [PATCH 09/77] linting and proptypes
---
client/coral-ui/components/Wizard.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/client/coral-ui/components/Wizard.js b/client/coral-ui/components/Wizard.js
index e598b3c30..429bce72c 100644
--- a/client/coral-ui/components/Wizard.js
+++ b/client/coral-ui/components/Wizard.js
@@ -1,7 +1,7 @@
import React, {PropTypes} from 'react';
const Wizard = (props) => {
- const {children, currentStep, nextStep, previousStep, goToStep, className = ''} = props;
+ const {children, currentStep, nextStep, previousStep, goToStep} = props;
return (
{React.Children.toArray(children)
@@ -24,6 +24,6 @@ Wizard.propTypes = {
nextStep: PropTypes.func.isRequired,
previousStep: PropTypes.func.isRequired,
goToStep: PropTypes.func.isRequired
-}
+};
export default Wizard;
From 6c01a37f6ab2c5ac20ef5c1caad66e934180dbc9 Mon Sep 17 00:00:00 2001
From: David Jay
Date: Wed, 1 Feb 2017 11:48:16 -0500
Subject: [PATCH 10/77] Removing user bio.
---
client/coral-embed-stream/src/Comment.js | 9 +--
client/coral-plugin-author-name/AuthorName.js | 27 +++++----
.../coral-settings/components/NotLoggedIn.js | 1 -
.../containers/SettingsContainer.js | 55 ++++++++++---------
4 files changed, 46 insertions(+), 46 deletions(-)
diff --git a/client/coral-embed-stream/src/Comment.js b/client/coral-embed-stream/src/Comment.js
index 529420941..a2a4c4c6e 100644
--- a/client/coral-embed-stream/src/Comment.js
+++ b/client/coral-embed-stream/src/Comment.js
@@ -92,14 +92,7 @@ class Comment extends React.Component {
style={{marginLeft: depth * 30}}>
diff --git a/client/coral-settings/containers/SettingsContainer.js b/client/coral-settings/containers/SettingsContainer.js
index f02badd80..4398ed5c6 100644
--- a/client/coral-settings/containers/SettingsContainer.js
+++ b/client/coral-settings/containers/SettingsContainer.js
@@ -4,12 +4,10 @@ import React, {Component} from 'react';
import I18n from 'coral-framework/modules/i18n/i18n';
import {myCommentHistory} from 'coral-framework/graphql/queries';
-import {saveBio} from 'coral-framework/actions/user';
-import BioContainer from './BioContainer';
import {link} from 'coral-framework/PymConnection';
import NotLoggedIn from '../components/NotLoggedIn';
-import {TabBar, Tab, TabContent, Spinner} from 'coral-ui';
+import {Spinner} from 'coral-ui';
import SettingsHeader from '../components/SettingsHeader';
import CommentHistory from 'coral-plugin-history/CommentHistory';
@@ -33,8 +31,7 @@ class SettingsContainer extends Component {
}
render() {
- const {loggedIn, userData, asset, showSignInDialog, data, user} = this.props;
- const {activeTab} = this.state;
+ const {loggedIn, asset, showSignInDialog, data} = this.props;
const {me} = this.props.data;
if (!loggedIn || !me) {
@@ -48,25 +45,30 @@ class SettingsContainer extends Component {
return (
-
- {lang.t('allComments')} ({user.myComments.length})
- {lang.t('profileSettings')}
-
-
- {
- me.comments.length ?
-
- :
- {lang.t('userNoComment')}
- }
-
-
-
-
+ {
+
+ // Hiding bio until moderation can get figured out
+ /*
+ {lang.t('allComments')} ({user.myComments.length})
+ {lang.t('profileSettings')}
+
+
*/
+ me.comments.length ?
+
+ :
+ {lang.t('userNoComment')}
+
+ // Hiding user bio pending effective moderation system.
+ /*
+
+
+ */
+ }
+
);
}
@@ -78,8 +80,9 @@ const mapStateToProps = state => ({
auth: state.auth.toJS()
});
-const mapDispatchToProps = dispatch => ({
- saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData))
+const mapDispatchToProps = () => ({
+
+ // saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData))
});
export default compose(
From 37975574ea0f214b1097134dc2962055b8f00671 Mon Sep 17 00:00:00 2001
From: David Jay
Date: Wed, 1 Feb 2017 12:26:01 -0500
Subject: [PATCH 11/77] Switching rejected usernames from suspended to banned.
---
.../src/containers/ModerationQueue/ModerationContainer.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js
index eef855df6..aa754b4ac 100644
--- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js
+++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js
@@ -118,7 +118,7 @@ const mapDispatchToProps = dispatch => {
userStatusUpdate: (status, userId, commentId) => dispatch(userStatusUpdate(status, userId, commentId)).then(() => {
dispatch(fetchModerationQueueComments());
}),
- suspendUser: (userId, subject, text) => dispatch(userStatusUpdate('suspended', userId))
+ suspendUser: (userId, subject, text) => dispatch(userStatusUpdate('BANNED', userId))
.then(() => dispatch(sendNotificationEmail(userId, subject, text)))
.then(() => dispatch(fetchModerationQueueComments()))
,
From 7866d1f8cdd79f6591edbad6cb25d96d4a90bd29 Mon Sep 17 00:00:00 2001
From: Belen Curcio
Date: Wed, 1 Feb 2017 15:17:15 -0300
Subject: [PATCH 12/77] Done Wizard mEnu
---
client/coral-admin/src/AppRouter.js | 18 ++++----
.../coral-admin/src/components/ui/Header.js | 35 ++++++++++-----
.../containers/Install/InstallContainer.js | 25 +++++++----
.../components/Steps/CreateYourAccount.js | 32 +++++++++++++
.../Install/components/Steps/FinalStep.js | 19 ++++++++
.../components/Steps/InviteTeamMembers.js | 35 +++++++++++++++
.../Install/components/Steps/style.css | 5 +++
client/coral-ui/components/WizardNav.css | 45 +++++++------------
client/coral-ui/components/WizardNav.js | 2 +-
9 files changed, 158 insertions(+), 58 deletions(-)
create mode 100644 client/coral-admin/src/containers/Install/components/Steps/CreateYourAccount.js
create mode 100644 client/coral-admin/src/containers/Install/components/Steps/FinalStep.js
create mode 100644 client/coral-admin/src/containers/Install/components/Steps/InviteTeamMembers.js
diff --git a/client/coral-admin/src/AppRouter.js b/client/coral-admin/src/AppRouter.js
index ebb79b4e1..bebe6a19b 100644
--- a/client/coral-admin/src/AppRouter.js
+++ b/client/coral-admin/src/AppRouter.js
@@ -10,14 +10,16 @@ import LayoutContainer from 'containers/LayoutContainer';
import InstallContainer from 'containers/Install/InstallContainer';
const routes = (
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
);
const AppRouter = () => ;
diff --git a/client/coral-admin/src/components/ui/Header.js b/client/coral-admin/src/components/ui/Header.js
index 4e2b391c8..abfb0ff13 100644
--- a/client/coral-admin/src/components/ui/Header.js
+++ b/client/coral-admin/src/components/ui/Header.js
@@ -6,19 +6,32 @@ import I18n from 'coral-framework/modules/i18n/i18n';
import translations from '../../translations.json';
import {Logo} from './Logo';
-export default ({handleLogout}) => (
+export default ({handleLogout, restricted = false}) => (
From e3da45daeb59523db9f3a17c4270f2696e0007b8 Mon Sep 17 00:00:00 2001
From: David Jay
Date: Wed, 1 Feb 2017 16:38:01 -0500
Subject: [PATCH 21/77] Displaying appropriate suspension message.
---
client/coral-embed-stream/src/Embed.js | 8 +++++++-
client/coral-framework/components/SuspendedAccount.js | 8 ++++++--
client/coral-framework/translations.json | 6 ++++--
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index 2a7057cca..b57bc799f 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -96,6 +96,8 @@ class Embed extends Component {
const openStream = closedAt === null;
+ const banned = user && user.status === 'BANNED';
+
const expandForLogin = showSignInDialog ? {
minHeight: document.body.scrollHeight + 200
} : {};
@@ -118,7 +120,11 @@ class Embed extends Component {
content={asset.settings.infoBoxContent}
enable={asset.settings.infoBoxEnable}
/>
- }>
+
+ }>
{
user
? (
+export default ({canEditName}) => (
- {lang.t('suspendedAccountMsg')}
+ {
+ canEditName ?
+ lang.t('editNameMsg')
+ : lang.t('bannedAccountMsg')
+ }
);
diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json
index 5bf9b40a9..a61213aab 100644
--- a/client/coral-framework/translations.json
+++ b/client/coral-framework/translations.json
@@ -3,7 +3,8 @@
"successUpdateSettings": "The changes you have made have been applied to the comment stream on this article",
"successBioUpdate": "Your Bio has been updated",
"contentNotAvailable": "This content is not available",
- "suspendedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
+ "bannedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
+ "editNameMsg": "Your account is currently suspended because your username has been deemed inappropriate. To restore your account, please enter a new username. You may contact moderator@fakeurl.com for more information.",
"error": {
"email": "Not a valid E-Mail",
"password": "Password must be at least 8 characters",
@@ -25,7 +26,8 @@
"successUpdateSettings": "La configuración de este articulo fue actualizada",
"successBioUpdate": "Tu bio fue actualizada",
"contentNotAvailable": "El contenido no se encuentra disponible",
- "suspendedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information",
+ "bannedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information",
+ "editNameMsg": "",
"error": {
"email": "No es un email válido",
"password": "La contraseña debe tener por lo menos 8 caracteres",
From 445eb97d7647dd25fa35e01980d1234e2c8a4679 Mon Sep 17 00:00:00 2001
From: gaba
Date: Wed, 1 Feb 2017 14:00:09 -0800
Subject: [PATCH 22/77] Moves create displayname dialog to sign-in plugin.
---
client/coral-embed-stream/src/Embed.js | 2 +-
client/coral-framework/actions/auth.js | 6 +-
client/coral-framework/components/Alert.js | 13 --
.../coral-framework/components/FormField.js | 18 ---
client/coral-framework/components/styles.css | 140 ------------------
client/coral-framework/translations.json | 20 ---
.../components/CreateDisplayNameDialog.js | 6 +-
.../containers/ChangeDisplayNameContainer.js | 0
client/coral-sign-in/translations.js | 24 ++-
9 files changed, 29 insertions(+), 200 deletions(-)
delete mode 100644 client/coral-framework/components/Alert.js
delete mode 100644 client/coral-framework/components/FormField.js
delete mode 100644 client/coral-framework/components/styles.css
rename client/{coral-framework => coral-sign-in}/components/CreateDisplayNameDialog.js (84%)
rename client/{coral-framework => coral-sign-in}/containers/ChangeDisplayNameContainer.js (100%)
diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index a5011f853..43b4eecae 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -19,7 +19,7 @@ import Count from 'coral-plugin-comment-count/CommentCount';
import CommentBox from 'coral-plugin-commentbox/CommentBox';
import UserBox from '../../coral-sign-in/components/UserBox';
import SignInContainer from '../../coral-sign-in/containers/SignInContainer';
-import ChangeDisplayNameContainer from '../../coral-framework/containers/ChangeDisplayNameContainer';
+import ChangeDisplayNameContainer from '../../coral-sign-in/containers/ChangeDisplayNameContainer';
import SuspendedAccount from '../../coral-framework/components/SuspendedAccount';
import SettingsContainer from '../../coral-settings/containers/SettingsContainer';
import RestrictedContent from '../../coral-framework/components/RestrictedContent';
diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js
index bd3b81fdf..914b88095 100644
--- a/client/coral-framework/actions/auth.js
+++ b/client/coral-framework/actions/auth.js
@@ -12,6 +12,9 @@ export const createDisplayNameRequest = () => ({type: actions.CREATE_DISPLAYNAME
export const showCreateDisplayNameDialog = () => ({type: actions.SHOW_CREATEDISPLAYNAME_DIALOG});
export const hideCreateDisplayNameDialog = () => ({type: actions.HIDE_CREATEDISPLAYNAME_DIALOG});
+const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS});
+const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error});
+
export const updateDisplayName = displayName => ({type: actions.UPDATE_DISPLAYNAME, displayName});
export const createDisplayName = (userId, formData) => dispatch => {
@@ -27,9 +30,6 @@ export const createDisplayName = (userId, formData) => dispatch => {
});
};
-const createDisplayNameSuccess = () => ({type: actions.CREATEDISPLAYNAME_SUCCESS});
-const createDisplayNameFailure = error => ({type: actions.CREATEDISPLAYNAME_FAILURE, error});
-
export const changeView = view => dispatch =>
dispatch({
type: actions.CHANGE_VIEW,
diff --git a/client/coral-framework/components/Alert.js b/client/coral-framework/components/Alert.js
deleted file mode 100644
index 019c3456a..000000000
--- a/client/coral-framework/components/Alert.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import React from 'react';
-import styles from './styles.css';
-
-const Alert = ({cStyle = 'error', children, className, ...props}) => (
-
- {children}
-
-);
-
-export default Alert;
diff --git a/client/coral-framework/components/FormField.js b/client/coral-framework/components/FormField.js
deleted file mode 100644
index ceb2d939e..000000000
--- a/client/coral-framework/components/FormField.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import styles from './styles.css';
-
-const FormField = ({className, showErrors = false, errorMsg, label, ...props}) => (
-
-
- {label}
-
-
- {showErrors && errorMsg && ! {errorMsg} }
-
-);
-
-export default FormField;
diff --git a/client/coral-framework/components/styles.css b/client/coral-framework/components/styles.css
deleted file mode 100644
index f9d0aec6d..000000000
--- a/client/coral-framework/components/styles.css
+++ /dev/null
@@ -1,140 +0,0 @@
-.dialog {
- border: none;
- box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
- width: 280px;
- top: 10px;
-}
-
-.header {
- margin-bottom: 20px;
-}
-
-.header h1, .separator h1{
- text-align: center;
- font-size: 1.2em;
-}
-
-.formField {
- margin-top: 15px;
-}
-
-.formField label {
- font-size: 1.08em;
- font-weight: bold;
- margin-bottom: 5px;
-}
-
-.formField input {
- width: 100%;
- display: block;
- border: none;
- outline: none;
- border: 1px solid rgba(0,0,0,.12);
- padding: 10px 6px;
- box-sizing: border-box;
- border-radius: 2px;
- margin: 5px auto;
-}
-
-.footer {
- margin: 20px auto 10px;
- text-align: center;
-}
-
-.footer span {
- display: block;
- margin-bottom: 5px;
-}
-
-.footer a {
- color: #2c69b6;
- cursor: pointer;
- margin: 0 5px;
-}
-
-.socialConnections {
- margin-bottom: 20px;
-}
-
-.signInButton {
- margin-top: 10px;
-}
-
-.close {
- font-size: 20px;
- line-height: 14px;
- top: 10px;
- right: 10px;
- position: absolute;
- display: block;
- font-weight: bold;
- color: #363636;
- cursor: pointer;
-}
-
-.close:hover {
- color: #6b6b6b;
-}
-
-input.error{
- border: solid 2px #f44336;
-}
-
-.errorMsg, .hint {
- color: grey;
- font-weight: 600;
- padding: 3px 0 16px;
-}
-
-.alert {
- padding: 10px;
- margin-bottom: 20px;
- border-radius: 2px;
-}
-
-.alert--success {
- border: solid 1px #1ec00e;
- background: #cbf1b8;
- color: #006900;
-}
-
-.alert--error {
- background: #FFEBEE;
- color: #B71C1C;
-}
-
-.userBox {
- padding: 10px 0 20px;
- letter-spacing: 0.1px;
-}
-
-.userBox a {
- color: black;
- font-weight: bold;
- cursor: pointer;
- margin: 0px;
- margin-left: 4px;
- padding-bottom: 2px;
- border-bottom: solid 1px black;
-}
-
-.attention {
- display: inline-block;
- width: 15px;
- height: 15px;
- background: #B71C1C;
- color: #FFEBEE;
- font-weight: bolder;
- padding: 4px;
- vertical-align: middle;
- border-radius: 20px;
- box-sizing: border-box;
- font-size: 9px;
- line-height: 7px;
- text-align: center;
- margin-right: 5px;
-}
-
-.action {
- margin-top: 15px;
-}
diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json
index 88886f8d1..07b719f6b 100644
--- a/client/coral-framework/translations.json
+++ b/client/coral-framework/translations.json
@@ -4,16 +4,6 @@
"successBioUpdate": "Your Bio has been updated",
"contentNotAvailable": "This content is not available",
"suspendedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
- "createdisplay": {
- "writeyourusername": "Write your username",
- "yourusername": "Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.",
- "displayName": "Display Name",
- "save": "Save",
- "requiredField": "Required field",
- "errorCreate": "Error when changing display name",
- "checkTheForm": "Invalid Form. Please, check the fields",
- "specialCharacters": "Display names can contain letters, numbers and _ only"
- },
"error": {
"emailNotVerified": "Email address {0} not verified.",
"email": "Not a valid E-Mail",
@@ -37,16 +27,6 @@
"successBioUpdate": "Tu bio fue actualizada",
"contentNotAvailable": "El contenido no se encuentra disponible",
"suspendedAccountMsg": "Tu cuenta se encuentra suspendida. Esto significa que no puedes dar Like, Marcar o escribir commentarios. Por favor, contacta moderator@fakeurl for more information",
- "createdisplay": {
- "writeyourusername": "Escribe tu nombre",
- "yourusername": "Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.",
- "displayName": "Nombre a mostrar",
- "save": "Guardar",
- "requiredField": "Campo necesario",
- "errorCreate": "Hubo un error al cambiar el nombre de usuario",
- "checkTheForm": "Formulario Invalido. Por favor, verifica los campos",
- "specialCharacters": "Sólo pueden contener letras, números y _"
- },
"error": {
"emailNotVerified": "Dirección de correo electrónico {0} no verificada.",
"email": "No es un email válido",
diff --git a/client/coral-framework/components/CreateDisplayNameDialog.js b/client/coral-sign-in/components/CreateDisplayNameDialog.js
similarity index 84%
rename from client/coral-framework/components/CreateDisplayNameDialog.js
rename to client/coral-sign-in/components/CreateDisplayNameDialog.js
index ee3e133e6..4d8ef9fb3 100644
--- a/client/coral-framework/components/CreateDisplayNameDialog.js
+++ b/client/coral-sign-in/components/CreateDisplayNameDialog.js
@@ -1,5 +1,5 @@
import React from 'react';
-import FormField from './FormField';
+import FormField from 'coral-ui/components/FormField';
import Alert from './Alert';
import Button from 'coral-ui/components/Button';
import {Dialog} from 'coral-ui';
@@ -25,7 +25,7 @@ const CreateDisplayNameDialog = ({open, handleClose, offset, formData, handleSub
-
{lang.t('createdisplay.yourusername')}
+
{lang.t('createdisplay.yourusername')}
{ props.auth.error &&
{props.auth.error} }
- { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} }
+ { props.errors.displayName && {lang.t('createdisplay.specialCharacters')} }
{lang.t('createdisplay.save')}
diff --git a/client/coral-framework/containers/ChangeDisplayNameContainer.js b/client/coral-sign-in/containers/ChangeDisplayNameContainer.js
similarity index 100%
rename from client/coral-framework/containers/ChangeDisplayNameContainer.js
rename to client/coral-sign-in/containers/ChangeDisplayNameContainer.js
diff --git a/client/coral-sign-in/translations.js b/client/coral-sign-in/translations.js
index 137141d34..5751370a6 100644
--- a/client/coral-sign-in/translations.js
+++ b/client/coral-sign-in/translations.js
@@ -26,7 +26,17 @@ export default {
passwordsDontMatch: 'Passwords don\'t match.',
specialCharacters: 'Display names can contain letters, numbers and _ only',
checkTheForm: 'Invalid Form. Please, check the fields'
- }
+ },
+ 'createdisplay': {
+ writeyourusername: 'Write your username',
+ yourusername: 'Your username is publicly visible on all comments you post. A username is needed before you can post your first comment.',
+ displayName: 'Display Name',
+ save: 'Save',
+ requiredField: 'Required field',
+ errorCreate: 'Error when changing display name',
+ checkTheForm: 'Invalid Form. Please, check the fields',
+ specialCharacters: 'Display names can contain letters, numbers and _ only'
+ },
},
es: {
'signIn': {
@@ -55,6 +65,16 @@ export default {
passwordsDontMatch: 'Las contraseñas no coinciden',
specialCharacters: 'Los nombres pueden contener letras, números y _',
checkTheForm: 'Formulario Inválido. Por favor, completa los campos'
- }
+ },
+ 'createdisplay': {
+ writeyourusername: 'Escribe tu nombre',
+ yourusername: 'Tu nombre es visible publicamente en todos los comentarios que publiques. Es necesario tener un nombre de usuario antes de poder publicar tu primer comentario.',
+ displayName: 'Nombre a mostrar',
+ save: 'Guardar',
+ requiredField: 'Campo necesario',
+ errorCreate: 'Hubo un error al cambiar el nombre de usuario',
+ checkTheForm: 'Formulario Invalido. Por favor, verifica los campos',
+ specialCharacters: 'Sólo pueden contener letras, números y _'
+ },
}
};
From d703cc21681cf7d0d7e55e4baf44d8520e3a738d Mon Sep 17 00:00:00 2001
From: David Jay
Date: Wed, 1 Feb 2017 19:53:37 -0500
Subject: [PATCH 23/77] Prompting user to update name when banned.
---
client/coral-embed-stream/src/Embed.js | 3 +
client/coral-framework/actions/user.js | 16 +---
.../components/RestrictedContent.css | 10 +++
.../components/SuspendedAccount.js | 82 +++++++++++++++++--
client/coral-framework/constants/user.js | 6 +-
client/coral-framework/translations.json | 9 +-
graph/mutators/index.js | 2 -
graph/mutators/user.js | 31 -------
graph/typeDefs.graphql | 2 +-
models/user.js | 2 +-
routes/api/account/index.js | 10 ++-
routes/api/users/index.js | 2 +-
services/users.js | 7 +-
test/services/users.js | 16 ++--
14 files changed, 123 insertions(+), 75 deletions(-)
delete mode 100644 graph/mutators/user.js
diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js
index b57bc799f..ceec3f1a9 100644
--- a/client/coral-embed-stream/src/Embed.js
+++ b/client/coral-embed-stream/src/Embed.js
@@ -11,6 +11,7 @@ const {fetchAssetSuccess} = assetActions;
import {queryStream} from 'coral-framework/graphql/queries';
import {postComment, postAction, deleteAction} from 'coral-framework/graphql/mutations';
+import {editName} from 'coral-framework/actions/user';
import {Notification, notificationActions, authActions, assetActions, pym} from 'coral-framework';
import Stream from './Stream';
@@ -123,6 +124,7 @@ class Embed extends Component {
}>
{
@@ -200,6 +202,7 @@ const mapDispatchToProps = dispatch => ({
loadAsset: (asset) => dispatch(fetchAssetSuccess(asset)),
addNotification: (type, text) => dispatch(addNotification(type, text)),
clearNotification: () => dispatch(clearNotification()),
+ editName: (displayName) => dispatch(editName(displayName)),
showSignInDialog: (offset) => dispatch(showSignInDialog(offset)),
logout: () => dispatch(logout()),
dispatch: d => dispatch(d)
diff --git a/client/coral-framework/actions/user.js b/client/coral-framework/actions/user.js
index 4620262d3..42d2e0398 100644
--- a/client/coral-framework/actions/user.js
+++ b/client/coral-framework/actions/user.js
@@ -1,4 +1,3 @@
-import * as actions from '../constants/user';
import {addNotification} from '../actions/notification';
import coralApi from '../helpers/response';
@@ -6,16 +5,9 @@ import I18n from 'coral-framework/modules/i18n/i18n';
import translations from './../translations';
const lang = new I18n(translations);
-const saveBioRequest = () => ({type: actions.SAVE_BIO_REQUEST});
-const saveBioSuccess = settings => ({type: actions.SAVE_BIO_SUCCESS, settings});
-const saveBioFailure = error => ({type: actions.SAVE_BIO_FAILURE, error});
-
-export const saveBio = (user_id, formData) => dispatch => {
- dispatch(saveBioRequest());
- coralApi('/account/settings', {method: 'PUT', body: formData})
+export const editName = (displayName) => (dispatch) => {
+ return coralApi('/account/displayname', {method: 'PUT', body: {displayName}})
.then(() => {
- dispatch(addNotification('success', lang.t('successBioUpdate')));
- dispatch(saveBioSuccess(formData));
- })
- .catch(error => dispatch(saveBioFailure(error)));
+ dispatch(addNotification('success', lang.t('successNameUpdate')));
+ });
};
diff --git a/client/coral-framework/components/RestrictedContent.css b/client/coral-framework/components/RestrictedContent.css
index 47ced7b0b..ca5a6517c 100644
--- a/client/coral-framework/components/RestrictedContent.css
+++ b/client/coral-framework/components/RestrictedContent.css
@@ -2,3 +2,13 @@
background: #D8D8D8;
padding: 25px;
}
+
+.editNameInput {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.alert {
+ margin-top: 10px;
+ color: #B71C1C;
+}
diff --git a/client/coral-framework/components/SuspendedAccount.js b/client/coral-framework/components/SuspendedAccount.js
index e6c53d038..0c6347fca 100644
--- a/client/coral-framework/components/SuspendedAccount.js
+++ b/client/coral-framework/components/SuspendedAccount.js
@@ -1,15 +1,79 @@
-import React from 'react';
+import React, {Component, PropTypes} from 'react';
import I18n from 'coral-framework/modules/i18n/i18n';
import translations from 'coral-framework/translations.json';
const lang = new I18n(translations);
import styles from './RestrictedContent.css';
+import {Button} from 'coral-ui';
+import validate from '../helpers/validate';
-export default ({canEditName}) => (
-
-
{
+class SuspendedAccount extends Component {
+
+ static propTypes = {
+ canEditName: PropTypes.bool,
+ editName: PropTypes.func.isRequired
+ }
+
+ state = {
+ displayName: '',
+ alert: ''
+ }
+
+ onSubmitClick = (e) => {
+ const {editName} = this.props;
+ const {displayName} = this.state;
+ e.preventDefault();
+ if (validate.displayName(displayName)) {
+ editName(displayName)
+ .then(() => window.reload())
+ .catch((error) => {
+ this.setState({alert: lang.t(`error.${error.message}`)});
+ });
+ } else {
+ this.setState({alert: lang.t('editName.error')});
+ }
+
+ }
+
+ render () {
+ const {canEditName} = this.props;
+ const {displayName, alert} = this.state;
+
+ return
+ {
+ canEditName ?
+ lang.t('editName.msg')
+ : lang.t('bannedAccountMsg')
+ }
+ {
canEditName ?
- lang.t('editNameMsg')
- : lang.t('bannedAccountMsg')
- }
-
-);
+
+
+ {alert}
+
+
+ {lang.t('editName.label')}
+
+
this.setState({displayName: e.target.value})}
+ rows={3}/>
+
+ {
+ lang.t('editName.button')
+ }
+
+
: null
+ }
+ ;
+ }
+}
+
+export default SuspendedAccount;
diff --git a/client/coral-framework/constants/user.js b/client/coral-framework/constants/user.js
index 9c6f508fe..a8e4585db 100644
--- a/client/coral-framework/constants/user.js
+++ b/client/coral-framework/constants/user.js
@@ -1,6 +1,6 @@
-export const SAVE_BIO_REQUEST = 'SAVE_BIO_REQUEST';
-export const SAVE_BIO_SUCCESS = 'SAVE_BIO_SUCCESS';
-export const SAVE_BIO_FAILURE = 'SAVE_BIO_FAILURE';
+export const EDIT_NAME_REQUEST = 'EDIT_NAME_REQUEST';
+export const EDIT_NAME_SUCCESS = 'EDIT_NAME_SUCCESS';
+export const EDIT_NAME_FAILURE = 'EDIT_NAME_FAILURE';
export const COMMENTS_BY_USER_REQUEST = 'COMMENTS_BY_USER_REQUEST';
export const COMMENTS_BY_USER_SUCCESS = 'COMMENTS_BY_USER_SUCCESS';
export const COMMENTS_BY_USER_FAILURE = 'COMMENTS_BY_USER_FAILURE';
diff --git a/client/coral-framework/translations.json b/client/coral-framework/translations.json
index a61213aab..80e865f8e 100644
--- a/client/coral-framework/translations.json
+++ b/client/coral-framework/translations.json
@@ -1,10 +1,15 @@
{
"en": {
"successUpdateSettings": "The changes you have made have been applied to the comment stream on this article",
- "successBioUpdate": "Your Bio has been updated",
+ "successNameUpdate": "Your display name has been updated",
"contentNotAvailable": "This content is not available",
"bannedAccountMsg": "Your account is currently suspended. This means that you cannot Like, Flag, or write comments. Please contact moderator@fakeurl.com for more information",
- "editNameMsg": "Your account is currently suspended because your username has been deemed inappropriate. To restore your account, please enter a new username. You may contact moderator@fakeurl.com for more information.",
+ "editName": {
+ "msg": "Your account is currently suspended because your display name has been deemed inappropriate. To restore your account, please enter a new username. You may contact moderator@fakeurl.com for more information.",
+ "label": "New Display Name",
+ "button": "Submit",
+ "error": "Display names can contain letters, numbers and _ only"
+ },
"error": {
"email": "Not a valid E-Mail",
"password": "Password must be at least 8 characters",
diff --git a/graph/mutators/index.js b/graph/mutators/index.js
index b799cf83d..58d0ed62c 100644
--- a/graph/mutators/index.js
+++ b/graph/mutators/index.js
@@ -2,7 +2,6 @@ const _ = require('lodash');
const Comment = require('./comment');
const Action = require('./action');
-const User = require('./user');
module.exports = (context) => {
@@ -10,7 +9,6 @@ module.exports = (context) => {
return _.merge(...[
Comment,
Action,
- User,
].map((mutators) => {
// Each set of mutators is a function which takes the context.
diff --git a/graph/mutators/user.js b/graph/mutators/user.js
deleted file mode 100644
index 96049bbab..000000000
--- a/graph/mutators/user.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const UsersService = require('../../services/users');
-
-/**
- * Updates a users settings.
- * @param {Object} user the user performing the request
- * @param {String} bio the new user bio
- * @return {Promise}
- */
-const updateUserSettings = ({user}, {bio}) => {
- return UsersService.updateSettings(user.id, {bio});
-};
-
-module.exports = (context) => {
-
- // TODO: refactor to something that'll return an error in the event an attempt
- // is made to mutate state while not logged in. There's got to be a better way
- // to do this.
- if (context.user && context.user.can('mutation:updateUserSettings')) {
- return {
- User: {
- updateSettings: (settings) => updateUserSettings(context, settings)
- }
- };
- }
-
- return {
- User: {
- updateSettings: () => {}
- }
- };
-};
diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql
index 1c1470f58..b1f9b82f7 100644
--- a/graph/typeDefs.graphql
+++ b/graph/typeDefs.graphql
@@ -145,7 +145,7 @@ type Asset {
# The scraped title of the asset.
title: String
- # The URL that the asset is locaed on.
+ # The URL that the asset is located on.
url: String
# The top level comments that are attached to the asset.
diff --git a/models/user.js b/models/user.js
index 7de99d211..e5db70ea6 100644
--- a/models/user.js
+++ b/models/user.js
@@ -146,7 +146,7 @@ const USER_GRAPH_OPERATIONS = [
'mutation:createComment',
'mutation:createAction',
'mutation:deleteAction',
- 'mutation:updateUserSettings'
+ 'mutation:editName'
];
/**
diff --git a/routes/api/account/index.js b/routes/api/account/index.js
index 4dd6add7c..b08bdfc2e 100644
--- a/routes/api/account/index.js
+++ b/routes/api/account/index.js
@@ -117,11 +117,17 @@ router.put('/password/reset', (req, res, next) => {
router.put('/displayname', authorization.needed(), (req, res, next) => {
UsersService
- .editUsername(req.user.id, req.body.displayName)
+ .editName(req.user.id, req.body.displayName)
.then(() => {
res.status(204).end();
})
- .catch(next);
+ .catch(error => {
+ if (error.code === 11000) {
+ next(errors.ErrDisplayTaken);
+ } else {
+ next(error);
+ }
+ });
});
module.exports = router;
diff --git a/routes/api/users/index.js b/routes/api/users/index.js
index 8b22adb36..5d1783cfe 100644
--- a/routes/api/users/index.js
+++ b/routes/api/users/index.js
@@ -59,7 +59,7 @@ router.post('/:user_id/status', authorization.needed('ADMIN'), (req, res, next)
router.post('/:user_id/username-enable', authorization.needed('ADMIN'), (req, res, next) => {
UsersService
- .toggleUsernameEdit(req.params.user_id, true)
+ .toggleNameEdit(req.params.user_id, true)
.then(() => {
res.status(204).end();
})
diff --git a/services/users.js b/services/users.js
index 42278f1c4..ec0967c3b 100644
--- a/services/users.js
+++ b/services/users.js
@@ -619,7 +619,7 @@ module.exports = class UsersService {
* @param {Boolean} canEditName sets whether the user can edit their name.
* @return {Promise}
*/
- static toggleUsernameEdit(id, canEditName) {
+ static toggleNameEdit(id, canEditName) {
return UserModel.update({id}, {
$set: {canEditName}
});
@@ -631,14 +631,15 @@ module.exports = class UsersService {
* @param {String} displayName The new displayname for the user.
* @return {Promise}
*/
- static editUsername(id, displayName) {
+ static editName(id, displayName) {
return UserModel.findOne({id})
.then((user) => {
return user.canEditName ?
UserModel.update({id}, {
$set: {
displayName: displayName.toLowerCase(),
- canEditName: false
+ canEditName: false,
+ status: 'PENDING'
}
})
: Promise.reject(new Error('Display name editing disabled for this account.'));
diff --git a/test/services/users.js b/test/services/users.js
index ef027a317..5774d45ae 100644
--- a/test/services/users.js
+++ b/test/services/users.js
@@ -209,10 +209,10 @@ describe('services.UsersService', () => {
});
});
- describe('#toggleUsernameEdit', () => {
+ describe('#toggleNameEdit', () => {
it('should toggle the canEditName field', () => {
return UsersService
- .toggleUsernameEdit(mockUsers[0].id, true)
+ .toggleNameEdit(mockUsers[0].id, true)
.then(() => UsersService.findById(mockUsers[0].id))
.then((user) => {
expect(user).to.have.property('canEditName', true);
@@ -220,11 +220,11 @@ describe('services.UsersService', () => {
});
});
- describe('#editUsername', () => {
+ describe('#editName', () => {
it('should let the user edit their username if the proper toggle is set', () => {
return UsersService
- .toggleUsernameEdit(mockUsers[0].id, true)
- .then(() => UsersService.editUsername(mockUsers[0].id, 'Jojo'))
+ .toggleNameEdit(mockUsers[0].id, true)
+ .then(() => UsersService.editName(mockUsers[0].id, 'Jojo'))
.then(() => UsersService.findById(mockUsers[0].id))
.then((user) => {
expect(user).to.have.property('displayName', 'jojo');
@@ -234,7 +234,7 @@ describe('services.UsersService', () => {
it('should return an error if canEditName is false', (done) => {
UsersService
- .editUsername(mockUsers[0].id, 'Jojo')
+ .editName(mockUsers[0].id, 'Jojo')
.then(() => UsersService.findById(mockUsers[0].id))
.then(() => {
done(new Error('Error expected'));
@@ -247,8 +247,8 @@ describe('services.UsersService', () => {
it('should return an error if the username is already taken', (done) => {
UsersService
- .toggleUsernameEdit(mockUsers[0].id, true)
- .then(() => UsersService.editUsername(mockUsers[0].id, 'Marvel'))
+ .toggleNameEdit(mockUsers[0].id, true)
+ .then(() => UsersService.editName(mockUsers[0].id, 'Marvel'))
.then(() => UsersService.findById(mockUsers[0].id))
.then(() => {
done(new Error('Error expected'));
From 97c3ebc3e039116933359562a86f83422430b0f2 Mon Sep 17 00:00:00 2001
From: David Jay
Date: Wed, 1 Feb 2017 20:55:45 -0500
Subject: [PATCH 24/77] Whitelisting usernames once they have been approved.
---
.../src/components/ModerationList.js | 2 +-
models/user.js | 2 +-
routes/api/users/index.js | 2 +-
services/users.js | 11 ++++++--
test/routes/api/user/index.js | 25 +++++++------------
5 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/client/coral-admin/src/components/ModerationList.js b/client/coral-admin/src/components/ModerationList.js
index c2ecab9a2..47e91e551 100644
--- a/client/coral-admin/src/components/ModerationList.js
+++ b/client/coral-admin/src/components/ModerationList.js
@@ -138,7 +138,7 @@ export default class ModerationList extends React.Component {
if (menuOption === 'REJECTED') {
this.setState({suspendUserModal: action});
} else if (menuOption === 'ACCEPTED') {
- this.props.userStatusUpdate('ACTIVE', action.item_id);
+ this.props.userStatusUpdate('APPROVED', action.item_id);
}
}
}
diff --git a/models/user.js b/models/user.js
index d483b1893..06dc3c7d1 100644
--- a/models/user.js
+++ b/models/user.js
@@ -12,7 +12,7 @@ const USER_STATUS = [
'ACTIVE',
'BANNED',
'PENDING',
- 'SUSPENDED',
+ 'APPROVED' // Indicates that the users' displayname has been approved
];
// ProfileSchema is the mongoose schema defined as the representation of a
diff --git a/routes/api/users/index.js b/routes/api/users/index.js
index f136fd776..0b7cd28aa 100644
--- a/routes/api/users/index.js
+++ b/routes/api/users/index.js
@@ -171,7 +171,7 @@ router.post('/:user_id/actions', authorization.needed(), (req, res, next) => {
// Set the user status to "pending" for review by moderators
if (action_type.slice(0, 4) === 'FLAG') {
- return UsersService.setStatus(req.user.id, 'PENDING')
+ return UsersService.setStatus(req.params.user_id, 'PENDING')
.then(() => action);
} else {
return action;
diff --git a/services/users.js b/services/users.js
index b9a64b288..157286ccf 100644
--- a/services/users.js
+++ b/services/users.js
@@ -349,8 +349,15 @@ module.exports = class UsersService {
// User status is not supported! Error out here.
return Promise.reject(new Error(`status ${status} is not supported`));
}
-
- return UserModel.update({id}, {$set: {status}});
+
+ return UserModel.findOne({id})
+ .then((user) => {
+ if (user.status === 'APPROVED' && status === 'PENDING') {
+ return Promise.resolve();
+ } else {
+ return UserModel.update({id}, {$set: {status}});
+ }
+ });
}
/**
diff --git a/test/routes/api/user/index.js b/test/routes/api/user/index.js
index 4de799df6..f6e202243 100644
--- a/test/routes/api/user/index.js
+++ b/test/routes/api/user/index.js
@@ -52,33 +52,26 @@ describe('/api/v1/users/:user_id/email/confirm', () => {
describe('/api/v1/users/:user_id/actions', () => {
- const users = [{
- displayName: 'Ana',
- email: 'ana@gmail.com',
- password: '123456789'
- }, {
- displayName: 'Maria',
- email: 'maria@gmail.com',
- password: '123456789'
- }];
+ let mockUser;
- beforeEach(() => {
- return SettingsService.init(settings).then(() => {
- return UsersService.createLocalUsers(users);
- });
- });
+ beforeEach(() => SettingsService.init(settings).then(() => {
+ return UsersService.createLocalUser('ana@gmail.com', '123321123', 'Ana');
+ })
+ .then((user) => {
+ mockUser = user;
+ }));
describe('#post', () => {
it('it should update actions', () => {
return chai.request(app)
- .post('/api/v1/users/abc/actions')
+ .post(`/api/v1/users/${mockUser.id}/actions`)
.set(passport.inject({id: '456', roles: ['ADMIN']}))
.send({'action_type': 'FLAG', metadata: {reason: 'Bio is too awesome.'}})
.then((res) => {
expect(res).to.have.status(201);
expect(res).to.have.body;
expect(res.body).to.have.property('action_type', 'FLAG');
- expect(res.body).to.have.property('item_id', 'abc');
+ expect(res.body).to.have.property('item_id', mockUser.id);
});
});
});
From 65aa5e7e92be6ff9d3f396e39796b05abf071306 Mon Sep 17 00:00:00 2001
From: Belen Curcio
Date: Thu, 2 Feb 2017 11:31:43 -0300
Subject: [PATCH 25/77] =?UTF-8?q?=C3=81dding=20Select,=20Options=20to=20Co?=
=?UTF-8?q?ral=20Ui=20and=20steps=20with=20formField?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../coral-admin/src/components/ui/Header.js | 74 ++++++++++---------
.../containers/Install/InstallContainer.js | 2 +-
.../components/Steps/AddOrganizationName.js | 17 +++--
.../components/Steps/CreateYourAccount.js | 50 ++++++++-----
.../Install/components/Steps/InitialStep.js | 2 +-
.../components/Steps/InviteTeamMembers.js | 45 ++++++-----
.../Install/components/Steps/style.css | 52 +++++++++----
.../src/containers/Install/style.css | 2 +-
client/coral-ui/components/Option.css | 3 +
client/coral-ui/components/Option.js | 14 ++++
client/coral-ui/components/Select.css | 33 +++++++++
client/coral-ui/components/Select.js | 14 ++++
client/coral-ui/components/WizardNav.css | 15 +++-
client/coral-ui/components/WizardNav.js | 7 +-
client/coral-ui/index.js | 2 +
15 files changed, 230 insertions(+), 102 deletions(-)
create mode 100644 client/coral-ui/components/Option.css
create mode 100644 client/coral-ui/components/Option.js
create mode 100644 client/coral-ui/components/Select.css
create mode 100644 client/coral-ui/components/Select.js
diff --git a/client/coral-admin/src/components/ui/Header.js b/client/coral-admin/src/components/ui/Header.js
index abfb0ff13..3e6598d6e 100644
--- a/client/coral-admin/src/components/ui/Header.js
+++ b/client/coral-admin/src/components/ui/Header.js
@@ -11,42 +11,44 @@ export default ({handleLogout, restricted = false}) => (
{
!restricted ?
-
-
- {lang.t('configure.moderate')}
-
-
- {lang.t('configure.community')}
-
-
- {lang.t('configure.configure')}
-
-
- {lang.t('configure.streams')}
-
-
- :
- null
- }
-
-
-
-
-
-
- Sign Out
-
-
-
-
- {`v${process.env.VERSION}`}
-
-
-
+
+
+
+ {lang.t('configure.moderate')}
+
+
+ {lang.t('configure.community')}
+
+
+ {lang.t('configure.configure')}
+
+
+ {lang.t('configure.streams')}
+
+
+
+
+
+
+
+
+ Sign Out
+
+
+
+
+ {`v${process.env.VERSION}`}
+
+
+
+
+ :
+ null
+ }
);
diff --git a/client/coral-admin/src/containers/Install/InstallContainer.js b/client/coral-admin/src/containers/Install/InstallContainer.js
index aac4654d3..350e60709 100644
--- a/client/coral-admin/src/containers/Install/InstallContainer.js
+++ b/client/coral-admin/src/containers/Install/InstallContainer.js
@@ -18,7 +18,7 @@ const InstallContainer = props => {
);
};
diff --git a/client/coral-admin/src/containers/Install/components/Steps/CreateYourAccount.js b/client/coral-admin/src/containers/Install/components/Steps/CreateYourAccount.js
index cb29c3429..f245218d8 100644
--- a/client/coral-admin/src/containers/Install/components/Steps/CreateYourAccount.js
+++ b/client/coral-admin/src/containers/Install/components/Steps/CreateYourAccount.js
@@ -1,30 +1,40 @@
import React from 'react';
import styles from './style.css';
-import {Button} from 'coral-ui';
+import {FormField, Button} from 'coral-ui';
const InitialStep = props => {
const {nextStep} = props;
return (
);
};
diff --git a/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js b/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
index 95043b515..51c40d44d 100644
--- a/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
+++ b/client/coral-admin/src/containers/Install/components/Steps/InitialStep.js
@@ -11,7 +11,7 @@ const InitialStep = props => {
Once you complete the following three steps, you will have a free
installation and provision of Mongo and Redis.
- Get Started
+ Get Started
);
};
diff --git a/client/coral-admin/src/containers/Install/components/Steps/InviteTeamMembers.js b/client/coral-admin/src/containers/Install/components/Steps/InviteTeamMembers.js
index 99ef84d19..156916ab0 100644
--- a/client/coral-admin/src/containers/Install/components/Steps/InviteTeamMembers.js
+++ b/client/coral-admin/src/containers/Install/components/Steps/InviteTeamMembers.js
@@ -1,6 +1,6 @@
import React from 'react';
import styles from './style.css';
-import {Button} from 'coral-ui';
+import {Button, Select, Option, FormField} from 'coral-ui';
const InviteTeamMembers = props => {
const {nextStep} = props;
@@ -11,23 +11,32 @@ const InviteTeamMembers = props => {
Once registered, new team members will receive an email to Create
their password.
-
-
- Email address
-
-
-
- Username
-
-
-
-
- Admin
- Moderator
-
-
- Invite team member
-
+
+
+
+
+
+
+
+
+ Assing a role
+
+ Admin
+ Moderator
+
+
+
+ Invite team member
+
+
);
};
diff --git a/client/coral-admin/src/containers/Install/components/Steps/style.css b/client/coral-admin/src/containers/Install/components/Steps/style.css
index c7d41aef0..9dd95f90b 100644
--- a/client/coral-admin/src/containers/Install/components/Steps/style.css
+++ b/client/coral-admin/src/containers/Install/components/Steps/style.css
@@ -1,34 +1,54 @@
.step {
+ padding: 20px 0;
+
+ h3 {
+ max-width: 450px;
+ margin: 0 auto;
+ text-align: left;
+ font-size: 1.4em;
+ font-weight: bold;
+ }
p {
max-width: 450px;
- margin: 10px auto 30px;
+ margin: 0 auto 30px;
+ font-size: 1.1em;
+ text-align: left;
}
> button {
- min-width: 140px;
+ min-width: 145px;
}
- form {
+ .form {
max-width: 300px;
margin: 30px auto;
- label {
- text-align: left;
- display: block;
+ form > button {
+ margin: 30px 0;
}
- input {
- border: solid 1px rgba(0, 0, 0, 0.23);
- padding: 10px 2px;
- border-radius: 3px;
- width: 100%;
- box-sizing: border-box;
- margin: 10px 0;
- transition: border-color 0.2 ease;
+ .formField {
+ label {
+ text-align: left;
+ display: block;
+ margin: 10px 0;
+ font-weight: 400;
+ font-size: 1.08em;
+ }
- &:focus {
- border-color: black;
+ > input {
+ border: solid 1px rgba(0, 0, 0, 0.23);
+ padding: 10px;
+ border-radius: 3px;
+ width: 100%;
+ box-sizing: border-box;
+ transition: border-color 0.2s ease;
+ font-size: 1em;
+
+ &:focus {
+ border-color: black;
+ }
}
}
}
diff --git a/client/coral-admin/src/containers/Install/style.css b/client/coral-admin/src/containers/Install/style.css
index 90c62c20e..62f7ffe04 100644
--- a/client/coral-admin/src/containers/Install/style.css
+++ b/client/coral-admin/src/containers/Install/style.css
@@ -2,7 +2,7 @@
max-width: 900px;
margin: 0 auto;
text-align: center;
- padding: 40px 0;
+ padding: 50px 0;
h2 {
font-size: 2em;
diff --git a/client/coral-ui/components/Option.css b/client/coral-ui/components/Option.css
new file mode 100644
index 000000000..54784d8fc
--- /dev/null
+++ b/client/coral-ui/components/Option.css
@@ -0,0 +1,3 @@
+.Option {
+
+}
diff --git a/client/coral-ui/components/Option.js b/client/coral-ui/components/Option.js
new file mode 100644
index 000000000..d322ef0ef
--- /dev/null
+++ b/client/coral-ui/components/Option.js
@@ -0,0 +1,14 @@
+import React from 'react';
+import {Option as OptionMDL} from 'react-mdl-selectfield';
+import styles from './Option.css';
+
+const Option = props => {
+ const {children, ...attrs} = props;
+ return (
+
+ {children}
+
+ );
+};
+
+export default Option;
diff --git a/client/coral-ui/components/Select.css b/client/coral-ui/components/Select.css
new file mode 100644
index 000000000..ac93a843c
--- /dev/null
+++ b/client/coral-ui/components/Select.css
@@ -0,0 +1,33 @@
+.Select {
+ position: relative;
+ width: 100%;
+ height: 40px;
+ background: #2c2c2c;
+ padding: 10px 15px;
+ box-sizing: border-box;
+ color: white;
+ border-radius: 2px;
+ 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);
+
+ > div {
+ padding: 0;
+ }
+
+ i {
+ position: absolute;
+ top: 7px;
+ right: 7px;
+ }
+
+ input {
+ padding: 0;
+ font-size: 13px;
+ letter-spacing: 0.7px;
+ font-weight: 400;
+ }
+
+ &:hover {
+ cursor: pointer;
+ }
+
+}
diff --git a/client/coral-ui/components/Select.js b/client/coral-ui/components/Select.js
new file mode 100644
index 000000000..731c50ddc
--- /dev/null
+++ b/client/coral-ui/components/Select.js
@@ -0,0 +1,14 @@
+import React from 'react';
+import {SelectField} from 'react-mdl-selectfield';
+import styles from './Select.css';
+
+const Select = props => {
+ const {children, ...attrs} = props;
+ return (
+
+ {children}
+
+ );
+};
+
+export default Select;
diff --git a/client/coral-ui/components/WizardNav.css b/client/coral-ui/components/WizardNav.css
index 90d07af09..001ee8603 100644
--- a/client/coral-ui/components/WizardNav.css
+++ b/client/coral-ui/components/WizardNav.css
@@ -13,7 +13,7 @@
position: relative;
padding-left: 40px;
border-radius: 1px;
-
+
&:hover {
cursor: pointer;
}
@@ -27,6 +27,10 @@
border-color: transparent transparent transparent #00796B;
}
}
+
+ i {
+ opacity: 1;
+ }
}
&.active {
@@ -41,6 +45,15 @@
}
}
+ i {
+ transition: opacity 0.2s ease;
+ opacity: 0;
+ vertical-align: middle;
+ font-size: 16px;
+ margin-top: -5px;
+ margin-left: 8px;
+ }
+
span {
padding: 10px 20px;
margin-right: 10px;
diff --git a/client/coral-ui/components/WizardNav.js b/client/coral-ui/components/WizardNav.js
index b5a8db549..9fd9a1f23 100644
--- a/client/coral-ui/components/WizardNav.js
+++ b/client/coral-ui/components/WizardNav.js
@@ -1,8 +1,9 @@
import React, {PropTypes} from 'react';
import styles from './WizardNav.css';
+import Icon from './Icon';
const WizardNav = props => {
- const {goToStep, currentStep, items} = props;
+ const {goToStep, currentStep, items, icon} = props;
return (