diff options
Diffstat (limited to 'web/react/components')
-rw-r--r-- | web/react/components/channel_header.jsx | 2 | ||||
-rw-r--r-- | web/react/components/create_comment.jsx | 2 | ||||
-rw-r--r-- | web/react/components/create_post.jsx | 4 | ||||
-rw-r--r-- | web/react/components/edit_channel_modal.jsx | 7 | ||||
-rw-r--r-- | web/react/components/file_upload.jsx | 2 | ||||
-rw-r--r-- | web/react/components/navbar.jsx | 2 | ||||
-rw-r--r-- | web/react/components/post_info.jsx | 4 | ||||
-rw-r--r-- | web/react/components/post_right.jsx | 2 | ||||
-rw-r--r-- | web/react/components/rename_channel_modal.jsx | 7 | ||||
-rw-r--r-- | web/react/components/rename_team_modal.jsx | 11 | ||||
-rw-r--r-- | web/react/components/sidebar_header.jsx | 4 | ||||
-rw-r--r-- | web/react/components/signup_user_complete.jsx | 11 | ||||
-rw-r--r-- | web/react/components/user_settings.jsx | 50 |
13 files changed, 86 insertions, 22 deletions
diff --git a/web/react/components/channel_header.jsx b/web/react/components/channel_header.jsx index 30435dc08..7a129f200 100644 --- a/web/react/components/channel_header.jsx +++ b/web/react/components/channel_header.jsx @@ -205,7 +205,7 @@ module.exports = React.createClass({ <th> <div className="dropdown channel-header__links"> <a href="#" className="dropdown-toggle theme" type="button" id="channel_header_right_dropdown" data-toggle="dropdown" aria-expanded="true"> - <span dangerouslySetInnerHTML={{__html: " <svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>"}} /> </a> + <span dangerouslySetInnerHTML={{__html: Constants.MENU_ICON }} /> </a> <ul className="dropdown-menu dropdown-menu-right" role="menu" aria-labelledby="channel_header_right_dropdown"> <li role="presentation"><a role="menuitem" href="#" onClick={this.searchMentions}>Recent Mentions</a></li> </ul> diff --git a/web/react/components/create_comment.jsx b/web/react/components/create_comment.jsx index 3f8e9ed2e..88c01c586 100644 --- a/web/react/components/create_comment.jsx +++ b/web/react/components/create_comment.jsx @@ -40,7 +40,7 @@ module.exports = React.createClass({ post.parent_id = this.props.parentId; post.filenames = this.state.previews; - this.setState({ submitting: true }); + this.setState({ submitting: true, limit_error: null }); client.createPost(post, ChannelStore.getCurrent(), function(data) { diff --git a/web/react/components/create_post.jsx b/web/react/components/create_post.jsx index 91d070958..87895588e 100644 --- a/web/react/components/create_post.jsx +++ b/web/react/components/create_post.jsx @@ -45,7 +45,7 @@ module.exports = React.createClass({ return; } - this.setState({ submitting: true }); + this.setState({ submitting: true, limit_error: null }); var user_id = UserStore.getCurrentId(); @@ -275,7 +275,7 @@ module.exports = React.createClass({ messageText = draft['message']; uploadsInProgress = draft['uploadsInProgress']; } - this.setState({ channel_id: channel_id, messageText: messageText, initialText: messageText, submitting: false, post_error: null, previews: previews, uploadsInProgress: uploadsInProgress }); + this.setState({ channel_id: channel_id, messageText: messageText, initialText: messageText, submitting: false, limit_error: null, server_error: null, post_error: null, previews: previews, uploadsInProgress: uploadsInProgress }); } }, _onActiveThreadChanged: function(rootId, parentId) { diff --git a/web/react/components/edit_channel_modal.jsx b/web/react/components/edit_channel_modal.jsx index d055feacd..a35a531b5 100644 --- a/web/react/components/edit_channel_modal.jsx +++ b/web/react/components/edit_channel_modal.jsx @@ -30,12 +30,19 @@ module.exports = React.createClass({ handleUserInput: function(e) { this.setState({ description: e.target.value }); }, + handleClose: function() { + this.setState({description: "", server_error: ""}); + }, componentDidMount: function() { var self = this; $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { var button = e.relatedTarget; self.setState({ description: $(button).attr('data-desc'), title: $(button).attr('data-title'), channel_id: $(button).attr('data-channelid'), server_error: "" }); }); + $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', this.handleClose) + }, + componentWillUnmount: function() { + $(this.refs.modal.getDOMNode()).off('hidden.bs.modal', this.handleClose) }, getInitialState: function() { return { description: "", title: "", channel_id: "" }; diff --git a/web/react/components/file_upload.jsx b/web/react/components/file_upload.jsx index f2429f17e..aee089dbc 100644 --- a/web/react/components/file_upload.jsx +++ b/web/react/components/file_upload.jsx @@ -15,7 +15,7 @@ module.exports = React.createClass({ // This looks redundant, but must be done this way due to // setState being an asynchronous call var numFiles = 0; - for(var i = 0; i < files.length && i < Constants.MAX_UPLOAD_FILES; i++) { + for(var i = 0; i < files.length; i++) { if (files[i].size <= Constants.MAX_FILE_SIZE) { numFiles++; } diff --git a/web/react/components/navbar.jsx b/web/react/components/navbar.jsx index 500fabb0e..6d23c0d9b 100644 --- a/web/react/components/navbar.jsx +++ b/web/react/components/navbar.jsx @@ -191,7 +191,7 @@ module.exports = React.createClass({ </button>; var right_sidebar_collapse_button= currentId == null ? null : <button type="button" className="navbar-toggle menu-toggle pull-right" data-toggle="collapse" data-target="#sidebar-nav" onClick={this.toggleRightSidebar}> - <span className="dropdown__icon"></span> + <span dangerouslySetInnerHTML={{__html: Constants.MENU_ICON }} /> </button>; diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx index d6422fe3a..8eaaf4e8c 100644 --- a/web/react/components/post_info.jsx +++ b/web/react/components/post_info.jsx @@ -4,6 +4,8 @@ var UserStore = require('../stores/user_store.jsx'); var utils = require('../utils/utils.jsx'); +var Constants = require('../utils/constants.jsx'); + module.exports = React.createClass({ getInitialState: function() { return { }; @@ -21,7 +23,7 @@ module.exports = React.createClass({ var comments = ""; var lastCommentClass = this.props.isLastComment ? " comment-icon__container__show" : " comment-icon__container__hide"; if (this.props.commentCount >= 1) { - comments = <a href="#" className={"comment-icon__container theme" + lastCommentClass} onClick={this.props.handleCommentClick}><span className="comment-icon" dangerouslySetInnerHTML={{__html: "<svg version='1.1' id='Layer_2' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='15px' height='15px' viewBox='1 1.5 15 15' enable-background='new 1 1.5 15 15' xml:space='preserve'> <g> <g> <path fill='#211B1B' d='M14,1.5H3c-1.104,0-2,0.896-2,2v8c0,1.104,0.896,2,2,2h1.628l1.884,3l1.866-3H14c1.104,0,2-0.896,2-2v-8 C16,2.396,15.104,1.5,14,1.5z M15,11.5c0,0.553-0.447,1-1,1H8l-1.493,2l-1.504-1.991L5,12.5H3c-0.552,0-1-0.447-1-1v-8 c0-0.552,0.448-1,1-1h11c0.553,0,1,0.448,1,1V11.5z'/> </g> </g> </svg>"}} />{this.props.commentCount}</a>; + comments = <a href="#" className={"comment-icon__container theme" + lastCommentClass} onClick={this.props.handleCommentClick}><span className="comment-icon" dangerouslySetInnerHTML={{__html: Constants.COMMENT_ICON }} />{this.props.commentCount}</a>; } return ( diff --git a/web/react/components/post_right.jsx b/web/react/components/post_right.jsx index 93f5d91b0..567be1962 100644 --- a/web/react/components/post_right.jsx +++ b/web/react/components/post_right.jsx @@ -111,7 +111,7 @@ RootPost = React.createClass({ } else { postFiles.push( <div className="post-image__column custom-file" key={fileInfo.path}> - <a href={fileInfo.path+"."+ext} download={fileInfo.name+"."+ext}> + <a href={fileInfo.path+"."+fileInfo.ext} download={fileInfo.name+"."+fileInfo.ext}> <div className={"file-icon "+utils.getIconClassName(ftype)}/> </a> </div> diff --git a/web/react/components/rename_channel_modal.jsx b/web/react/components/rename_channel_modal.jsx index 2ae331626..9e4a25f85 100644 --- a/web/react/components/rename_channel_modal.jsx +++ b/web/react/components/rename_channel_modal.jsx @@ -89,12 +89,19 @@ module.exports = React.createClass({ this.refs.channel_name.getDOMNode().value = channel_name; this.setState({ channel_name: channel_name }) }, + handleClose: function() { + this.setState({display_name: "", channel_name: "", display_name_error: "", server_error: "", name_error: ""}); + }, componentDidMount: function() { var self = this; $(this.refs.modal.getDOMNode()).on('show.bs.modal', function(e) { var button = $(e.relatedTarget); self.setState({ display_name: button.attr('data-display'), title: button.attr('data-name'), channel_id: button.attr('data-channelid') }); }); + $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', this.handleClose); + }, + componentWillUnmount: function() { + $(this.refs.modal.getDOMNode()).off('hidden.bs.modal', this.handleClose); }, getInitialState: function() { return { display_name: "", channel_name: "", channel_id: "" }; diff --git a/web/react/components/rename_team_modal.jsx b/web/react/components/rename_team_modal.jsx index a6da57b67..dfd775a3b 100644 --- a/web/react/components/rename_team_modal.jsx +++ b/web/react/components/rename_team_modal.jsx @@ -44,11 +44,14 @@ module.exports = React.createClass({ onNameChange: function() { this.setState({ name: this.refs.name.getDOMNode().value }) }, + handleClose: function() { + this.setState({ name: this.props.teamDisplayName, name_error: "", server_error: ""}); + }, componentDidMount: function() { - var self = this; - $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', function(e) { - self.setState({ name: self.props.teamDisplayName }); - }); + $(this.refs.modal.getDOMNode()).on('hidden.bs.modal', this.handleClose); + }, + componentWillUnmount: function() { + $(this.refs.modal.getDOMNode()).off('hidden.bs.modal', this.handleClose); }, getInitialState: function() { return { name: this.props.teamDisplayName }; diff --git a/web/react/components/sidebar_header.jsx b/web/react/components/sidebar_header.jsx index 859e425a6..5b442aeac 100644 --- a/web/react/components/sidebar_header.jsx +++ b/web/react/components/sidebar_header.jsx @@ -6,6 +6,8 @@ var utils = require('../utils/utils.jsx'); var client = require('../utils/client.jsx'); var UserStore = require('../stores/user_store.jsx'); +var Constants = require('../utils/constants.jsx'); + function getStateFromStores() { return { teams: UserStore.getTeams() }; } @@ -75,7 +77,7 @@ var NavbarDropdown = React.createClass({ <ul className="nav navbar-nav navbar-right"> <li className="dropdown"> <a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> - <span className="dropdown__icon" dangerouslySetInnerHTML={{__html: " <svg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'width='4px' height='16px' viewBox='0 0 8 32' enable-background='new 0 0 8 32' xml:space='preserve'> <g> <circle cx='4' cy='4.062' r='4'/> <circle cx='4' cy='16' r='4'/> <circle cx='4' cy='28' r='4'/> </g> </svg>"}} /> + <span className="dropdown__icon" dangerouslySetInnerHTML={{__html: Constants.MENU_ICON }} /> </a> <ul className="dropdown-menu" role="menu"> <li><a href="#" data-toggle="modal" data-target="#user_settings1">Account Settings</a></li> diff --git a/web/react/components/signup_user_complete.jsx b/web/react/components/signup_user_complete.jsx index dc5ba64aa..bbf1f670c 100644 --- a/web/react/components/signup_user_complete.jsx +++ b/web/react/components/signup_user_complete.jsx @@ -117,24 +117,24 @@ module.exports = React.createClass({ var signup_message; if (auth_services.indexOf("gitlab") >= 0) { - signup_message = <p>{"Choose your username and password for the " + this.props.teamDisplayName + " " + strings.Team} <a href={"/"+this.props.teamName+"/signup/gitlab"+window.location.search}>{"or sign up with GitLab."}</a></p>; - } else { - signup_message = <p>{"Choose your username and password for the " + this.props.teamDisplayName + " " + strings.Team + "."}</p>; + signup_message = <div><a className="btn btn-custom-login gitlab" href={"/"+this.props.teamName+"/signup/gitlab"+window.location.search}><span className="icon" />{"with GitLab"}</a> + <div className="or__container"><span>or</span></div></div>; } return ( <div> <img className="signup-team-logo" src="/static/images/logo.png" /> - <h4>Welcome to { config.SiteName }</h4> + <h3 className="text-center extra-margin">Signup to { config.SiteName }</h3> <div className="form-group form-group--small"> <span></span> </div> { signup_message } - <p>Your username can be made of lowercase letters and numbers.</p> <label className="control-label">Username</label> <div className={ name_error ? "form-group has-error" : "form-group" }> <input type="text" ref="name" className="form-control" placeholder="" maxLength="128" /> { name_error } + <p className="form__hint">Your username can be made of lowercase letters and numbers.</p> + <p className="form__hint">{"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others"}</p> </div> { email } <label className="control-label">Password</label> @@ -142,7 +142,6 @@ module.exports = React.createClass({ <input type="password" ref="password" className="form-control" placeholder="" maxLength="128" /> { password_error } </div> - <p>{"Pick something " + strings.Team + "mates will recognize. Your username is how you will appear to others"}</p> <p className={ this.state.original_email == "" ? "hidden" : ""}>{ yourEmailIs } You’ll use this address to sign in to {config.SiteName}.</p> <div className="checkbox"><label><input type="checkbox" ref="email_service" /> It's ok to send me occassional email with updates about the {config.SiteName} service. </label></div> <p><button onClick={this.handleSubmit} className="btn-primary btn">Create Account</button></p> diff --git a/web/react/components/user_settings.jsx b/web/react/components/user_settings.jsx index 298f5ee70..2ac9a2371 100644 --- a/web/react/components/user_settings.jsx +++ b/web/react/components/user_settings.jsx @@ -11,6 +11,7 @@ var client = require('../utils/client.jsx'); var AsyncClient = require('../utils/async_client.jsx'); var utils = require('../utils/utils.jsx'); var Constants = require('../utils/constants.jsx'); +var assign = require('object-assign'); function getNotificationsStateFromStores() { var user = UserStore.getCurrentUser(); @@ -95,11 +96,20 @@ var NotificationsTab = React.createClass({ }.bind(this) ); }, + handleClose: function() { + $(this.getDOMNode()).find(".form-control").each(function() { + this.value = ""; + }); + + this.setState(assign({},getNotificationsStateFromStores(),{server_error: null})); + }, componentDidMount: function() { UserStore.addChangeListener(this._onChange); + $('#user_settings1').on('hidden.bs.modal', this.handleClose); }, componentWillUnmount: function() { UserStore.removeChangeListener(this._onChange); + $('#user_settings1').off('hidden.bs.modal', this.handleClose); }, _onChange: function() { var newState = getNotificationsStateFromStores(); @@ -502,6 +512,18 @@ var SecurityTab = React.createClass({ handleDevicesOpen: function() { $("#user_settings1").modal('hide'); }, + handleClose: function() { + $(this.getDOMNode()).find(".form-control").each(function() { + this.value = ""; + }); + this.setState({current_password: '', new_password: '', confirm_password: '', server_error: null, password_error: null}); + }, + componentDidMount: function() { + $('#user_settings1').on('hidden.bs.modal', this.handleClose); + }, + componentWillUnmount: function() { + $('#user_settings1').off('hidden.bs.modal', this.handleClose); + }, getInitialState: function() { return { current_password: '', new_password: '', confirm_password: '' }; }, @@ -699,13 +721,15 @@ var GeneralTab = React.createClass({ if(!this.submitActive) return; - if(this.state.picture.type !== "image/jpeg") { - this.setState({client_error: "Only JPG images may be used for profile pictures"}); + var picture = this.state.picture; + + if(picture.type !== "image/jpeg" && picture.type !== "image/png") { + this.setState({client_error: "Only JPG or PNG images may be used for profile pictures"}); return; } formData = new FormData(); - formData.append('image', this.state.picture, this.state.picture.name); + formData.append('image', picture, picture.name); client.uploadProfileImage(formData, function(data) { @@ -751,6 +775,19 @@ var GeneralTab = React.createClass({ this.submitActive = false this.props.updateSection(section); }, + handleClose: function() { + $(this.getDOMNode()).find(".form-control").each(function() { + this.value = ""; + }); + + this.setState(assign({}, this.getInitialState(), {client_error: null, server_error: null, email_error: null})); + }, + componentDidMount: function() { + $('#user_settings1').on('hidden.bs.modal', this.handleClose); + }, + componentWillUnmount: function() { + $('#user_settings1').off('hidden.bs.modal', this.handleClose); + }, getInitialState: function() { var user = this.props.user; @@ -994,10 +1031,14 @@ var AppearanceTab = React.createClass({ var hex = utils.rgb2hex(e.target.style.backgroundColor); this.setState({ theme: hex.toLowerCase() }); }, + handleClose: function() { + this.setState({server_error: null}); + }, componentDidMount: function() { if (this.props.activeSection === "theme") { $(this.refs[this.state.theme].getDOMNode()).addClass('active-border'); } + $('#user_settings1').on('hidden.bs.modal', this.handleClose); }, componentDidUpdate: function() { if (this.props.activeSection === "theme") { @@ -1005,6 +1046,9 @@ var AppearanceTab = React.createClass({ $(this.refs[this.state.theme].getDOMNode()).addClass('active-border'); } }, + componentWillUnmount: function() { + $('#user_settings1').off('hidden.bs.modal', this.handleClose); + }, getInitialState: function() { var user = UserStore.getCurrentUser(); var theme = config.ThemeColors != null ? config.ThemeColors[0] : "#2389d7"; |