mirror of
https://github.com/lingble/twenty.git
synced 2025-10-30 12:22:29 +00:00
refactor: rely on recoil and scoped hotkeys to select all items and reset selection
This commit is contained in:
@@ -61,6 +61,7 @@ export const RecordBoard = () => {
|
|||||||
columnIdsState,
|
columnIdsState,
|
||||||
columnsFamilySelector,
|
columnsFamilySelector,
|
||||||
recordIdsByColumnIdFamilyState,
|
recordIdsByColumnIdFamilyState,
|
||||||
|
allRecordIdsSelector,
|
||||||
} = useRecordBoardStates(recordBoardId);
|
} = useRecordBoardStates(recordBoardId);
|
||||||
|
|
||||||
const columnIds = useRecoilValue(columnIdsState);
|
const columnIds = useRecoilValue(columnIdsState);
|
||||||
@@ -80,6 +81,20 @@ export const RecordBoard = () => {
|
|||||||
callback: resetRecordSelection,
|
callback: resetRecordSelection,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectAll = useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
() => {
|
||||||
|
const allRecordIds = snapshot
|
||||||
|
.getLoadable(allRecordIdsSelector())
|
||||||
|
.getValue();
|
||||||
|
|
||||||
|
for (const recordId of allRecordIds) {
|
||||||
|
setRecordAsSelected(recordId, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[allRecordIdsSelector, setRecordAsSelected],
|
||||||
|
);
|
||||||
|
|
||||||
useScopedHotkeys([Key.Escape], resetRecordSelection, TableHotkeyScope.Table);
|
useScopedHotkeys([Key.Escape], resetRecordSelection, TableHotkeyScope.Table);
|
||||||
|
|
||||||
const handleDragEnd: OnDragEndResponder = useRecoilCallback(
|
const handleDragEnd: OnDragEndResponder = useRecoilCallback(
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { recordBoardObjectSingularNameComponentState } from '@/object-record/rec
|
|||||||
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
import { recordBoardRecordIdsByColumnIdComponentFamilyState } from '@/object-record/record-board/states/recordBoardRecordIdsByColumnIdComponentFamilyState';
|
||||||
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
import { recordBoardShouldFetchMoreInColumnComponentFamilyState } from '@/object-record/record-board/states/recordBoardShouldFetchMoreInColumnComponentFamilyState';
|
||||||
import { recordBoardSortsComponentState } from '@/object-record/record-board/states/recordBoardSortsComponentState';
|
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 { recordBoardColumnsComponentFamilySelector } from '@/object-record/record-board/states/selectors/recordBoardColumnsComponentFamilySelector';
|
||||||
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
import { recordBoardSelectedRecordIdsComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardSelectedRecordIdsComponentSelector';
|
||||||
import { recordBoardShouldFetchMoreComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector';
|
import { recordBoardShouldFetchMoreComponentSelector } from '@/object-record/record-board/states/selectors/recordBoardShouldFetchMoreComponentFamilySelector';
|
||||||
@@ -76,6 +77,10 @@ export const useRecordBoardStates = (recordBoardId?: string) => {
|
|||||||
isRecordBoardCardSelectedComponentFamilyState,
|
isRecordBoardCardSelectedComponentFamilyState,
|
||||||
scopeId,
|
scopeId,
|
||||||
),
|
),
|
||||||
|
allRecordIdsSelector: extractComponentReadOnlySelector(
|
||||||
|
recordBoardAllRecordIdsComponentSelector,
|
||||||
|
scopeId,
|
||||||
|
),
|
||||||
selectedRecordIdsSelector: extractComponentReadOnlySelector(
|
selectedRecordIdsSelector: extractComponentReadOnlySelector(
|
||||||
recordBoardSelectedRecordIdsComponentSelector,
|
recordBoardSelectedRecordIdsComponentSelector,
|
||||||
scopeId,
|
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 { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||||
|
|
||||||
import { RecordUpdateContext } from '../contexts/EntityUpdateMutationHookContext';
|
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`
|
const StyledTableWithHeader = styled.div`
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -40,6 +46,23 @@ export const RecordTableWithWrappers = ({
|
|||||||
recordTableId,
|
recordTableId,
|
||||||
viewBarId,
|
viewBarId,
|
||||||
}: RecordTableWithWrappersProps) => {
|
}: RecordTableWithWrappersProps) => {
|
||||||
|
const { resetTableRowSelection, selectAllRows } = useRecordTable({
|
||||||
|
recordTableId,
|
||||||
|
});
|
||||||
|
|
||||||
|
useScopedHotkeys(
|
||||||
|
Key.Escape,
|
||||||
|
resetTableRowSelection,
|
||||||
|
ActionBarHotkeyScope.ActionBar,
|
||||||
|
);
|
||||||
|
|
||||||
|
useScopedHotkeys('ctrl+a,meta+a', selectAllRows, TableHotkeyScope.Table);
|
||||||
|
useScopedHotkeys(
|
||||||
|
'ctrl+a,meta+a',
|
||||||
|
selectAllRows,
|
||||||
|
TableHotkeyScope.TableSoftFocus,
|
||||||
|
);
|
||||||
|
|
||||||
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
|
const { saveViewFields } = useSaveCurrentViewFields(viewBarId);
|
||||||
|
|
||||||
const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular });
|
const { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular });
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { RefObject, useCallback, useEffect } from 'react';
|
|
||||||
import {
|
import {
|
||||||
boxesIntersect,
|
boxesIntersect,
|
||||||
useSelectionContainer,
|
useSelectionContainer,
|
||||||
@@ -22,53 +21,10 @@ export const DragSelect = ({
|
|||||||
onDragSelectionStart,
|
onDragSelectionStart,
|
||||||
onDragSelectionEnd,
|
onDragSelectionEnd,
|
||||||
}: DragSelectProps) => {
|
}: DragSelectProps) => {
|
||||||
const handleKeyDown = useCallback(
|
|
||||||
(event: KeyboardEvent) => {
|
|
||||||
if (event.key === 'a' && (event.ctrlKey || event.metaKey)) {
|
|
||||||
event.preventDefault();
|
|
||||||
const items = dragSelectable.current?.querySelectorAll<HTMLElement>(
|
|
||||||
'[data-selectable-id]',
|
|
||||||
);
|
|
||||||
if (!items) return;
|
|
||||||
|
|
||||||
queueMicrotask(() => {
|
|
||||||
items.forEach((item) => {
|
|
||||||
const id = item.getAttribute('data-selectable-id');
|
|
||||||
if (id !== null) {
|
|
||||||
onDragSelectionChange(id, true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.key === 'Escape') {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
const items = dragSelectable.current?.querySelectorAll<HTMLElement>(
|
|
||||||
'[data-selectable-id]',
|
|
||||||
);
|
|
||||||
if (!items) return;
|
|
||||||
|
|
||||||
queueMicrotask(() => {
|
|
||||||
items.forEach((item) => {
|
|
||||||
const id = item.getAttribute('data-selectable-id');
|
|
||||||
if (id !== null) {
|
|
||||||
onDragSelectionChange(id, false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[dragSelectable, onDragSelectionChange],
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
document.addEventListener('keydown', handleKeyDown);
|
|
||||||
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
||||||
}, [handleKeyDown]);
|
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const { isDragSelectionStartEnabled } = useDragSelect();
|
const { isDragSelectionStartEnabled } = useDragSelect();
|
||||||
|
|
||||||
const { DragSelection } = useSelectionContainer({
|
const { DragSelection } = useSelectionContainer({
|
||||||
shouldStartSelecting: (target) => {
|
shouldStartSelecting: (target) => {
|
||||||
if (!isDragSelectionStartEnabled()) {
|
if (!isDragSelectionStartEnabled()) {
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ export const useSetHotkeyScope = () =>
|
|||||||
|
|
||||||
set(internalHotkeysEnabledScopesState, scopesToSet);
|
set(internalHotkeysEnabledScopesState, scopesToSet);
|
||||||
set(currentHotkeyScopeState, newHotkeyScope);
|
set(currentHotkeyScopeState, newHotkeyScope);
|
||||||
|
|
||||||
|
console.log(scopesToSet);
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user