From bb25056d9afca501f147450466aaeecca9fef66f Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Tue, 27 Oct 2015 22:18:52 -0700 Subject: PLT-340 --- .../components/admin_console/team_settings.jsx | 34 ++ web/react/components/invite_member_modal.jsx | 3 +- web/react/components/login.jsx | 59 +++- web/react/components/navbar_dropdown.jsx | 2 +- web/react/components/sidebar_right_menu.jsx | 3 +- web/react/components/signup_team.jsx | 48 +++ web/react/components/team_general_tab.jsx | 367 +++++++++++++++++++-- web/react/components/team_settings.jsx | 8 +- web/react/components/team_settings_modal.jsx | 2 - web/react/pages/channel.jsx | 2 +- web/react/pages/login.jsx | 1 + web/react/pages/signup_team.jsx | 14 +- web/react/utils/client.jsx | 10 +- web/sass-files/sass/partials/_signup.scss | 28 ++ web/web.go | 34 +- 15 files changed, 543 insertions(+), 72 deletions(-) (limited to 'web') 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))) { @@ -242,6 +243,39 @@ export default class TeamSettings extends React.Component { +
+ +
+ + +

{'When true, teams that are configured to show in team directory will show on main page inplace of creating a new team.'}

+
+
+
{serverError} 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 = ( - with GitLab + {'with GitLab'} ); } @@ -154,7 +154,7 @@ export default class Login extends React.Component { type='submit' className='btn btn-primary' > - Sign in + {'Sign in'}
@@ -166,7 +166,7 @@ export default class Login extends React.Component {
{loginMessage}
- or + {'or'}
); @@ -176,16 +176,48 @@ export default class Login extends React.Component { if (emailSignup) { forgotPassword = (
- I forgot my password + {'I forgot my password'} +
+ ); + } + + let userSignUp = null; + if (this.props.inviteId) { + userSignUp = ( +
+ {'Do not have an account? '} + + {'Create one now'} + + +
+ ); + } + + let teamSignUp = null; + if (global.window.mm_config.EnableTeamCreation === 'true') { + teamSignUp = ( +
+ {'Want to create your own team? '} + + {'Sign up now'} + +
); } return (
-
Sign in to:
+
{'Sign in to:'}

{teamDisplayName}

-

on {global.window.mm_config.SiteName}

+

{'on '}{global.window.mm_config.SiteName}

{verifiedBox}
@@ -193,20 +225,12 @@ export default class Login extends React.Component {
{loginMessage} {emailSignup} + {userSignUp}
{'Find other teams'}
{forgotPassword} -
- {'Want to create your own team? '} - - Sign up now - - -
+ {teamSignUp}
); @@ -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 2b68645e5..cc041e094 100644 --- a/web/react/components/navbar_dropdown.jsx +++ b/web/react/components/navbar_dropdown.jsx @@ -111,7 +111,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'} 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} >Get Team Invite Link ); diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx index 1858703ef..814ec2fc1 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') { @@ -31,11 +36,49 @@ export default class TeamSignUp extends React.Component { } } + componentDidMount() { + if (global.window.mm_config.EnableTeamListing === 'true' && this.props.teams.length === 1) { + window.location.href = '/' + this.props.teams[0].name; + } + } + updatePage(page) { this.setState({page}); } render() { + if (this.state.page === 'team_listing') { + return ( +
+

{'Choose a Team'}

+
+ { + this.props.teams.map((team) => { + return ( +
+ +
+ {team.display_name} +
+
+
+ ); + }) + } +
+
+ ); + } + if (this.state.page === 'choose') { return ( { + 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 +121,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; + + const inviteId = this.state.invite_id.trim(); + if (inviteId) { + state.clientError = ''; + } else { + state.clientError = 'This field is required'; + valid = false; + } + + this.setState(state); - Client.updateTeamDisplayName(data, - function nameChangeSuccess() { + 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 +198,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 +246,178 @@ export default class GeneralTab extends React.Component { serverError = this.state.serverError; } + let teamListingSection; + if (this.props.activeSection === 'team_listing') { + const inputs = [ +
+
+ +
+
+
+ +
+
+

{'When allowed then the team will appear on the main page as part of team directory if team browsing is enabled in the system console.'}
+
+ ]; + + teamListingSection = ( + + ); + } else { + let describe = ''; + if (this.state.allow_team_listing === true) { + describe = 'Yes'; + } else { + describe = 'No'; + } + + teamListingSection = ( + + ); + } + + let openInviteSection; + if (this.props.activeSection === 'open_invite') { + const inputs = [ +
+
+ +
+
+
+ +
+
+

{'When allowed the team signup link will be included on the login page and anyone can signup to this team.'}
+
+ ]; + + openInviteSection = ( + + ); + } else { + let describe = ''; + if (this.state.allow_open_invite === true) { + describe = 'Yes'; + } else { + describe = 'No'; + } + + openInviteSection = ( + + ); + } + + let inviteSection; + + if (this.props.activeSection === 'invite_id') { + const inputs = []; + + inputs.push( +
+ +
+ +
+

{'When allowing open invites this code is used as part of the signup process. Changing this code will invalidate the previous open signup link.'}
+
+ +
+
+ ); + + inviteSection = ( + + ); + } else { + inviteSection = ( + + ); + } + let nameSection; if (this.props.activeSection === 'name') { - let inputs = []; + const inputs = []; let teamNameLabel = 'Team Name'; if (Utils.isMobile()) { @@ -127,17 +448,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 = ( ); } @@ -158,16 +479,19 @@ export default class GeneralTab extends React.Component { ref='title' > - General Settings + {'General Settings'}
-

General Settings

+

{'General Settings'}

{nameSection} + {openInviteSection} + {teamListingSection} + {inviteSection}
@@ -178,6 +502,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} />
); @@ -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} /> @@ -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( - , + , 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) { , 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( - , + , document.getElementById('signup-team') ); } diff --git a/web/react/utils/client.jsx b/web/react/utils/client.jsx index bf117b3b3..e1dee9c65 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..3cfda39e7 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,19 @@ 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) + l4g.Info(teams) + + for _, team := range teams { + page.Props[team.Name] = team.DisplayName + } + } + page.Render(c, w) } else { teamChan := api.Srv.Store.Team().Get(c.Session.TeamId) @@ -240,6 +239,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 +289,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 { -- cgit v1.2.3-1-g7c22 From be0bf941bf91d632efc2bf035864c161b656f094 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Tue, 27 Oct 2015 22:32:16 -0700 Subject: Removing console.log --- web/react/components/team_general_tab.jsx | 2 -- 1 file changed, 2 deletions(-) (limited to 'web') diff --git a/web/react/components/team_general_tab.jsx b/web/react/components/team_general_tab.jsx index 760c43965..591d031bf 100644 --- a/web/react/components/team_general_tab.jsx +++ b/web/react/components/team_general_tab.jsx @@ -45,8 +45,6 @@ export default class GeneralTab extends React.Component { newId += Math.floor(Math.random() * 16).toString(16); } - console.log(newId); - this.setState({invite_id: newId}); } -- cgit v1.2.3-1-g7c22 From 0b967b2acb5d5dc2da4f18c20a1cc4f8d1c8d8b1 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Wed, 28 Oct 2015 08:58:27 -0700 Subject: Moving single team redirect to backend --- web/react/components/signup_team.jsx | 6 ------ web/web.go | 7 +++++-- 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'web') diff --git a/web/react/components/signup_team.jsx b/web/react/components/signup_team.jsx index 814ec2fc1..f926f5cbb 100644 --- a/web/react/components/signup_team.jsx +++ b/web/react/components/signup_team.jsx @@ -36,12 +36,6 @@ export default class TeamSignUp extends React.Component { } } - componentDidMount() { - if (global.window.mm_config.EnableTeamListing === 'true' && this.props.teams.length === 1) { - window.location.href = '/' + this.props.teams[0].name; - } - } - updatePage(page) { this.setState({page}); } diff --git a/web/web.go b/web/web.go index 3cfda39e7..424adea93 100644 --- a/web/web.go +++ b/web/web.go @@ -166,11 +166,14 @@ func root(c *api.Context, w http.ResponseWriter, r *http.Request) { return } else { teams := result.Data.([]*model.Team) - l4g.Info(teams) - 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) -- cgit v1.2.3-1-g7c22 From bedf85a122359a70cbb21be1219a5d566466273e Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Thu, 29 Oct 2015 08:54:27 -0700 Subject: Adding error when enabling team dir without global prop being set. --- web/react/components/team_general_tab.jsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'web') diff --git a/web/react/components/team_general_tab.jsx b/web/react/components/team_general_tab.jsx index 591d031bf..69ba44664 100644 --- a/web/react/components/team_general_tab.jsx +++ b/web/react/components/team_general_tab.jsx @@ -53,7 +53,12 @@ export default class GeneralTab extends React.Component { } handleTeamListingRadio(listing) { - this.setState({allow_team_listing: 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) { @@ -263,6 +268,7 @@ export default class GeneralTab extends React.Component {
-

{'When allowed then the team will appear on the main page as part of team directory if team browsing is enabled in the system console.'}
+

{'When allowed the team will appear on the main page as part of team directory.'}
]; @@ -282,6 +288,7 @@ export default class GeneralTab extends React.Component { inputs={inputs} submit={this.handleTeamListingSubmit} server_error={serverError} + client_error={clientError} updateSection={this.onUpdateTeamListingSection} /> ); -- cgit v1.2.3-1-g7c22