Commit 1038ef54 authored by Jacob Schatz's avatar Jacob Schatz

Merge branch 'issue-boards-keyboard-shortcut' into 'master'

Added keyboard shortcut to navigate to issue boards

## What does this MR do?

Adds a keyboard shortcut of `g l` to navigate to issue boards.

`g b` would work nicer. However that is taken by builds. Open to suggestions.

## What are the relevant issue numbers?

Closes #21218

See merge request !6248
parents 8e4a33f2 07d39ac0
...@@ -30,6 +30,7 @@ v 8.12.0 (unreleased) ...@@ -30,6 +30,7 @@ v 8.12.0 (unreleased)
- Add `web_url` field to issue, merge request, and snippet API objects (Ben Boeckel) - Add `web_url` field to issue, merge request, and snippet API objects (Ben Boeckel)
- Enable pipeline events by default !6278 - Enable pipeline events by default !6278
- Move parsing of sidekiq ps into helper !6245 (pascalbetz) - Move parsing of sidekiq ps into helper !6245 (pascalbetz)
- Added go to issue boards keyboard shortcut
- Expose `sha` and `merge_commit_sha` in merge request API (Ben Boeckel) - Expose `sha` and `merge_commit_sha` in merge request API (Ben Boeckel)
- Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling) - Set path for all JavaScript cookies to honor GitLab's subdirectory setting !5627 (Mike Greiling)
- Fix blame table layout width - Fix blame table layout width
......
...@@ -34,6 +34,9 @@ ...@@ -34,6 +34,9 @@
Mousetrap.bind('g i', function() { Mousetrap.bind('g i', function() {
return ShortcutsNavigation.findAndFollowLink('.shortcuts-issues'); return ShortcutsNavigation.findAndFollowLink('.shortcuts-issues');
}); });
Mousetrap.bind('g l', function() {
ShortcutsNavigation.findAndFollowLink('.shortcuts-issue-boards');
});
Mousetrap.bind('g m', function() { Mousetrap.bind('g m', function() {
return ShortcutsNavigation.findAndFollowLink('.shortcuts-merge_requests'); return ShortcutsNavigation.findAndFollowLink('.shortcuts-merge_requests');
}); });
......
...@@ -162,6 +162,12 @@ ...@@ -162,6 +162,12 @@
.key i .key i
%td %td
Go to issues Go to issues
%tr
%td.shortcut
.key g
.key l
%td
Go to issue boards
%tr %tr
%td.shortcut %td.shortcut
.key g .key g
......
...@@ -113,3 +113,7 @@ ...@@ -113,3 +113,7 @@
%li.hidden %li.hidden
= link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do = link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits' do
Commits Commits
-# Shortcut to issue boards
%li.hidden
= link_to 'Issue Boards', namespace_project_board_path(@project.namespace, @project), title: 'Issue Boards', class: 'shortcuts-issue-boards'
...@@ -2,6 +2,7 @@ require 'rails_helper' ...@@ -2,6 +2,7 @@ require 'rails_helper'
describe 'Issue Boards', feature: true, js: true do describe 'Issue Boards', feature: true, js: true do
include WaitForAjax include WaitForAjax
include WaitForVueResource
let(:project) { create(:empty_project, :public) } let(:project) { create(:empty_project, :public) }
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -187,13 +188,13 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -187,13 +188,13 @@ describe 'Issue Boards', feature: true, js: true do
expect(page).to have_content('Showing 20 of 56 issues') expect(page).to have_content('Showing 20 of 56 issues')
evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight") evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
wait_for_vue_resource(spinner: false) wait_for_vue_resource
expect(page).to have_selector('.card', count: 40) expect(page).to have_selector('.card', count: 40)
expect(page).to have_content('Showing 40 of 56 issues') expect(page).to have_content('Showing 40 of 56 issues')
evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight") evaluate_script("document.querySelectorAll('.board .board-list')[0].scrollTop = document.querySelectorAll('.board .board-list')[0].scrollHeight")
wait_for_vue_resource(spinner: false) wait_for_vue_resource
expect(page).to have_selector('.card', count: 56) expect(page).to have_selector('.card', count: 56)
expect(page).to have_content('Showing all issues') expect(page).to have_content('Showing all issues')
...@@ -372,7 +373,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -372,7 +373,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within '.dropdown-menu-author' do page.within '.dropdown-menu-author' do
click_link(user2.name) click_link(user2.name)
end end
wait_for_vue_resource(spinner: false) wait_for_vue_resource
expect(find('.js-author-search')).to have_content(user2.name) expect(find('.js-author-search')).to have_content(user2.name)
end end
...@@ -398,7 +399,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -398,7 +399,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within '.dropdown-menu-assignee' do page.within '.dropdown-menu-assignee' do
click_link(user.name) click_link(user.name)
end end
wait_for_vue_resource(spinner: false) wait_for_vue_resource
expect(find('.js-assignee-search')).to have_content(user.name) expect(find('.js-assignee-search')).to have_content(user.name)
end end
...@@ -424,7 +425,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -424,7 +425,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within '.milestone-filter' do page.within '.milestone-filter' do
click_link(milestone.title) click_link(milestone.title)
end end
wait_for_vue_resource(spinner: false) wait_for_vue_resource
expect(find('.js-milestone-select')).to have_content(milestone.title) expect(find('.js-milestone-select')).to have_content(milestone.title)
end end
...@@ -449,7 +450,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -449,7 +450,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within '.dropdown-menu-labels' do page.within '.dropdown-menu-labels' do
click_link(testing.title) click_link(testing.title)
wait_for_vue_resource(spinner: false) wait_for_vue_resource
find('.dropdown-menu-close').click find('.dropdown-menu-close').click
end end
end end
...@@ -478,7 +479,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -478,7 +479,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within '.dropdown-menu-labels' do page.within '.dropdown-menu-labels' do
click_link(testing.title) click_link(testing.title)
wait_for_vue_resource(spinner: false) wait_for_vue_resource
find('.dropdown-menu-close').click find('.dropdown-menu-close').click
end end
end end
...@@ -509,9 +510,9 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -509,9 +510,9 @@ describe 'Issue Boards', feature: true, js: true do
page.within(find('.dropdown-menu-labels')) do page.within(find('.dropdown-menu-labels')) do
click_link(testing.title) click_link(testing.title)
wait_for_vue_resource(spinner: false) wait_for_vue_resource
click_link(bug.title) click_link(bug.title)
wait_for_vue_resource(spinner: false) wait_for_vue_resource
find('.dropdown-menu-close').click find('.dropdown-menu-close').click
end end
end end
...@@ -536,7 +537,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -536,7 +537,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within '.dropdown-menu-labels' do page.within '.dropdown-menu-labels' do
click_link("No Label") click_link("No Label")
wait_for_vue_resource(spinner: false) wait_for_vue_resource
find('.dropdown-menu-close').click find('.dropdown-menu-close').click
end end
end end
...@@ -559,7 +560,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -559,7 +560,7 @@ describe 'Issue Boards', feature: true, js: true do
expect(page).to have_selector('.card', count: 6) expect(page).to have_selector('.card', count: 6)
expect(find('.card', match: :first)).to have_content(bug.title) expect(find('.card', match: :first)).to have_content(bug.title)
click_button(bug.title) click_button(bug.title)
wait_for_vue_resource(spinner: false) wait_for_vue_resource
end end
wait_for_vue_resource wait_for_vue_resource
...@@ -584,7 +585,7 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -584,7 +585,7 @@ describe 'Issue Boards', feature: true, js: true do
page.within(find('.card', match: :first)) do page.within(find('.card', match: :first)) do
click_button(bug.title) click_button(bug.title)
end end
wait_for_vue_resource(spinner: false) wait_for_vue_resource
expect(page).to have_selector('.card', count: 1) expect(page).to have_selector('.card', count: 1)
end end
...@@ -647,14 +648,4 @@ describe 'Issue Boards', feature: true, js: true do ...@@ -647,14 +648,4 @@ describe 'Issue Boards', feature: true, js: true do
wait_for_vue_resource wait_for_vue_resource
end end
def wait_for_vue_resource(spinner: true)
Timeout.timeout(Capybara.default_max_wait_time) do
loop until page.evaluate_script('Vue.activeResources').zero?
end
if spinner
expect(find('.boards-list')).not_to have_selector('.fa-spinner')
end
end
end end
require 'rails_helper'
describe 'Issue Boards shortcut', feature: true, js: true do
include WaitForVueResource
let(:project) { create(:empty_project) }
before do
project.create_board
project.board.lists.create(list_type: :backlog)
project.board.lists.create(list_type: :done)
login_as :admin
visit namespace_project_path(project.namespace, project)
end
it 'takes user to issue board index' do
find('body').native.send_keys('gl')
expect(page).to have_selector('.boards-list')
wait_for_vue_resource
end
end
module WaitForVueResource
def wait_for_vue_resource(spinner: true)
Timeout.timeout(Capybara.default_max_wait_time) do
loop until page.evaluate_script('Vue.activeResources').zero?
end
end
end
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