From 8376ff623380d20b8e4e26fa6abb2dd775930a7c Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Mon, 21 Mar 2016 15:08:26 -0400 Subject: Adding loading indicator after clicking invite channel member button --- webapp/components/channel_invite_button.jsx | 91 +++++++++++++++++++++++++++++ webapp/components/channel_invite_modal.jsx | 51 ++++++---------- webapp/components/filtered_user_list.jsx | 5 +- webapp/components/user_list.jsx | 7 ++- webapp/components/user_list_row.jsx | 9 ++- 5 files changed, 123 insertions(+), 40 deletions(-) create mode 100644 webapp/components/channel_invite_button.jsx (limited to 'webapp') diff --git a/webapp/components/channel_invite_button.jsx b/webapp/components/channel_invite_button.jsx new file mode 100644 index 000000000..b5a690845 --- /dev/null +++ b/webapp/components/channel_invite_button.jsx @@ -0,0 +1,91 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import React from 'react'; + +import * as AsyncClient from 'utils/async_client.jsx'; +import * as Client from 'utils/client.jsx'; + +import {FormattedMessage} from 'react-intl'; + +import loadingGif from 'images/load.gif'; + +export default class ChannelInviteButton extends React.Component { + static get propTypes() { + return { + user: React.PropTypes.object.isRequired, + channel: React.PropTypes.object.isRequired, + onInviteError: React.PropTypes.func.isRequired + }; + } + + constructor(props) { + super(props); + + this.handleClick = this.handleClick.bind(this); + + this.state = { + addingUser: false + }; + } + + handleClick(e) { + e.preventDefault(); + + if (this.state.addingUser) { + return; + } + + this.setState({ + addingUser: true + }); + + const data = { + user_id: this.props.user.id + }; + + Client.addChannelMember( + this.props.channel.id, + data, + () => { + this.setState({ + addingUser: false + }); + + this.props.onInviteError(null); + AsyncClient.getChannelExtraInfo(); + }, + (err) => { + this.setState({ + addingUser: false + }); + + this.props.onInviteError(err); + } + ); + } + + render() { + if (this.state.addingUser) { + return ( + + ); + } + + return ( + + + + + ); + } +} diff --git a/webapp/components/channel_invite_modal.jsx b/webapp/components/channel_invite_modal.jsx index dfb0d4187..c7c1906a5 100644 --- a/webapp/components/channel_invite_modal.jsx +++ b/webapp/components/channel_invite_modal.jsx @@ -2,6 +2,7 @@ // See License.txt for license information. import $ from 'jquery'; +import ChannelInviteButton from './channel_invite_button.jsx'; import FilteredUserList from './filtered_user_list.jsx'; import LoadingScreen from './loading_screen.jsx'; @@ -9,7 +10,6 @@ import ChannelStore from 'stores/channel_store.jsx'; import UserStore from 'stores/user_store.jsx'; import * as Utils from 'utils/utils.jsx'; -import * as Client from 'utils/client.jsx'; import * as AsyncClient from 'utils/async_client.jsx'; import {FormattedMessage} from 'react-intl'; @@ -23,9 +23,8 @@ export default class ChannelInviteModal extends React.Component { super(props); this.onListenerChange = this.onListenerChange.bind(this); - this.handleInvite = this.handleInvite.bind(this); this.getStateFromStores = this.getStateFromStores.bind(this); - this.createInviteButton = this.createInviteButton.bind(this); + this.handleInviteError = this.handleInviteError.bind(this); this.state = this.getStateFromStores(); } @@ -120,36 +119,16 @@ export default class ChannelInviteModal extends React.Component { this.setState(newState); } } - handleInvite(user) { - const data = { - user_id: user.id - }; - - Client.addChannelMember( - this.props.channel.id, - data, - () => { - this.setState({inviteError: null}); - AsyncClient.getChannelExtraInfo(); - }, - (err) => { - this.setState({inviteError: err.message}); - } - ); - } - createInviteButton({user}) { - return ( - - - - - ); + handleInviteError(err) { + if (err) { + this.setState({ + inviteError: err.message + }); + } else { + this.setState({ + inviteError: null + }); + } } render() { var inviteError = null; @@ -169,7 +148,11 @@ export default class ChannelInviteModal extends React.Component { ); } diff --git a/webapp/components/filtered_user_list.jsx b/webapp/components/filtered_user_list.jsx index 1e4afd2be..bd6c49714 100644 --- a/webapp/components/filtered_user_list.jsx +++ b/webapp/components/filtered_user_list.jsx @@ -114,6 +114,7 @@ class FilteredUserList extends React.Component { @@ -123,13 +124,15 @@ class FilteredUserList extends React.Component { FilteredUserList.defaultProps = { users: [], - actions: [] + actions: [], + actionProps: {} }; FilteredUserList.propTypes = { intl: intlShape.isRequired, users: React.PropTypes.arrayOf(React.PropTypes.object), actions: React.PropTypes.arrayOf(React.PropTypes.func), + actionProps: React.PropTypes.object, style: React.PropTypes.object }; diff --git a/webapp/components/user_list.jsx b/webapp/components/user_list.jsx index 2140158e6..b5d42decc 100644 --- a/webapp/components/user_list.jsx +++ b/webapp/components/user_list.jsx @@ -18,6 +18,7 @@ export default class UserList extends React.Component { key={user.id} user={user} actions={this.props.actions} + actionProps={this.props.actionProps} /> ); }); @@ -42,10 +43,12 @@ export default class UserList extends React.Component { UserList.defaultProps = { users: [], - actions: [] + actions: [], + actionProps: {} }; UserList.propTypes = { users: React.PropTypes.arrayOf(React.PropTypes.object), - actions: React.PropTypes.arrayOf(React.PropTypes.func) + actions: React.PropTypes.arrayOf(React.PropTypes.func), + actionProps: React.PropTypes.object }; diff --git a/webapp/components/user_list_row.jsx b/webapp/components/user_list_row.jsx index ed3a29a61..f6fd91688 100644 --- a/webapp/components/user_list_row.jsx +++ b/webapp/components/user_list_row.jsx @@ -6,7 +6,7 @@ import PreferenceStore from 'stores/preference_store.jsx'; import * as Utils from 'utils/utils.jsx'; import React from 'react'; -export default function UserListRow({user, actions}) { +export default function UserListRow({user, actions, actionProps}) { const nameFormat = PreferenceStore.get(Constants.Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', ''); let name = user.username; @@ -21,6 +21,7 @@ export default function UserListRow({user, actions}) { ); }); @@ -56,10 +57,12 @@ export default function UserListRow({user, actions}) { } UserListRow.defaultProps = { - actions: [] + actions: [], + actionProps: {} }; UserListRow.propTypes = { user: React.PropTypes.object.isRequired, - actions: React.PropTypes.arrayOf(React.PropTypes.func) + actions: React.PropTypes.arrayOf(React.PropTypes.func), + actionProps: React.PropTypes.object }; -- cgit v1.2.3-1-g7c22