diff options
author | Phil Hughes <me@iamphill.com> | 2019-02-18 09:43:13 +0000 |
---|---|---|
committer | Phil Hughes <me@iamphill.com> | 2019-02-18 09:43:13 +0000 |
commit | e49ff61571f82863c1c464d8211d2e8d8adc50fb (patch) | |
tree | d71539ccf7aa99663546cd82eeebc7584e21de88 | |
parent | e52f97a9ad2e5eea4ea90d38748d9ea14db5a2fe (diff) | |
parent | 8441fc479904a830ae7573003488cdc2ab5e585a (diff) | |
download | gitlab-ce-e49ff61571f82863c1c464d8211d2e8d8adc50fb.tar.gz |
Merge branch 'winh-reply-button-focus' into 'master'
Focus reply field when clicking "reply to comment" button
See merge request gitlab-org/gitlab-ce!24867
6 files changed, 37 insertions, 49 deletions
diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue index 969d5b69c25..de1ea0f58d6 100644 --- a/app/assets/javascripts/notes/components/note_actions.vue +++ b/app/assets/javascripts/notes/components/note_actions.vue @@ -23,11 +23,6 @@ export default { type: [String, Number], required: true, }, - discussionId: { - type: String, - required: false, - default: '', - }, noteUrl: { type: String, required: false, @@ -176,7 +171,7 @@ export default { v-if="showReplyButton" ref="replyButton" class="js-reply-button" - :note-id="discussionId" + @startReplying="$emit('startReplying')" /> <div v-if="canEdit" class="note-actions-item"> <button diff --git a/app/assets/javascripts/notes/components/note_actions/reply_button.vue b/app/assets/javascripts/notes/components/note_actions/reply_button.vue index b2f9d7f128a..f50cab81efe 100644 --- a/app/assets/javascripts/notes/components/note_actions/reply_button.vue +++ b/app/assets/javascripts/notes/components/note_actions/reply_button.vue @@ -1,5 +1,4 @@ <script> -import { mapActions } from 'vuex'; import { GlTooltipDirective, GlButton } from '@gitlab/ui'; import Icon from '~/vue_shared/components/icon.vue'; @@ -12,15 +11,6 @@ export default { directives: { GlTooltip: GlTooltipDirective, }, - props: { - noteId: { - type: String, - required: true, - }, - }, - methods: { - ...mapActions(['convertToDiscussion']), - }, }; </script> @@ -32,7 +22,7 @@ export default { class="note-action-button" variant="transparent" :title="__('Reply to comment')" - @click="convertToDiscussion(noteId)" + @click="$emit('startReplying')" > <icon name="comment" css-classes="link-highlight" /> </gl-button> diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index 47054e337a7..2d6fd8b116f 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -26,6 +26,7 @@ import resolvable from '../mixins/resolvable'; import discussionNavigation from '../mixins/discussion_navigation'; import ReplyPlaceholder from './discussion_reply_placeholder.vue'; import jumpToNextDiscussionButton from './discussion_jump_to_next_button.vue'; +import eventHub from '../event_hub'; export default { name: 'NoteableDiscussion', @@ -246,6 +247,12 @@ export default { } }, }, + created() { + eventHub.$on('startReplying', this.onStartReplying); + }, + beforeDestroy() { + eventHub.$off('startReplying', this.onStartReplying); + }, methods: { ...mapActions([ 'saveNote', @@ -350,6 +357,11 @@ Please check your network connection and try again.`; deleteNoteHandler(note) { this.$emit('noteDeleted', this.discussion, note); }, + onStartReplying(discussionId) { + if (this.discussion.id === discussionId) { + this.showReplyForm(); + } + }, }, }; </script> @@ -412,6 +424,7 @@ Please check your network connection and try again.`; :help-page-path="helpPagePath" :show-reply-button="canReply" @handleDeleteNote="deleteNoteHandler" + @startReplying="showReplyForm" > <note-edited-text v-if="discussion.resolved" diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue index 56108a58010..04e74a43acc 100644 --- a/app/assets/javascripts/notes/components/noteable_note.vue +++ b/app/assets/javascripts/notes/components/noteable_note.vue @@ -29,11 +29,6 @@ export default { type: Object, required: true, }, - discussion: { - type: Object, - required: false, - default: null, - }, line: { type: Object, required: false, @@ -49,6 +44,11 @@ export default { required: false, default: () => null, }, + showReplyButton: { + type: Boolean, + required: false, + default: false, + }, }, data() { return { @@ -91,13 +91,6 @@ export default { } return ''; }, - showReplyButton() { - if (!this.discussion || !this.getNoteableData.current_user.can_create_note) { - return false; - } - - return this.discussion.individual_note && !this.commentsDisabled; - }, actionText() { if (!this.commit) { return ''; @@ -260,10 +253,10 @@ export default { :is-resolved="note.resolved" :is-resolving="isResolving" :resolved-by="note.resolved_by" - :discussion-id="discussionId" @handleEdit="editHandler" @handleDelete="deleteHandler" @handleResolve="resolveHandler" + @startReplying="$emit('startReplying')" /> </div> <div class="timeline-discussion-body"> diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue index 9eb69dd91ae..a63571edcea 100644 --- a/app/assets/javascripts/notes/components/notes_app.vue +++ b/app/assets/javascripts/notes/components/notes_app.vue @@ -64,6 +64,7 @@ export default { 'getNotesDataByProp', 'isLoading', 'commentsDisabled', + 'getNoteableData', ]), noteableType() { return this.noteableData.noteableType; @@ -79,6 +80,9 @@ export default { return this.discussions; }, + canReply() { + return this.getNoteableData.current_user.can_create_note && !this.commentsDisabled; + }, }, watch: { shouldShow() { @@ -129,6 +133,7 @@ export default { 'setNotesFetchedState', 'expandDiscussion', 'startTaskList', + 'convertToDiscussion', ]), fetchNotes() { if (this.isFetching) return null; @@ -176,6 +181,11 @@ export default { } } }, + startReplying(discussionId) { + return this.convertToDiscussion(discussionId) + .then(() => this.$nextTick()) + .then(() => eventHub.$emit('startReplying', discussionId)); + }, }, systemNote: constants.SYSTEM_NOTE, }; @@ -206,7 +216,8 @@ export default { v-else :key="discussion.id" :note="discussion.notes[0]" - :discussion="discussion" + :show-reply-button="canReply" + @startReplying="startReplying(discussion.id)" /> </template> <noteable-discussion diff --git a/spec/javascripts/notes/components/note_actions/reply_button_spec.js b/spec/javascripts/notes/components/note_actions/reply_button_spec.js index 11e1664a3f4..11fb89808d9 100644 --- a/spec/javascripts/notes/components/note_actions/reply_button_spec.js +++ b/spec/javascripts/notes/components/note_actions/reply_button_spec.js @@ -3,27 +3,14 @@ import { createLocalVue, mount } from '@vue/test-utils'; import ReplyButton from '~/notes/components/note_actions/reply_button.vue'; describe('ReplyButton', () => { - const noteId = 'dummy-note-id'; - let wrapper; - let convertToDiscussion; beforeEach(() => { const localVue = createLocalVue(); - convertToDiscussion = jasmine.createSpy('convertToDiscussion'); localVue.use(Vuex); - const store = new Vuex.Store({ - actions: { - convertToDiscussion, - }, - }); wrapper = mount(ReplyButton, { - propsData: { - noteId, - }, - store, sync: false, localVue, }); @@ -33,14 +20,13 @@ describe('ReplyButton', () => { wrapper.destroy(); }); - it('dispatches convertToDiscussion with note ID on click', () => { + it('emits startReplying on click', () => { const button = wrapper.find({ ref: 'button' }); button.trigger('click'); - expect(convertToDiscussion).toHaveBeenCalledTimes(1); - const [, payload] = convertToDiscussion.calls.argsFor(0); - - expect(payload).toBe(noteId); + expect(wrapper.emitted()).toEqual({ + startReplying: [[]], + }); }); }); |