From fbcc2a740c8600bad964015c1b74b552f51c2e24 Mon Sep 17 00:00:00 2001 From: SleepWalker Date: Fri, 3 Mar 2017 07:48:25 +0200 Subject: [PATCH] #304: show Create new account link on LoginPanel for authorized users --- src/components/auth/RejectionLink.jsx | 12 +++++++++++- src/components/auth/login/Login.intl.json | 1 + src/components/auth/login/Login.jsx | 4 ++++ src/services/authFlow/LoginState.js | 5 +++++ tests/services/authFlow/LoginState.test.js | 9 +++++++++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/components/auth/RejectionLink.jsx b/src/components/auth/RejectionLink.jsx index d0630a7..5806311 100644 --- a/src/components/auth/RejectionLink.jsx +++ b/src/components/auth/RejectionLink.jsx @@ -2,7 +2,15 @@ import React, { PropTypes } from 'react'; import { FormattedMessage as Message } from 'react-intl'; +import { userShape } from 'components/user/User'; + export default function RejectionLink(props, context) { + if (props.isAvailable && !props.isAvailable(context)) { + // TODO: if want to properly support multiple links, we should control + // the dividers ' | ' rendered from factory too + return null; + } + return ( { event.preventDefault(); @@ -16,6 +24,7 @@ export default function RejectionLink(props, context) { RejectionLink.displayName = 'RejectionLink'; RejectionLink.propTypes = { + isAvailable: PropTypes.func, // a function from context to allow link visibility control // eslint-disable-next-line react/forbid-prop-types payload: PropTypes.object, // Custom payload for active state label: PropTypes.shape({ @@ -23,5 +32,6 @@ RejectionLink.propTypes = { }).isRequired }; RejectionLink.contextTypes = { - reject: PropTypes.func.isRequired + reject: PropTypes.func.isRequired, + user: userShape }; diff --git a/src/components/auth/login/Login.intl.json b/src/components/auth/login/Login.intl.json index 3b1e41a..93f82eb 100644 --- a/src/components/auth/login/Login.intl.json +++ b/src/components/auth/login/Login.intl.json @@ -1,4 +1,5 @@ { + "createNewAccount": "Create new account", "loginTitle": "Sign in", "emailOrUsername": "E‑mail or username", "next": "Next" diff --git a/src/components/auth/login/Login.jsx b/src/components/auth/login/Login.jsx index 81e1509..8ed6058 100644 --- a/src/components/auth/login/Login.jsx +++ b/src/components/auth/login/Login.jsx @@ -9,6 +9,10 @@ export default factory({ footer: { color: 'green', label: messages.next + }, + links: { + isAvailable: (context) => !context.user.isGuest, + label: messages.createNewAccount } }); diff --git a/src/services/authFlow/LoginState.js b/src/services/authFlow/LoginState.js index abb281b..3cfdce6 100644 --- a/src/services/authFlow/LoginState.js +++ b/src/services/authFlow/LoginState.js @@ -2,6 +2,7 @@ import logger from 'services/logger'; import AbstractState from './AbstractState'; import PasswordState from './PasswordState'; +import RegisterState from './RegisterState'; export default class LoginState extends AbstractState { enter(context) { @@ -29,6 +30,10 @@ export default class LoginState extends AbstractState { ); } + reject(context) { + context.setState(new RegisterState()); + } + goBack(context) { context.run('goBack', '/'); } diff --git a/tests/services/authFlow/LoginState.test.js b/tests/services/authFlow/LoginState.test.js index 0e91f2c..aeef849 100644 --- a/tests/services/authFlow/LoginState.test.js +++ b/tests/services/authFlow/LoginState.test.js @@ -2,6 +2,7 @@ import sinon from 'sinon'; import LoginState from 'services/authFlow/LoginState'; import PasswordState from 'services/authFlow/PasswordState'; +import RegisterState from 'services/authFlow/RegisterState'; import { bootstrap, expectState, expectNavigate, expectRun } from './helpers'; @@ -82,6 +83,14 @@ describe('LoginState', () => { }); }); + describe('#reject', () => { + it('should transition to register state', () => { + expectState(mock, RegisterState); + + state.reject(context); + }); + }); + describe('#goBack', () => { it('should return to previous page', () => { expectRun(mock, 'goBack', '/');