diff options
author | Winnie Hellmann <winnie@gitlab.com> | 2018-08-28 19:19:52 +0300 |
---|---|---|
committer | Winnie Hellmann <winnie@gitlab.com> | 2018-10-02 12:12:22 +0300 |
commit | 23563f5e0a5f3875289569126562f0f2fc63d3a6 (patch) | |
tree | dc7b3935d22f7ad12ef2508b0713e24780d7d95c | |
parent | 7c1cfd0bf5fd394e0e4387e350d69767aa873f84 (diff) |
Highlight current user in comments and system notes
7 files changed, 106 insertions, 4 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/highlight_current_user.js b/app/assets/javascripts/behaviors/markdown/highlight_current_user.js new file mode 100644 index 00000000000..6208b3f0032 --- /dev/null +++ b/app/assets/javascripts/behaviors/markdown/highlight_current_user.js @@ -0,0 +1,17 @@ +/** + * Highlights the current user in existing elements with a user ID data attribute. + * + * @param elements DOM elements that represent user mentions + */ +export default function highlightCurrentUser(elements) { + const currentUserId = gon && gon.current_user_id; + if (!currentUserId) { + return; + } + + elements.forEach(element => { + if (parseInt(element.dataset.user, 10) === currentUserId) { + element.classList.add('current-user'); + } + }); +} diff --git a/app/assets/javascripts/behaviors/markdown/render_gfm.js b/app/assets/javascripts/behaviors/markdown/render_gfm.js index 429455f97ec..a2d4331b6d1 100644 --- a/app/assets/javascripts/behaviors/markdown/render_gfm.js +++ b/app/assets/javascripts/behaviors/markdown/render_gfm.js @@ -2,6 +2,7 @@ import $ from 'jquery'; import syntaxHighlight from '~/syntax_highlight'; import renderMath from './render_math'; import renderMermaid from './render_mermaid'; +import highlightCurrentUser from './highlight_current_user'; // Render GitLab flavoured Markdown // @@ -11,6 +12,7 @@ $.fn.renderGFM = function renderGFM() { syntaxHighlight(this.find('.js-syntax-highlight')); renderMath(this.find('.js-render-math')); renderMermaid(this.find('.js-render-mermaid')); + highlightCurrentUser(this.find('.gfm-project_member').get()); return this; }; diff --git a/app/assets/javascripts/notes/components/notes_app.vue b/app/assets/javascripts/notes/components/notes_app.vue index d8e8efb982a..618a1581d8f 100644 --- a/app/assets/javascripts/notes/components/notes_app.vue +++ b/app/assets/javascripts/notes/components/notes_app.vue @@ -11,6 +11,7 @@ import commentForm from './comment_form.vue'; import placeholderNote from '../../vue_shared/components/notes/placeholder_note.vue'; import placeholderSystemNote from '../../vue_shared/components/notes/placeholder_system_note.vue'; import skeletonLoadingContainer from '../../vue_shared/components/notes/skeleton_note.vue'; +import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user'; export default { name: 'NotesApp', @@ -96,6 +97,9 @@ export default { }); } }, + updated() { + this.$nextTick(() => highlightCurrentUser(this.$el.querySelectorAll('.gfm-project_member'))); + }, methods: { ...mapActions({ fetchDiscussions: 'fetchDiscussions', diff --git a/app/assets/stylesheets/framework/gfm.scss b/app/assets/stylesheets/framework/gfm.scss index d2ba76f5160..50d4298d418 100644 --- a/app/assets/stylesheets/framework/gfm.scss +++ b/app/assets/stylesheets/framework/gfm.scss @@ -11,6 +11,10 @@ padding: 0 2px; background-color: $blue-100; border-radius: $border-radius-default; + + &.current-user { + background-color: $orange-100; + } } .gfm-color_chip { diff --git a/changelogs/unreleased/winh-highlight-current-user.yml b/changelogs/unreleased/winh-highlight-current-user.yml new file mode 100644 index 00000000000..125a5c08c4e --- /dev/null +++ b/changelogs/unreleased/winh-highlight-current-user.yml @@ -0,0 +1,5 @@ +--- +title: Highlight current user in comments +merge_request: 21406 +author: +type: changed diff --git a/spec/features/issues/notes_on_issues_spec.rb b/spec/features/issues/notes_on_issues_spec.rb index f08c73f947c..fed77453cbb 100644 --- a/spec/features/issues/notes_on_issues_spec.rb +++ b/spec/features/issues/notes_on_issues_spec.rb @@ -3,6 +3,12 @@ require 'spec_helper' describe 'Create notes on issues', :js do let(:user) { create(:user) } + def submit_comment(text) + fill_in 'note[note]', with: text + click_button 'Comment' + wait_for_requests + end + shared_examples 'notes with reference' do let(:issue) { create(:issue, project: project) } let(:note_text) { "Check #{mention.to_reference}" } @@ -12,10 +18,7 @@ describe 'Create notes on issues', :js do sign_in(user) visit project_issue_path(project, issue) - fill_in 'note[note]', with: note_text - click_button 'Comment' - - wait_for_requests + submit_comment(note_text) end it 'creates a note with reference and cross references the issue' do @@ -74,4 +77,16 @@ describe 'Create notes on issues', :js do let(:mention) { create(:merge_request, source_project: project) } end end + + it 'highlights the current user in a comment' do + project = create(:project) + issue = create(:issue, project: project) + project.add_developer(user) + sign_in(user) + + visit project_issue_path(project, issue) + submit_comment("@#{user.username} note to self") + + expect(page).to have_selector '.gfm-project_member.current-user', text: user.username + end end diff --git a/spec/javascripts/behaviors/markdown/highlight_current_user_spec.js b/spec/javascripts/behaviors/markdown/highlight_current_user_spec.js new file mode 100644 index 00000000000..3305ddc412d --- /dev/null +++ b/spec/javascripts/behaviors/markdown/highlight_current_user_spec.js @@ -0,0 +1,55 @@ +import highlightCurrentUser from '~/behaviors/markdown/highlight_current_user'; + +describe('highlightCurrentUser', () => { + let rootElement; + let elements; + + beforeEach(() => { + setFixtures(` + <div id="dummy-root-element"> + <div data-user="1">@first</div> + <div data-user="2">@second</div> + </div> + `); + rootElement = document.getElementById('dummy-root-element'); + elements = rootElement.querySelectorAll('[data-user]'); + }); + + describe('without current user', () => { + beforeEach(() => { + window.gon = window.gon || {}; + window.gon.current_user_id = null; + }); + + afterEach(() => { + delete window.gon.current_user_id; + }); + + it('does not highlight the user', () => { + const initialHtml = rootElement.outerHTML; + + highlightCurrentUser(elements); + + expect(rootElement.outerHTML).toBe(initialHtml); + }); + }); + + describe('with current user', () => { + beforeEach(() => { + window.gon = window.gon || {}; + window.gon.current_user_id = 2; + }); + + afterEach(() => { + delete window.gon.current_user_id; + }); + + it('highlights current user', () => { + highlightCurrentUser(elements); + + expect(elements.length).toBe(2); + expect(elements[0]).not.toHaveClass('current-user'); + expect(elements[1]).toHaveClass('current-user'); + }); + }); +}); |