import React, { useMemo, useCallback } from 'react'; import { useSelector } from 'react-redux'; import { format as formatDate, parseISO, isValid as isDateValid } from 'date-fns'; import { getAccountsById, getCategoriesById } from 'loot-core/src/client/reducers/queries'; import { integerToCurrency } from 'loot-core/src/shared/util'; import { Table, Row, Field, Cell, SelectCell } from 'loot-design/src/components/table'; import { useSelectedItems, useSelectedDispatch } from 'loot-design/src/components/useSelected'; import { styles } from 'loot-design/src/style'; import ArrowsSynchronize from 'loot-design/src/svg/v2/ArrowsSynchronize'; import DisplayId from '../util/DisplayId'; function serializeTransaction(transaction, dateFormat) { let { date } = transaction; if (!isDateValid(parseISO(date))) { date = null; } return { ...transaction, date: date ? formatDate(parseISO(date), dateFormat) : null }; } const TransactionRow = React.memo(function TransactionRow({ transaction, fields, payees, categories, accounts, selected }) { // TODO: Convert these to use fetched queries let c = getCategoriesById(categories)[transaction.category]; let a = getAccountsById(accounts)[transaction.account]; let dispatchSelected = useSelectedDispatch(); let schedule = transaction.schedule; return ( { dispatchSelected({ type: 'select', id: transaction.id }); }} selected={selected} /> {fields.map((field, i) => { switch (field) { case 'date': return ( {transaction.date} ); case 'imported_payee': return ( {transaction.imported_payee} ); case 'payee': return ( {() => ( <> {transaction.schedule && ( )} )} ); case 'category': return ( {c ? c.name : ''} ); case 'account': return ( {a.name} ); case 'notes': return ( {transaction.notes} ); case 'amount': return ( {integerToCurrency(transaction.amount)} ); default: return null; } })} ); }); export default function SimpleTransactionsTable({ transactions, schedules, fields = ['date', 'payee', 'amount'], style }) { let { payees, categories, accounts, dateFormat } = useSelector(state => { return { payees: state.queries.payees, accounts: state.queries.accounts, categories: state.queries.categories.grouped, dateFormat: state.prefs.local.dateFormat || 'MM/dd/yyyy' }; }); let selectedItems = useSelectedItems(); let dispatchSelected = useSelectedDispatch(); let memoFields = useMemo(() => fields, [JSON.stringify(fields)]); let serializedTransactions = useMemo(() => { return transactions.map(trans => serializeTransaction(trans, dateFormat)); }, [transactions]); let renderItem = useCallback( ({ item }) => { return ( ); }, [payees, categories, memoFields, selectedItems] ); return ( 0} width={20} onSelect={() => dispatchSelected({ type: 'select-all' })} /> {fields.map((field, i) => { switch (field) { case 'date': return ( Date ); case 'imported_payee': return ( Imported payee ); case 'payee': return ( Payee ); case 'category': return ( Category ); case 'account': return ( Account ); case 'notes': return ( Notes ); case 'amount': return ( Amount ); default: return null; } })} } renderItem={renderItem} /> ); }