Skip to content

Commit

Permalink
Fix #3230
Browse files Browse the repository at this point in the history
  • Loading branch information
joel-jeremy committed Sep 9, 2024
1 parent d752389 commit 55f6c11
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 86 deletions.
33 changes: 19 additions & 14 deletions packages/desktop-client/src/components/accounts/Account.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React, {
createRef,
useMemo,
type ReactElement,
useEffect,
} from 'react';
import { Trans } from 'react-i18next';
import { useSelector } from 'react-redux';
Expand Down Expand Up @@ -53,7 +54,10 @@ import { useDateFormat } from '../../hooks/useDateFormat';
import { useFailedAccounts } from '../../hooks/useFailedAccounts';
import { useLocalPref } from '../../hooks/useLocalPref';
import { usePayees } from '../../hooks/usePayees';
import { usePreviewTransactions } from '../../hooks/usePreviewTransactions';
import {
type PreviewTransactionEntity,
usePreviewTransactions,
} from '../../hooks/usePreviewTransactions';
import {
SelectedProviderWithItems,
type Actions,
Expand Down Expand Up @@ -141,7 +145,6 @@ type AllTransactionsProps = {
transactions: TransactionEntity[],
balances: Record<string, { balance: number }> | null,
) => ReactElement;
collapseTransactions: (ids: string[]) => void;
};

