diff --git a/packages/desktop-client/src/components/ManageRules.js b/packages/desktop-client/src/components/ManageRules.js index ca9b979cace1bedca795c5eae5d40832133c5893..dc4fdf4068f91639af3796cd1e6be26318babf69 100644 --- a/packages/desktop-client/src/components/ManageRules.js +++ b/packages/desktop-client/src/components/ManageRules.js @@ -329,8 +329,8 @@ let Rule = memo( <SelectCell exposed={hovered || selected || editing} focused={focusedField === 'select'} - onSelect={() => { - dispatchSelected({ type: 'select', id: rule.id }); + onSelect={e => { + dispatchSelected({ type: 'select', id: rule.id, event: e }); }} onEdit={() => onEdit(rule.id, 'select')} selected={selected} @@ -478,7 +478,7 @@ function RulesHeader() { exposed={true} focused={false} selected={selectedItems.size > 0} - onSelect={() => dispatchSelected({ type: 'select-all' })} + onSelect={e => dispatchSelected({ type: 'select-all', event: e })} /> <Cell value="Stage" width={50} /> <Cell value="Rule" width="flex" /> diff --git a/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js b/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js index dad8e1afd453cd0f2a02f27cad05de255031cbbb..d7db23f5a56222df976d11e6dabfe7884b34f5bf 100644 --- a/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js +++ b/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js @@ -51,8 +51,8 @@ const TransactionRow = memo(function TransactionRow({ <SelectCell exposed={true} focused={false} - onSelect={() => { - dispatchSelected({ type: 'select', id: transaction.id }); + onSelect={e => { + dispatchSelected({ type: 'select', id: transaction.id, event: e }); }} selected={selected} /> @@ -185,7 +185,7 @@ export default function SimpleTransactionsTable({ focused={false} selected={selectedItems.size > 0} width={20} - onSelect={() => dispatchSelected({ type: 'select-all' })} + onSelect={e => dispatchSelected({ type: 'select-all', event: e })} /> {fields.map((field, i) => { switch (field) { diff --git a/packages/desktop-client/src/components/accounts/TransactionsTable.js b/packages/desktop-client/src/components/accounts/TransactionsTable.js index 1430124989b823c94c47d9301b7a13322a462c22..76fe8dde030485a4aef1729d3a858fc3c1a3cb81 100644 --- a/packages/desktop-client/src/components/accounts/TransactionsTable.js +++ b/packages/desktop-client/src/components/accounts/TransactionsTable.js @@ -255,7 +255,7 @@ export const TransactionHeader = memo( focused={false} selected={hasSelected} width={20} - onSelect={() => dispatchSelected({ type: 'select-all' })} + onSelect={e => dispatchSelected({ type: 'select-all', event: e })} /> <Cell value="Date" width={110} /> {showAccount && <Cell value="Account" width="flex" />} @@ -690,8 +690,8 @@ export const Transaction = memo(function Transaction(props) { <SelectCell exposed={hovered || selected || editing} focused={focusedField === 'select'} - onSelect={() => { - dispatchSelected({ type: 'select', id: transaction.id }); + onSelect={e => { + dispatchSelected({ type: 'select', id: transaction.id, event: e }); }} onEdit={() => onEdit(id, 'select')} selected={selected} diff --git a/packages/desktop-client/src/components/payees/index.js b/packages/desktop-client/src/components/payees/index.js index 09da634f91bb091373d54035228150420b72881c..4a75e3f909ef02dfca75458e83b8ccc6e23fc4a9 100644 --- a/packages/desktop-client/src/components/payees/index.js +++ b/packages/desktop-client/src/components/payees/index.js @@ -138,8 +138,8 @@ let Payee = memo( } focused={focusedField === 'select'} selected={selected} - onSelect={() => { - dispatchSelected({ type: 'select', id: payee.id }); + onSelect={e => { + dispatchSelected({ type: 'select', id: payee.id, event: e }); }} /> <InputCell @@ -247,7 +247,7 @@ function PayeeTableHeader() { exposed={true} focused={false} selected={selectedItems.size > 0} - onSelect={() => dispatchSelected({ type: 'select-all' })} + onSelect={e => dispatchSelected({ type: 'select-all', event: e })} /> <Cell value="Name" width="flex" /> </TableHeader> diff --git a/packages/desktop-client/src/components/schedules/DiscoverSchedules.js b/packages/desktop-client/src/components/schedules/DiscoverSchedules.js index 9e8965fb60802c512744072134f0fdedd6dc8021..939165e4d48d8be91735ec172d3b23a65d3d2a3c 100644 --- a/packages/desktop-client/src/components/schedules/DiscoverSchedules.js +++ b/packages/desktop-client/src/components/schedules/DiscoverSchedules.js @@ -35,8 +35,8 @@ function DiscoverSchedulesTable({ schedules, loading }) { height={ROW_HEIGHT} inset={15} backgroundColor="transparent" - onClick={() => { - dispatchSelected({ type: 'select', id: item.id }); + onClick={e => { + dispatchSelected({ type: 'select', id: item.id, event: e }); }} borderColor={selected ? colors.b8 : colors.border} style={{ @@ -51,8 +51,8 @@ function DiscoverSchedulesTable({ schedules, loading }) { exposed={true} focused={false} selected={selected} - onSelect={() => { - dispatchSelected({ type: 'select', id: item.id }); + onSelect={e => { + dispatchSelected({ type: 'select', id: item.id, event: e }); }} /> <Field width="flex"> @@ -76,7 +76,7 @@ function DiscoverSchedulesTable({ schedules, loading }) { exposed={true} focused={false} selected={selectedItems.size > 0} - onSelect={() => dispatchSelected({ type: 'select-all' })} + onSelect={e => dispatchSelected({ type: 'select-all', event: e })} /> <Field width="flex">Payee</Field> <Field width="flex">Account</Field> diff --git a/packages/desktop-client/src/components/table.js b/packages/desktop-client/src/components/table.js index 001b4c8fbb00d75073bafc30d4d436605f7cc5aa..585d57eb120e42e55bde67bbf5caef1623a402a6 100644 --- a/packages/desktop-client/src/components/table.js +++ b/packages/desktop-client/src/components/table.js @@ -491,7 +491,7 @@ export const CellButton = forwardRef( if (e.key === 'x' || e.key === ' ') { e.preventDefault(); if (!disabled) { - onSelect && onSelect(); + onSelect && onSelect(e); } } }} @@ -513,9 +513,9 @@ export const CellButton = forwardRef( onClick={ clickBehavior === 'none' ? null - : () => { + : e => { if (!disabled) { - onSelect && onSelect(); + onSelect && onSelect(e); onEdit && onEdit(); } } @@ -545,7 +545,7 @@ export function SelectCell({ style={[{ alignItems: 'center', userSelect: 'none' }, style]} onClick={e => { e.stopPropagation(); - onSelect && onSelect(); + onSelect && onSelect(e); onEdit && onEdit(); }} > diff --git a/packages/desktop-client/src/hooks/useSelected.js b/packages/desktop-client/src/hooks/useSelected.js index ef031056ebef642367ad606baa8c977f2592804b..0db6c65b4b62f73e0e6b14c1dcc67359fdc7d045 100644 --- a/packages/desktop-client/src/hooks/useSelected.js +++ b/packages/desktop-client/src/hooks/useSelected.js @@ -10,8 +10,7 @@ import { useSelector } from 'react-redux'; import { listen } from 'loot-core/src/platform/client/fetch'; import * as undo from 'loot-core/src/platform/client/undo'; - -import { hasModifierKey } from '../util/keys'; +import { isNonProductionEnvironment } from 'loot-core/src/shared/environment'; function iterateRange(range, func) { let from = Math.min(range.start, range.end); @@ -29,9 +28,9 @@ export default function useSelected(name, items, initialSelectedIds) { case 'select': { let { selectedRange } = state; let selectedItems = new Set(state.selectedItems); - let { id } = action; + let { id, event } = action; - if (hasModifierKey('shift') && selectedRange) { + if (event.shiftKey && selectedRange) { let idx = items.findIndex(p => p.id === id); let startIdx = items.findIndex(p => p.id === selectedRange.start); let endIdx = items.findIndex(p => p.id === selectedRange.end); @@ -224,17 +223,24 @@ export function SelectedProvider({ instance, fetchAllIds, children }) { let dispatch = useCallback( async action => { + if (!action.event && isNonProductionEnvironment()) { + throw new Error('SelectedDispatch actions must have an event'); + } if (action.type === 'select-all') { if (latestItems.current && latestItems.current.size > 0) { - return instance.dispatch({ type: 'select-none' }); + return instance.dispatch({ + type: 'select-none', + event: action.event, + }); } else { if (fetchAllIds) { return instance.dispatch({ type: 'select-all', ids: await fetchAllIds(), + event: action.event, }); } - return instance.dispatch({ type: 'select-all' }); + return instance.dispatch({ type: 'select-all', event: action.event }); } } return instance.dispatch(action); diff --git a/packages/desktop-client/src/util/keys.js b/packages/desktop-client/src/util/keys.js deleted file mode 100644 index e9db15a5c77d839c18a36a74c66e34dec3c3e3b5..0000000000000000000000000000000000000000 --- a/packages/desktop-client/src/util/keys.js +++ /dev/null @@ -1,65 +0,0 @@ -// TODO: This is a barebones module for now, need to think about a -// generic way keys are handled across the app - -let _keyHandlers = {}; - -let _modifierState = { - shift: false, - ctrl: false, - alt: false, - meta: false, -}; - -export function hasModifierKey(modifier) { - return !!_modifierState[modifier]; -} - -export function registerKeyHandler(key, func) { - if (!_keyHandlers[key]) { - _keyHandlers[key] = []; - } - _keyHandlers[key].push(func); - - return () => { - _keyHandlers[key] = _keyHandlers[key].filter(f => f !== func); - }; -} - -document.addEventListener('keydown', e => { - if (e.key === 'Shift') { - _modifierState.shift = true; - } - if (e.key === 'Control') { - _modifierState.ctrl = true; - } - if (e.key === 'Alt') { - _modifierState.alt = true; - } - if (e.key === 'Meta') { - _modifierState.meta = true; - } - - if (!(e.target && e.target.matches('input'))) { - let handlers = _keyHandlers[e.key.toUpperCase()]; - if (handlers && handlers.length > 0) { - handlers[handlers.length - 1](_modifierState); - e.preventDefault(); - e.stopPropagation(); - } - } -}); - -document.addEventListener('keyup', e => { - if (e.key === 'Shift') { - _modifierState.shift = false; - } - if (e.key === 'Control') { - _modifierState.ctrl = false; - } - if (e.key === 'Alt') { - _modifierState.alt = false; - } - if (e.key === 'Meta') { - _modifierState.meta = false; - } -}); diff --git a/upcoming-release-notes/1022.md b/upcoming-release-notes/1022.md new file mode 100644 index 0000000000000000000000000000000000000000..a86afe93f77f9b704ca7a8b0f8baf13e8ac5406d --- /dev/null +++ b/upcoming-release-notes/1022.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [j-f1] +--- + +Improve behavior of shift-clicking checkboxes to select multiple transactions.