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
This commit is contained in:
commit
e49ff61571
6 changed files with 37 additions and 49 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: [[]],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue