From 562c9652d687bb03d0aa5b744016946d7a293a82 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Tue, 29 Mar 2016 18:39:25 -0500 Subject: [PATCH 01/13] Put owner and participating people first --- app/services/projects/participants_service.rb | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index 0004a399f4..ba88ba73c3 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -1,6 +1,7 @@ module Projects class ParticipantsService < BaseService def execute(note_type, note_id) + @target = get_target(note_type, note_id) participating = if note_type && note_id participants_in(note_type, note_id) @@ -8,35 +9,43 @@ module Projects [] end project_members = sorted(project.team.members) - participants = all_members + groups + project_members + participating + participants = target_owner + participating + all_members + groups + project_members participants.uniq end - def participants_in(type, id) - target = - case type - when "Issue" - project.issues.find_by_iid(id) - when "MergeRequest" - project.merge_requests.find_by_iid(id) - when "Commit" - project.commit(id) - end - - return [] unless target + def get_target(type, id) + case type + when "Issue" + project.issues.find_by_iid(id) + when "MergeRequest" + project.merge_requests.find_by_iid(id) + when "Commit" + project.commit(id) + end + end - users = target.participants(current_user) + def target_owner + [{ + name: @target.author.name, + username: @target.author.username + }] + end + + def participants_in(type, id) + return [] unless @target + + users = @target.participants(current_user) sorted(users) end def sorted(users) - users.uniq.to_a.compact.sort_by(&:username).map do |user| + users.uniq.to_a.compact.sort_by(&:username).map do |user| { username: user.username, name: user.name } end end def groups - current_user.authorized_groups.sort_by(&:path).map do |group| + current_user.authorized_groups.sort_by(&:path).map do |group| count = group.users.count { username: group.path, name: group.name, count: count } end From ad48ecacaef508139117ceaea1a9eeaeb7046b48 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Tue, 29 Mar 2016 18:53:01 -0500 Subject: [PATCH 02/13] Update method name and remove unneeded params --- app/services/projects/participants_service.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index ba88ba73c3..800747b7ef 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -4,7 +4,7 @@ module Projects @target = get_target(note_type, note_id) participating = if note_type && note_id - participants_in(note_type, note_id) + participants_in_target else [] end @@ -31,7 +31,7 @@ module Projects }] end - def participants_in(type, id) + def participants_in_target return [] unless @target users = @target.participants(current_user) From 16459fddd4857bc18a917e13989b755468cfd7e8 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Wed, 30 Mar 2016 15:19:56 -0500 Subject: [PATCH 03/13] Fixes multiple ajax request and incorrect data being set for the current issuable --- .../javascripts/gfm_auto_complete.js.coffee | 63 ++++++++++++++----- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee index 4718bcf7a1..61e3f811e7 100644 --- a/app/assets/javascripts/gfm_auto_complete.js.coffee +++ b/app/assets/javascripts/gfm_auto_complete.js.coffee @@ -2,6 +2,8 @@ window.GitLab ?= {} GitLab.GfmAutoComplete = + dataLoading: false + dataSource: '' # Emoji @@ -17,17 +19,41 @@ GitLab.GfmAutoComplete = template: '
  • ${id} ${title}
  • ' # Add GFM auto-completion to all input fields, that accept GFM input. - setup: -> - input = $('.js-gfm-input') + setup: (wrap) -> + @input = $('.js-gfm-input') + # destroy previous instances + @destroyAtWho() + + # set up instances + @setupAtWho() + + if @dataSource + if !@dataLoading + @dataLoading = true + + # We should wait until initializations are done + # and only trigger the last .setup since + # The previous .dataSource belongs to the previous issuable + # and the last one will have the **proper** .dataSource property + # TODO: Make this a singleton and turn off events when moving to another page + setTimeout( => + fetch = @fetchData(@dataSource) + fetch.done (data) => + @dataLoading = false + @loadData(data) + , 1000) + + + setupAtWho: -> # Emoji - input.atwho + @input.atwho at: ':' displayTpl: @Emoji.template insertTpl: ':${name}:' # Team Members - input.atwho + @input.atwho at: '@' displayTpl: @Members.template insertTpl: '${atwho-at}${username}' @@ -42,7 +68,7 @@ GitLab.GfmAutoComplete = title: sanitize(title) search: sanitize("#{m.username} #{m.name}") - input.atwho + @input.atwho at: '#' alias: 'issues' searchKey: 'search' @@ -55,7 +81,7 @@ GitLab.GfmAutoComplete = title: sanitize(i.title) search: "#{i.iid} #{i.title}" - input.atwho + @input.atwho at: '!' alias: 'mergerequests' searchKey: 'search' @@ -68,13 +94,18 @@ GitLab.GfmAutoComplete = title: sanitize(m.title) search: "#{m.iid} #{m.title}" - if @dataSource - $.getJSON(@dataSource).done (data) -> - # load members - input.atwho 'load', '@', data.members - # load issues - input.atwho 'load', 'issues', data.issues - # load merge requests - input.atwho 'load', 'mergerequests', data.mergerequests - # load emojis - input.atwho 'load', ':', data.emojis + destroyAtWho: -> + @input.atwho('destroy') + + fetchData: (dataSource) -> + $.getJSON(dataSource) + + loadData: (data) -> + # load members + @input.atwho 'load', '@', data.members + # load issues + @input.atwho 'load', 'issues', data.issues + # load merge requests + @input.atwho 'load', 'mergerequests', data.mergerequests + # load emojis + @input.atwho 'load', ':', data.emojis From 05628e0c2ffc5a3378ad4d89a212b1bd652a9d60 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Wed, 30 Mar 2016 16:29:42 -0500 Subject: [PATCH 04/13] Fixes failing spec --- app/services/projects/participants_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index 800747b7ef..1eaecc0d27 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -25,6 +25,8 @@ module Projects end def target_owner + return [] unless @target && @target.author.present? + [{ name: @target.author.name, username: @target.author.username From 1eeabdc6a5c5ad751891d725a0957a24282f7a9c Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Fri, 8 Apr 2016 12:23:44 -0500 Subject: [PATCH 05/13] Change variable name --- app/services/projects/participants_service.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index 1eaecc0d27..11dc3542fa 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -1,9 +1,9 @@ module Projects class ParticipantsService < BaseService - def execute(note_type, note_id) - @target = get_target(note_type, note_id) + def execute(noteable_type, noteable_id) + @target = get_target(noteable_type, noteable_id) participating = - if note_type && note_id + if noteable_type && noteable_id participants_in_target else [] From a96dc944289e01f7b41112343cf20ca2791860ca Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Fri, 8 Apr 2016 13:36:55 -0500 Subject: [PATCH 06/13] Memoize target --- app/services/projects/participants_service.rb | 42 +++++++++---------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/app/services/projects/participants_service.rb b/app/services/projects/participants_service.rb index 11dc3542fa..02c4eee3d0 100644 --- a/app/services/projects/participants_service.rb +++ b/app/services/projects/participants_service.rb @@ -1,42 +1,40 @@ module Projects class ParticipantsService < BaseService def execute(noteable_type, noteable_id) - @target = get_target(noteable_type, noteable_id) - participating = - if noteable_type && noteable_id - participants_in_target - else - [] - end + @noteable_type = noteable_type + @noteable_id = noteable_id project_members = sorted(project.team.members) - participants = target_owner + participating + all_members + groups + project_members + participants = target_owner + participants_in_target + all_members + groups + project_members participants.uniq end - def get_target(type, id) - case type - when "Issue" - project.issues.find_by_iid(id) - when "MergeRequest" - project.merge_requests.find_by_iid(id) - when "Commit" - project.commit(id) - end + def target + @target ||= + case @noteable_type + when "Issue" + project.issues.find_by_iid(@noteable_id) + when "MergeRequest" + project.merge_requests.find_by_iid(@noteable_id) + when "Commit" + project.commit(@noteable_id) + else + nil + end end def target_owner - return [] unless @target && @target.author.present? + return [] unless target && target.author.present? [{ - name: @target.author.name, - username: @target.author.username + name: target.author.name, + username: target.author.username }] end def participants_in_target - return [] unless @target + return [] unless target - users = @target.participants(current_user) + users = target.participants(current_user) sorted(users) end From 42848f2684c093c114abf20dd5d73a195ec6a451 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Fri, 8 Apr 2016 13:45:24 -0500 Subject: [PATCH 07/13] Update CHANGELOG --- CHANGELOG | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index f1320b6a28..7754c3fb9f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -79,6 +79,9 @@ v 8.6.6 - Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413 - Fix error on language detection when repository has no HEAD (e.g., master branch) (Jeroen Bobbeldijk). !3654 - Fix revoking of authorized OAuth applications (Connor Shea). !3690 + - Fix error on language detection when repository has no HEAD (e.g., master branch). !3654 (Jeroen Bobbeldijk) + - Project switcher uses new dropdown styling + - Author and participants are displayed first on users autocompletion v 8.6.5 - Fix importing from GitHub Enterprise. !3529 From a740f0bc99a67d25ed156353055de3b4fe0064a6 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Fri, 8 Apr 2016 19:35:43 -0500 Subject: [PATCH 08/13] Add tests for autocomplete on a Issue --- .../participants_autocomplete_spec.rb | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 spec/features/participants_autocomplete_spec.rb diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb new file mode 100644 index 0000000000..f966fcbbfa --- /dev/null +++ b/spec/features/participants_autocomplete_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +feature 'Member autocomplete', feature: true do + let(:project) { create(:project, :public) } + let(:user) { create(:user) } + let(:participant) { create(:user) } + let(:author) { create(:user) } + let(:issue) { create(:issue, author: author, project: project) } + + before do + login_as user + end + + describe 'On a Issue', js: true do + before do + create(:note, note: 'ultralight beam', noteable: issue, author: participant) + visit_issue(project, issue) + end + + describe 'adding a new note' do + describe 'when typing @' do + + before do + sleep 1 + page.within('.new-note') do + sleep 1 + find('#note_note').native.send_keys('@') + end + end + + it 'suggestions are displayed' do + expect(page).to have_selector('.atwho-view', visible: true) + end + + it 'author is a suggestion' do + page.within('.atwho-view', visible: true) do + expect(page).to have_content(author.username) + end + end + + it 'participant is a suggestion' do + page.within('.atwho-view', visible: true) do + expect(page).to have_content(participant.username) + end + end + end + end + end + + def visit_issue(project, issue) + visit namespace_project_issue_path(project.namespace, project, issue) + end +end From 40efb4eb1fb3a1863f16488c7a468d4ca140500a Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Sat, 9 Apr 2016 01:34:07 -0500 Subject: [PATCH 09/13] Add tests for autocomplete on a Merge Request --- .../participants_autocomplete_spec.rb | 81 ++++++++++++------- 1 file changed, 52 insertions(+), 29 deletions(-) diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index f966fcbbfa..5f1b5fd6b5 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -5,49 +5,72 @@ feature 'Member autocomplete', feature: true do let(:user) { create(:user) } let(:participant) { create(:user) } let(:author) { create(:user) } - let(:issue) { create(:issue, author: author, project: project) } before do login_as user end - describe 'On a Issue', js: true do + shared_examples "open suggestions" do + it 'suggestions are displayed' do + expect(page).to have_selector('.atwho-view', visible: true) + end + + it 'author is suggested' do + page.within('.atwho-view', visible: true) do + expect(page).to have_content(author.username) + end + end + + it 'participant is suggested' do + page.within('.atwho-view', visible: true) do + expect(page).to have_content(participant.username) + end + end + end + + context 'On a Issue adding a new note', js: true do before do - create(:note, note: 'ultralight beam', noteable: issue, author: participant) + issue = create(:issue, author: author, project: project) + create(:note, note: 'Ultralight Beam', noteable: issue, author: participant) visit_issue(project, issue) end - describe 'adding a new note' do - describe 'when typing @' do - - before do - sleep 1 - page.within('.new-note') do - sleep 1 - find('#note_note').native.send_keys('@') - end - end - - it 'suggestions are displayed' do - expect(page).to have_selector('.atwho-view', visible: true) - end - - it 'author is a suggestion' do - page.within('.atwho-view', visible: true) do - expect(page).to have_content(author.username) - end - end - - it 'participant is a suggestion' do - page.within('.atwho-view', visible: true) do - expect(page).to have_content(participant.username) - end - end + context 'when typing @' do + include_examples "open suggestions" + before do + open_member_suggestions end end end + context 'On a Merge Request adding a new note', js: true do + before do + merge = create(:merge_request, source_project: project, target_project: project, author: author) + create(:note, note: 'Ultralight Beam', noteable: merge, author: participant) + visit_merge_request(project, merge) + end + + context 'when typing @' do + include_examples "open suggestions" + before do + open_member_suggestions + end + end + end + + def open_member_suggestions + sleep 1 + page.within('.new-note') do + sleep 1 + find('#note_note').native.send_keys('@') + end + end + def visit_issue(project, issue) visit namespace_project_issue_path(project.namespace, project, issue) end + + def visit_merge_request(project, merge) + visit namespace_project_merge_request_path(project.namespace, project, merge) + end end From a53e912bc0578febf87f722887a100f2c6e4670f Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Mon, 11 Apr 2016 14:02:00 -0500 Subject: [PATCH 10/13] Change context description --- spec/features/participants_autocomplete_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index 5f1b5fd6b5..b566a036a4 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -28,7 +28,7 @@ feature 'Member autocomplete', feature: true do end end - context 'On a Issue adding a new note', js: true do + context 'adding a new note on a Issue', js: true do before do issue = create(:issue, author: author, project: project) create(:note, note: 'Ultralight Beam', noteable: issue, author: participant) @@ -43,7 +43,7 @@ feature 'Member autocomplete', feature: true do end end - context 'On a Merge Request adding a new note', js: true do + context 'adding a new note on a Merge Request ', js: true do before do merge = create(:merge_request, source_project: project, target_project: project, author: author) create(:note, note: 'Ultralight Beam', noteable: merge, author: participant) From 18b4291181ba126a21137320a9f7b7f503c1d776 Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Wed, 13 Apr 2016 13:50:17 -0500 Subject: [PATCH 11/13] Add tests for autocomplete on a Commit --- .../participants_autocomplete_spec.rb | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb index b566a036a4..1adab7e9c6 100644 --- a/spec/features/participants_autocomplete_spec.rb +++ b/spec/features/participants_autocomplete_spec.rb @@ -7,6 +7,7 @@ feature 'Member autocomplete', feature: true do let(:author) { create(:user) } before do + allow_any_instance_of(Commit).to receive(:author).and_return(author) login_as user end @@ -58,6 +59,23 @@ feature 'Member autocomplete', feature: true do end end + context 'adding a new note on a Commit ', js: true do + let(:commit) { project.commit } + + before do + allow(commit).to receive(:author).and_return(author) + create(:note_on_commit, author: participant, project: project, commit_id: project.repository.commit.id, note: 'No More Parties in LA') + visit_commit(project, commit) + end + + context 'when typing @' do + include_examples "open suggestions" + before do + open_member_suggestions + end + end + end + def open_member_suggestions sleep 1 page.within('.new-note') do @@ -73,4 +91,8 @@ feature 'Member autocomplete', feature: true do def visit_merge_request(project, merge) visit namespace_project_merge_request_path(project.namespace, project, merge) end + + def visit_commit(project, commit) + visit namespace_project_commit_path(project.namespace, project, commit) + end end From 6e00c3635bfdf10ef2ada7a5b8af3fbc88f7f58a Mon Sep 17 00:00:00 2001 From: Alfredo Sumaran Date: Thu, 14 Apr 2016 12:19:33 -0500 Subject: [PATCH 12/13] Update CHANGELOG --- CHANGELOG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 7754c3fb9f..bc523533ee 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -74,6 +74,7 @@ v 8.7.0 (unreleased) - Selected diff rows highlight - Fix emoji categories in the emoji picker - Add encrypted credentials for imported projects and migrate old ones + - Author and participants are displayed first on users autocompletion v 8.6.6 - Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413 @@ -81,7 +82,6 @@ v 8.6.6 - Fix revoking of authorized OAuth applications (Connor Shea). !3690 - Fix error on language detection when repository has no HEAD (e.g., master branch). !3654 (Jeroen Bobbeldijk) - Project switcher uses new dropdown styling - - Author and participants are displayed first on users autocompletion v 8.6.5 - Fix importing from GitHub Enterprise. !3529 From 5ddda30c353569d3d0af52c0112be4e66f890586 Mon Sep 17 00:00:00 2001 From: Jacob Schatz Date: Sat, 16 Apr 2016 08:59:56 -0400 Subject: [PATCH 13/13] Remove errors from CHANGELOG --- CHANGELOG | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index bc523533ee..5c375fcdb3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -80,8 +80,6 @@ v 8.6.6 - Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413 - Fix error on language detection when repository has no HEAD (e.g., master branch) (Jeroen Bobbeldijk). !3654 - Fix revoking of authorized OAuth applications (Connor Shea). !3690 - - Fix error on language detection when repository has no HEAD (e.g., master branch). !3654 (Jeroen Bobbeldijk) - - Project switcher uses new dropdown styling v 8.6.5 - Fix importing from GitHub Enterprise. !3529