Fix shortcuts inconsistencies (#12624)

Fixes https://github.com/twentyhq/core-team-issues/issues/1093

The search shortcut and the go to shortcuts were not always available.
They worked after a refresh but not when clicking outside of a table or
a board, or when a table row or board card was focus.
This PR fixes this:


https://github.com/user-attachments/assets/f454037b-9dfd-4f9c-9124-43f4b8b5cec8
This commit is contained in:
Raphaël Bosi
2025-06-16 16:10:27 +02:00
committed by GitHub
parent e41d2f9f53
commit ed1593c089
13 changed files with 58 additions and 7 deletions

View File

@ -147,6 +147,7 @@ export const PageChangeEffect = () => {
setHotkeyScope(RecordIndexHotkeyScope.RecordIndex, { setHotkeyScope(RecordIndexHotkeyScope.RecordIndex, {
goto: true, goto: true,
keyboardShortcutMenu: true, keyboardShortcutMenu: true,
searchRecords: true,
}); });
break; break;
} }
@ -154,6 +155,7 @@ export const PageChangeEffect = () => {
setHotkeyScope(PageHotkeyScope.RecordShowPage, { setHotkeyScope(PageHotkeyScope.RecordShowPage, {
goto: true, goto: true,
keyboardShortcutMenu: true, keyboardShortcutMenu: true,
searchRecords: true,
}); });
break; break;
} }
@ -191,6 +193,7 @@ export const PageChangeEffect = () => {
keyboardShortcutMenu: false, keyboardShortcutMenu: false,
commandMenu: false, commandMenu: false,
commandMenuOpen: false, commandMenuOpen: false,
searchRecords: false,
}); });
break; break;
} }

View File

@ -53,7 +53,7 @@ export const useCommandMenuHotKeys = () => {
openRecordsSearchPage(); openRecordsSearchPage();
}, },
false, false,
AppHotkeyScope.KeyboardShortcutMenu, AppHotkeyScope.SearchRecords,
[openRecordsSearchPage], [openRecordsSearchPage],
{ {
ignoreModifiers: true, ignoreModifiers: true,

View File

@ -13,6 +13,12 @@ import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotV
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2'; import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { useRecoilCallback } from 'recoil'; import { useRecoilCallback } from 'recoil';
const BOARD_NAVIGATION_CUSTOM_SCOPES = {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
};
export const RecordBoardHotkeyEffect = () => { export const RecordBoardHotkeyEffect = () => {
const { recordBoardId } = useContext(RecordBoardContext); const { recordBoardId } = useContext(RecordBoardContext);
@ -54,6 +60,7 @@ export const RecordBoardHotkeyEffect = () => {
() => { () => {
setHotkeyScopeAndMemorizePreviousScope({ setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus, scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
}); });
move('left'); move('left');
}, },
@ -65,6 +72,7 @@ export const RecordBoardHotkeyEffect = () => {
() => { () => {
setHotkeyScopeAndMemorizePreviousScope({ setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus, scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
}); });
move('right'); move('right');
}, },
@ -76,6 +84,7 @@ export const RecordBoardHotkeyEffect = () => {
() => { () => {
setHotkeyScopeAndMemorizePreviousScope({ setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus, scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
}); });
move('up'); move('up');
}, },
@ -87,6 +96,7 @@ export const RecordBoardHotkeyEffect = () => {
() => { () => {
setHotkeyScopeAndMemorizePreviousScope({ setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus, scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
}); });
move('down'); move('down');
}, },

View File

@ -5,6 +5,12 @@ import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousH
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { Key } from 'ts-key-enum'; import { Key } from 'ts-key-enum';
const TABLE_NAVIGATION_CUSTOM_SCOPES = {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
};
export const useMapKeyboardToFocus = (recordTableId?: string) => { export const useMapKeyboardToFocus = (recordTableId?: string) => {
const { setHotkeyScopeAndMemorizePreviousScope } = usePreviousHotkeyScope(); const { setHotkeyScopeAndMemorizePreviousScope } = usePreviousHotkeyScope();
@ -33,6 +39,7 @@ export const useMapKeyboardToFocus = (recordTableId?: string) => {
() => { () => {
setHotkeyScopeAndMemorizePreviousScope({ setHotkeyScopeAndMemorizePreviousScope({
scope: TableHotkeyScope.TableFocus, scope: TableHotkeyScope.TableFocus,
customScopes: TABLE_NAVIGATION_CUSTOM_SCOPES,
}); });
move('up'); move('up');
}, },
@ -45,6 +52,7 @@ export const useMapKeyboardToFocus = (recordTableId?: string) => {
() => { () => {
setHotkeyScopeAndMemorizePreviousScope({ setHotkeyScopeAndMemorizePreviousScope({
scope: TableHotkeyScope.TableFocus, scope: TableHotkeyScope.TableFocus,
customScopes: TABLE_NAVIGATION_CUSTOM_SCOPES,
}); });
move('down'); move('down');
}, },

View File

@ -44,7 +44,11 @@ export const RecordTableBodyFocusClickOutsideEffect = ({
} }
leaveTableFocus(); leaveTableFocus();
setHotkeyScope(RecordIndexHotkeyScope.RecordIndex); setHotkeyScope(RecordIndexHotkeyScope.RecordIndex, {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
}, },
}); });

View File

