mirror of
https://github.com/lingble/twenty.git
synced 2025-10-29 20:02:29 +00:00
fix: Added keyboard functionality for esc and Ctrl + a (#8282)
## Description - This PR fixes #8247 #8206 - Adds keyboard functionality for esc (deselect all records) and Ctrl + a (select records) ## Changes https://github.com/user-attachments/assets/7b2718d6-dbe5-4cd8-8ead-b6baed1fc357 Merged during stream 🎉 --------- Co-authored-by: Devessier <baptiste@devessier.fr>
This commit is contained in:
@@ -4,6 +4,7 @@ import { useContext, useRef } from 'react';
|
||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope';
|
||||
import { RecordBoardHeader } from '@/object-record/record-board/components/RecordBoardHeader';
|
||||
import { RecordBoardStickyHeaderEffect } from '@/object-record/record-board/components/RecordBoardStickyHeaderEffect';
|
||||
import { RECORD_BOARD_CLICK_OUTSIDE_LISTENER_ID } from '@/object-record/record-board/constants/RecordBoardClickOutsideListenerId';
|
||||
@@ -61,6 +62,7 @@ export const RecordBoard = () => {
|
||||
columnIdsState,
|
||||
columnsFamilySelector,
|
||||
recordIdsByColumnIdFamilyState,
|
||||
allRecordIdsSelector,
|
||||
} = useRecordBoardStates(recordBoardId);
|
||||
|
||||
const columnIds = useRecoilValue(columnIdsState);
|
||||
@@ -80,7 +82,28 @@ export const RecordBoard = () => {
|
||||
callback: resetRecordSelection,
|
||||
});
|
||||
|
||||
useScopedHotkeys([Key.Escape], resetRecordSelection, TableHotkeyScope.Table);
|
||||
const selectAll = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
() => {
|
||||
const allRecordIds = snapshot
|
||||
.getLoadable(allRecordIdsSelector())
|
||||
.getValue();
|
||||
|
||||
for (const recordId of allRecordIds) {
|
||||
setRecordAsSelected(recordId, true);
|
||||
}
|
||||
},
|
||||
[allRecordIdsSelector, setRecordAsSelected],
|
||||
);
|
||||
|
||||
useScopedHotkeys('ctrl+a,meta+a', selectAll, TableHotkeyScope.Table);
|
||||
useScopedHotkeys('ctrl+a,meta+a', selectAll, ActionBarHotkeyScope.ActionBar);
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.Escape,
|
||||
resetRecordSelection,
|
||||
ActionBarHotkeyScope.ActionBar,
|
||||
);
|
||||
|
||||
const handleDragEnd: OnDragEndResponder = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { recordBoardObjectSingularNameComponentState } from '@/object-record/rec
|
||||
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
||||
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
||||
import { recordBoardSortsComponentState } from '@/object-record/record-board/states/recordBoardSortsComponentState';
|
||||
import { recordBoardAllRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardAllRecordIdsComponentSelector';
|
||||
import { recordBoardColumnsComponentFamilySelector } from '@/object-record/record-board/states/selectors/recordBoardColumnsComponentFamilySelector';
|
||||
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
||||
import { recordBoardShouldFetchMoreComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector';
|
||||
@@ -76,6 +77,10 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
|
||||
isRecordBoardCardSelectedComponentFamilyState,
|
||||
scopeId,
|
||||
),
|
||||
allRecordIdsSelector: extractComponentReadOnlySelector(
|
||||
recordBoardAllRecordIdsComponentSelector,
|
||||
scopeId,
|
||||
),
|
||||
selectedRecordIdsSelector: extractComponentReadOnlySelector(
|
||||
recordBoardSelectedRecordIdsComponentSelector,
|
||||
scopeId,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { recordBoardColumnIdsComponentState } from '@/object-record/record-board/states/recordBoardColumnIdsComponentState';
|
||||
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
||||
import { createComponentReadOnlySelector } from '@/ui/utilities/state/component-state/utils/createComponentReadOnlySelector';
|
||||
|
||||
export const recordBoardAllRecordIdsComponentSelector =
|
||||
createComponentReadOnlySelector<string[]>({
|
||||
key: 'recordBoardAllRecordIdsComponentSelector',
|
||||
get:
|
||||
({ scopeId }) =>
|
||||
({ get }) => {
|
||||
const columnIds = get(recordBoardColumnIdsComponentState({ scopeId }));
|
||||
|
||||
const recordIdsByColumn = columnIds.map((columnId) =>
|
||||
get(
|
||||
recordBoardRecordIdsByColumnIdComponentFamilyState({
|
||||
scopeId,
|
||||
familyKey: columnId,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
const recordIds = recordIdsByColumn.flat();
|
||||
|
||||
return recordIds;
|
||||
},
|
||||
});
|
||||
@@ -11,6 +11,12 @@ import { useSaveCurrentViewFields } from '@/views/hooks/useSaveCurrentViewFields
|
||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||
|
||||
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
|
||||
import { useRecordTable } from '../hooks/useRecordTable';
|
||||
|
||||
import { ActionBarHotkeyScope } from '@/action-menu/types/ActionBarHotKeyScope';
|
||||
import { TableHotkeyScope } from '@/object-record/record-table/types/TableHotkeyScope';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
const StyledTableWithHeader = styled.div`
|
||||
height: 100%;
|
||||
@@ -40,6 +46,23 @@ export const RecordTableWithWrappers = ({
|
||||
recordTableId,
|
||||
viewBarId,
|
||||
}: RecordTableWithWrappersProps) => {
|
||||
const { resetTableRowSelection, selectAllRows } = useRecordTable({
|
||||
recordTableId,
|
||||
});
|
||||
|
||||
useScopedHotkeys('ctrl+a,meta+a', selectAllRows, TableHotkeyScope.Table);
|
||||
useScopedHotkeys(
|
||||
'ctrl+a,meta+a',
|
||||
selectAllRows,
|
||||
ActionBarHotkeyScope.ActionBar,
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.Escape,
|
||||
resetTableRowSelection,
|
||||
ActionBarHotkeyScope.ActionBar,
|
||||
);
|
||||
|
||||
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
|
||||
|
||||
const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular });
|
||||
|
||||
@@ -22,7 +22,9 @@ export const DragSelect = ({
|
||||
onDragSelectionEnd,
|
||||
}: DragSelectProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
const { isDragSelectionStartEnabled } = useDragSelect();
|
||||
|
||||
const { DragSelection } = useSelectionContainer({
|
||||
shouldStartSelecting: (target) => {
|
||||
if (!isDragSelectionStartEnabled()) {
|
||||
|
||||
Reference in New Issue
Block a user