function AllTransactions({
Expand All @@ -151,14 +154,18 @@ function AllTransactions({
showBalances,
filtered,
children,
collapseTransactions,
}: AllTransactionsProps) {
const accountId = account?.id;
const prependTransactions: (TransactionEntity & { _inverse?: boolean })[] =
usePreviewTransactions(collapseTransactions).map(trans => ({
...trans,
_inverse: accountId ? accountId !== trans.account : false,
}));
const { dispatch: splitsExpandedDispatch } = useSplitsExpanded();
const prependTransactions: PreviewTransactionEntity[] =
usePreviewTransactions({ accountId });

useEffect(() => {
splitsExpandedDispatch({
type: 'close-splits',
ids: prependTransactions.filter(t => t.is_parent).map(t => t.id),
});
}, [prependTransactions, splitsExpandedDispatch]);

transactions ??= [];

Expand All @@ -181,9 +188,10 @@ function AllTransactions({
const scheduledBalances = [...prependTransactions]
.reverse()
.map(scheduledTransaction => {
const amount =
(scheduledTransaction._inverse ? -1 : 1) *
getScheduledAmount(scheduledTransaction.amount);
const amount = getScheduledAmount(
scheduledTransaction.amount,
scheduledTransaction._inverse,
);
return {
// TODO: fix me
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -1651,9 +1659,6 @@ class AccountInternal extends PureComponent<
balances={balances}
showBalances={showBalances}
filtered={transactionsFiltered}
collapseTransactions={ids =>
this.props.splitsExpandedDispatch({ type: 'close-splits', ids })
}
>
{(allTransactions, allBalances) => (
<SelectedProviderWithItems
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ function TransactionListWithPreviews({ account }) {
const [isSearching, setIsSearching] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [transactions, setTransactions] = useState([]);
const prependTransactions = usePreviewTransactions();
const prependTransactions = usePreviewTransactions({
accountId: account?.id,
});
const allTransactions = useMemo(
() =>
!isSearching ? prependTransactions.concat(transactions) : transactions,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ import { Button } from '../../common/Button2';
import { Text } from '../../common/Text';
import { TextOneLine } from '../../common/TextOneLine';
import { View } from '../../common/View';
import { usePrettyPayee } from '../usePrettyPayee';

import { lookupName, getDescriptionPretty, Status } from './TransactionEdit';
import { lookupName, Status } from './TransactionEdit';

const ROW_HEIGHT = 50;

Expand Down Expand Up @@ -71,11 +72,12 @@ export const Transaction = memo(function Transaction({
is_parent: isParent,
is_child: isChild,
schedule,
_inverse,
} = transaction;

const payee = usePayee(payeeId);
const account = useAccount(accountId);
const transferAcct = useAccount(payee?.transfer_acct);
const transferAccount = useAccount(payee?.transfer_acct);
const isPreview = isPreviewId(id);

const { longPressProps } = useLongPress({
Expand All @@ -97,19 +99,19 @@ export const Transaction = memo(function Transaction({

let amount = originalAmount;
if (isPreview) {
amount = getScheduledAmount(amount);
amount = getScheduledAmount(amount, _inverse);
}

const categoryName = lookupName(categories, categoryId);

const prettyDescription = getDescriptionPretty(
const prettyPayee = usePrettyPayee({
transaction,
payee,
transferAcct,
);
transferAccount,
});
const specialCategory = account?.offbudget
? 'Off Budget'
: transferAcct && !transferAcct.offbudget
: transferAccount && !transferAccount.offbudget
? 'Transfer'
: isParent
? 'Split'
Expand Down Expand Up @@ -171,13 +173,13 @@ export const Transaction = memo(function Transaction({
...textStyle,
fontSize: 14,
fontWeight: isAdded ? '600' : '400',
...(prettyDescription === '' && {
...(prettyPayee === '' && {
color: theme.tableTextLight,
fontStyle: 'italic',
}),
}}
>
{prettyDescription || 'Empty'}
{prettyPayee || 'Empty'}
</TextOneLine>
</View>
{isPreview ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,14 @@ import { MobilePageHeader, Page } from '../../Page';
import { AmountInput } from '../../util/AmountInput';
import { MobileBackButton } from '../MobileBackButton';
import { FieldLabel, TapField, InputField, BooleanField } from '../MobileForms';
import { usePrettyPayee } from '../usePrettyPayee';

import { FocusableAmountInput } from './FocusableAmountInput';

function getFieldName(transactionId, field) {
return `${field}-${transactionId}`;
}

export function getDescriptionPretty(transaction, payee, transferAcct) {
const { amount } = transaction;

if (transferAcct) {
return `Transfer ${amount > 0 ? 'from' : 'to'} ${transferAcct.name}`;
} else if (payee) {
return payee.name;
}

return '';
}

function serializeTransaction(transaction, dateFormat) {
const { date, amount } = transaction;
return {
Expand Down Expand Up @@ -288,7 +277,8 @@ const ChildTransactionEdit = forwardRef(
amountFocused,
amountSign,
getCategory,
getPrettyPayee,
getPayee,
getTransferAccount,
isOffBudget,
isBudgetTransfer,
onEditField,
Expand All @@ -299,6 +289,11 @@ const ChildTransactionEdit = forwardRef(
) => {
const { editingField, onRequestActiveEdit, onClearActiveEdit } =
useSingleActiveEditForm();
const prettyPayee = usePrettyPayee({
transaction,
payee: getPayee(transaction),
transferAccount: getTransferAccount(transaction),
});
return (
<View
innerRef={ref}
Expand All @@ -322,7 +317,7 @@ const ChildTransactionEdit = forwardRef(
editingField &&
editingField !== getFieldName(transaction.id, 'payee')
}
value={getPrettyPayee(transaction)}
value={prettyPayee}
onClick={() => onEditField(transaction.id, 'payee')}
data-testid={`payee-field-${transaction.id}`}
/>
Expand Down Expand Up @@ -488,22 +483,13 @@ const TransactionEditInner = memo(function TransactionEditInner({
return trans?.payee && payeesById?.[trans.payee];
};

const getTransferAcct = trans => {
const getTransferAccount = trans => {
const payee = trans && getPayee(trans);
return payee?.transfer_acct && accountsById?.[payee.transfer_acct];
};

const getPrettyPayee = trans => {
if (trans && trans.is_parent) {
return 'Split';
}
const transPayee = trans && getPayee(trans);
const transTransferAcct = trans && getTransferAcct(trans);
return getDescriptionPretty(trans, transPayee, transTransferAcct);
};

const isBudgetTransfer = trans => {
const transferAcct = trans && getTransferAcct(trans);
const transferAcct = trans && getTransferAccount(trans);
return transferAcct && !transferAcct.offbudget;
};

Expand Down Expand Up @@ -700,11 +686,11 @@ const TransactionEditInner = memo(function TransactionEditInner({

const account = getAccount(transaction);
const isOffBudget = account && !!account.offbudget;
const title = getDescriptionPretty(
const title = usePrettyPayee({
transaction,
getPayee(transaction),
getTransferAcct(transaction),
);
payee: getPayee(transaction),
transferAccount: getTransferAccount(transaction),
});

const transactionDate = parseDate(transaction.date, dateFormat, new Date());
const dateDefaultValue = monthUtils.dayFromDate(transactionDate);
Expand Down Expand Up @@ -775,7 +761,7 @@ const TransactionEditInner = memo(function TransactionEditInner({
fontWeight: 300,
}),
}}
value={getPrettyPayee(transaction)}
value={title}
disabled={
editingField &&
editingField !== getFieldName(transaction.id, 'payee')
Expand Down Expand Up @@ -823,7 +809,8 @@ const TransactionEditInner = memo(function TransactionEditInner({
}}
isOffBudget={isOffBudget}
getCategory={getCategory}
getPrettyPayee={getPrettyPayee}
getPayee={getPayee}
getTransferAccount={getTransferAccount}
isBudgetTransfer={isBudgetTransfer}
onUpdate={onUpdate}
onEditField={onEditField}
Expand Down
42 changes: 42 additions & 0 deletions packages/desktop-client/src/components/mobile/usePrettyPayee.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { isPreviewId } from 'loot-core/shared/transactions';

Check warning on line 1 in packages/desktop-client/src/components/mobile/usePrettyPayee.tsx

View workflow job for this annotation

GitHub Actions / lint

Only files containing JSX may use the extension '.tsx'

Check warning on line 1 in packages/desktop-client/src/components/mobile/usePrettyPayee.tsx

View workflow job for this annotation

GitHub Actions / lint

There should be at least one empty line between import groups
import { useAccount } from '../../hooks/useAccount';

Check warning on line 2 in packages/desktop-client/src/components/mobile/usePrettyPayee.tsx

View workflow job for this annotation

GitHub Actions / lint

There should be at least one empty line between import groups
import {

Check warning on line 3 in packages/desktop-client/src/components/mobile/usePrettyPayee.tsx

View workflow job for this annotation

GitHub Actions / lint

All imports in the declaration are only used as types. Use `import type`

Check warning on line 3 in packages/desktop-client/src/components/mobile/usePrettyPayee.tsx

View workflow job for this annotation

GitHub Actions / lint

`loot-core/types/models` import should occur before import of `../../hooks/useAccount`
AccountEntity,
PayeeEntity,
TransactionEntity,
} from 'loot-core/types/models';

type UsePrettyPayeeProps = {
transaction: TransactionEntity & { _inverse?: boolean };
payee?: PayeeEntity;
transferAccount?: AccountEntity;
};

export function usePrettyPayee({
transaction,
payee,
transferAccount,
}: UsePrettyPayeeProps) {
const { id, amount: originalAmount, account, _inverse } = transaction;
const transactionAccount = useAccount(account);

const isPreview = isPreviewId(id);
const amount = isPreview
? (_inverse ? -1 : 1) * originalAmount
: originalAmount;

if (transferAccount) {
const transferAccountName = isPreview
? _inverse
? transactionAccount?.name
: transferAccount.name
: transferAccount.name;
return `Transfer ${amount > 0 ? 'from' : 'to'} ${transferAccountName}`;
} else if (transaction.is_parent) {
return 'Split';
} else if (payee) {
return payee.name;
}

return '';
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function serializeTransaction(transaction, showZeroInDeposit) {
let { amount, date } = transaction;

if (isPreviewId(transaction.id)) {
amount = (transaction._inverse ? -1 : 1) * getScheduledAmount(amount);
amount = getScheduledAmount(amount, transaction._inverse);
}

let debit = amount < 0 ? -amount : null;
Expand Down Expand Up @@ -744,6 +744,16 @@ function PayeeCell({
);
}

const payeeIconButtonStyle = {
marginLeft: -5,
marginRight: 2,
width: 23,
height: 23,
color: 'inherit',
};
const scheduleIconStyle = { width: 13, height: 13 };
const transferIconStyle = { width: 10, height: 10 };

function PayeeIcons({
transaction,
transferAccount,
Expand All @@ -757,35 +767,21 @@ function PayeeIcons({
? scheduleData.schedules.find(s => s.id === scheduleId)
: null;

const buttonStyle = useMemo(
() => ({
marginLeft: -5,
marginRight: 2,
width: 23,
height: 23,
color: 'inherit',
}),
[],
);

const scheduleIconStyle = useMemo(() => ({ width: 13, height: 13 }), []);

const transferIconStyle = useMemo(() => ({ width: 10, height: 10 }), []);

if (schedule == null && transferAccount == null) {
// Neither a valid scheduled transaction nor a transfer.
return null;
}

const recurring = schedule && schedule._date && !!schedule._date.frequency;
const isDeposit = (transaction._inverse ? -1 : 1) * transaction.amount > 0;

return (
<>
{schedule && (
<Button
variant="bare"
aria-label="See schedule details"
style={buttonStyle}
style={payeeIconButtonStyle}
onPress={() => {
onNavigateToSchedule(scheduleId);
}}
Expand All @@ -801,14 +797,14 @@ function PayeeIcons({
<Button
variant="bare"
aria-label="See transfer account"
style={buttonStyle}
style={payeeIconButtonStyle}
onPress={() => {
if (!isTemporaryId(transaction.id)) {
onNavigateToTransferAccount(transferAccount.id);
}
}}
>
{(transaction._inverse ? -1 : 1) * transaction.amount > 0 ? (
{isDeposit ? (
<SvgLeftArrow2 style={transferIconStyle} />
) : (
<SvgRightArrow2 style={transferIconStyle} />
Expand Down
Loading

0 comments on commit 55f6c11

Please sign in to comment.