@ -37,6 +37,7 @@ export const RecordTableBodyFocusKeyboardEffect = () => {
setHotkeyScope(RecordIndexHotkeyScope.RecordIndex, { setHotkeyScope(RecordIndexHotkeyScope.RecordIndex, {
goto: true, goto: true,
keyboardShortcutMenu: true, keyboardShortcutMenu: true,
searchRecords: true,
}); });
} }
}, },

View File

@ -94,6 +94,10 @@ describe('useCloseRecordTableCellInGroup', () => {
expect(result.current.isDragSelectionStartEnabled()).toBe(true); expect(result.current.isDragSelectionStartEnabled()).toBe(true);
expect(result.current.currentTableCellInEditModePosition).toBe(null); expect(result.current.currentTableCellInEditModePosition).toBe(null);
expect(setHotkeyScope).toHaveBeenCalledWith('table-focus'); expect(setHotkeyScope).toHaveBeenCalledWith('table-focus', {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
}); });
}); });

View File

@ -95,6 +95,10 @@ describe('useCloseRecordTableCellNoGroup', () => {
expect(result.current.isDragSelectionStartEnabled()).toBe(true); expect(result.current.isDragSelectionStartEnabled()).toBe(true);
expect(result.current.currentTableCellInEditModePosition).toBe(null); expect(result.current.currentTableCellInEditModePosition).toBe(null);
expect(setHotkeyScope).toHaveBeenCalledWith('table-focus'); expect(setHotkeyScope).toHaveBeenCalledWith('table-focus', {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
}); });
}); });

View File

@ -27,7 +27,11 @@ export const useCloseRecordTableCellInGroup = () => {
toggleClickOutside(true); toggleClickOutside(true);
setDragSelectionStartEnabled(true); setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode(); closeCurrentTableCellInEditMode();
setHotkeyScope(TableHotkeyScope.TableFocus); setHotkeyScope(TableHotkeyScope.TableFocus, {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
}, },
[ [
closeCurrentTableCellInEditMode, closeCurrentTableCellInEditMode,

View File

@ -26,7 +26,11 @@ export const useCloseRecordTableCellNoGroup = () => {
toggleClickOutside(true); toggleClickOutside(true);
setDragSelectionStartEnabled(true); setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode(); closeCurrentTableCellInEditMode();
setHotkeyScope(TableHotkeyScope.TableFocus); setHotkeyScope(TableHotkeyScope.TableFocus, {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
}, [ }, [
closeCurrentTableCellInEditMode, closeCurrentTableCellInEditMode,
setDragSelectionStartEnabled, setDragSelectionStartEnabled,

View File

@ -19,7 +19,9 @@ const areCustomScopesEqual = (
customScopesA?.commandMenu === customScopesB?.commandMenu && customScopesA?.commandMenu === customScopesB?.commandMenu &&
customScopesA?.commandMenuOpen === customScopesB?.commandMenuOpen && customScopesA?.commandMenuOpen === customScopesB?.commandMenuOpen &&
customScopesA?.goto === customScopesB?.goto && customScopesA?.goto === customScopesB?.goto &&
customScopesA?.keyboardShortcutMenu === customScopesB?.keyboardShortcutMenu customScopesA?.keyboardShortcutMenu ===
customScopesB?.keyboardShortcutMenu &&
customScopesA?.searchRecords === customScopesB?.searchRecords
); );
}; };
@ -60,6 +62,7 @@ export const useSetHotkeyScope = () =>
commandMenuOpen: customScopes?.commandMenuOpen ?? true, commandMenuOpen: customScopes?.commandMenuOpen ?? true,
goto: customScopes?.goto ?? false, goto: customScopes?.goto ?? false,
keyboardShortcutMenu: customScopes?.keyboardShortcutMenu ?? false, keyboardShortcutMenu: customScopes?.keyboardShortcutMenu ?? false,
searchRecords: customScopes?.searchRecords ?? false,
}, },
}; };
@ -81,6 +84,10 @@ export const useSetHotkeyScope = () =>
scopesToSet.push(AppHotkeyScope.KeyboardShortcutMenu); scopesToSet.push(AppHotkeyScope.KeyboardShortcutMenu);
} }
if (newHotkeyScope?.customScopes?.searchRecords === true) {
scopesToSet.push(AppHotkeyScope.SearchRecords);
}
scopesToSet.push(newHotkeyScope.scope); scopesToSet.push(newHotkeyScope.scope);
if (DEBUG_HOTKEY_SCOPE) { if (DEBUG_HOTKEY_SCOPE) {

View File

@ -3,6 +3,7 @@ export enum AppHotkeyScope {
Goto = 'goto', Goto = 'goto',
CommandMenu = 'command-menu', CommandMenu = 'command-menu',
CommandMenuOpen = 'command-menu-open', CommandMenuOpen = 'command-menu-open',
SearchRecords = 'search-records',
KeyboardShortcutMenu = 'keyboard-shortcut-menu', KeyboardShortcutMenu = 'keyboard-shortcut-menu',
KeyboardShortcutMenuOpen = 'keyboard-shortcut-menu-open', KeyboardShortcutMenuOpen = 'keyboard-shortcut-menu-open',
} }

View File

@ -3,4 +3,5 @@ export type CustomHotkeyScopes = {
commandMenu?: boolean; commandMenu?: boolean;
commandMenuOpen?: boolean; commandMenuOpen?: boolean;
keyboardShortcutMenu?: boolean; keyboardShortcutMenu?: boolean;
searchRecords?: boolean;
}; };