mirror of
				https://github.com/lingble/twenty.git
				synced 2025-10-31 04:37:56 +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, | ||||
|     columnsFamilySelector, | ||||
|     recordIdsByColumnIdFamilyState, | ||||
|     allRecordIdsSelector, | ||||
|   } = useRecordBoardStates(recordBoardId); | ||||
|  | ||||
|   const columnIds = useRecoilValue(columnIdsState); | ||||
| @@ -80,6 +81,20 @@ export const RecordBoard = () => { | ||||
|     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); | ||||
|  | ||||
|   const handleDragEnd: OnDragEndResponder = useRecoilCallback( | ||||
|   | ||||
| @@ -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( | ||||
|     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 { deleteOneRecord } = useDeleteOneRecord({ objectNameSingular }); | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| import { RefObject, useCallback, useEffect } from 'react'; | ||||
| import { | ||||
|   boxesIntersect, | ||||
|   useSelectionContainer, | ||||
| @@ -22,53 +21,10 @@ export const DragSelect = ({ | ||||
|   onDragSelectionStart, | ||||
|   onDragSelectionEnd, | ||||
| }: 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 { isDragSelectionStartEnabled } = useDragSelect(); | ||||
|  | ||||
|   const { DragSelection } = useSelectionContainer({ | ||||
|     shouldStartSelecting: (target) => { | ||||
|       if (!isDragSelectionStartEnabled()) { | ||||
|   | ||||
| @@ -88,6 +88,8 @@ export const useSetHotkeyScope = () => | ||||
|  | ||||
|         set(internalHotkeysEnabledScopesState, scopesToSet); | ||||
|         set(currentHotkeyScopeState, newHotkeyScope); | ||||
|  | ||||
|         console.log(scopesToSet); | ||||
|       }, | ||||
|     [], | ||||
|   ); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Devessier
					Devessier