diff options
-rw-r--r-- | doc/developer/Setup.md | 26 | ||||
-rw-r--r-- | web/react/components/register_app_modal.jsx | 192 | ||||
-rw-r--r-- | web/react/components/user_settings/user_settings_developer.jsx | 12 | ||||
-rw-r--r-- | web/react/dispatcher/event_helpers.jsx | 7 | ||||
-rw-r--r-- | web/react/stores/modal_store.jsx | 1 | ||||
-rw-r--r-- | web/react/utils/constants.jsx | 3 | ||||
-rw-r--r-- | web/react/utils/text_formatting.jsx | 2 |
7 files changed, 154 insertions, 89 deletions
diff --git a/doc/developer/Setup.md b/doc/developer/Setup.md index 882aac530..24e7d6a90 100644 --- a/doc/developer/Setup.md +++ b/doc/developer/Setup.md @@ -11,7 +11,10 @@ Developer Machine Setup `docker-machine ip dev` 3. Add a line to your /etc/hosts that goes `<Docker IP> dockerhost` 4. Run `docker-machine env dev` and copy the export statements to your ~/.bash_profile -2. Download Go 1.5.1 from http://golang.org/dl/ +2. Download Go 1.5.1 and Node.js using Homebrew + 1. Download Homebrew from http://brew.sh/ + 2. `brew install go` + 3. `brew install node` 3. Set up your Go workspace 1. `mkdir ~/go` 2. Add the following to your ~/.bash_profile @@ -21,20 +24,17 @@ Developer Machine Setup If you don't increase the file handle limit you may see some weird build issues with browserify or npm. 3. Reload your bash profile `source ~/.bash_profile` -4. Install Node.js using Homebrew - 1. Download Homebrew from http://brew.sh/ - 2. `brew install node` -5. Install Compass +4. Install Compass 1. Run `ruby -v` and check the ruby version is 1.8.7 or higher 2. `sudo gem install compass` -6. Download Mattermost +5. Download Mattermost `cd ~/go` `mkdir -p src/github.com/mattermost` `cd src/github.com/mattermost` `git clone https://github.com/mattermost/platform.git` `cd platform` -7. Run unit tests on Mattermost using `make test` to make sure the installation was successful -8. If tests passed, you can now run Mattermost using `make run` +6. Run unit tests on Mattermost using `make test` to make sure the installation was successful +7. If tests passed, you can now run Mattermost using `make run` Any issues? Please let us know on our forums at: http://forum.mattermost.org @@ -64,13 +64,9 @@ Any issues? Please let us know on our forums at: http://forum.mattermost.org If you don't increase the file handle limit you may see some weird build issues with browserify or npm. 3. Reload your bashrc `source ~/.bashrc` -6. Install Node.js - 1. Download the newest version of the Node.js sources from https://nodejs.org/en/download/ - 2. Extract the contents of the package and cd into the extracted files - 3. Compile and install Node.js - `./configure` - `make` - `make install` +6. Install Node.js + `curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -` + `sudo apt-get install -y nodejs` 7. Install Ruby and Compass `apt-get install ruby` `apt-get install ruby-dev` diff --git a/web/react/components/register_app_modal.jsx b/web/react/components/register_app_modal.jsx index 100600c4b..f49b33f73 100644 --- a/web/react/components/register_app_modal.jsx +++ b/web/react/components/register_app_modal.jsx @@ -2,21 +2,57 @@ // See License.txt for license information. import * as Client from '../utils/client.jsx'; +import ModalStore from '../stores/modal_store.jsx'; + +const Modal = ReactBootstrap.Modal; + +import Constants from '../utils/constants.jsx'; +const ActionTypes = Constants.ActionTypes; export default class RegisterAppModal extends React.Component { constructor() { super(); - this.register = this.register.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); this.onHide = this.onHide.bind(this); this.save = this.save.bind(this); + this.updateShow = this.updateShow.bind(this); - this.state = {clientId: '', clientSecret: '', saved: false}; + this.state = { + clientId: '', + clientSecret: '', + saved: false, + show: false + }; } componentDidMount() { - $(ReactDOM.findDOMNode(this)).on('hide.bs.modal', this.onHide); + ModalStore.addModalListener(ActionTypes.TOGGLE_REGISTER_APP_MODAL, this.updateShow); + } + componentWillUnmount() { + ModalStore.removeModalListener(ActionTypes.TOGGLE_REGISTER_APP_MODAL, this.updateShow); + } + updateShow(show) { + if (!show) { + if (this.state.clientId !== '' && !this.state.saved) { + return; + } + + this.setState({ + clientId: '', + clientSecret: '', + saved: false, + homepageError: null, + callbackError: null, + serverError: null, + nameError: null + }); + } + + this.setState({show}); } - register() { + handleSubmit(e) { + e.preventDefault(); + var state = this.state; state.serverError = null; @@ -94,6 +130,7 @@ export default class RegisterAppModal extends React.Component { } var body = ''; + var footer = ''; if (this.state.clientId === '') { body = ( <div className='settings-modal'> @@ -148,24 +185,29 @@ export default class RegisterAppModal extends React.Component { </div> </div> {serverError} - <hr /> - <a - className='btn btn-sm theme pull-right' - href='#' - data-dismiss='modal' - aria-label='Close' - > - {'Cancel'} - </a> - <a - className='btn btn-sm btn-primary pull-right' - onClick={this.register} - > - {'Register'} - </a> </div> </div> ); + + footer = ( + <div> + <button + type='button' + className='btn btn-default' + onClick={() => this.updateShow(false)} + > + {'Cancel'} + </button> + <button + onClick={this.handleSubmit} + type='submit' + className='btn btn-primary' + tabIndex='3' + > + {'Register'} + </button> + </div> + ); } else { var btnClass = ' disabled'; if (this.state.saved) { @@ -173,17 +215,35 @@ export default class RegisterAppModal extends React.Component { } body = ( - <div className='form-group user-settings'> - <h3>{'Your Application Credentials'}</h3> - <br/> - <br/> - <label className='col-sm-12 control-label'>{'Client ID: '}{this.state.clientId}</label> - <label className='col-sm-12 control-label'>{'Client Secret: '}{this.state.clientSecret}</label> + <div className='form-horizontal user-settings'> + <h4 className='padding-bottom x3'>{'Your Application Credentials'}</h4> <br/> + <div className='row'> + <label className='col-sm-4 control-label'>{'Client ID'}</label> + <div className='col-sm-7'> + <input + className='form-control' + type='text' + value={this.state.clientId} + readOnly='true' + /> + </div> + </div> <br/> + <div className='row padding-top x2'> + <label className='col-sm-4 control-label'>{'Client Secret'}</label> + <div className='col-sm-7'> + <input + className='form-control' + type='text' + value={this.state.clientSecret} + readOnly='true' + /> + </div> + </div> <br/> <br/> - <strong>{'Save these somewhere SAFE and SECURE. We can retrieve your Client Id if you lose it, but your Client Secret will be lost forever if you were to lose it.'}</strong> + <strong>{'Save these somewhere SAFE and SECURE. Treat your Client ID as your app\'s username and your Client Secret as the app\'s password.'}</strong> <br/> <br/> <div className='checkbox'> @@ -192,56 +252,50 @@ export default class RegisterAppModal extends React.Component { ref='save' type='checkbox' checked={this.state.saved} - onClick={this.save} - > - {'I have saved both my Client Id and Client Secret somewhere safe'} - </input> + onChange={this.save} + /> + {'I have saved both my Client Id and Client Secret somewhere safe'} </label> </div> - <a - className={'btn btn-sm btn-primary pull-right' + btnClass} - href='#' - data-dismiss='modal' - aria-label='Close' - > - {'Close'} - </a> </div> ); + + footer = ( + <a + className={'btn btn-sm btn-primary pull-right' + btnClass} + href='#' + onClick={(e) => { + e.preventDefault(); + this.updateShow(false); + }} + > + {'Close'} + </a> + ); } return ( - <div - className='modal fade' - ref='modal' - id='register_app' - role='dialog' - aria-hidden='true' - > - <div className='modal-dialog'> - <div className='modal-content'> - <div className='modal-header'> - <button - type='button' - className='close' - data-dismiss='modal' - aria-label='Close' - > - <span aria-hidden='true'>{'×'}</span> - </button> - <h4 - className='modal-title' - ref='title' - > - {'Developer Applications'} - </h4> - </div> - <div className='modal-body'> - {body} - </div> - </div> - </div> - </div> + <span> + <Modal + show={this.state.show} + onHide={() => this.updateShow(false)} + > + <Modal.Header closeButton={true}> + <Modal.Title>{'Developer Applications'}</Modal.Title> + </Modal.Header> + <form + role='form' + className='form-horizontal' + > + <Modal.Body> + {body} + </Modal.Body> + <Modal.Footer> + {footer} + </Modal.Footer> + </form> + </Modal> + </span> ); } } diff --git a/web/react/components/user_settings/user_settings_developer.jsx b/web/react/components/user_settings/user_settings_developer.jsx index 2d02c255a..01e13be57 100644 --- a/web/react/components/user_settings/user_settings_developer.jsx +++ b/web/react/components/user_settings/user_settings_developer.jsx @@ -3,16 +3,19 @@ import SettingItemMin from '../setting_item_min.jsx'; import SettingItemMax from '../setting_item_max.jsx'; +import * as EventHelpers from '../../dispatcher/event_helpers.jsx'; export default class DeveloperTab extends React.Component { constructor(props) { super(props); + this.register = this.register.bind(this); + this.state = {}; } register() { - $('#user_settings1').modal('hide'); - $('#register_app').modal('show'); + this.props.closeModal(); + EventHelpers.showRegisterAppModal(); } render() { var appSection; @@ -21,7 +24,10 @@ export default class DeveloperTab extends React.Component { var inputs = []; inputs.push( - <div className='form-group'> + <div + key='registerbtn' + className='form-group' + > <div className='col-sm-7'> <a className='btn btn-sm btn-primary' diff --git a/web/react/dispatcher/event_helpers.jsx b/web/react/dispatcher/event_helpers.jsx index d7f255aaa..856eec2f1 100644 --- a/web/react/dispatcher/event_helpers.jsx +++ b/web/react/dispatcher/event_helpers.jsx @@ -104,3 +104,10 @@ export function showInviteMemberModal() { value: true }); } + +export function showRegisterAppModal() { + AppDispatcher.handleViewAction({ + type: ActionTypes.TOGGLE_REGISTER_APP_MODAL, + value: true + }); +} diff --git a/web/react/stores/modal_store.jsx b/web/react/stores/modal_store.jsx index a26a97f53..9f33cf022 100644 --- a/web/react/stores/modal_store.jsx +++ b/web/react/stores/modal_store.jsx @@ -35,6 +35,7 @@ class ModalStoreClass extends EventEmitter { case ActionTypes.TOGGLE_INVITE_MEMBER_MODAL: case ActionTypes.TOGGLE_DELETE_POST_MODAL: case ActionTypes.TOGGLE_GET_TEAM_INVITE_LINK_MODAL: + case ActionTypes.TOGGLE_REGISTER_APP_MODAL: this.emit(type, value, args); break; } diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx index cbeab18ba..99bd2453c 100644 --- a/web/react/utils/constants.jsx +++ b/web/react/utils/constants.jsx @@ -49,7 +49,8 @@ export default { TOGGLE_IMPORT_THEME_MODAL: null, TOGGLE_INVITE_MEMBER_MODAL: null, TOGGLE_DELETE_POST_MODAL: null, - TOGGLE_GET_TEAM_INVITE_LINK_MODAL: null + TOGGLE_GET_TEAM_INVITE_LINK_MODAL: null, + TOGGLE_REGISTER_APP_MODAL: null }), PayloadSources: keyMirror({ diff --git a/web/react/utils/text_formatting.jsx b/web/react/utils/text_formatting.jsx index 3a912fd75..f0bd46f9d 100644 --- a/web/react/utils/text_formatting.jsx +++ b/web/react/utils/text_formatting.jsx @@ -188,7 +188,7 @@ function highlightCurrentMentions(text, tokens) { const newAlias = `MM_SELFMENTION${index}`; newTokens.set(newAlias, { - value: `<span class='mention-highlight'>${alias}</span>` + token.extraText, + value: `<span class='mention-highlight'>${alias}</span>` + (token.extraText || ''), originalText: token.originalText }); output = output.replace(alias, newAlias); |