From 6fecfcc7ca9f7cf29b4cf87ebeb63b09df70a8c7 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Thu, 26 May 2016 09:46:18 -0400 Subject: Refactor login, claim and create_team into views and add actions (#3110) --- .../create_team/components/display_name.jsx | 38 +++------ .../components/create_team/components/team_url.jsx | 95 +++++++--------------- webapp/components/create_team/create_team.jsx | 72 ---------------- .../create_team/create_team_controller.jsx | 72 ++++++++++++++++ 4 files changed, 115 insertions(+), 162 deletions(-) delete mode 100644 webapp/components/create_team/create_team.jsx create mode 100644 webapp/components/create_team/create_team_controller.jsx (limited to 'webapp/components/create_team') diff --git a/webapp/components/create_team/components/display_name.jsx b/webapp/components/create_team/components/display_name.jsx index e8f1717bb..e6dcd221a 100644 --- a/webapp/components/create_team/components/display_name.jsx +++ b/webapp/components/create_team/components/display_name.jsx @@ -1,29 +1,19 @@ // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // See License.txt for license information. -import ReactDOM from 'react-dom'; -import * as utils from 'utils/utils.jsx'; -import Client from 'utils/web_client.jsx'; -import {Link} from 'react-router'; +import {track} from 'actions/analytics_actions.jsx'; -import {injectIntl, intlShape, defineMessages, FormattedMessage} from 'react-intl'; +import * as Utils from 'utils/utils.jsx'; +import Constants from 'utils/constants.jsx'; import logoImage from 'images/logo.png'; -const holders = defineMessages({ - required: { - id: 'create_team.display_name.required', - defaultMessage: 'This field is required' - }, - charLength: { - id: 'create_team.display_name.charLength', - defaultMessage: 'Name must be 4 or more characters up to a maximum of 15' - } -}); - import React from 'react'; +import ReactDOM from 'react-dom'; +import {Link} from 'react-router'; +import {FormattedMessage} from 'react-intl'; -class TeamSignupDisplayNamePage extends React.Component { +export default class TeamSignupDisplayNamePage extends React.Component { constructor(props) { super(props); @@ -35,19 +25,18 @@ class TeamSignupDisplayNamePage extends React.Component { submitNext(e) { e.preventDefault(); - const {formatMessage} = this.props.intl; var displayName = ReactDOM.findDOMNode(this.refs.name).value.trim(); if (!displayName) { - this.setState({nameError: formatMessage(holders.required)}); + this.setState({nameError: Utils.localizeMessage('create_team.display_name.required', 'This field is required')}); return; - } else if (displayName.length < 4 || displayName.length > 15) { - this.setState({nameError: formatMessage(holders.charLength)}); + } else if (displayName.length < Constants.MIN_TEAMNAME_LENGTH || displayName.length > Constants.MAX_TEAMNAME_LENGTH) { + this.setState({nameError: Utils.localizeMessage('create_team.display_name.charLength', 'Name must be 4 or more characters up to a maximum of 15')}); return; } this.props.state.wizard = 'team_url'; this.props.state.team.display_name = displayName; - this.props.state.team.name = utils.cleanUpUrlable(displayName); + this.props.state.team.name = Utils.cleanUpUrlable(displayName); this.props.updateParent(this.props.state); } @@ -57,7 +46,7 @@ class TeamSignupDisplayNamePage extends React.Component { } render() { - Client.track('signup', 'signup_team_02_name'); + track('signup', 'signup_team_02_name'); var nameError = null; var nameDivClass = 'form-group'; @@ -128,9 +117,6 @@ class TeamSignupDisplayNamePage extends React.Component { } TeamSignupDisplayNamePage.propTypes = { - intl: intlShape.isRequired, state: React.PropTypes.object, updateParent: React.PropTypes.func }; - -export default injectIntl(TeamSignupDisplayNamePage); diff --git a/webapp/components/create_team/components/team_url.jsx b/webapp/components/create_team/components/team_url.jsx index 34e696938..b6c634816 100644 --- a/webapp/components/create_team/components/team_url.jsx +++ b/webapp/components/create_team/components/team_url.jsx @@ -2,45 +2,20 @@ // See License.txt for license information. import $ from 'jquery'; -import ReactDOM from 'react-dom'; + import * as Utils from 'utils/utils.jsx'; -import Client from 'utils/web_client.jsx'; -import * as AsyncClient from 'utils/async_client.jsx'; -import TeamStore from 'stores/team_store.jsx'; -import UserStore from 'stores/user_store.jsx'; -import Constants from 'utils/constants.jsx'; -import {browserHistory} from 'react-router'; -import {injectIntl, intlShape, defineMessages, FormattedMessage, FormattedHTMLMessage} from 'react-intl'; +import {checkIfTeamExists, createTeam} from 'actions/team_actions.jsx'; +import {track} from 'actions/analytics_actions.jsx'; +import Constants from 'utils/constants.jsx'; import logoImage from 'images/logo.png'; -const holders = defineMessages({ - required: { - id: 'create_team.team_url.required', - defaultMessage: 'This field is required' - }, - regex: { - id: 'create_team.team_url.regex', - defaultMessage: "Use only lower case letters, numbers and dashes. Must start with a letter and can't end in a dash." - }, - charLength: { - id: 'create_team.team_url.charLength', - defaultMessage: 'Name must be 4 or more characters up to a maximum of 15' - }, - taken: { - id: 'create_team.team_url.taken', - defaultMessage: 'URL is taken or contains a reserved word' - }, - unavailable: { - id: 'create_team.team_url.unavailable', - defaultMessage: 'This URL is unavailable. Please try another.' - } -}); - import React from 'react'; +import ReactDOM from 'react-dom'; +import {FormattedMessage, FormattedHTMLMessage} from 'react-intl'; -class TeamUrl extends React.Component { +export default class TeamUrl extends React.Component { constructor(props) { super(props); @@ -58,10 +33,9 @@ class TeamUrl extends React.Component { submitNext(e) { e.preventDefault(); - const {formatMessage} = this.props.intl; const name = ReactDOM.findDOMNode(this.refs.name).value.trim(); if (!name) { - this.setState({nameError: formatMessage(holders.required)}); + this.setState({nameError: Utils.localizeMessage('create_team.team_url.required', 'This field is required')}); return; } @@ -69,17 +43,17 @@ class TeamUrl extends React.Component { const urlRegex = /^[a-z]+([a-z\-0-9]+|(__)?)[a-z0-9]+$/g; if (cleanedName !== name || !urlRegex.test(name)) { - this.setState({nameError: formatMessage(holders.regex)}); + this.setState({nameError: Utils.localizeMessage('create_team.team_url.regex', "Use only lower case letters, numbers and dashes. Must start with a letter and can't end in a dash.")}); return; - } else if (cleanedName.length < 4 || cleanedName.length > 15) { - this.setState({nameError: formatMessage(holders.charLength)}); + } else if (cleanedName.length < Constants.MIN_TEAMNAME_LENGTH || cleanedName.length > Constants.MAX_TEAMNAME_LENGTH) { + this.setState({nameError: Utils.localizeMessage('create_team.team_url.charLength', 'Name must be 4 or more characters up to a maximum of 15')}); return; } if (global.window.mm_config.RestrictTeamNames === 'true') { for (let index = 0; index < Constants.RESERVED_TEAM_NAMES.length; index++) { if (cleanedName.indexOf(Constants.RESERVED_TEAM_NAMES[index]) === 0) { - this.setState({nameError: formatMessage(holders.taken)}); + this.setState({nameError: Utils.localizeMessage('create_team.team_url.taken', 'URL is taken or contains a reserved word')}); return; } } @@ -90,30 +64,24 @@ class TeamUrl extends React.Component { teamSignup.team.type = 'O'; teamSignup.team.name = name; - Client.findTeamByName(name, - (findTeam) => { - if (findTeam) { - this.setState({nameError: formatMessage(holders.unavailable)}); - $('#finish-button').button('reset'); - } else { - Client.createTeam(teamSignup.team, - (team) => { - Client.track('signup', 'signup_team_08_complete'); - $('#sign-up-button').button('reset'); - AsyncClient.getDirectProfiles(); - TeamStore.saveTeam(team); - TeamStore.appendTeamMember({team_id: team.id, user_id: UserStore.getCurrentId(), roles: 'admin'}); - TeamStore.emitChange(); - browserHistory.push('/' + team.name + '/channels/town-square'); - }, - (err) => { - this.setState({nameError: err.message}); - $('#finish-button').button('reset'); - } - ); - + checkIfTeamExists(name, + (foundTeam) => { + if (foundTeam) { + this.setState({nameError: Utils.localizeMessage('create_team.team_url.unavailable', 'This URL is unavailable. Please try another.')}); $('#finish-button').button('reset'); + return; } + + createTeam(teamSignup.team, + () => { + track('signup', 'signup_team_08_complete'); + $('#sign-up-button').button('reset'); + }, + (err) => { + this.setState({nameError: err.message}); + $('#finish-button').button('reset'); + } + ); }, (err) => { this.setState({nameError: err.message}); @@ -121,15 +89,17 @@ class TeamUrl extends React.Component { } ); } + handleFocus(e) { e.preventDefault(); e.currentTarget.select(); } + render() { $('body').tooltip({selector: '[data-toggle=tooltip]', trigger: 'hover click'}); - Client.track('signup', 'signup_team_03_url'); + track('signup', 'signup_team_03_url'); let nameError = null; let nameDivClass = 'form-group'; @@ -223,9 +193,6 @@ class TeamUrl extends React.Component { } TeamUrl.propTypes = { - intl: intlShape.isRequired, state: React.PropTypes.object, updateParent: React.PropTypes.func }; - -export default injectIntl(TeamUrl); diff --git a/webapp/components/create_team/create_team.jsx b/webapp/components/create_team/create_team.jsx deleted file mode 100644 index 8a119a122..000000000 --- a/webapp/components/create_team/create_team.jsx +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import ErrorBar from 'components/error_bar.jsx'; - -import {FormattedMessage} from 'react-intl'; -import {browserHistory, Link} from 'react-router'; - -import React from 'react'; - -export default class CreateTeam extends React.Component { - constructor(props) { - super(props); - - this.submit = this.submit.bind(this); - this.updateParent = this.updateParent.bind(this); - - const state = {}; - state.team = {}; - state.wizard = 'display_name'; - this.state = state; - } - - submit() { - // todo fill in - } - - componentDidMount() { - browserHistory.push('/create_team/display_name'); - } - - updateParent(state) { - this.setState(state); - browserHistory.push('/create_team/' + state.wizard); - } - - render() { - return ( -
- -
- - - - -
-
-
-

{global.window.mm_config.SiteName}

-

- -

-
- {React.cloneElement(this.props.children, { - state: this.state, - updateParent: this.updateParent - })} -
-
-
-
- ); - } -} - -CreateTeam.propTypes = { - children: React.PropTypes.node -}; diff --git a/webapp/components/create_team/create_team_controller.jsx b/webapp/components/create_team/create_team_controller.jsx new file mode 100644 index 000000000..ad2a008bd --- /dev/null +++ b/webapp/components/create_team/create_team_controller.jsx @@ -0,0 +1,72 @@ +// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import ErrorBar from 'components/error_bar.jsx'; + +import {FormattedMessage} from 'react-intl'; +import {browserHistory, Link} from 'react-router'; + +import React from 'react'; + +export default class CreateTeamController extends React.Component { + constructor(props) { + super(props); + + this.submit = this.submit.bind(this); + this.updateParent = this.updateParent.bind(this); + + const state = {}; + state.team = {}; + state.wizard = 'display_name'; + this.state = state; + } + + submit() { + // todo fill in + } + + componentDidMount() { + browserHistory.push('/create_team/display_name'); + } + + updateParent(state) { + this.setState(state); + browserHistory.push('/create_team/' + state.wizard); + } + + render() { + return ( +
+ +
+ + + + +
+
+
+

{global.window.mm_config.SiteName}

+

+ +

+
+ {React.cloneElement(this.props.children, { + state: this.state, + updateParent: this.updateParent + })} +
+
+
+
+ ); + } +} + +CreateTeamController.propTypes = { + children: React.PropTypes.node +}; -- cgit v1.2.3-1-g7c22