Commit f1524bc5 authored by Sudheer's avatar Sudheer Committed by Carlos Tadeu Panato Junior

MM-12283 Add loader for more_channels modal (#1798)

* MM-12283 Add loader for more_channels modal

  * Add loader when searching for channels

* Fix prop name to channelsRequestStarted

 * Update snapshot

* Remove obsolete snapshot
parent efa293b2
......@@ -6,9 +6,9 @@ import {bindActionCreators} from 'redux';
import {createSelector} from 'reselect';
import {getChannels} from 'mattermost-redux/actions/channels';
import {getOtherChannels} from 'mattermost-redux/selectors/entities/channels';
import {getCurrentTeam} from 'mattermost-redux/selectors/entities/teams';
import {RequestStatus} from 'mattermost-redux/constants';
import MoreChannels from './more_channels.jsx';
......@@ -24,6 +24,7 @@ function mapStateToProps(state) {
channels: getNotArchivedOtherChannels(state) || [],
teamId: team.id,
teamName: team.name,
channelsRequestStarted: state.requests.channels.getChannels.status === RequestStatus.STARTED,
};
}
......
......@@ -26,6 +26,7 @@ export default class MoreChannels extends React.Component {
teamName: PropTypes.string.isRequired,
onModalDismissed: PropTypes.func,
handleNewChannel: PropTypes.func,
channelsRequestStarted: PropTypes.bool,
actions: PropTypes.shape({
getChannels: PropTypes.func.isRequired,
}).isRequired,
......@@ -41,6 +42,7 @@ export default class MoreChannels extends React.Component {
search: false,
searchedChannels: [],
serverError: null,
searching: false,
};
}
......@@ -98,10 +100,11 @@ export default class MoreChannels extends React.Component {
if (term === '') {
this.onChange(true);
this.setState({search: false, searchedChannels: []});
this.setState({search: false, searchedChannels: [], searching: false});
this.searchTimeoutId = '';
return;
}
this.setState({search: true, searching: true});
const searchTimeoutId = setTimeout(
() => {
......@@ -122,13 +125,14 @@ export default class MoreChannels extends React.Component {
}
setSearchResults = (channels) => {
this.setState({search: true, searchedChannels: channels.filter((c) => c.delete_at === 0)});
this.setState({searchedChannels: channels.filter((c) => c.delete_at === 0), searching: false});
}
render() {
const {
channels,
teamId,
channelsRequestStarted,
} = this.props;
const {
......@@ -136,6 +140,7 @@ export default class MoreChannels extends React.Component {
searchedChannels,
serverError: serverErrorState,
show,
searching,
} = this.state;
let serverError;
......@@ -201,6 +206,7 @@ export default class MoreChannels extends React.Component {
search={this.search}
handleJoin={this.handleJoin}
noResultsText={createChannelHelpText}
loading={search ? searching : channelsRequestStarted}
/>
{serverError}
</Modal.Body>
......
......@@ -36,7 +36,7 @@ export default class SearchableChannelList extends React.Component {
componentDidMount() {
// only focus the search box on desktop so that we don't cause the keyboard to open on mobile
if (!UserAgent.isMobile()) {
if (!UserAgent.isMobile() && this.refs.filter) {
this.refs.filter.focus();
}
}
......@@ -131,8 +131,8 @@ export default class SearchableChannelList extends React.Component {
let nextButton;
let previousButton;
if (channels == null) {
listContent = <LoadingScreen/>;
if (this.props.loading && channels.length === 0) {
listContent = <LoadingScreen style={{marginTop: '50%'}}/>;
} else if (channels.length === 0) {
listContent = (
<div className='no-channel-message'>
......@@ -224,4 +224,5 @@ SearchableChannelList.propTypes = {
search: PropTypes.func.isRequired,
handleJoin: PropTypes.func.isRequired,
noResultsText: PropTypes.object,
loading: PropTypes.bool,
};
......@@ -81,6 +81,7 @@ exports[`components/MoreChannels should match snapshot and state 1`] = `
channelsPerPage={50}
handleJoin={[Function]}
isSearch={false}
loading={false}
nextPage={[Function]}
noResultsText={
<Connect(TeamPermissionGate)
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/SearchableChannelList should match init snapshot 1`] = `
<div
className="filtered-user-list"
>
<div
className="filter-row"
>
<div
className="col-sm-12"
>
<QuickInput
className="form-control filter-textbox"
delayInputUpdate={false}
id="searchChannelsTextbox"
onInput={[Function]}
placeholder="Search channels"
value=""
/>
</div>
</div>
<div
className="more-modal__list"
>
<div>
<LoadingScreen
position="relative"
style={
Object {
"marginTop": "50%",
}
}
/>
</div>
</div>
<div
className="filter-controls"
/>
</div>
`;
......@@ -5,12 +5,14 @@ import React from 'react';
import {shallow} from 'enzyme';
import MoreChannels from 'components/more_channels/more_channels.jsx';
import SearchableChannelList from 'components/searchable_channel_list.jsx';
describe('components/MoreChannels', () => {
const baseProps = {
channels: [{id: 'channel_id_1', delete_at: 0}],
teamId: 'team_id',
teamName: 'team_name',
channelsRequestStarted: false,
onModalDismissed: () => {}, // eslint-disable-line no-empty-function
handleNewChannel: () => {}, // eslint-disable-line no-empty-function
actions: {
......@@ -29,6 +31,7 @@ describe('components/MoreChannels', () => {
expect(wrapper.state('show')).toEqual(true);
expect(wrapper.state('search')).toEqual(false);
expect(wrapper.state('serverError')).toBeNull();
expect(wrapper.state('searching')).toEqual(false);
// on componentDidMount
expect(actions.getChannels).toHaveBeenCalledTimes(1);
......@@ -80,4 +83,14 @@ describe('components/MoreChannels', () => {
expect(actions.getChannels).toHaveBeenCalledTimes(2);
expect(actions.getChannels).toHaveBeenCalledWith(props.teamId, 2, 50);
});
test('should have loading prop true when searching state is true', () => {
const wrapper = shallow(
<MoreChannels {...baseProps}/>
);
wrapper.setState({search: true, searching: true});
const searchList = wrapper.find(SearchableChannelList);
expect(searchList.props().loading).toEqual(true);
});
});
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import {shallow} from 'enzyme';
import SearchableChannelList from 'components/searchable_channel_list.jsx';
describe('components/SearchableChannelList', () => {
const baseProps = {
channels: [],
isSearch: false,
channelsPerPage: 10,
nextPage: () => {}, // eslint-disable-line no-empty-function
search: () => {}, // eslint-disable-line no-empty-function
handleJoin: () => {}, // eslint-disable-line no-empty-function
loading: true,
};
test('should match init snapshot', () => {
const wrapper = shallow(
<SearchableChannelList {...baseProps}/>
);
expect(wrapper).toMatchSnapshot();
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment