Commit 00526c7b authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '241058-mg-update-reply-placeholder' into 'master'

Replace styled discussion reply button with textarea

See merge request gitlab-org/gitlab!54380
parents 9939a5f9 946ac88e
...@@ -257,8 +257,8 @@ export default { ...@@ -257,8 +257,8 @@ export default {
<reply-placeholder <reply-placeholder
v-if="!isFormVisible" v-if="!isFormVisible"
class="qa-discussion-reply" class="qa-discussion-reply"
:button-text="__('Reply...')" :placeholder-text="__('Reply…')"
@onClick="showForm" @focus="showForm"
/> />
<apollo-mutation <apollo-mutation
v-else v-else
......
...@@ -35,8 +35,9 @@ export default { ...@@ -35,8 +35,9 @@ export default {
<slot v-if="hasForm" name="form"></slot> <slot v-if="hasForm" name="form"></slot>
<template v-else-if="renderReplyPlaceholder"> <template v-else-if="renderReplyPlaceholder">
<reply-placeholder <reply-placeholder
:button-text="__('Start a new discussion...')" :placeholder-text="__('Start a new discussion…')"
@onClick="$emit('showNewDiscussionForm')" :label-text="__('New discussion')"
@focus="$emit('showNewDiscussionForm')"
/> />
</template> </template>
</template> </template>
......
...@@ -50,8 +50,8 @@ export default { ...@@ -50,8 +50,8 @@ export default {
<div class="discussion-with-resolve-btn clearfix"> <div class="discussion-with-resolve-btn clearfix">
<reply-placeholder <reply-placeholder
data-qa-selector="discussion_reply_tab" data-qa-selector="discussion_reply_tab"
:button-text="s__('MergeRequests|Reply...')" :placeholder-text="__('Reply…')"
@onClick="$emit('showReplyForm')" @focus="$emit('showReplyForm')"
/> />
<div v-if="userCanResolveDiscussion" class="btn-group discussion-actions" role="group"> <div v-if="userCanResolveDiscussion" class="btn-group discussion-actions" role="group">
......
<script> <script>
import { __ } from '~/locale';
export default { export default {
name: 'ReplyPlaceholder', name: 'ReplyPlaceholder',
props: { props: {
buttonText: { placeholderText: {
type: String,
required: false,
default: __('Reply…'),
},
labelText: {
type: String, type: String,
required: true, required: false,
default: __('Reply to comment'),
}, },
}, },
}; };
</script> </script>
<template> <template>
<button <textarea
ref="button" ref="textarea"
type="button" rows="1"
class="js-vue-discussion-reply btn btn-text-field" class="reply-placeholder-text-field js-vue-discussion-reply"
:title="s__('MergeRequests|Add a reply')" :placeholder="placeholderText"
@click="$emit('onClick')" :aria-label="labelText"
> @focus="$emit('focus')"
{{ buttonText }} ></textarea>
</button>
</template> </template>
...@@ -345,7 +345,7 @@ export default { ...@@ -345,7 +345,7 @@ export default {
class="note-textarea js-gfm-input js-note-text js-autosize markdown-area js-vue-issue-note-form" class="note-textarea js-gfm-input js-note-text js-autosize markdown-area js-vue-issue-note-form"
data-qa-selector="reply_field" data-qa-selector="reply_field"
dir="auto" dir="auto"
:aria-label="__('Description')" :aria-label="__('Reply to comment')"
:placeholder="__('Write a comment or drag your files here…')" :placeholder="__('Write a comment or drag your files here…')"
@keydown.meta.enter="handleKeySubmit()" @keydown.meta.enter="handleKeySubmit()"
@keydown.ctrl.enter="handleKeySubmit()" @keydown.ctrl.enter="handleKeySubmit()"
......
...@@ -216,6 +216,7 @@ ...@@ -216,6 +216,7 @@
color: $gray-700; color: $gray-700;
} }
// deprecated class
&.btn-text-field { &.btn-text-field {
width: 100%; width: 100%;
text-align: left; text-align: left;
......
...@@ -453,7 +453,7 @@ ...@@ -453,7 +453,7 @@
.search-token-target-branch { .search-token-target-branch {
.value { .value {
font-family: $monospace-font; font-family: $monospace-font;
font-size: 13px; font-size: $gl-font-size-monospace;
} }
} }
......
...@@ -604,7 +604,7 @@ pre { ...@@ -604,7 +604,7 @@ pre {
display: block; display: block;
padding: $gl-padding-8 $input-horizontal-padding; padding: $gl-padding-8 $input-horizontal-padding;
margin: 0 0 $gl-padding-8; margin: 0 0 $gl-padding-8;
font-size: 13px; font-size: $gl-font-size-monospace;
word-break: break-all; word-break: break-all;
word-wrap: break-word; word-wrap: break-word;
color: $gl-text-color; color: $gl-text-color;
...@@ -646,7 +646,7 @@ code { ...@@ -646,7 +646,7 @@ code {
*/ */
textarea.js-gfm-input { textarea.js-gfm-input {
font-family: $monospace-font; font-family: $monospace-font;
font-size: 13px; font-size: $gl-font-size-monospace;
} }
.strikethrough { .strikethrough {
......
...@@ -302,8 +302,20 @@ table { ...@@ -302,8 +302,20 @@ table {
width: 100%; width: 100%;
} }
} }
}
.discussion-reply-holder {
.reply-placeholder-text-field {
font-family: $monospace-font;
font-size: $gl-font-size-monospace;
border-radius: $gl-border-radius-base;
width: 100%;
resize: none;
padding: $gl-padding-8 $gl-padding-12;
line-height: 1;
border-color: $border-color;
background-color: $white;
.btn-text-field {
@include media-breakpoint-down(xs) { @include media-breakpoint-down(xs) {
margin-bottom: $gl-padding-8; margin-bottom: $gl-padding-8;
} }
......
---
title: Update accessibility of the "Reply to discussion" UX
merge_request: 54380
author:
type: other
...@@ -18644,9 +18644,6 @@ msgstr "" ...@@ -18644,9 +18644,6 @@ msgstr ""
msgid "MergeRequestDiffs|Select comment starting line" msgid "MergeRequestDiffs|Select comment starting line"
msgstr "" msgstr ""
msgid "MergeRequests|Add a reply"
msgstr ""
msgid "MergeRequests|An error occurred while checking whether another squash is in progress." msgid "MergeRequests|An error occurred while checking whether another squash is in progress."
msgstr "" msgstr ""
...@@ -18656,9 +18653,6 @@ msgstr "" ...@@ -18656,9 +18653,6 @@ msgstr ""
msgid "MergeRequests|Failed to squash. Should be done manually." msgid "MergeRequests|Failed to squash. Should be done manually."
msgstr "" msgstr ""
msgid "MergeRequests|Reply..."
msgstr ""
msgid "MergeRequests|Resolve this thread in a new issue" msgid "MergeRequests|Resolve this thread in a new issue"
msgstr "" msgstr ""
...@@ -19935,6 +19929,9 @@ msgstr "" ...@@ -19935,6 +19929,9 @@ msgstr ""
msgid "New directory" msgid "New directory"
msgstr "" msgstr ""
msgid "New discussion"
msgstr ""
msgid "New environment" msgid "New environment"
msgstr "" msgstr ""
...@@ -24867,7 +24864,7 @@ msgstr "" ...@@ -24867,7 +24864,7 @@ msgstr ""
msgid "Reply to this email directly or %{view_it_on_gitlab}." msgid "Reply to this email directly or %{view_it_on_gitlab}."
msgstr "" msgstr ""
msgid "Reply..." msgid "Reply"
msgstr "" msgstr ""
msgid "Repo by URL" msgid "Repo by URL"
...@@ -27974,7 +27971,7 @@ msgstr "" ...@@ -27974,7 +27971,7 @@ msgstr ""
msgid "Start a Free Ultimate Trial" msgid "Start a Free Ultimate Trial"
msgstr "" msgstr ""
msgid "Start a new discussion..." msgid "Start a new discussion"
msgstr "" msgstr ""
msgid "Start a new merge request" msgid "Start a new merge request"
......
...@@ -994,7 +994,7 @@ RSpec.describe 'GFM autocomplete', :js do ...@@ -994,7 +994,7 @@ RSpec.describe 'GFM autocomplete', :js do
end end
def start_and_cancel_discussion def start_and_cancel_discussion
click_button('Reply...') find_field('Reply…').click
fill_in('note_note', with: 'Whoops!') fill_in('note_note', with: 'Whoops!')
......
...@@ -223,7 +223,7 @@ end ...@@ -223,7 +223,7 @@ end
def write_reply_to_discussion(button_text: 'Start a review', text: 'Line is wrong', resolve: false, unresolve: false) def write_reply_to_discussion(button_text: 'Start a review', text: 'Line is wrong', resolve: false, unresolve: false)
page.within(first('.diff-files-holder .discussion-reply-holder')) do page.within(first('.diff-files-holder .discussion-reply-holder')) do
click_button('Reply...') find_field('Reply…', match: :first).click
fill_in('note_note', with: text) fill_in('note_note', with: text)
......
...@@ -192,7 +192,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do ...@@ -192,7 +192,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do
it 'adds as discussion' do it 'adds as discussion' do
should_allow_commenting(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_22_22"]'), asset_form_reset: false) should_allow_commenting(find('[id="6eb14e00385d2fb284765eb1cd8d420d33d63fc9_22_22"]'), asset_form_reset: false)
expect(page).to have_css('.notes_holder .note.note-discussion', count: 1) expect(page).to have_css('.notes_holder .note.note-discussion', count: 1)
expect(page).to have_button('Reply...') expect(page).to have_field('Reply…')
end end
end end
end end
......
...@@ -149,7 +149,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do ...@@ -149,7 +149,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to comment' do it 'allows user to comment' do
page.within '.diff-content' do page.within '.diff-content' do
click_button 'Reply...' find_field('Reply…').click
find(".js-unresolve-checkbox").set false find(".js-unresolve-checkbox").set false
find('.js-note-text').set 'testing' find('.js-note-text').set 'testing'
...@@ -179,7 +179,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do ...@@ -179,7 +179,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to comment & unresolve thread' do it 'allows user to comment & unresolve thread' do
page.within '.diff-content' do page.within '.diff-content' do
click_button 'Reply...' find_field('Reply…').click
find('.js-note-text').set 'testing' find('.js-note-text').set 'testing'
...@@ -208,7 +208,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do ...@@ -208,7 +208,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to comment & resolve thread' do it 'allows user to comment & resolve thread' do
page.within '.diff-content' do page.within '.diff-content' do
click_button 'Reply...' find_field('Reply…').click
find('.js-note-text').set 'testing' find('.js-note-text').set 'testing'
...@@ -442,7 +442,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do ...@@ -442,7 +442,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'allows user to comment & resolve thread' do it 'allows user to comment & resolve thread' do
page.within '.diff-content' do page.within '.diff-content' do
click_button 'Reply...' find_field('Reply…').click
find('.js-note-text').set 'testing' find('.js-note-text').set 'testing'
...@@ -461,7 +461,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do ...@@ -461,7 +461,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
page.within '.diff-content' do page.within '.diff-content' do
click_button 'Resolve thread' click_button 'Resolve thread'
click_button 'Reply...' find_field('Reply…').click
find('.js-note-text').set 'testing' find('.js-note-text').set 'testing'
......
...@@ -37,7 +37,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do ...@@ -37,7 +37,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
end end
it 'does not render avatars after commenting on discussion tab' do it 'does not render avatars after commenting on discussion tab' do
click_button 'Reply...' find_field('Reply…').click
page.within('.js-discussion-note-form') do page.within('.js-discussion-note-form') do
find('.note-textarea').native.send_keys('Test comment') find('.note-textarea').native.send_keys('Test comment')
...@@ -132,7 +132,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do ...@@ -132,7 +132,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
end end
it 'adds avatar when commenting' do it 'adds avatar when commenting' do
click_button 'Reply...' find_field('Reply…', match: :first).click
page.within '.js-discussion-note-form' do page.within '.js-discussion-note-form' do
find('.js-note-text').native.send_keys('Test') find('.js-note-text').native.send_keys('Test')
...@@ -151,7 +151,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do ...@@ -151,7 +151,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
it 'adds multiple comments' do it 'adds multiple comments' do
3.times do 3.times do
click_button 'Reply...' find_field('Reply…', match: :first).click
page.within '.js-discussion-note-form' do page.within '.js-discussion-note-form' do
find('.js-note-text').native.send_keys('Test') find('.js-note-text').native.send_keys('Test')
......
...@@ -60,7 +60,7 @@ RSpec.describe 'Merge request > User sees threads', :js do ...@@ -60,7 +60,7 @@ RSpec.describe 'Merge request > User sees threads', :js do
it 'can be replied to' do it 'can be replied to' do
within(".discussion[data-discussion-id='#{discussion_id}']") do within(".discussion[data-discussion-id='#{discussion_id}']") do
click_button 'Reply...' find_field('Reply…').click
fill_in 'note[note]', with: 'Test!' fill_in 'note[note]', with: 'Test!'
click_button 'Comment' click_button 'Comment'
......
...@@ -27,7 +27,7 @@ RSpec.describe 'Merge request > User sees notes from forked project', :js do ...@@ -27,7 +27,7 @@ RSpec.describe 'Merge request > User sees notes from forked project', :js do
expect(page).to have_content('A commit comment') expect(page).to have_content('A commit comment')
page.within('.discussion-notes') do page.within('.discussion-notes') do
find('.btn-text-field').click find_field('Reply…').click
scroll_to(page.find('#note_note', visible: false)) scroll_to(page.find('#note_note', visible: false))
find('#note_note').send_keys('A reply comment') find('#note_note').send_keys('A reply comment')
find('.js-comment-button').click find('.js-comment-button').click
......
...@@ -83,7 +83,7 @@ RSpec.describe 'User comments on a diff', :js do ...@@ -83,7 +83,7 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests wait_for_requests
click_button 'Reply...' find_field('Reply…', match: :first).click
find('.js-suggestion-btn').click find('.js-suggestion-btn').click
......
...@@ -93,7 +93,7 @@ describe('Design discussions component', () => { ...@@ -93,7 +93,7 @@ describe('Design discussions component', () => {
}); });
it('does not render a checkbox in reply form', () => { it('does not render a checkbox in reply form', () => {
findReplyPlaceholder().vm.$emit('onClick'); findReplyPlaceholder().vm.$emit('focus');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(findResolveCheckbox().exists()).toBe(false); expect(findResolveCheckbox().exists()).toBe(false);
...@@ -124,7 +124,7 @@ describe('Design discussions component', () => { ...@@ -124,7 +124,7 @@ describe('Design discussions component', () => {
}); });
it('renders a checkbox with Resolve thread text in reply form', () => { it('renders a checkbox with Resolve thread text in reply form', () => {
findReplyPlaceholder().vm.$emit('onClick'); findReplyPlaceholder().vm.$emit('focus');
wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id }); wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id });
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
...@@ -193,7 +193,7 @@ describe('Design discussions component', () => { ...@@ -193,7 +193,7 @@ describe('Design discussions component', () => {
}); });
it('renders a checkbox with Unresolve thread text in reply form', () => { it('renders a checkbox with Unresolve thread text in reply form', () => {
findReplyPlaceholder().vm.$emit('onClick'); findReplyPlaceholder().vm.$emit('focus');
wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id }); wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id });
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
...@@ -205,7 +205,7 @@ describe('Design discussions component', () => { ...@@ -205,7 +205,7 @@ describe('Design discussions component', () => {
it('hides reply placeholder and opens form on placeholder click', () => { it('hides reply placeholder and opens form on placeholder click', () => {
createComponent(); createComponent();
findReplyPlaceholder().vm.$emit('onClick'); findReplyPlaceholder().vm.$emit('focus');
wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id }); wrapper.setProps({ discussionWithOpenForm: defaultMockDiscussion.id });
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
...@@ -307,7 +307,7 @@ describe('Design discussions component', () => { ...@@ -307,7 +307,7 @@ describe('Design discussions component', () => {
it('emits openForm event on opening the form', () => { it('emits openForm event on opening the form', () => {
createComponent(); createComponent();
findReplyPlaceholder().vm.$emit('onClick'); findReplyPlaceholder().vm.$emit('focus');
expect(wrapper.emitted('open-form')).toBeTruthy(); expect(wrapper.emitted('open-form')).toBeTruthy();
}); });
......
...@@ -96,7 +96,7 @@ describe('DiscussionActions', () => { ...@@ -96,7 +96,7 @@ describe('DiscussionActions', () => {
it('emits showReplyForm event when clicking on reply placeholder', () => { it('emits showReplyForm event when clicking on reply placeholder', () => {
jest.spyOn(wrapper.vm, '$emit'); jest.spyOn(wrapper.vm, '$emit');
wrapper.find(ReplyPlaceholder).find('button').trigger('click'); wrapper.find(ReplyPlaceholder).find('textarea').trigger('focus');
expect(wrapper.vm.$emit).toHaveBeenCalledWith('showReplyForm'); expect(wrapper.vm.$emit).toHaveBeenCalledWith('showReplyForm');
}); });
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue';
const buttonText = 'Test Button Text'; const placeholderText = 'Test Button Text';
describe('ReplyPlaceholder', () => { describe('ReplyPlaceholder', () => {
let wrapper; let wrapper;
const findButton = () => wrapper.find({ ref: 'button' }); const findTextarea = () => wrapper.find({ ref: 'textarea' });
beforeEach(() => { beforeEach(() => {
wrapper = shallowMount(ReplyPlaceholder, { wrapper = shallowMount(ReplyPlaceholder, {
propsData: { propsData: {
buttonText, placeholderText,
}, },
}); });
}); });
...@@ -20,17 +20,17 @@ describe('ReplyPlaceholder', () => { ...@@ -20,17 +20,17 @@ describe('ReplyPlaceholder', () => {
wrapper.destroy(); wrapper.destroy();
}); });
it('emits onClick event on button click', () => { it('emits focus event on button click', () => {
findButton().trigger('click'); findTextarea().trigger('focus');
return wrapper.vm.$nextTick().then(() => { return wrapper.vm.$nextTick().then(() => {
expect(wrapper.emitted()).toEqual({ expect(wrapper.emitted()).toEqual({
onClick: [[]], focus: [[]],
}); });
}); });
}); });
it('should render reply button', () => { it('should render reply button', () => {
expect(findButton().text()).toEqual(buttonText); expect(findTextarea().attributes('placeholder')).toEqual(placeholderText);
}); });
}); });
...@@ -65,7 +65,7 @@ describe('noteable_discussion component', () => { ...@@ -65,7 +65,7 @@ describe('noteable_discussion component', () => {
expect(wrapper.vm.isReplying).toEqual(false); expect(wrapper.vm.isReplying).toEqual(false);
const replyPlaceholder = wrapper.find(ReplyPlaceholder); const replyPlaceholder = wrapper.find(ReplyPlaceholder);
replyPlaceholder.vm.$emit('onClick'); replyPlaceholder.vm.$emit('focus');
await nextTick(); await nextTick();
expect(wrapper.vm.isReplying).toEqual(true); expect(wrapper.vm.isReplying).toEqual(true);
......
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