diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue index 91158ef15c82bae70684be2b572b50a2eaaad610..bcf594a7b1ce98d5da25f4fcdeefebee7148893c 100644 --- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue +++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue @@ -160,7 +160,7 @@ export default { labelSearchField() { return this.isEmailSignupEnabled ? this.$options.labels.searchField - : s__('InviteMembersModal|Username'); + : s__('InviteMembersModal|Username or name'); }, isEmptyInvites() { return Boolean(this.newUsersToInvite.length); diff --git a/app/assets/javascripts/invite_members/components/members_token_select.vue b/app/assets/javascripts/invite_members/components/members_token_select.vue index 015cadc99933cdf68bb70e44cc77b192ac57ca11..928f81daf92b1c2e6511a27f59324e16aebd7d4c 100644 --- a/app/assets/javascripts/invite_members/components/members_token_select.vue +++ b/app/assets/javascripts/invite_members/components/members_token_select.vue @@ -183,6 +183,12 @@ export default { this.$emit('clear'); }, + handleTab(event) { + if (this.originalInput.length > 0) { + event.preventDefault(); + this.$refs.tokenSelector.handleEnter(); + } + }, hasError(token) { return Object.keys(this.invalidMembers).includes(memberName(token)); }, @@ -196,6 +202,7 @@ export default { <template> <gl-token-selector + ref="tokenSelector" v-model="selectedTokens" :state="exceptionState" :dropdown-items="users" @@ -210,6 +217,7 @@ export default { @input="handleInput" @focus="handleFocus" @token-remove="handleTokenRemove" + @keydown.tab="handleTab" > <template #token-content="{ token }"> <gl-icon diff --git a/app/assets/javascripts/invite_members/constants.js b/app/assets/javascripts/invite_members/constants.js index 3b2840ecf11403a69dd9b934b697f396da298d2c..f2a6cccbe35ed6d8da31585dfe60d6ae06c36a7c 100644 --- a/app/assets/javascripts/invite_members/constants.js +++ b/app/assets/javascripts/invite_members/constants.js @@ -39,7 +39,7 @@ export const MEMBERS_TO_PROJECT_DEFAULT_INTRO_TEXT = s__( export const MEMBERS_TO_PROJECT_CELEBRATE_INTRO_TEXT = s__( "InviteMembersModal|Congratulations on creating your project, you're almost there!", ); -export const MEMBERS_SEARCH_FIELD = s__('InviteMembersModal|Username or email address'); +export const MEMBERS_SEARCH_FIELD = s__('InviteMembersModal|Username, name or email address'); export const MEMBERS_PLACEHOLDER = s__('InviteMembersModal|Select members or type email addresses'); export const GROUP_MODAL_DEFAULT_TITLE = s__('InviteMembersModal|Invite a group'); diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 1636654e297b456d7289c231c105d09aafa7ce30..dd05b368fa1de87fadfb94d85063aa6d726a3f76 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -26142,10 +26142,10 @@ msgstr "" msgid "InviteMembersModal|To invite new users to this top-level group, you must remove existing users. You can still add existing users from the top-level group, including any subgroups and projects." msgstr "" -msgid "InviteMembersModal|Username" +msgid "InviteMembersModal|Username or name" msgstr "" -msgid "InviteMembersModal|Username or email address" +msgid "InviteMembersModal|Username, name or email address" msgstr "" msgid "InviteMembersModal|You only have space for %{count} more %{members} in %{name}" diff --git a/spec/frontend/invite_members/components/members_token_select_spec.js b/spec/frontend/invite_members/components/members_token_select_spec.js index a4b8a8b01975747045c0fb52baa3b048802aa621..1cda9853ccdd32cc950686cbcad840d74c61cbb4 100644 --- a/spec/frontend/invite_members/components/members_token_select_spec.js +++ b/spec/frontend/invite_members/components/members_token_select_spec.js @@ -12,6 +12,7 @@ const placeholder = 'Search for a member'; const user1 = { id: 1, name: 'John Smith', username: 'one_1', avatar_url: '' }; const user2 = { id: 2, name: 'Jane Doe', username: 'two_2', avatar_url: '' }; const allUsers = [user1, user2]; +const handleEnterSpy = jest.fn(); const createComponent = (props) => { return shallowMount(MembersTokenSelect, { @@ -22,7 +23,11 @@ const createComponent = (props) => { ...props, }, stubs: { - GlTokenSelector: stubComponent(GlTokenSelector), + GlTokenSelector: stubComponent(GlTokenSelector, { + methods: { + handleEnter: handleEnterSpy, + }, + }), }, }); }; @@ -173,6 +178,14 @@ describe('MembersTokenSelect', () => { }); }); }); + + it('allows tab to function as enter', () => { + tokenSelector.vm.$emit('text-input', 'username'); + + tokenSelector.vm.$emit('keydown', new KeyboardEvent('keydown', { key: 'Tab' })); + + expect(handleEnterSpy).toHaveBeenCalled(); + }); }); describe('when user is selected', () => {