mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
246 lines
8.7 KiB
JavaScript
246 lines
8.7 KiB
JavaScript
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
|
// See License.txt for license information.
|
|
|
|
import {checkIfTeamExists, createTeam} from 'actions/team_actions.jsx';
|
|
import {track} from 'actions/analytics_actions.jsx';
|
|
import Constants from 'utils/constants.jsx';
|
|
import * as URL from 'utils/url.jsx';
|
|
|
|
import logoImage from 'images/logo.png';
|
|
|
|
import React from 'react';
|
|
import ReactDOM from 'react-dom';
|
|
import {Button, Tooltip, OverlayTrigger} from 'react-bootstrap';
|
|
import {FormattedMessage, FormattedHTMLMessage} from 'react-intl';
|
|
|
|
export default class TeamUrl extends React.Component {
|
|
constructor(props) {
|
|
super(props);
|
|
|
|
this.submitBack = this.submitBack.bind(this);
|
|
this.submitNext = this.submitNext.bind(this);
|
|
this.handleFocus = this.handleFocus.bind(this);
|
|
|
|
this.state = {
|
|
nameError: '',
|
|
isLoading: false
|
|
};
|
|
}
|
|
|
|
submitBack(e) {
|
|
e.preventDefault();
|
|
this.props.state.wizard = 'display_name';
|
|
this.props.updateParent(this.props.state);
|
|
}
|
|
|
|
submitNext(e) {
|
|
e.preventDefault();
|
|
|
|
const name = ReactDOM.findDOMNode(this.refs.name).value.trim();
|
|
const cleanedName = URL.cleanUpUrlable(name);
|
|
const urlRegex = /^[a-z]+([a-z\-0-9]+|(__)?)[a-z0-9]+$/g;
|
|
|
|
if (!name) {
|
|
this.setState({nameError: (
|
|
<FormattedMessage
|
|
id='create_team.team_url.required'
|
|
defaultMessage='This field is required'
|
|
/>)
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (cleanedName.length < Constants.MIN_TEAMNAME_LENGTH || cleanedName.length > Constants.MAX_TEAMNAME_LENGTH) {
|
|
this.setState({nameError: (
|
|
<FormattedMessage
|
|
id='create_team.team_url.charLength'
|
|
defaultMessage='Name must be {min} or more characters up to a maximum of {max}'
|
|
values={{
|
|
min: Constants.MIN_TEAMNAME_LENGTH,
|
|
max: Constants.MAX_TEAMNAME_LENGTH
|
|
}}
|
|
/>)
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (cleanedName !== name || !urlRegex.test(name)) {
|
|
this.setState({nameError: (
|
|
<FormattedMessage
|
|
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."
|
|
/>)
|
|
});
|
|
return;
|
|
}
|
|
|
|
for (let index = 0; index < Constants.RESERVED_TEAM_NAMES.length; index++) {
|
|
if (cleanedName.indexOf(Constants.RESERVED_TEAM_NAMES[index]) === 0) {
|
|
this.setState({nameError: (
|
|
<FormattedMessage
|
|
id='create_team.team_url.taken'
|
|
defaultMessage='URL is taken or contains a reserved word'
|
|
/>)
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
this.setState({isLoading: true});
|
|
var teamSignup = JSON.parse(JSON.stringify(this.props.state));
|
|
teamSignup.team.type = 'O';
|
|
teamSignup.team.name = name;
|
|
|
|
checkIfTeamExists(name,
|
|
(foundTeam) => {
|
|
if (foundTeam) {
|
|
this.setState({nameError: (
|
|
<FormattedMessage
|
|
id='create_team.team_url.unavailable'
|
|
defaultMessage='This URL is unavailable. Please try another.'
|
|
/>)
|
|
});
|
|
this.setState({isLoading: false});
|
|
return;
|
|
}
|
|
|
|
createTeam(teamSignup.team,
|
|
() => {
|
|
track('signup', 'signup_team_08_complete');
|
|
},
|
|
(err) => {
|
|
this.setState({nameError: err.message});
|
|
this.setState({isLoading: false});
|
|
}
|
|
);
|
|
},
|
|
(err) => {
|
|
this.setState({nameError: err.message});
|
|
}
|
|
);
|
|
}
|
|
|
|
handleFocus(e) {
|
|
e.preventDefault();
|
|
e.currentTarget.select();
|
|
}
|
|
|
|
render() {
|
|
track('signup', 'signup_team_03_url');
|
|
|
|
let nameError = null;
|
|
let nameDivClass = 'form-group';
|
|
if (this.state.nameError) {
|
|
nameError = <label className='control-label'>{this.state.nameError}</label>;
|
|
nameDivClass += ' has-error';
|
|
}
|
|
|
|
const title = `${URL.getSiteURL()}/`;
|
|
const urlTooltip = (
|
|
<Tooltip id='urlTooltip'>{title}</Tooltip>
|
|
);
|
|
|
|
let finishMessage = (
|
|
<FormattedMessage
|
|
id='create_team.team_url.finish'
|
|
defaultMessage='Finish'
|
|
/>
|
|
);
|
|
|
|
if (this.state.isLoading) {
|
|
finishMessage = (
|
|
<FormattedMessage
|
|
id='create_team.team_url.creatingTeam'
|
|
defaultMessage='Creating team...'
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div>
|
|
<form>
|
|
<img
|
|
className='signup-team-logo'
|
|
src={logoImage}
|
|
/>
|
|
<h2>
|
|
<FormattedMessage
|
|
id='create_team.team_url.teamUrl'
|
|
defaultMessage='Team URL'
|
|
/>
|
|
</h2>
|
|
<div className={nameDivClass}>
|
|
<div className='row'>
|
|
<div className='col-sm-11'>
|
|
<div className='input-group input-group--limit'>
|
|
<OverlayTrigger
|
|
delayShow={Constants.OVERLAY_TIME_DELAY}
|
|
placement='top'
|
|
overlay={urlTooltip}
|
|
>
|
|
<span className='input-group-addon'>
|
|
{title}
|
|
</span>
|
|
</OverlayTrigger>
|
|
<input
|
|
type='text'
|
|
ref='name'
|
|
className='form-control'
|
|
placeholder=''
|
|
maxLength='128'
|
|
defaultValue={this.props.state.team.name}
|
|
autoFocus={true}
|
|
onFocus={this.handleFocus}
|
|
spellCheck='false'
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{nameError}
|
|
</div>
|
|
<p>
|
|
<FormattedMessage
|
|
id='create_team.team_url.webAddress'
|
|
defaultMessage='Choose the web address of your new team:'
|
|
/>
|
|
</p>
|
|
<ul className='color--light'>
|
|
<FormattedHTMLMessage
|
|
id='create_team.team_url.hint'
|
|
defaultMessage="<li>Short and memorable is best</li>
|
|
<li>Use lowercase letters, numbers and dashes</li>
|
|
<li>Must start with a letter and can't end in a dash</li>"
|
|
/>
|
|
</ul>
|
|
<div className='margin--extra'>
|
|
<Button
|
|
type='submit'
|
|
bsStyle='primary'
|
|
disabled={this.state.isLoading}
|
|
onClick={this.submitNext}
|
|
>
|
|
{finishMessage}
|
|
</Button>
|
|
</div>
|
|
<div className='margin--extra'>
|
|
<a
|
|
href='#'
|
|
onClick={this.submitBack}
|
|
>
|
|
<FormattedMessage
|
|
id='create_team.team_url.back'
|
|
defaultMessage='Back to previous step'
|
|
/>
|
|
</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
TeamUrl.propTypes = {
|
|
state: React.PropTypes.object,
|
|
updateParent: React.PropTypes.func
|
|
};
|