From 3b71f418596524096e4413c94eb7af300503bef2 Mon Sep 17 00:00:00 2001 From: Jeff Tucker Date: Tue, 9 Sep 2025 14:23:25 -0400 Subject: [PATCH 1/4] Add shortcut to return to homepage --- .../behaviors/shortcuts/keybindings.js | 7 ++++++ .../behaviors/shortcuts/shortcuts.js | 2 ++ locale/gitlab.pot | 3 +++ spec/features/dashboard/shortcuts_spec.rb | 6 +++++ .../behaviors/shortcuts/keybindings_spec.js | 16 +++++++++++++ .../behaviors/shortcuts/shortcuts_spec.js | 23 +++++++++++++++++++ 6 files changed, 57 insertions(+) diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js index a001bfe67a4fec..13b7636c142c25 100644 --- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js +++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js @@ -138,6 +138,12 @@ export const DUO_CHAT = { defaultKeys: ['d'], }; +export const GO_TO_HOMEPAGE = { + id: 'globalShortcuts.goToHomepage', + description: __('Go to homepage'), + defaultKeys: ['shift+h'], +}; + export const BOLD_TEXT = { id: 'editing.boldText', description: __('Bold text'), @@ -622,6 +628,7 @@ const GLOBAL_SHORTCUTS_GROUP = { name: __('Global Shortcuts'), keybindings: [ TOGGLE_KEYBOARD_SHORTCUTS_DIALOG, + GO_TO_HOMEPAGE, GO_TO_YOUR_PROJECTS, GO_TO_YOUR_GROUPS, GO_TO_ACTIVITY_FEED, diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js index f0666da0261d76..0a6ad60a3c2b04 100644 --- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js +++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js @@ -19,6 +19,7 @@ import { TOGGLE_CANARY, TOGGLE_MARKDOWN_PREVIEW, FIND_AND_REPLACE, + GO_TO_HOMEPAGE, GO_TO_YOUR_TODO_LIST, GO_TO_ACTIVITY_FEED, GO_TO_YOUR_ISSUES, @@ -86,6 +87,7 @@ export default class Shortcuts { [HIDE_APPEARING_CONTENT, Shortcuts.hideAppearingContent], [TOGGLE_CANARY, Shortcuts.onToggleCanary], + [GO_TO_HOMEPAGE, () => findAndFollowLink('.brand-logo')], [GO_TO_YOUR_TODO_LIST, () => findAndFollowLink('.shortcuts-todos')], [GO_TO_ACTIVITY_FEED, () => findAndFollowLink('.dashboard-shortcuts-activity')], [GO_TO_YOUR_ISSUES, () => findAndFollowLink('.dashboard-shortcuts-issues')], diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a5954aa0a5c12a..a9f19599b42c24 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -30900,6 +30900,9 @@ msgstr "" msgid "Go to find file" msgstr "" +msgid "Go to homepage" +msgstr "" + msgid "Go to issue boards" msgstr "" diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb index 6a4349fe40855c..a8d81b510c703c 100644 --- a/spec/features/dashboard/shortcuts_spec.rb +++ b/spec/features/dashboard/shortcuts_spec.rb @@ -20,6 +20,12 @@ end it 'navigates to pages' do + find('body').send_keys([:shift, 'H']) + + expect(page).to have_current_path(root_path) + + visit root_dashboard_path + find('body').send_keys([:shift, 'I']) check_page_title('Issues') diff --git a/spec/frontend/behaviors/shortcuts/keybindings_spec.js b/spec/frontend/behaviors/shortcuts/keybindings_spec.js index 2738339db2d5be..d2445f63ea60a6 100644 --- a/spec/frontend/behaviors/shortcuts/keybindings_spec.js +++ b/spec/frontend/behaviors/shortcuts/keybindings_spec.js @@ -8,6 +8,7 @@ import { HIDE_APPEARING_CONTENT, LOCAL_STORAGE_KEY, BOLD_TEXT, + GO_TO_HOMEPAGE, } from '~/behaviors/shortcuts/keybindings'; describe('~/behaviors/shortcuts/keybindings', () => { @@ -121,4 +122,19 @@ describe('~/behaviors/shortcuts/keybindings', () => { expect(keysFor(HIDE_APPEARING_CONTENT)).toEqual(['esc']); }); }); + + describe('GO_TO_HOMEPAGE command', () => { + beforeEach(() => { + setupCustomizations(); + }); + + it('has the correct default keybinding', () => { + expect(keysFor(GO_TO_HOMEPAGE)).toEqual(['shift+h']); + }); + + it('is included in the global shortcuts group', () => { + const globalGroup = keybindingGroups.find((group) => group.id === 'globalShortcuts'); + expect(globalGroup.keybindings).toContain(GO_TO_HOMEPAGE); + }); + }); }); diff --git a/spec/frontend/behaviors/shortcuts/shortcuts_spec.js b/spec/frontend/behaviors/shortcuts/shortcuts_spec.js index cedbf22e43cd53..5fb8be85d723db 100644 --- a/spec/frontend/behaviors/shortcuts/shortcuts_spec.js +++ b/spec/frontend/behaviors/shortcuts/shortcuts_spec.js @@ -3,11 +3,14 @@ import { flatten } from 'lodash'; import htmlSnippetsShow from 'test_fixtures/snippets/show.html'; import { Mousetrap } from '~/lib/mousetrap'; import { waitForElement } from '~/lib/utils/dom_utils'; +import findAndFollowLink from '~/lib/utils/navigation_utility'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import Shortcuts, { LOCAL_MOUSETRAP_DATA_KEY } from '~/behaviors/shortcuts/shortcuts'; import MarkdownPreview from '~/behaviors/preview_markdown'; import { useMockInternalEventsTracking } from 'helpers/tracking_internal_events_helper'; +jest.mock('~/lib/utils/navigation_utility'); + const mockSearchInput = document.createElement('input'); jest.mock('~/lib/utils/dom_utils', () => ({ @@ -197,6 +200,26 @@ describe('Shortcuts', () => { }); }); + describe('homepage navigation shortcut', () => { + it('calls findAndFollowLink with .brand-logo selector when homepage shortcut is triggered', () => { + // Find the homepage shortcut binding in the Mousetrap.bind calls + const bindCalls = Mousetrap.prototype.bind.mock.calls; + const homepageBinding = bindCalls.find(([keys]) => + Array.isArray(keys) ? keys.includes('shift+h') : keys === 'shift+h', + ); + + expect(homepageBinding).toBeDefined(); + + const [, callback] = homepageBinding; + + // Execute the callback + callback(); + + // Verify findAndFollowLink was called with the correct selector + expect(findAndFollowLink).toHaveBeenCalledWith('.brand-logo'); + }); + }); + describe('adding shortcuts', () => { it('add calls Mousetrap.bind correctly', () => { const mockCommand = { defaultKeys: ['m'] }; -- GitLab From ede49a2fdbdf6508f5879613f72b43fc16cb3f5d Mon Sep 17 00:00:00 2001 From: Jeff Tucker Date: Tue, 9 Sep 2025 14:34:53 -0400 Subject: [PATCH 2/4] Update documentation --- doc/user/shortcuts.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md index 8d239d5bd8fe75..c110a1def8d7c2 100644 --- a/doc/user/shortcuts.md +++ b/doc/user/shortcuts.md @@ -33,6 +33,7 @@ These shortcuts are available in most areas of GitLab: | Keyboard shortcut | Description | |------------------------------------|-------------| | ? | Show or hide the shortcut reference sheet. | +| Shift + h | Go to the homepage. | | Shift + p | Go to your **Projects** page. | | Shift + g | Go to your **Groups** page. | | Shift + a | Go to your **Activity** page. | -- GitLab From 6f408d68257ed2ce6799c6abebc158432d4fc721 Mon Sep 17 00:00:00 2001 From: Jeff Tucker Date: Tue, 9 Sep 2025 16:12:56 -0400 Subject: [PATCH 3/4] Fix specs --- spec/features/dashboard/shortcuts_spec.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/spec/features/dashboard/shortcuts_spec.rb b/spec/features/dashboard/shortcuts_spec.rb index a8d81b510c703c..6066bd57d01806 100644 --- a/spec/features/dashboard/shortcuts_spec.rb +++ b/spec/features/dashboard/shortcuts_spec.rb @@ -20,12 +20,6 @@ end it 'navigates to pages' do - find('body').send_keys([:shift, 'H']) - - expect(page).to have_current_path(root_path) - - visit root_dashboard_path - find('body').send_keys([:shift, 'I']) check_page_title('Issues') @@ -57,6 +51,10 @@ find('body').send_keys([:shift, 'L']) check_page_title('Milestones') + + find('body').send_keys([:shift, 'H']) + + check_page_title('Projects') # This will need to change when we remove the `personal_homepage` feature flag end end -- GitLab From 5b249c50bb803f01b709a87c74082caa13047a20 Mon Sep 17 00:00:00 2001 From: Jeff Tucker Date: Wed, 10 Sep 2025 08:40:11 -0400 Subject: [PATCH 4/4] This test is better managed in feature specs --- .../behaviors/shortcuts/shortcuts_spec.js | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/spec/frontend/behaviors/shortcuts/shortcuts_spec.js b/spec/frontend/behaviors/shortcuts/shortcuts_spec.js index 5fb8be85d723db..c1b32ecc01f976 100644 --- a/spec/frontend/behaviors/shortcuts/shortcuts_spec.js +++ b/spec/frontend/behaviors/shortcuts/shortcuts_spec.js @@ -3,7 +3,6 @@ import { flatten } from 'lodash'; import htmlSnippetsShow from 'test_fixtures/snippets/show.html'; import { Mousetrap } from '~/lib/mousetrap'; import { waitForElement } from '~/lib/utils/dom_utils'; -import findAndFollowLink from '~/lib/utils/navigation_utility'; import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import Shortcuts, { LOCAL_MOUSETRAP_DATA_KEY } from '~/behaviors/shortcuts/shortcuts'; import MarkdownPreview from '~/behaviors/preview_markdown'; @@ -200,26 +199,6 @@ describe('Shortcuts', () => { }); }); - describe('homepage navigation shortcut', () => { - it('calls findAndFollowLink with .brand-logo selector when homepage shortcut is triggered', () => { - // Find the homepage shortcut binding in the Mousetrap.bind calls - const bindCalls = Mousetrap.prototype.bind.mock.calls; - const homepageBinding = bindCalls.find(([keys]) => - Array.isArray(keys) ? keys.includes('shift+h') : keys === 'shift+h', - ); - - expect(homepageBinding).toBeDefined(); - - const [, callback] = homepageBinding; - - // Execute the callback - callback(); - - // Verify findAndFollowLink was called with the correct selector - expect(findAndFollowLink).toHaveBeenCalledWith('.brand-logo'); - }); - }); - describe('adding shortcuts', () => { it('add calls Mousetrap.bind correctly', () => { const mockCommand = { defaultKeys: ['m'] }; -- GitLab