diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/react/components/admin_console/team_settings.jsx | 34 | ||||
-rw-r--r-- | web/react/components/invite_member_modal.jsx | 3 | ||||
-rw-r--r-- | web/react/components/login.jsx | 59 | ||||
-rw-r--r-- | web/react/components/navbar_dropdown.jsx | 2 | ||||
-rw-r--r-- | web/react/components/sidebar_right_menu.jsx | 3 | ||||
-rw-r--r-- | web/react/components/signup_team.jsx | 42 | ||||
-rw-r--r-- | web/react/components/team_general_tab.jsx | 372 | ||||
-rw-r--r-- | web/react/components/team_settings.jsx | 8 | ||||
-rw-r--r-- | web/react/components/team_settings_modal.jsx | 2 | ||||
-rw-r--r-- | web/react/pages/channel.jsx | 2 | ||||
-rw-r--r-- | web/react/pages/login.jsx | 1 | ||||
-rw-r--r-- | web/react/pages/signup_team.jsx | 14 | ||||
-rw-r--r-- | web/react/utils/client.jsx | 10 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_signup.scss | 28 | ||||
-rw-r--r-- | web/web.go | 37 |
15 files changed, 545 insertions, 72 deletions
diff --git a/web/react/components/admin_console/team_settings.jsx b/web/react/components/admin_console/team_settings.jsx index 9ecd14a1e..6587184ea 100644 --- a/web/react/components/admin_console/team_settings.jsx +++ b/web/react/components/admin_console/team_settings.jsx @@ -32,6 +32,7 @@ export default class TeamSettings extends React.Component { config.TeamSettings.EnableTeamCreation = ReactDOM.findDOMNode(this.refs.EnableTeamCreation).checked; config.TeamSettings.EnableUserCreation = ReactDOM.findDOMNode(this.refs.EnableUserCreation).checked; config.TeamSettings.RestrictTeamNames = ReactDOM.findDOMNode(this.refs.RestrictTeamNames).checked; + config.TeamSettings.EnableTeamListing = ReactDOM.findDOMNode(this.refs.EnableTeamListing).checked; var MaxUsersPerTeam = 50; if (!isNaN(parseInt(ReactDOM.findDOMNode(this.refs.MaxUsersPerTeam).value, 10))) { @@ -243,6 +244,39 @@ export default class TeamSettings extends React.Component { </div> <div className='form-group'> + <label + className='control-label col-sm-4' + htmlFor='EnableTeamListing' + > + {'Enable Team Directory: '} + </label> + <div className='col-sm-8'> + <label className='radio-inline'> + <input + type='radio' + name='EnableTeamListing' + value='true' + ref='EnableTeamListing' + defaultChecked={this.props.config.TeamSettings.EnableTeamListing} + onChange={this.handleChange} + /> + {'true'} + </label> + <label className='radio-inline'> + <input + type='radio' + name='EnableTeamListing' + value='false' + defaultChecked={!this.props.config.TeamSettings.EnableTeamListing} + onChange={this.handleChange} + /> + {'false'} + </label> + <p className='help-text'>{'When true, teams that are configured to show in team directory will show on main page inplace of creating a new team.'}</p> + </div> + </div> + + <div className='form-group'> <div className='col-sm-12'> {serverError} <button diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx index 86a4b04cf..bea700725 100644 --- a/web/react/components/invite_member_modal.jsx +++ b/web/react/components/invite_member_modal.jsx @@ -4,6 +4,7 @@ var utils = require('../utils/utils.jsx'); var Client = require('../utils/client.jsx'); var UserStore = require('../stores/user_store.jsx'); +var TeamStore = require('../stores/team_store.jsx'); var ConfirmModal = require('./confirm_modal.jsx'); export default class InviteMemberModal extends React.Component { @@ -292,7 +293,7 @@ export default class InviteMemberModal extends React.Component { } else { var teamInviteLink = null; if (currentUser && this.props.teamType === 'O') { - var linkUrl = utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + currentUser.team_id; + var linkUrl = utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + TeamStore.getCurrent().invite_id; var link = ( <a diff --git a/web/react/components/login.jsx b/web/react/components/login.jsx index 108735caf..c519959af 100644 --- a/web/react/components/login.jsx +++ b/web/react/components/login.jsx @@ -101,7 +101,7 @@ export default class Login extends React.Component { href={'/' + teamName + '/login/gitlab'} > <span className='icon' /> - <span>with GitLab</span> + <span>{'with GitLab'}</span> </a> ); } @@ -154,7 +154,7 @@ export default class Login extends React.Component { type='submit' className='btn btn-primary' > - Sign in + {'Sign in'} </button> </div> </div> @@ -166,7 +166,7 @@ export default class Login extends React.Component { <div> {loginMessage} <div className='or__container'> - <span>or</span> + <span>{'or'}</span> </div> </div> ); @@ -176,16 +176,48 @@ export default class Login extends React.Component { if (emailSignup) { forgotPassword = ( <div className='form-group'> - <a href={'/' + teamName + '/reset_password'}>I forgot my password</a> + <a href={'/' + teamName + '/reset_password'}>{'I forgot my password'}</a> + </div> + ); + } + + let userSignUp = null; + if (this.props.inviteId) { + userSignUp = ( + <div> + <span>{'Do not have an account? '} + <a + href={'/signup_user_complete/?id=' + this.props.inviteId} + className='signup-team-login' + > + {'Create one now'} + </a> + </span> + </div> + ); + } + + let teamSignUp = null; + if (global.window.mm_config.EnableTeamCreation === 'true') { + teamSignUp = ( + <div className='margin--extra'> + <span>{'Want to create your own team? '} + <a + href='/' + className='signup-team-login' + > + {'Sign up now'} + </a> + </span> </div> ); } return ( <div className='signup-team__container'> - <h5 className='margin--less'>Sign in to:</h5> + <h5 className='margin--less'>{'Sign in to:'}</h5> <h2 className='signup-team__name'>{teamDisplayName}</h2> - <h2 className='signup-team__subdomain'>on {global.window.mm_config.SiteName}</h2> + <h2 className='signup-team__subdomain'>{'on '}{global.window.mm_config.SiteName}</h2> <form onSubmit={this.handleSubmit}> {verifiedBox} <div className={'form-group' + errorClass}> @@ -193,20 +225,12 @@ export default class Login extends React.Component { </div> {loginMessage} {emailSignup} + {userSignUp} <div className='form-group margin--extra form-group--small'> <span><a href='/find_team'>{'Find other teams'}</a></span> </div> {forgotPassword} - <div className='margin--extra'> - <span>{'Want to create your own team? '} - <a - href='/' - className='signup-team-login' - > - Sign up now - </a> - </span> - </div> + {teamSignUp} </form> </div> ); @@ -219,5 +243,6 @@ Login.defaultProps = { }; Login.propTypes = { teamName: React.PropTypes.string, - teamDisplayName: React.PropTypes.string + teamDisplayName: React.PropTypes.string, + inviteId: React.PropTypes.string }; diff --git a/web/react/components/navbar_dropdown.jsx b/web/react/components/navbar_dropdown.jsx index 2b0f3c40e..dc21fad21 100644 --- a/web/react/components/navbar_dropdown.jsx +++ b/web/react/components/navbar_dropdown.jsx @@ -112,7 +112,7 @@ export default class NavbarDropdown extends React.Component { data-toggle='modal' data-target='#get_link' data-title='Team Invite' - data-value={Utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + currentUser.team_id} + data-value={Utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + TeamStore.getCurrent().invite_id} > {'Get Team Invite Link'} </a> diff --git a/web/react/components/sidebar_right_menu.jsx b/web/react/components/sidebar_right_menu.jsx index fddc98c9d..9350bbd42 100644 --- a/web/react/components/sidebar_right_menu.jsx +++ b/web/react/components/sidebar_right_menu.jsx @@ -2,6 +2,7 @@ // See License.txt for license information. var UserStore = require('../stores/user_store.jsx'); +var TeamStore = require('../stores/team_store.jsx'); var client = require('../utils/client.jsx'); var utils = require('../utils/utils.jsx'); @@ -51,7 +52,7 @@ export default class SidebarRightMenu extends React.Component { data-toggle='modal' data-target='#get_link' data-title='Team Invite' - data-value={utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + currentUser.team_id} + data-value={utils.getWindowLocationOrigin() + '/signup_user_complete/?id=' + TeamStore.getCurrent().invite_id} ><i className='glyphicon glyphicon-link'></i>Get Team Invite Link</a> </li> ); diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx index 1858703ef..f926f5cbb 100644 --- a/web/react/components/signup_team.jsx +++ b/web/react/components/signup_team.jsx @@ -12,6 +12,11 @@ export default class TeamSignUp extends React.Component { this.updatePage = this.updatePage.bind(this); + if (global.window.mm_config.EnableTeamListing === 'true') { + this.state = {page: 'team_listing'}; + return; + } + var count = 0; if (global.window.mm_config.EnableSignUpWithEmail === 'true') { @@ -36,6 +41,38 @@ export default class TeamSignUp extends React.Component { } render() { + if (this.state.page === 'team_listing') { + return ( + <div> + <h3>{'Choose a Team'}</h3> + <div className='signup-team-all'> + { + this.props.teams.map((team) => { + return ( + <div + key={'team_' + team.name} + className='signup-team-dir' + > + <a + href={'/' + team.name} + > + <div className='signup-team-dir__group'> + <span className='signup-team-dir__name'>{team.display_name}</span> + <span + className='glyphicon glyphicon-menu-right right signup-team-dir__arrow' + aria-hidden='true' + /> + </div> + </a> + </div> + ); + }) + } + </div> + </div> + ); + } + if (this.state.page === 'choose') { return ( <ChoosePage @@ -51,3 +88,8 @@ export default class TeamSignUp extends React.Component { } } } + +TeamSignUp.propTypes = { + teams: React.PropTypes.array +}; + diff --git a/web/react/components/team_general_tab.jsx b/web/react/components/team_general_tab.jsx index 923180e27..69ba44664 100644 --- a/web/react/components/team_general_tab.jsx +++ b/web/react/components/team_general_tab.jsx @@ -6,29 +6,112 @@ const SettingItemMax = require('./setting_item_max.jsx'); const Client = require('../utils/client.jsx'); const Utils = require('../utils/utils.jsx'); +const TeamStore = require('../stores/team_store.jsx'); export default class GeneralTab extends React.Component { constructor(props) { super(props); this.handleNameSubmit = this.handleNameSubmit.bind(this); + this.handleInviteIdSubmit = this.handleInviteIdSubmit.bind(this); + this.handleOpenInviteSubmit = this.handleOpenInviteSubmit.bind(this); + this.handleTeamListingSubmit = this.handleTeamListingSubmit.bind(this); this.handleClose = this.handleClose.bind(this); - this.onUpdateSection = this.onUpdateSection.bind(this); + this.onUpdateNameSection = this.onUpdateNameSection.bind(this); this.updateName = this.updateName.bind(this); + this.onUpdateInviteIdSection = this.onUpdateInviteIdSection.bind(this); + this.updateInviteId = this.updateInviteId.bind(this); + this.onUpdateOpenInviteSection = this.onUpdateOpenInviteSection.bind(this); + this.handleOpenInviteRadio = this.handleOpenInviteRadio.bind(this); + this.onUpdateTeamListingSection = this.onUpdateTeamListingSection.bind(this); + this.handleTeamListingRadio = this.handleTeamListingRadio.bind(this); + this.handleGenerateInviteId = this.handleGenerateInviteId.bind(this); - this.state = {name: this.props.teamDisplayName, serverError: '', clientError: ''}; + this.state = { + name: props.team.display_name, + invite_id: props.team.invite_id, + allow_open_invite: props.team.allow_open_invite, + allow_team_listing: props.team.allow_team_listing, + serverError: '', + clientError: '' + }; } + + handleGenerateInviteId(e) { + e.preventDefault(); + + var newId = ''; + for (var i = 0; i < 32; i++) { + newId += Math.floor(Math.random() * 16).toString(16); + } + + this.setState({invite_id: newId}); + } + + handleOpenInviteRadio(openInvite) { + this.setState({allow_open_invite: openInvite}); + } + + handleTeamListingRadio(listing) { + if (global.window.mm_config.EnableTeamListing !== 'true' && listing) { + ReactDOM.findDOMNode(this.refs.teamListingRadioNo).checked = true; + this.setState({clientError: 'Team directory has been disabled. Please ask a system admin to enable it.'}); + } else { + this.setState({allow_team_listing: listing}); + } + } + + handleOpenInviteSubmit(e) { + e.preventDefault(); + + var state = {serverError: '', clientError: ''}; + + var data = this.props.team; + data.allow_open_invite = this.state.allow_open_invite; + Client.updateTeam(data, + (team) => { + TeamStore.saveTeam(team); + TeamStore.emitChange(); + this.props.updateSection(''); + }, + (err) => { + state.serverError = err.message; + this.setState(state); + } + ); + } + + handleTeamListingSubmit(e) { + e.preventDefault(); + + var state = {serverError: '', clientError: ''}; + + var data = this.props.team; + data.allow_team_listing = this.state.allow_team_listing; + Client.updateTeam(data, + (team) => { + TeamStore.saveTeam(team); + TeamStore.emitChange(); + this.props.updateSection(''); + }, + (err) => { + state.serverError = err.message; + this.setState(state); + } + ); + } + handleNameSubmit(e) { e.preventDefault(); - let state = {serverError: '', clientError: ''}; + var state = {serverError: '', clientError: ''}; let valid = true; const name = this.state.name.trim(); if (!name) { state.clientError = 'This field is required'; valid = false; - } else if (name === this.props.teamDisplayName) { + } else if (name === this.props.team.display_name) { state.clientError = 'Please choose a new name for your team'; valid = false; } else { @@ -41,37 +124,76 @@ export default class GeneralTab extends React.Component { return; } - let data = {}; - data.new_name = name; + var data = this.props.team; + data.display_name = this.state.name; + Client.updateTeam(data, + (team) => { + TeamStore.saveTeam(team); + TeamStore.emitChange(); + this.props.updateSection(''); + }, + (err) => { + state.serverError = err.message; + this.setState(state); + } + ); + } + + handleInviteIdSubmit(e) { + e.preventDefault(); + + var state = {serverError: '', clientError: ''}; + let valid = true; - Client.updateTeamDisplayName(data, - function nameChangeSuccess() { + const inviteId = this.state.invite_id.trim(); + if (inviteId) { + state.clientError = ''; + } else { + state.clientError = 'This field is required'; + valid = false; + } + + this.setState(state); + + if (!valid) { + return; + } + + var data = this.props.team; + data.invite_id = this.state.invite_id; + Client.updateTeam(data, + (team) => { + TeamStore.saveTeam(team); + TeamStore.emitChange(); this.props.updateSection(''); - $('#team_settings').modal('hide'); - window.location.reload(); - }.bind(this), - function nameChangeFail(err) { + }, + (err) => { state.serverError = err.message; this.setState(state); - }.bind(this) + } ); } + componentWillReceiveProps(newProps) { if (newProps.team && newProps.teamDisplayName) { this.setState({name: newProps.teamDisplayName}); } } + handleClose() { this.setState({clientError: '', serverError: ''}); this.props.updateSection(''); } + componentDidMount() { $('#team_settings').on('hidden.bs.modal', this.handleClose); } + componentWillUnmount() { $('#team_settings').off('hidden.bs.modal', this.handleClose); } - onUpdateSection(e) { + + onUpdateNameSection(e) { e.preventDefault(); if (this.props.activeSection === 'name') { this.props.updateSection(''); @@ -79,10 +201,44 @@ export default class GeneralTab extends React.Component { this.props.updateSection('name'); } } + + onUpdateInviteIdSection(e) { + e.preventDefault(); + if (this.props.activeSection === 'invite_id') { + this.props.updateSection(''); + } else { + this.props.updateSection('invite_id'); + } + } + + onUpdateOpenInviteSection(e) { + e.preventDefault(); + if (this.props.activeSection === 'open_invite') { + this.props.updateSection(''); + } else { + this.props.updateSection('open_invite'); + } + } + + onUpdateTeamListingSection(e) { + e.preventDefault(); + if (this.props.activeSection === 'team_listing') { + this.props.updateSection(''); + } else { + this.props.updateSection('team_listing'); + } + } + updateName(e) { e.preventDefault(); this.setState({name: e.target.value}); } + + updateInviteId(e) { + e.preventDefault(); + this.setState({invite_id: e.target.value}); + } + render() { let clientError = null; let serverError = null; @@ -93,10 +249,180 @@ export default class GeneralTab extends React.Component { serverError = this.state.serverError; } + let teamListingSection; + if (this.props.activeSection === 'team_listing') { + const inputs = [ + <div key='userTeamListingOptions'> + <div className='radio'> + <label> + <input + name='userTeamListingOptions' + type='radio' + defaultChecked={this.state.allow_team_listing} + onChange={this.handleTeamListingRadio.bind(this, true)} + /> + {'Yes'} + </label> + <br/> + </div> + <div className='radio'> + <label> + <input + ref='teamListingRadioNo' + name='userTeamListingOptions' + type='radio' + defaultChecked={!this.state.allow_team_listing} + onChange={this.handleTeamListingRadio.bind(this, false)} + /> + {'No'} + </label> + <br/> + </div> + <div><br/>{'When allowed the team will appear on the main page as part of team directory.'}</div> + </div> + ]; + + teamListingSection = ( + <SettingItemMax + title='Allow in Team Directory' + inputs={inputs} + submit={this.handleTeamListingSubmit} + server_error={serverError} + client_error={clientError} + updateSection={this.onUpdateTeamListingSection} + /> + ); + } else { + let describe = ''; + if (this.state.allow_team_listing === true) { + describe = 'Yes'; + } else { + describe = 'No'; + } + + teamListingSection = ( + <SettingItemMin + title='Allow in Team Directory' + describe={describe} + updateSection={this.onUpdateTeamListingSection} + /> + ); + } + + let openInviteSection; + if (this.props.activeSection === 'open_invite') { + const inputs = [ + <div key='userOpenInviteOptions'> + <div className='radio'> + <label> + <input + name='userOpenInviteOptions' + type='radio' + defaultChecked={this.state.allow_open_invite} + onChange={this.handleOpenInviteRadio.bind(this, true)} + /> + {'Yes'} + </label> + <br/> + </div> + <div className='radio'> + <label> + <input + name='userOpenInviteOptions' + type='radio' + defaultChecked={!this.state.allow_open_invite} + onChange={this.handleOpenInviteRadio.bind(this, false)} + /> + {'No'} + </label> + <br/> + </div> + <div><br/>{'When allowed the team signup link will be included on the login page and anyone can signup to this team.'}</div> + </div> + ]; + + openInviteSection = ( + <SettingItemMax + title='Allow Open Invitations' + inputs={inputs} + submit={this.handleOpenInviteSubmit} + server_error={serverError} + updateSection={this.onUpdateOpenInviteSection} + /> + ); + } else { + let describe = ''; + if (this.state.allow_open_invite === true) { + describe = 'Yes'; + } else { + describe = 'No'; + } + + openInviteSection = ( + <SettingItemMin + title='Allow Open Invitations' + describe={describe} + updateSection={this.onUpdateOpenInviteSection} + /> + ); + } + + let inviteSection; + + if (this.props.activeSection === 'invite_id') { + const inputs = []; + + inputs.push( + <div + key='teamInviteSetting' + className='form-group' + > + <label className='col-sm-5 control-label'>{'Invite Code'}</label> + <div className='col-sm-7'> + <input + className='form-control' + type='text' + onChange={this.updateInviteId} + value={this.state.invite_id} + maxLength='32' + /> + </div> + <div><br/>{'When allowing open invites this code is used as part of the signup process. Changing this code will invalidate the previous open signup link.'}</div> + <div className='help-text'> + <button + className='btn btn-default' + onClick={this.handleGenerateInviteId} + > + {'Re-Generate'} + </button> + </div> + </div> + ); + + inviteSection = ( + <SettingItemMax + title={`Invite Code`} + inputs={inputs} + submit={this.handleInviteIdSubmit} + server_error={serverError} + client_error={clientError} + updateSection={this.onUpdateInviteIdSection} + /> + ); + } else { + inviteSection = ( + <SettingItemMin + title={`Invite Code`} + describe={`Click 'Edit' to re-generate invite Code.`} + updateSection={this.onUpdateInviteIdSection} + /> + ); + } + let nameSection; if (this.props.activeSection === 'name') { - let inputs = []; + const inputs = []; let teamNameLabel = 'Team Name'; if (Utils.isMobile()) { @@ -127,17 +453,17 @@ export default class GeneralTab extends React.Component { submit={this.handleNameSubmit} server_error={serverError} client_error={clientError} - updateSection={this.onUpdateSection} + updateSection={this.onUpdateNameSection} /> ); } else { - let describe = this.state.name; + var describe = this.state.name; nameSection = ( <SettingItemMin title={`Team Name`} describe={describe} - updateSection={this.onUpdateSection} + updateSection={this.onUpdateNameSection} /> ); } @@ -158,16 +484,19 @@ export default class GeneralTab extends React.Component { ref='title' > <i className='modal-back'></i> - General Settings + {'General Settings'} </h4> </div> <div ref='wrapper' className='user-settings' > - <h3 className='tab-header'>General Settings</h3> + <h3 className='tab-header'>{'General Settings'}</h3> <div className='divider-dark first'/> {nameSection} + {openInviteSection} + {teamListingSection} + {inviteSection} <div className='divider-dark'/> </div> </div> @@ -178,6 +507,5 @@ export default class GeneralTab extends React.Component { GeneralTab.propTypes = { updateSection: React.PropTypes.func.isRequired, team: React.PropTypes.object.isRequired, - activeSection: React.PropTypes.string.isRequired, - teamDisplayName: React.PropTypes.string.isRequired + activeSection: React.PropTypes.string.isRequired }; diff --git a/web/react/components/team_settings.jsx b/web/react/components/team_settings.jsx index e14da4f04..09674f1ef 100644 --- a/web/react/components/team_settings.jsx +++ b/web/react/components/team_settings.jsx @@ -37,7 +37,6 @@ export default class TeamSettings extends React.Component { team={this.state.team} activeSection={this.props.activeSection} updateSection={this.props.updateSection} - teamDisplayName={this.props.teamDisplayName} /> </div> ); @@ -72,12 +71,11 @@ export default class TeamSettings extends React.Component { TeamSettings.defaultProps = { activeTab: '', - activeSection: '', - teamDisplayName: '' + activeSection: '' }; + TeamSettings.propTypes = { activeTab: React.PropTypes.string.isRequired, activeSection: React.PropTypes.string.isRequired, - updateSection: React.PropTypes.func.isRequired, - teamDisplayName: React.PropTypes.string.isRequired + updateSection: React.PropTypes.func.isRequired }; diff --git a/web/react/components/team_settings_modal.jsx b/web/react/components/team_settings_modal.jsx index 5c5995020..17fe31c65 100644 --- a/web/react/components/team_settings_modal.jsx +++ b/web/react/components/team_settings_modal.jsx @@ -82,7 +82,6 @@ export default class TeamSettingsModal extends React.Component { activeTab={this.state.activeTab} activeSection={this.state.activeSection} updateSection={this.updateSection} - teamDisplayName={this.props.teamDisplayName} /> </div> </div> @@ -95,5 +94,4 @@ export default class TeamSettingsModal extends React.Component { } TeamSettingsModal.propTypes = { - teamDisplayName: React.PropTypes.string.isRequired }; diff --git a/web/react/pages/channel.jsx b/web/react/pages/channel.jsx index 03e049db0..7a04c5979 100644 --- a/web/react/pages/channel.jsx +++ b/web/react/pages/channel.jsx @@ -90,7 +90,7 @@ function setupChannelPage(props) { ); ReactDOM.render( - <TeamSettingsModal teamDisplayName={props.TeamDisplayName} />, + <TeamSettingsModal />, document.getElementById('team_settings_modal') ); diff --git a/web/react/pages/login.jsx b/web/react/pages/login.jsx index 430de980c..9865e6fd2 100644 --- a/web/react/pages/login.jsx +++ b/web/react/pages/login.jsx @@ -8,6 +8,7 @@ function setupLoginPage(props) { <Login teamDisplayName={props.TeamDisplayName} teamName={props.TeamName} + inviteId={props.InviteId} />, document.getElementById('login') ); diff --git a/web/react/pages/signup_team.jsx b/web/react/pages/signup_team.jsx index dc8394a77..caa93b5bf 100644 --- a/web/react/pages/signup_team.jsx +++ b/web/react/pages/signup_team.jsx @@ -3,9 +3,19 @@ var SignupTeam = require('../components/signup_team.jsx'); -function setupSignupTeamPage() { +function setupSignupTeamPage(props) { + var teams = []; + + for (var prop in props) { + if (props.hasOwnProperty(prop)) { + if (prop !== 'Title') { + teams.push({name: prop, display_name: props[prop]}); + } + } + } + ReactDOM.render( - <SignupTeam />, + <SignupTeam teams={teams} />, document.getElementById('signup-team') ); } diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx index aeb39d8a8..7ce1346f9 100644 --- a/web/react/utils/client.jsx +++ b/web/react/utils/client.jsx @@ -442,16 +442,16 @@ export function inviteMembers(data, success, error) { track('api', 'api_teams_invite_members'); } -export function updateTeamDisplayName(data, success, error) { +export function updateTeam(team, success, error) { $.ajax({ - url: '/api/v1/teams/update_name', + url: '/api/v1/teams/update', dataType: 'json', contentType: 'application/json', type: 'POST', - data: JSON.stringify(data), + data: JSON.stringify(team), success, - error: function onError(xhr, status, err) { - var e = handleError('updateTeamDisplayName', xhr, status, err); + error: (xhr, status, err) => { + var e = handleError('updateTeam', xhr, status, err); error(e); } }); diff --git a/web/sass-files/sass/partials/_signup.scss b/web/sass-files/sass/partials/_signup.scss index 6d0256142..14c676f82 100644 --- a/web/sass-files/sass/partials/_signup.scss +++ b/web/sass-files/sass/partials/_signup.scss @@ -313,6 +313,34 @@ } +.signup-team-all { + width: 280px; + box-shadow: 3px 3px 1px #d5d5d5; + margin: 0px 0px 0px 5px; +} + +.signup-team-dir { + background: #fafafa; + border-bottom: 1px solid #d5d5d5; +} + +.signup-team-dir__group { + padding: 15px 10px 15px 10px; +} + +.signup-team-dir__name { + line-height: 1.3 !important; + font-size: 1.5em !important; + font-weight: 300 !important; +} + +.signup-team-dir__arrow { + float: right; + line-height: 1.3 !important; + font-size: 1.5em !important; + font-weight: 300 !important; +} + .authorize-box { margin: 100px auto; width:500px; diff --git a/web/web.go b/web/web.go index bffe4858e..424adea93 100644 --- a/web/web.go +++ b/web/web.go @@ -152,20 +152,6 @@ func CheckBrowserCompatability(c *api.Context, r *http.Request) bool { } -// func getTeamAndUser(c *api.Context) (*model.Team, *model.User) { -// if tr := <-api.Srv.Store.Team().Get(c.Session.TeamId); tr.Err != nil { -// c.Err = tr.Err -// return nil, nil -// } else { -// if ur := <-api.Srv.Store.User().Get(c.Session.UserId); ur.Err != nil { -// c.Err = ur.Err -// return nil, nil -// } else { -// return tr.Data.(*model.Team), ur.Data.(*model.User) -// } -// } -// } - func root(c *api.Context, w http.ResponseWriter, r *http.Request) { if !CheckBrowserCompatability(c, r) { @@ -174,6 +160,22 @@ func root(c *api.Context, w http.ResponseWriter, r *http.Request) { if len(c.Session.UserId) == 0 { page := NewHtmlTemplatePage("signup_team", "Signup") + + if result := <-api.Srv.Store.Team().GetAllTeamListing(); result.Err != nil { + c.Err = result.Err + return + } else { + teams := result.Data.([]*model.Team) + for _, team := range teams { + page.Props[team.Name] = team.DisplayName + } + + if len(teams) == 1 && *utils.Cfg.TeamSettings.EnableTeamListing { + http.Redirect(w, r, c.GetSiteURL()+"/"+teams[0].Name, http.StatusTemporaryRedirect) + return + } + } + page.Render(c, w) } else { teamChan := api.Srv.Store.Team().Get(c.Session.TeamId) @@ -240,6 +242,11 @@ func login(c *api.Context, w http.ResponseWriter, r *http.Request) { page := NewHtmlTemplatePage("login", "Login") page.Props["TeamDisplayName"] = team.DisplayName page.Props["TeamName"] = team.Name + + if team.AllowOpenInvite { + page.Props["InviteId"] = team.InviteId + } + page.Render(c, w) } @@ -285,7 +292,7 @@ func signupUserComplete(c *api.Context, w http.ResponseWriter, r *http.Request) if len(id) > 0 { props = make(map[string]string) - if result := <-api.Srv.Store.Team().Get(id); result.Err != nil { + if result := <-api.Srv.Store.Team().GetByInviteId(id); result.Err != nil { c.Err = result.Err return } else { |