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

View File

@ -53,7 +53,7 @@ export const useCommandMenuHotKeys = () => {
openRecordsSearchPage();
},
false,
AppHotkeyScope.KeyboardShortcutMenu,
AppHotkeyScope.SearchRecords,
[openRecordsSearchPage],
{
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 { useRecoilCallback } from 'recoil';
const BOARD_NAVIGATION_CUSTOM_SCOPES = {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
};
export const RecordBoardHotkeyEffect = () => {
const { recordBoardId } = useContext(RecordBoardContext);
@ -54,6 +60,7 @@ export const RecordBoardHotkeyEffect = () => {
() => {
setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
});
move('left');
},
@ -65,6 +72,7 @@ export const RecordBoardHotkeyEffect = () => {
() => {
setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
});
move('right');
},
@ -76,6 +84,7 @@ export const RecordBoardHotkeyEffect = () => {
() => {
setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
});
move('up');
},
@ -87,6 +96,7 @@ export const RecordBoardHotkeyEffect = () => {
() => {
setHotkeyScopeAndMemorizePreviousScope({
scope: BoardHotkeyScope.BoardFocus,
customScopes: BOARD_NAVIGATION_CUSTOM_SCOPES,
});
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 { Key } from 'ts-key-enum';
const TABLE_NAVIGATION_CUSTOM_SCOPES = {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
};
export const useMapKeyboardToFocus = (recordTableId?: string) => {
const { setHotkeyScopeAndMemorizePreviousScope } = usePreviousHotkeyScope();
@ -33,6 +39,7 @@ export const useMapKeyboardToFocus = (recordTableId?: string) => {
() => {
setHotkeyScopeAndMemorizePreviousScope({
scope: TableHotkeyScope.TableFocus,
customScopes: TABLE_NAVIGATION_CUSTOM_SCOPES,
});
move('up');
},
@ -45,6 +52,7 @@ export const useMapKeyboardToFocus = (recordTableId?: string) => {
() => {
setHotkeyScopeAndMemorizePreviousScope({
scope: TableHotkeyScope.TableFocus,
customScopes: TABLE_NAVIGATION_CUSTOM_SCOPES,
});
move('down');
},

View File

@ -44,7 +44,11 @@ export const RecordTableBodyFocusClickOutsideEffect = ({
}
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, {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
}
},

View File

@ -94,6 +94,10 @@ describe('useCloseRecordTableCellInGroup', () => {
expect(result.current.isDragSelectionStartEnabled()).toBe(true);
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.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);
setDragSelectionStartEnabled(true);
closeCurrentTableCellInEditMode();
setHotkeyScope(TableHotkeyScope.TableFocus);
setHotkeyScope(TableHotkeyScope.TableFocus, {
goto: true,
keyboardShortcutMenu: true,
searchRecords: true,
});
},
[
closeCurrentTableCellInEditMode,

View File

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

View File

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

View File

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

View File

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