MM-18571: Include self user in autocomplete (#3761)
* Include current user in search * Removed unused parameters * Include new text in i18n * Update autocomplete tests to include current user * Use FormattedText * Update app/selectors/autocomplete.test.js Co-Authored-By: Miguel Alatzar <migbot@users.noreply.github.com> Co-authored-by: Miguel Alatzar <migbot@users.noreply.github.com>
This commit is contained in:
parent
7733a714de
commit
ce53a7ac29
5 changed files with 62 additions and 14 deletions
|
|
@ -13,6 +13,7 @@ import {paddingHorizontal as padding} from 'app/components/safe_area_view/iphone
|
|||
import {BotTag, GuestTag} from 'app/components/tag';
|
||||
import TouchableWithFeedback from 'app/components/touchable_with_feedback';
|
||||
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
export default class AtMentionItem extends PureComponent {
|
||||
static propTypes = {
|
||||
|
|
@ -25,6 +26,7 @@ export default class AtMentionItem extends PureComponent {
|
|||
isBot: PropTypes.bool,
|
||||
theme: PropTypes.object.isRequired,
|
||||
isLandscape: PropTypes.bool.isRequired,
|
||||
isCurrentUser: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
|
@ -47,6 +49,7 @@ export default class AtMentionItem extends PureComponent {
|
|||
isBot,
|
||||
isLandscape,
|
||||
isGuest,
|
||||
isCurrentUser,
|
||||
} = this.props;
|
||||
|
||||
const style = getStyleFromTheme(theme);
|
||||
|
|
@ -78,6 +81,12 @@ export default class AtMentionItem extends PureComponent {
|
|||
/>
|
||||
{hasFullName && <Text style={style.rowUsername}>{' - '}</Text>}
|
||||
{hasFullName && <Text style={style.rowFullname}>{`${firstName} ${lastName}`}</Text>}
|
||||
{isCurrentUser &&
|
||||
<FormattedText
|
||||
style={style.rowFullname}
|
||||
id='suggestion.mention.you'
|
||||
defaultMessage='(you)'
|
||||
/>}
|
||||
</TouchableWithFeedback>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {getUser} from 'mattermost-redux/selectors/entities/users';
|
||||
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';
|
||||
|
||||
import {getTheme} from 'mattermost-redux/selectors/entities/preferences';
|
||||
|
||||
|
|
@ -23,6 +23,7 @@ function mapStateToProps(state, ownProps) {
|
|||
isGuest: isGuest(user),
|
||||
theme: getTheme(state),
|
||||
isLandscape: isLandscape(state),
|
||||
isCurrentUser: getCurrentUserId(state) === user.id,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {General} from 'mattermost-redux/constants';
|
|||
import {getConfig} from 'mattermost-redux/selectors/entities/general';
|
||||
import {getMyChannels, getOtherChannels} from 'mattermost-redux/selectors/entities/channels';
|
||||
import {
|
||||
getCurrentUser, getCurrentUserId, getProfilesInCurrentChannel,
|
||||
getCurrentUser, getProfilesInCurrentChannel,
|
||||
getProfilesNotInCurrentChannel, getProfilesInCurrentTeam,
|
||||
} from 'mattermost-redux/selectors/entities/users';
|
||||
import {sortChannelsByDisplayName} from 'mattermost-redux/utils/channel_utils';
|
||||
|
|
@ -64,9 +64,8 @@ export const getMatchTermForChannelMention = (() => {
|
|||
|
||||
export const filterMembersInChannel = createSelector(
|
||||
getProfilesInCurrentChannel,
|
||||
getCurrentUserId,
|
||||
(state, matchTerm) => matchTerm,
|
||||
(profilesInChannel, currentUserId, matchTerm) => {
|
||||
(profilesInChannel, matchTerm) => {
|
||||
if (matchTerm === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -74,12 +73,12 @@ export const filterMembersInChannel = createSelector(
|
|||
let profiles;
|
||||
if (matchTerm) {
|
||||
profiles = profilesInChannel.filter((p) => {
|
||||
return ((p.id !== currentUserId && p.delete_at === 0) && (
|
||||
return (p.delete_at === 0 && (
|
||||
p.username.toLowerCase().includes(matchTerm) || p.email.toLowerCase().includes(matchTerm) ||
|
||||
p.first_name.toLowerCase().includes(matchTerm) || p.last_name.toLowerCase().includes(matchTerm)));
|
||||
});
|
||||
} else {
|
||||
profiles = profilesInChannel.filter((p) => p.id !== currentUserId && p.delete_at === 0);
|
||||
profiles = profilesInChannel.filter((p) => p.delete_at === 0);
|
||||
}
|
||||
|
||||
// already sorted
|
||||
|
|
@ -89,9 +88,8 @@ export const filterMembersInChannel = createSelector(
|
|||
|
||||
export const filterMembersNotInChannel = createSelector(
|
||||
getProfilesNotInCurrentChannel,
|
||||
getCurrentUserId,
|
||||
(state, matchTerm) => matchTerm,
|
||||
(profilesNotInChannel, currentUserId, matchTerm) => {
|
||||
(profilesNotInChannel, matchTerm) => {
|
||||
if (matchTerm === null) {
|
||||
return null;
|
||||
}
|
||||
|
|
@ -104,7 +102,7 @@ export const filterMembersNotInChannel = createSelector(
|
|||
p.email.toLowerCase().includes(matchTerm) ||
|
||||
p.first_name.toLowerCase().includes(matchTerm) ||
|
||||
p.last_name.toLowerCase().includes(matchTerm)
|
||||
) && (p.delete_at === 0 && p.id !== currentUserId);
|
||||
) && p.delete_at === 0;
|
||||
});
|
||||
} else {
|
||||
profiles = profilesNotInChannel.filter((p) => p.delete_at === 0);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import assert from 'assert';
|
|||
import {
|
||||
getMatchTermForAtMention,
|
||||
filterMembersNotInChannel,
|
||||
filterMembersInChannel,
|
||||
} from 'app/selectors/autocomplete';
|
||||
|
||||
/* eslint-disable max-nested-callbacks */
|
||||
|
|
@ -67,24 +68,24 @@ describe('Selectors.Autocomplete', () => {
|
|||
users: {
|
||||
currentUserId: 'current-user-id',
|
||||
profiles: {
|
||||
'current-user-id': {id: 'current-user-id', username: 'current', delete_at: 0},
|
||||
'current-user-id': {id: 'current-user-id', username: 'current', first_name: 'Current', last_name: 'User', email: 'current@user.com', delete_at: 0},
|
||||
'test-user-id': {id: 'test-user-id', username: 'test', first_name: 'Test', last_name: 'User', email: 'test@example.com', delete_at: 0},
|
||||
'another-user-id': {id: 'another-user-id', username: 'another', first_name: 'Another', last_name: 'One', email: 'another@example.com', delete_at: 0},
|
||||
'deleted-user-id': {id: 'deleted-user-id', username: 'deleted', first_name: 'Remvoed', last_name: 'Friend', email: 'deleted@example.com', delete_at: 123},
|
||||
},
|
||||
profilesNotInChannel: {
|
||||
'current-channel-id': new Set(['test-user-id', 'another-user-id', 'deleted-user-id']),
|
||||
'current-channel-id': new Set(['current-user-id', 'test-user-id', 'another-user-id', 'deleted-user-id']),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let profiles = filterMembersNotInChannel(state, '');
|
||||
expect(profiles.length).toBe(2);
|
||||
expect(profiles.length).toBe(3);
|
||||
|
||||
// filter to get the current user, should return zero results
|
||||
// filter to get the current user, should return single result
|
||||
profiles = filterMembersNotInChannel(state, 'current');
|
||||
expect(profiles.length).toBe(0);
|
||||
expect(profiles.length).toBe(1);
|
||||
|
||||
profiles = filterMembersNotInChannel(state, 'tes');
|
||||
expect(profiles.length).toBe(1);
|
||||
|
|
@ -95,4 +96,42 @@ describe('Selectors.Autocomplete', () => {
|
|||
profiles = filterMembersNotInChannel(state, 'example');
|
||||
expect(profiles.length).toBe(2);
|
||||
});
|
||||
|
||||
it('Should return profiles in channel', () => {
|
||||
const state = {
|
||||
entities: {
|
||||
channels: {
|
||||
currentChannelId: 'current-channel-id',
|
||||
},
|
||||
users: {
|
||||
currentUserId: 'current-user-id',
|
||||
profiles: {
|
||||
'current-user-id': {id: 'current-user-id', username: 'current', first_name: 'Current', last_name: 'User', email: 'current@user.com', delete_at: 0},
|
||||
'test-user-id': {id: 'test-user-id', username: 'test', first_name: 'Test', last_name: 'User', email: 'test@example.com', delete_at: 0},
|
||||
'another-user-id': {id: 'another-user-id', username: 'another', first_name: 'Another', last_name: 'One', email: 'another@example.com', delete_at: 0},
|
||||
'deleted-user-id': {id: 'deleted-user-id', username: 'deleted', first_name: 'Removed', last_name: 'Friend', email: 'deleted@example.com', delete_at: 123},
|
||||
'another-channel-user-id': {id: 'another-channel-user-id', username: 'another_channel', first_name: 'Another', last_name: 'Channel', email: 'another_channel@example.com', delete_at: 0},
|
||||
},
|
||||
profilesInChannel: {
|
||||
'current-channel-id': new Set(['current-user-id', 'test-user-id', 'another-user-id', 'deleted-user-id']),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let profiles = filterMembersInChannel(state, '');
|
||||
expect(profiles).toHaveLength(3);
|
||||
|
||||
profiles = filterMembersInChannel(state, 'current');
|
||||
expect(profiles).toHaveLength(1);
|
||||
|
||||
profiles = filterMembersInChannel(state, 'tes');
|
||||
expect(profiles.length).toBe(1);
|
||||
|
||||
profiles = filterMembersInChannel(state, 'one');
|
||||
expect(profiles.length).toBe(1);
|
||||
|
||||
profiles = filterMembersInChannel(state, 'example');
|
||||
expect(profiles.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -562,6 +562,7 @@
|
|||
"suggestion.mention.morechannels": "Other Channels",
|
||||
"suggestion.mention.nonmembers": "Not in Channel",
|
||||
"suggestion.mention.special": "Special Mentions",
|
||||
"suggestion.mention.you": "(you)",
|
||||
"suggestion.search.direct": "Direct Messages",
|
||||
"suggestion.search.private": "Private Channels",
|
||||
"suggestion.search.public": "Public Channels",
|
||||
|
|
|
|||
Loading…
Reference in a new issue