diff --git a/packages/desktop-client/src/components/payees/index.js b/packages/desktop-client/src/components/payees/ManagePayees.js similarity index 57% rename from packages/desktop-client/src/components/payees/index.js rename to packages/desktop-client/src/components/payees/ManagePayees.js index b679ea8797b..8b2762b6877 100644 --- a/packages/desktop-client/src/components/payees/index.js +++ b/packages/desktop-client/src/components/payees/ManagePayees.js @@ -1,6 +1,5 @@ -import React, { +import { forwardRef, - memo, useState, useEffect, useLayoutEffect, @@ -20,27 +19,15 @@ import useSelected, { useSelectedDispatch, } from '../../hooks/useSelected'; import useStableCallback from '../../hooks/useStableCallback'; -import Delete from '../../icons/v0/Delete'; import ExpandArrow from '../../icons/v0/ExpandArrow'; -import Merge from '../../icons/v0/Merge'; -import ArrowThinRight from '../../icons/v1/ArrowThinRight'; import { theme } from '../../style'; import Button from '../common/Button'; -import Menu from '../common/Menu'; import Search from '../common/Search'; -import Text from '../common/Text'; import View from '../common/View'; -import { - Table, - TableHeader, - Row, - Cell, - InputCell, - SelectCell, - CellButton, - useTableNavigator, -} from '../table'; -import { Tooltip } from '../tooltips'; +import { TableHeader, Cell, SelectCell, useTableNavigator } from '../table'; + +import PayeeMenu from './PayeeMenu'; +import PayeeTable from './PayeeTable'; let getPayeesById = memoizeOne(payees => groupById(payees)); @@ -48,179 +35,6 @@ function plural(count, singleText, pluralText) { return count === 1 ? singleText : pluralText; } -function RuleButton({ ruleCount, focused, onEdit, onClick }) { - return ( - - - - {ruleCount > 0 ? ( - <> - {ruleCount} associated {plural(ruleCount, 'rule', 'rules')} - - ) : ( - <>Create rule - )} - - - - - ); -} - -let Payee = memo( - ({ - style, - payee, - ruleCount, - selected, - hovered, - editing, - focusedField, - onViewRules, - onCreateRule, - onHover, - onEdit, - onUpdate, - }) => { - let { id } = payee; - let dispatchSelected = useSelectedDispatch(); - let borderColor = selected ? theme.tableBorderSelected : theme.tableBorder; - let backgroundFocus = hovered || focusedField === 'select'; - - return ( - onHover && onHover(payee.id)} - > - { - dispatchSelected({ type: 'select', id: payee.id, event: e }); - }} - /> - - !payee.transfer_acct && onUpdate(id, 'name', value) - } - onExpose={() => onEdit(id, 'name')} - inputProps={{ readOnly: !!payee.transfer_acct }} - /> - onEdit(id, 'rule-count')} - onClick={() => - ruleCount > 0 ? onViewRules(payee.id) : onCreateRule(payee.id) - } - /> - - ); - }, -); - -const PayeeTable = forwardRef( - ( - { - payees, - ruleCounts, - navigator, - categoryGroups, - highlightedRows, - ruleActions, - onUpdate, - onViewRules, - onCreateRule, - }, - ref, - ) => { - let [hovered, setHovered] = useState(null); - let selectedItems = useSelectedItems(); - - useLayoutEffect(() => { - let firstSelected = [...selectedItems][0]; - ref.current.scrollTo(firstSelected, 'center'); - navigator.onEdit(firstSelected, 'select'); - }, []); - - let onHover = useCallback(id => { - setHovered(id); - }, []); - - return ( - setHovered(null)}> - { - return ( - - ); - }} - /> - - ); - }, -); - function PayeeTableHeader() { let borderColor = theme.tableborder; let dispatchSelected = useSelectedDispatch(); @@ -267,68 +81,6 @@ function EmptyMessage({ text, style }) { ); } -function PayeeMenu({ payeesById, selectedPayees, onDelete, onMerge, onClose }) { - // Transfer accounts are never editable - let isDisabled = [...selectedPayees].some( - id => payeesById[id] == null || payeesById[id].transfer_acct, - ); - - return ( - - { - onClose(); - switch (type) { - case 'delete': - onDelete(); - break; - case 'merge': - onMerge(); - break; - default: - } - }} - footer={ - - {[...selectedPayees] - .slice(0, 4) - .map(id => payeesById[id].name) - .join(', ') + (selectedPayees.size > 4 ? ', and more' : '')} - - } - items={[ - { - icon: Delete, - name: 'delete', - text: 'Delete', - disabled: isDisabled, - }, - { - icon: Merge, - iconSize: 9, - name: 'merge', - text: 'Merge', - disabled: isDisabled || selectedPayees.size < 2, - }, - Menu.line, - ]} - /> - - ); -} - export const ManagePayees = forwardRef( ( { diff --git a/packages/desktop-client/src/components/payees/ManagePayeesWithData.js b/packages/desktop-client/src/components/payees/ManagePayeesWithData.js index a99364df503..51ad66eb37c 100644 --- a/packages/desktop-client/src/components/payees/ManagePayeesWithData.js +++ b/packages/desktop-client/src/components/payees/ManagePayeesWithData.js @@ -7,7 +7,7 @@ import { applyChanges } from 'loot-core/src/shared/util'; import { useActions } from '../../hooks/useActions'; import useCategories from '../../hooks/useCategories'; -import { ManagePayees } from '.'; +import { ManagePayees } from './ManagePayees'; export default function ManagePayeesWithData({ initialSelectedIds }) { let initialPayees = useSelector(state => state.queries.payees); diff --git a/packages/desktop-client/src/components/payees/PayeeMenu.js b/packages/desktop-client/src/components/payees/PayeeMenu.js new file mode 100644 index 00000000000..3d261a4b674 --- /dev/null +++ b/packages/desktop-client/src/components/payees/PayeeMenu.js @@ -0,0 +1,74 @@ +import Delete from '../../icons/v0/Delete'; +import Merge from '../../icons/v0/Merge'; +import { theme } from '../../style'; +import Menu from '../common/Menu'; +import View from '../common/View'; +import { Tooltip } from '../tooltips'; + +export default function PayeeMenu({ + payeesById, + selectedPayees, + onDelete, + onMerge, + onClose, +}) { + // Transfer accounts are never editable + let isDisabled = [...selectedPayees].some( + id => payeesById[id] == null || payeesById[id].transfer_acct, + ); + + return ( + + { + onClose(); + switch (type) { + case 'delete': + onDelete(); + break; + case 'merge': + onMerge(); + break; + default: + } + }} + footer={ + + {[...selectedPayees] + .slice(0, 4) + .map(id => payeesById[id].name) + .join(', ') + (selectedPayees.size > 4 ? ', and more' : '')} + + } + items={[ + { + icon: Delete, + name: 'delete', + text: 'Delete', + disabled: isDisabled, + }, + { + icon: Merge, + iconSize: 9, + name: 'merge', + text: 'Merge', + disabled: isDisabled || selectedPayees.size < 2, + }, + Menu.line, + ]} + /> + + ); +} diff --git a/packages/desktop-client/src/components/payees/PayeeTable.js b/packages/desktop-client/src/components/payees/PayeeTable.js new file mode 100644 index 00000000000..e5d9ad27d16 --- /dev/null +++ b/packages/desktop-client/src/components/payees/PayeeTable.js @@ -0,0 +1,68 @@ +import { forwardRef, useState, useLayoutEffect, useCallback } from 'react'; + +import { useSelectedItems } from '../../hooks/useSelected'; +import View from '../common/View'; +import { Table } from '../table'; + +import PayeeTableRow from './PayeeTableRow'; + +const PayeeTable = forwardRef( + ( + { + payees, + ruleCounts, + navigator, + categoryGroups, + highlightedRows, + ruleActions, + onUpdate, + onViewRules, + onCreateRule, + }, + ref, + ) => { + let [hovered, setHovered] = useState(null); + let selectedItems = useSelectedItems(); + + useLayoutEffect(() => { + let firstSelected = [...selectedItems][0]; + ref.current.scrollTo(firstSelected, 'center'); + navigator.onEdit(firstSelected, 'select'); + }, []); + + let onHover = useCallback(id => { + setHovered(id); + }, []); + + return ( + setHovered(null)}> +
{ + return ( + + ); + }} + /> + + ); + }, +); + +export default PayeeTable; diff --git a/packages/desktop-client/src/components/payees/PayeeTableRow.js b/packages/desktop-client/src/components/payees/PayeeTableRow.js new file mode 100644 index 00000000000..8be52b3ba9a --- /dev/null +++ b/packages/desktop-client/src/components/payees/PayeeTableRow.js @@ -0,0 +1,123 @@ +import { memo } from 'react'; + +import { useSelectedDispatch } from '../../hooks/useSelected'; +import ArrowThinRight from '../../icons/v1/ArrowThinRight'; +import { theme } from '../../style'; +import Text from '../common/Text'; +import { Row, Cell, InputCell, SelectCell, CellButton } from '../table'; + +function RuleButton({ ruleCount, focused, onEdit, onClick }) { + return ( + + + + {ruleCount > 0 ? ( + <> + {ruleCount} associated {ruleCount === 1 ? 'rule' : 'rules'} + + ) : ( + <>Create rule + )} + + + + + ); +} + +const PayeeTableRow = memo( + ({ + style, + payee, + ruleCount, + selected, + hovered, + editing, + focusedField, + onViewRules, + onCreateRule, + onHover, + onEdit, + onUpdate, + }) => { + let { id } = payee; + let dispatchSelected = useSelectedDispatch(); + let borderColor = selected ? theme.tableBorderSelected : theme.tableBorder; + let backgroundFocus = hovered || focusedField === 'select'; + + return ( + onHover && onHover(payee.id)} + > + { + dispatchSelected({ type: 'select', id: payee.id, event: e }); + }} + /> + + !payee.transfer_acct && onUpdate(id, 'name', value) + } + onExpose={() => onEdit(id, 'name')} + inputProps={{ readOnly: !!payee.transfer_acct }} + /> + onEdit(id, 'rule-count')} + onClick={() => + ruleCount > 0 ? onViewRules(payee.id) : onCreateRule(payee.id) + } + /> + + ); + }, +); + +export default PayeeTableRow; diff --git a/upcoming-release-notes/1950.md b/upcoming-release-notes/1950.md new file mode 100644 index 00000000000..6da3bb5035a --- /dev/null +++ b/upcoming-release-notes/1950.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [kymckay] +--- + +Split up large payee management components file.