Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wrong scheduled transfer payment direction on PWA #3402

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

joel-jeremy
Copy link
Contributor

@joel-jeremy joel-jeremy commented Sep 9, 2024

Fixes #3230

@actual-github-bot actual-github-bot bot changed the title Fix #3230 [WIP] Fix #3230 Sep 9, 2024
Copy link

netlify bot commented Sep 9, 2024

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 1c7376d
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/671f165d34941e0008422bb8
😎 Deploy Preview https://deploy-preview-3402.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@joel-jeremy joel-jeremy changed the title [WIP] Fix #3230 [Mobile] Fix wrong schedule transfer direction on PWA Sep 9, 2024
@joel-jeremy joel-jeremy changed the title [Mobile] Fix wrong schedule transfer direction on PWA [Mobile] Fix wrong scheduled transfer direction on PWA Sep 9, 2024
Copy link
Contributor

github-actions bot commented Sep 9, 2024

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
9 5.32 MB → 5.32 MB (+724 B) +0.01%
Changeset
File Δ Size
src/components/mobile/usePrettyPayee.ts 🆕 +660 B 0 B → 660 B
home/runner/work/actual/actual/packages/loot-core/src/shared/schedules.ts 📈 +119 B (+2.24%) 5.19 kB → 5.31 kB
src/components/mobile/transactions/Transaction.jsx 📈 +26 B (+0.41%) 6.14 kB → 6.16 kB
src/components/mobile/accounts/AccountTransactions.tsx 📈 +32 B (+0.40%) 7.78 kB → 7.81 kB
src/components/accounts/Account.tsx 📈 +56 B (+0.12%) 43.91 kB → 43.96 kB
src/components/transactions/TransactionsTable.jsx 📉 -86 B (-0.13%) 63.53 kB → 63.45 kB
src/components/mobile/transactions/TransactionEdit.jsx 📉 -73 B (-0.21%) 34.16 kB → 34.09 kB
src/hooks/usePreviewTransactions.ts 📉 -10 B (-0.60%) 1.64 kB → 1.63 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/index.js 3.33 MB → 3.33 MB (+732 B) +0.02%
static/js/narrow.js 82.57 kB → 82.6 kB (+32 B) +0.04%

Smaller

Asset File Size % Changed
static/js/wide.js 232.16 kB → 232.13 kB (-30 B) -0.01%
static/js/usePreviewTransactions.js 1.64 kB → 1.63 kB (-10 B) -0.60%

Unchanged

Asset File Size % Changed
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/AppliedFilters.js 21.3 kB 0%
static/js/ReportRouter.js 1.5 MB 0%

Copy link
Contributor

github-actions bot commented Sep 9, 2024

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 1.27 MB → 1.27 MB (+30 B) +0.00%
Changeset
File Δ Size
packages/loot-core/src/shared/schedules.ts 📈 +123 B (+1.32%) 9.1 kB → 9.22 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
kcab.worker.js 1.27 MB → 1.27 MB (+30 B) +0.00%

Smaller

No assets were smaller

Unchanged

No assets were unchanged

@joel-jeremy joel-jeremy changed the title [Mobile] Fix wrong scheduled transfer direction on PWA Fix wrong scheduled transfer direction on PWA Sep 9, 2024
@joel-jeremy joel-jeremy changed the title Fix wrong scheduled transfer direction on PWA Fix wrong scheduled transfer payment direction on PWA Sep 10, 2024
Comment on lines -1654 to 1689
collapseTransactions={ids =>
this.props.splitsExpandedDispatch({ type: 'close-splits', ids })
}
>
Copy link
Contributor

@jfdoming jfdoming Sep 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the change from a callback to a useEffect, I now see a very brief flash of expanded preview transactions on desktop. It's not a big deal, but any ideas on how we can avoid that?

Repro: create test budget, update the "Fast Internet" schedule to a date in the future, and make it a splitting rule. Then view the "Bank of America" account

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be fixed now :)

Copy link
Contributor

coderabbitai bot commented Sep 18, 2024

Walkthrough

The pull request introduces significant changes to the transaction handling logic across multiple components in the desktop client and mobile applications. Key modifications include the removal of the collapseTransactions prop, updates to the usePreviewTransactions hook for better account-specific data retrieval, and the introduction of a new custom hook, usePrettyPayee, for formatting payee descriptions. Additionally, the handling of scheduled amounts has been refined to account for transaction directionality, enhancing the overall clarity and functionality of the transaction management system.

Assessment against linked issues

Objective Addressed Explanation
Ensure scheduled transaction amounts display correctly in PWA (Issue #3230)

Possibly related PRs

Suggested labels

:sparkles: Merged

Suggested reviewers

  • youngcw
  • MikesGlitch

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Outside diff range and nitpick comments (1)
packages/loot-core/src/shared/schedules.ts (1)

272-281: LGTM!

The changes to the getScheduledAmount function look good. The function now correctly handles both number and object inputs, and the inverse flag is used to conditionally negate the input values.

Consider simplifying the object case by using object destructuring and the ternary operator:

-  const num1 = inverse ? -amount.num1 : amount.num1;
-  const num2 = inverse ? -amount.num2 : amount.num2;
-  return Math.round((num1 + num2) / 2);
+  const { num1, num2 } = amount;
+  return Math.round((inverse ? -num1 : num1 + inverse ? -num2 : num2) / 2);
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 17fd068 and 01e41fa.

Files selected for processing (10)
  • packages/desktop-client/src/components/accounts/Account.tsx (4 hunks)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.jsx (1 hunks)
  • packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (4 hunks)
  • packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (8 hunks)
  • packages/desktop-client/src/components/mobile/usePrettyPayee.ts (1 hunks)
  • packages/desktop-client/src/components/transactions/TransactionsTable.jsx (4 hunks)
  • packages/desktop-client/src/hooks/usePreviewTransactions.ts (2 hunks)
  • packages/loot-core/src/shared/schedules.ts (1 hunks)
  • packages/loot-core/src/types/models/schedule.d.ts (1 hunks)
  • upcoming-release-notes/3402.md (1 hunks)
Additional comments not posted (31)
upcoming-release-notes/3402.md (1)

1-6: Release note looks good!

The release note accurately summarizes the bug fix based on the provided PR objectives and summary. It concisely describes the issue of wrong scheduled transaction amounts in the PWA and implies that the fix addresses this problem.

packages/desktop-client/src/components/mobile/usePrettyPayee.ts (1)

1-43: LGTM! The usePrettyPayee hook is well-implemented and covers various scenarios.

The usePrettyPayee hook is a great addition to the codebase. It provides a centralized and reusable way to format payee strings based on the context of a financial transaction. The hook takes into account various scenarios such as preview transactions, inverse transactions, transfer accounts, parent transactions, and regular payees.

The logic within the hook is well-structured and correctly extracts relevant properties from the transaction object. It utilizes the isPreviewId function to determine if the transaction is a preview and adjusts the amount accordingly based on the _inverse flag. The handling of transfer accounts considers both preview and inverse scenarios, ensuring accurate representation of the transfer direction.

The hook also handles parent transactions by returning the string "Split" and falls back to returning the payee's name if no specific conditions are met. In case none of the conditions are satisfied, it returns an empty string as a fallback.

Overall, the usePrettyPayee hook enhances the user experience by providing clear and contextual descriptions of transactions. It is a valuable addition to the codebase and will help maintain consistency in displaying payee information across the application.

packages/desktop-client/src/hooks/usePreviewTransactions.ts (4)

9-12: LGTM!

The imports are necessary and look good.


16-18: LGTM!

The new PreviewTransactionEntity type is necessary for adding the _inverse property to the TransactionEntity type. The type definition looks good.


64-69: LGTM!

The change in the setPreviewTransactions function is necessary for setting the _inverse property for each transaction. The logic and syntax look good.


20-24: Verify the function signature change in the codebase.

The change in the function signature is necessary for accepting the accountId parameter. The function signature looks good.

Run the following script to verify the function usage:

Verification successful

Function signature change verified successfully

The usePreviewTransactions function is correctly used with the new signature in the codebase. The only usage found is in ./packages/desktop-client/src/components/accounts/Account.tsx on line 161, where it's called as usePreviewTransactions({ accountId }). This matches the new signature that accepts an object with an optional accountId property.

No other occurrences of the function usage were found, suggesting that the changes have been properly applied throughout the codebase.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all function calls to `usePreviewTransactions` match the new signature.

# Test: Search for the function usage. Expect: Only occurrences of the new signature.
rg --type typescript -A 5 $'usePreviewTransactions'

Length of output: 85


Script:

#!/bin/bash
# Description: Verify all function calls to `usePreviewTransactions` match the new signature.

# Search for .ts and .tsx files containing usePreviewTransactions
find . -type f \( -name "*.ts" -o -name "*.tsx" \) -print0 | xargs -0 grep -n -A 5 "usePreviewTransactions" | grep -v "packages/desktop-client/src/hooks/usePreviewTransactions.ts"

Length of output: 1403

packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (7)

29-29: LGTM!

The import statement for the usePrettyPayee hook is valid and follows the correct syntax. The naming convention suggests its purpose is to format or enhance the payee information for display.


75-75: Verify the purpose and usage of the _inverse property.

The newly destructured _inverse property from the transaction object suggests it represents some form of inversion or opposite state related to the transaction. However, its specific purpose and how it is used within the component is not clear from this line alone.

Please provide more context on what this property represents and how it is utilized in the component's logic, especially in relation to the transaction's state or behavior.


80-80: LGTM!

Renaming the variable from transferAcct to transferAccount enhances code readability by using a more descriptive and intuitive name. This change does not affect the functionality as it is a local variable.


107-111: LGTM!

The usage of the usePrettyPayee hook to derive the prettyPayee value is a good approach. By passing the relevant data (transaction, payee, transferAccount) to the hook, it encapsulates the logic to determine the appropriate payee name or details for display purposes. This promotes code reusability and keeps the component focused on rendering concerns.


102-102: Verify the behavior of getScheduledAmount and the impact of _inverse.

The amount value is conditionally assigned the result of getScheduledAmount(amount, _inverse) when isPreview is true. This suggests that for preview transactions, the scheduled amount needs to be calculated considering the _inverse property. However, the specific logic inside the getScheduledAmount function is not visible in this code snippet.

Please provide more context on how the _inverse property is used within getScheduledAmount and how it affects the calculated amount. It would be helpful to review the implementation of getScheduledAmount to ensure the behavior aligns with the expected functionality for preview transactions.


114-114: LGTM!

The update in the ternary operator condition to use the renamed transferAccount variable is consistent with the previous variable renaming. This change maintains the existing logic while improving code readability.


176-182: LGTM!

The conditional style update based on prettyPayee being an empty string is a reasonable approach to visually distinguish the case when there is no meaningful payee information available. Setting the color to theme.tableTextLight and font style to 'italic' provides a clear indication of this scenario.

Additionally, updating the displayed payee text from prettyDescription to prettyPayee aligns with the introduction of the usePrettyPayee hook and ensures that the UI reflects the formatted or enhanced payee information derived from the hook.

packages/desktop-client/src/components/mobile/accounts/AccountTransactions.jsx (1)

147-149: LGTM! The code change addresses the PR objective.

The modification to the usePreviewTransactions hook, passing the accountId derived from the account prop, allows the hook to retrieve transactions specific to the selected account. This change should help resolve the issue of incorrect display of payment and debit directions for upcoming transfer transactions in the PWA.

The logic for combining the transactions remains intact, ensuring that the component continues to function as expected.

packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (6)

64-64: Great refactor!

Introducing the usePrettyPayee custom hook is a nice way to centralize the payee description generation logic. It enhances maintainability and readability by encapsulating this functionality in a single place.


Line range hint 280-296: Looks good!

The ChildTransactionEdit component has been updated to use the usePrettyPayee hook for retrieving the pretty payee description. This change aligns with the introduction of the hook and ensures consistency in handling payee information.

Additionally, the prop renaming from getTransferAcct to getTransferAccount enhances code clarity.


486-492: Nice renaming!

Renaming the getTransferAcct function to getTransferAccount enhances code clarity and readability. This change makes the purpose of the function more evident.


689-693: Good usage of the new hook!

The TransactionEditInner component now directly uses the usePrettyPayee hook to obtain the title. This change aligns with the introduction of the hook and ensures consistency in retrieving the payee description across the codebase.


764-764: Consistent usage of usePrettyPayee.

The title value is now obtained using the usePrettyPayee hook, which is consistent with the changes made in other parts of the code. This ensures a unified approach to retrieving the payee description.


812-813: Prop renaming for clarity.

Renaming the getTransferAcct prop to getTransferAccount improves code clarity and readability. This change makes the purpose of the prop more evident and aligns with the function renaming.

packages/desktop-client/src/components/accounts/Account.tsx (5)

8-8: LGTM!

The useLayoutEffect import seems to be valid based on its usage later in the code.


160-161: LGTM!

The usage of usePreviewTransactions hook with { accountId } as an argument and typing prependTransactions as PreviewTransactionEntity[] looks good.


163-168: LGTM!

The usage of useLayoutEffect hook to dispatch an action for closing splits of parent transactions whenever prependTransactions changes looks good. The side effect is well-defined and the dependencies are correctly specified.


57-60: Verify the usage of imported type and hook.

The new import statements seem to be valid. However, verify that PreviewTransactionEntity type and usePreviewTransactions hook are being used correctly in the component.

Run the following script to verify the usage:

Verification successful

Imports are correctly used in the component.

The PreviewTransactionEntity type and usePreviewTransactions hook are both properly imported and utilized in the Account.tsx component:

  • PreviewTransactionEntity is used to type the prependTransactions variable.
  • usePreviewTransactions hook is called with the accountId parameter.

These imports are necessary and correctly implemented.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `PreviewTransactionEntity` type and `usePreviewTransactions` hook.

# Test: Search for the usage of `PreviewTransactionEntity` type. Expect: At least one match.
rg --type typescript $'PreviewTransactionEntity' -A 5

# Test: Search for the usage of `usePreviewTransactions` hook. Expect: At least one match.
rg --type typescript $'usePreviewTransactions\(' -A 5

Length of output: 177


Script:

#!/bin/bash
# Description: Verify the usage of `PreviewTransactionEntity` type and `usePreviewTransactions` hook.

# Find TypeScript files and search for `PreviewTransactionEntity`
fd -e ts -e tsx | xargs rg 'PreviewTransactionEntity' -n -A 5

# Find TypeScript files and search for `usePreviewTransactions`
fd -e ts -e tsx | xargs rg 'usePreviewTransactions\(' -n -A 5

Length of output: 3988


191-194: Verify the correctness of _inverse property on scheduledTransaction objects.

The change assumes that the _inverse property is correctly set on the scheduledTransaction objects returned by the usePreviewTransactions hook. Verify that this assumption holds true. If the property is correctly set, then this change looks good.

Run the following script to verify the _inverse property:

Verification successful

The _inverse property is correctly implemented and used.

The verification process confirms that the _inverse property is properly set on scheduledTransaction objects returned by the usePreviewTransactions hook. The property is determined based on whether the transaction's account matches the current accountId:

_inverse: accountId ? accountId !== t.account : false,

This implementation ensures that the _inverse property correctly indicates whether a transaction is incoming or outgoing relative to the current account. The property is then used appropriately in other parts of the codebase, such as in the usePrettyPayee hook and when calculating scheduled amounts.

The change in the original review comment, which directly passes scheduledTransaction._inverse to the getScheduledAmount function, is consistent with this implementation and can be approved.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that `scheduledTransaction` objects have the correct `_inverse` property.

# Test: Search for the usage of `usePreviewTransactions` hook and print the `_inverse` property of returned objects. 
# Expect: `_inverse` property should be a boolean value.
rg --type typescript $'usePreviewTransactions\(' -A 10 | rg $'_inverse'

Length of output: 104


Script:

#!/bin/bash
# Description: Verify the usage of usePreviewTransactions hook and _inverse property

# Search for usePreviewTransactions in .ts and .tsx files
echo "Searching for usePreviewTransactions:"
rg --type ts "usePreviewTransactions" -A 10

# Search for _inverse property in .ts and .tsx files
echo "\nSearching for _inverse property:"
rg --type ts "_inverse"

# Search for both usePreviewTransactions and _inverse in proximity
echo "\nSearching for usePreviewTransactions and _inverse in proximity:"
rg --type ts -e "usePreviewTransactions" -e "_inverse" -C 15

Length of output: 22673

packages/desktop-client/src/components/transactions/TransactionsTable.jsx (6)

94-94: LGTM!

Passing the transaction._inverse value to getScheduledAmount enhances the clarity of the amount calculation by directly incorporating the inverse logic into the function call.


746-752: LGTM!

Defining the payeeIconButtonStyle object improves code maintainability by centralizing the styles for payee icon buttons.


753-754: LGTM!

Defining the scheduleIconStyle and transferIconStyle objects improves code maintainability by centralizing the styles for schedule and transfer icons.


775-775: LGTM!

Extracting the logic for determining whether a transaction is a deposit into the isDeposit variable improves code readability and clarity.


783-783: LGTM!

Using the centralized payeeIconButtonStyle object for the style prop of the Button component ensures consistent styling and improves maintainability.


Line range hint 799-810: LGTM!

The changes in this code segment improve the maintainability and clarity of the transfer button:

  • Using the centralized payeeIconButtonStyle object for consistent styling.
  • Conditionally rendering arrow icons based on the isDeposit variable to clearly indicate the transfer direction.

@youngcw youngcw added this to the v24.10.0 milestone Sep 20, 2024
@jfdoming
Copy link
Contributor

jfdoming commented Sep 24, 2024

Thanks for the fix! It does seem to work better now, but I'm always a little wary of useLayoutEffect because it causes React to do two full renders. Since we don't actually need the first render at all (we're not measuring any component's size or something, just updating the state in a deterministic way), do you think another way can work?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (11)
packages/desktop-client/src/components/mobile/usePrettyPayee.ts (2)

29-42: Refactor nested ternary operators for better readability.

The conditional logic effectively handles different scenarios and addresses the issue mentioned in the PR objectives. However, the nested ternary operators for transferAccountName could be simplified for better readability and maintainability.

Consider refactoring the transferAccountName assignment:

-    const transferAccountName = isPreview
-      ? _inverse
-        ? transactionAccount?.name
-        : transferAccount.name
-      : transferAccount.name;
+    const transferAccountName = isPreview && _inverse
+      ? transactionAccount?.name
+      : transferAccount.name;

This refactored version simplifies the logic while maintaining the same functionality.

The overall logic for handling different scenarios (transfer, split transaction, payee) is well-structured and follows good practices with early returns.


1-43: Overall implementation looks good, but consider performance optimization.

The usePrettyPayee hook effectively addresses the issue of incorrect display of payment and debit directions for upcoming transfer transactions. The implementation is well-structured, type-safe, and handles various scenarios appropriately.

However, there's an important consideration raised in the PR comments regarding the use of useLayoutEffect. While this hook doesn't directly use useLayoutEffect, it's crucial to ensure that any components using usePrettyPayee are not unnecessarily triggering additional renders.

To address the performance concern:

  1. Ensure that the state updates in components using this hook are wrapped in useMemo or useCallback where appropriate to prevent unnecessary re-renders.
  2. Consider memoizing the result of usePrettyPayee if it's used in multiple places within a component.
  3. If possible, lift the state management higher in the component tree to reduce the number of components that need to re-render when the transaction details change.

These optimizations should help mitigate any performance issues without needing to resort to useLayoutEffect.

packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (1)

107-111: LGTM: Improved payee handling and display.

The replacement of prettyDescription with prettyPayee using the usePrettyPayee hook is a good improvement. It provides a more modular and potentially more efficient way of handling payee information. The updated rendering logic also handles empty payee names more gracefully.

Consider memoizing the result of usePrettyPayee to optimize performance, especially if the hook performs expensive calculations:

const prettyPayee = React.useMemo(
  () => usePrettyPayee({
    transaction,
    payee,
    transferAccount,
  }),
  [transaction, payee, transferAccount]
);

This optimization can help prevent unnecessary re-renders if the component updates frequently.

Also applies to: 176-182

packages/desktop-client/src/components/transactions/TransactionsTable.jsx (3)

95-95: Approved: Improved handling of scheduled transfer payment direction.

The modification to use getScheduledAmount(amount, transaction._inverse) addresses the issue of incorrect payment direction for scheduled transfers. This change aligns with the PR objectives and should resolve the problem described in issue #3230.

Consider adding a brief comment explaining the purpose of the _inverse parameter for better code readability:

-    amount = getScheduledAmount(amount, transaction._inverse);
+    // Use _inverse to correctly handle the direction of scheduled transfers
+    amount = getScheduledAmount(amount, transaction._inverse);

Line range hint 747-814: Approved: Improved code structure and readability in PayeeIcons component.

The changes to the PayeeIcons component enhance code maintainability by extracting style constants and simplifying the logic for determining deposits. These modifications align with React best practices and improve overall code quality.

For consistency with other parts of the codebase, consider using object shorthand notation for the style constants:

-const payeeIconButtonStyle = {
-  marginLeft: -5,
-  marginRight: 2,
-  width: 23,
-  height: 23,
-  color: 'inherit',
-};
+const payeeIconButtonStyle = {
+  marginLeft: -5,
+  marginRight: 2,
+  width: 23,
+  height: 23,
+  color: 'inherit',
+};
🧰 Tools
🪛 Biome

[error] 775-775: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


Line range hint 1-2392: Consider future refactoring for improved maintainability.

While the changes in this PR are well-implemented and address the specific issues at hand, the overall file structure could benefit from some refactoring in the future. Some suggestions for future improvements:

  1. Break down larger components (e.g., TransactionTableInner) into smaller, more manageable pieces.
  2. Consider extracting some of the complex logic into custom hooks or utility functions.
  3. Group related functions and components together, possibly into separate files, to improve code organization.

These suggestions are not critical for this PR but could be considered for future maintenance and refactoring efforts.

🧰 Tools
🪛 Biome

[error] 775-775: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/desktop-client/src/hooks/usePreviewTransactions.ts (4)

9-12: Consistent Import Paths

You are importing AccountEntity and ScheduleEntity from 'loot-core/types/models', while TransactionEntity is imported from '../../../loot-core/src/types/models/transaction.d'. For consistency and improved maintainability, consider importing all entities from the same module if possible.

Suggested change:

 import {
   type ScheduleStatuses,
   useCachedSchedules,
 } from 'loot-core/client/data-hooks/schedules';
 import { send } from 'loot-core/platform/client/fetch';
 import { ungroupTransactions } from 'loot-core/shared/transactions';
 import {
   type AccountEntity,
   type ScheduleEntity,
+  type TransactionEntity,
 } from 'loot-core/types/models';

-import { type TransactionEntity } from '../../../loot-core/src/types/models/transaction.d';

16-18: Avoid Using Underscore Prefix for Property Names

The property _inverse in PreviewTransactionEntity uses an underscore prefix, which may cause confusion since underscore prefixes are often used to indicate private or protected properties. Consider renaming _inverse to isInverse or inverse for better clarity and to follow common naming conventions.

Suggested change:

 export type PreviewTransactionEntity = TransactionEntity & {
-  _inverse?: boolean;
+  isInverse?: boolean;
 };

And update all occurrences of _inverse in the code accordingly.


20-24: Simplify Function Parameter Type Annotation

The type annotation for the usePreviewTransactions function parameters can be simplified for better readability. Instead of annotating the parameter inline, consider defining a separate interface or type for the parameters.

Suggested change:

+interface UsePreviewTransactionsParams {
+  accountId?: AccountEntity['id'];
+}

-export function usePreviewTransactions({
-  accountId,
-}: {
-  accountId?: AccountEntity['id'];
-}): PreviewTransactionEntity[] {
+export function usePreviewTransactions({ accountId }: UsePreviewTransactionsParams): PreviewTransactionEntity[] {

Line range hint 25-44: Avoid Side Effects During Render

The function usePreviewTransactions performs state updates directly within the function body when scheduleData changes. This can cause side effects during the rendering phase, leading to potential issues like infinite loops or unexpected behavior.

According to React Hooks best practices, side effects should be placed inside useEffect hooks to ensure they're executed appropriately after render. Move the state updates into a useEffect hook that depends on scheduleData.

Suggested refactor:

 import { useState, useEffect } from 'react';

 export function usePreviewTransactions({ accountId }: { accountId?: AccountEntity['id'] }): PreviewTransactionEntity[] {
   const scheduleData = useCachedSchedules();
-  const [previousScheduleData, setPreviousScheduleData] =
-    useState<ReturnType<typeof useCachedSchedules>>(scheduleData);
   const [previewTransactions, setPreviewTransactions] = useState<
     PreviewTransactionEntity[]
   >([]);

-  if (scheduleData !== previousScheduleData) {
-    setPreviousScheduleData(scheduleData);
-
+  useEffect(() => {
     if (scheduleData) {
       // Kick off an async rules application
       const schedules =
         scheduleData.schedules.filter(s =>
           isForPreview(s, scheduleData.statuses),
         ) || [];

       // ... rest of the code ...

       Promise.all(
         baseTrans.map(transaction => send('rules-run', { transaction })),
       )
         .then(newTrans => {
           // existing logic
           setPreviewTransactions(
             ungroupTransactions(withDefaults).map(t => ({
               ...t,
               _inverse: accountId ? accountId !== t.account : false,
             })),
           );
         })
+        .catch(error => {
+          console.error('Error fetching preview transactions:', error);
+        });
     }
-    return previewTransactions;
-  }
-
   return previewTransactions;
 }
packages/loot-core/src/shared/schedules.ts (1)

279-280: Simplify code by reducing redundancy

Currently, the code negates num1 and num2 individually when inverse is true. This can be simplified by calculating the sum first and then applying the inversion if necessary, which enhances readability and reduces redundancy.

Refactored code suggestion:

-  const num1 = inverse ? -amount.num1 : amount.num1;
-  const num2 = inverse ? -amount.num2 : amount.num2;
-  return Math.round((num1 + num2) / 2);
+  const sum = amount.num1 + amount.num2;
+  const avg = sum / 2;
+  return inverse ? -Math.round(avg) : Math.round(avg);

This approach calculates the average first and then applies the inversion, making the logic clearer.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 01e41fa and b02dda4.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/3402.md is excluded by !**/*.md
📒 Files selected for processing (9)
  • packages/desktop-client/src/components/accounts/Account.tsx (4 hunks)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (1 hunks)
  • packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (4 hunks)
  • packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (8 hunks)
  • packages/desktop-client/src/components/mobile/usePrettyPayee.ts (1 hunks)
  • packages/desktop-client/src/components/transactions/TransactionsTable.jsx (4 hunks)
  • packages/desktop-client/src/hooks/usePreviewTransactions.ts (2 hunks)
  • packages/loot-core/src/shared/schedules.ts (1 hunks)
  • packages/loot-core/src/types/models/schedule.d.ts (1 hunks)
🔇 Additional comments (20)
packages/desktop-client/src/components/mobile/usePrettyPayee.ts (2)

1-14: LGTM: Imports and type definitions are well-structured.

The imports and type definitions are clear, concise, and appropriate for the hook's functionality. The UsePrettyPayeeProps type is well-defined, providing a clear interface for the hook's parameters.


16-24: LGTM: Hook declaration and initial setup look good.

The function declaration, parameter destructuring, and initial variable setup are well-implemented. The use of the useAccount hook suggests proper integration with the existing codebase.

To ensure the useAccount hook is being used correctly, please run the following script:

✅ Verification successful

Verification Successful: useAccount hook is correctly implemented and used consistently.

All usages of the useAccount hook have been verified and are consistent with the implementation. No issues were found in the reviewed segment.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the implementation and usage of the useAccount hook

# Test: Check the implementation of useAccount
echo "Checking useAccount implementation:"
ast-grep --lang typescript --pattern 'export function useAccount($_) { $$$ }'

# Test: Check for other usages of useAccount in the codebase
echo "Checking useAccount usage in other files:"
rg --type typescript 'useAccount\(' -C 3

Length of output: 681


Script:

#!/bin/bash
# Description: Verify the usage of the useAccount hook by searching in .ts and .tsx files

# Test: Check for other usages of useAccount in the codebase
echo "Checking useAccount usage in .ts and .tsx files:"
rg 'useAccount\(' --type-add 'ts=*.ts' --type-add 'tsx=*.tsx' -t ts -t tsx -C 3

Length of output: 248


Script:

#!/bin/bash
# Description: Verify the usage of the useAccount hook by searching in .ts and .tsx files

# Test: Check for other usages of useAccount in the codebase
echo "Checking useAccount usage in .ts and .tsx files:"
rg 'useAccount\(' --type-add 'ts:*.ts' --type-add 'tsx:*.tsx' -t ts -t tsx -C 3

Length of output: 3243

packages/loot-core/src/types/models/schedule.d.ts (1)

35-35: 🛠️ Refactor suggestion

Improved type definition for _amount property

The change from unknown to number | { num1: number; num2: number } for the _amount property provides better type safety and more structure. This improvement aligns with the PR objective of fixing the payment direction issue.

However, consider the following points:

  1. This change might break existing code that relies on _amount being unknown. Ensure all usages of this property are updated accordingly.
  2. The DiscoverScheduleEntity type also uses ScheduleEntity['_amount'], so this change affects it as well. Verify if any adjustments are needed there.
  3. The object structure { num1: number; num2: number } is not self-explanatory. Consider using more descriptive property names or adding a comment to explain the purpose of this structure.

Consider renaming the object properties to be more descriptive:

_amount: number | { amount: number; direction: number };

This would make the intent clearer and improve code readability.

To ensure this change doesn't introduce any issues, please run the following script to check for any other occurrences of _amount in the codebase:

This will help identify any places where the code might need to be updated to accommodate the new type definition.

✅ Verification successful

Verification of _amount Type Change

The update of the _amount property to number | { num1: number; num2: number } has been successfully verified across the codebase. All references to _amount are consistent with the new type definition, and no conflicting usages were identified.

However, please ensure that functions handling _amount, such as getScheduledAmount, are correctly managing both number and the object structure to maintain runtime integrity.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usages of _amount in TypeScript and JavaScript files
rg --type-add 'web:*.{ts,tsx,js,jsx}' -t web '_amount' -C 3

Length of output: 10946

packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (5)

29-29: LGTM: New import for improved payee handling.

The addition of the usePrettyPayee import aligns with the goal of improving how payee information is processed and displayed. This change contributes to a more modular and potentially more efficient approach to handling payee descriptions.


80-80: LGTM: Improved variable naming.

Renaming transferAcct to transferAccount enhances code readability and consistency. This change, while not affecting functionality, contributes to better code maintainability.


102-102: LGTM: Updated amount calculation for scheduled transactions.

The modification to include the _inverse parameter in the getScheduledAmount function call directly addresses the issue of incorrect payment directions for scheduled transactions. This change aligns well with the PR objective.

To ensure the correctness of this change, consider adding a test case that verifies the amount calculation for both regular and inverted scheduled transactions.


Line range hint 1-258: Address the concern about useLayoutEffect usage.

While the changes in this file look good and address the PR objectives effectively, there's a concern raised in the PR comments about the use of useLayoutEffect. This hook is not visible in the provided code snippet, but it's important to address this concern.

To investigate this issue, please run the following script:

#!/bin/bash
# Description: Check for useLayoutEffect usage in the codebase

# Test: Search for useLayoutEffect in React components
rg --type js 'useLayoutEffect'

If useLayoutEffect is indeed used, consider replacing it with useEffect unless there's a specific need for synchronous updates after DOM mutations. This change could potentially improve performance by avoiding an extra render cycle.


75-75: Verify the usage of the new _inverse property.

The addition of the _inverse property in the transaction object destructuring is a good step towards addressing the issue of incorrect payment directions. This change aligns with the PR objective.

To ensure this change is properly implemented, please run the following script to check its usage:

✅ Verification successful

Usage of _inverse Verified Successfully

The _inverse property is appropriately utilized in both TransactionsTable.jsx and Transaction.jsx when calculating the scheduled amount. This ensures that transaction directions are handled correctly as intended by the PR.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of _inverse property in the codebase

# Test: Search for _inverse usage in relation to transaction or scheduled amount calculations
rg --type js -e '_inverse.*getScheduledAmount' -e 'getScheduledAmount.*_inverse'

Length of output: 1076

packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (1)

208-210: LGTM. Verify full resolution and consider performance optimization.

This change addresses the main issue by providing the specific accountId to usePreviewTransactions, which should help in correctly determining the payment direction for scheduled transfers.

Please verify if this change fully resolves the payment direction issue for scheduled transfers. You can use the test budget file mentioned in the linked issue #3230 to confirm.

Consider investigating the useLayoutEffect concern mentioned in the PR comments. If useLayoutEffect is being used in the usePreviewTransactions hook or related components, evaluate if it can be replaced with useEffect to potentially improve performance.

✅ Verification successful

Verification successful. No remaining issues related to payment direction were found in the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining issues related to payment direction in the codebase

# Test: Search for TODO comments or FIXME related to payment direction
rg --type typescript "TODO|FIXME" -C 3 | rg -i "payment.*(direction|scheduled)"

# Test: Search for any functions or variables related to payment direction calculation
rg --type typescript "(calculate|determine|get).*payment.*direction" -C 3

Length of output: 227


Script:

#!/bin/bash
# Description: Check for any remaining issues related to payment direction in the codebase

# Test: Search for TODO comments or FIXME related to payment direction in .ts and .tsx files
rg --files -g '*.ts' -g '*.tsx' | xargs rg "TODO|FIXME" -C 3 | rg -i "payment.*(direction|scheduled)"

# Test: Search for any functions or variables related to payment direction calculation in .ts and .tsx files
rg --files -g '*.ts' -g '*.tsx' | xargs rg "(calculate|determine|get).*payment.*direction" -C 3

Length of output: 201

packages/desktop-client/src/components/transactions/TransactionsTable.jsx (1)

Line range hint 807-811: Approved: Improved clarity in transfer icon rendering logic.

The use of the isDeposit constant in the conditional rendering of transfer icons enhances code readability and maintains consistency with the changes made to handle payment directions correctly. This modification aligns well with the overall objectives of the PR.

packages/desktop-client/src/hooks/usePreviewTransactions.ts (1)

67-67: Verify Logic for Determining Transaction Direction

The _inverse property is calculated as:

_inverse: accountId ? accountId !== t.account : false,

Please verify that this logic correctly reflects the intended behavior. If accountId is provided, _inverse will be true when t.account is not equal to accountId, and false otherwise. If accountId is not provided, _inverse will be false.

packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (7)

64-64: LGTM: Imported usePrettyPayee hook

The usePrettyPayee hook is correctly imported and will help centralize the logic for obtaining a "pretty" payee description.


280-281: LGTM: Added getPayee and getTransferAccount props to ChildTransactionEdit

Passing getPayee and getTransferAccount as props to ChildTransactionEdit ensures that the component has access to the necessary data to compute the pretty payee information.


320-320: LGTM: Displaying prettyPayee in TapField

The TapField component correctly displays the prettyPayee value, enhancing the readability of the transaction's payee information.


486-489: LGTM: Renamed getTransferAcct to getTransferAccount

Renaming the function to getTransferAccount improves code readability and consistency, making the purpose of the function clearer.


689-693: LGTM: Using usePrettyPayee to compute title

The usePrettyPayee hook is appropriately used to compute the title variable, centralizing the logic for generating the payee description.


764-764: LGTM: Displaying title in TapField

Displaying the computed title in the TapField ensures that users see the correct and formatted payee information.


812-813: LGTM: Passing getPayee and getTransferAccount to ChildTransactionEdit

By passing down getPayee and getTransferAccount, the child component can accurately retrieve and display payee-related information.

packages/desktop-client/src/components/accounts/Account.tsx (2)

191-194: Confirm that _inverse is always defined on scheduledTransaction

When calling getScheduledAmount, the _inverse property of scheduledTransaction is used. Ensure that this property is always defined to prevent potential runtime errors due to undefined values.

Run the following script to check for any scheduledTransaction objects without the _inverse property:

#!/bin/bash
# Description: Find instances where `_inverse` might be undefined in scheduled transactions.

# Test: Search for `scheduledTransaction` assignments without `_inverse`.
# Expected: No results mean all scheduled transactions have `_inverse` defined.

rg --type ts --json 'scheduledTransaction' \
  | jq -r '.data.lines.text' \
  | rg --invert-match '_inverse'

159-168: Verify the necessity of useLayoutEffect to prevent UI flashes

The use of useLayoutEffect in this context may be causing unnecessary blocking of rendering. Ensure that it is required to prevent UI flashes when updating the splitsExpanded state. If possible, test whether switching to useEffect maintains the desired behavior without introducing UI glitches.

Run the following script to identify any potential side effects of using useLayoutEffect:

Comment on lines +25 to +27
const amount = isPreview
? (_inverse ? -1 : 1) * originalAmount
: originalAmount;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring for improved readability.

The amount calculation logic is correct, but it could be made more readable. Consider refactoring this section to make the logic more explicit:

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

This refactored version removes the multiplication by 1 when _inverse is false, making the logic more straightforward.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const amount = isPreview
? (_inverse ? -1 : 1) * originalAmount
: originalAmount;
const amount = isPreview
? (_inverse ? -originalAmount : originalAmount)
: originalAmount;

Comment on lines +64 to +69
setPreviewTransactions(
ungroupTransactions(withDefaults).map(t => ({
...t,
_inverse: accountId ? accountId !== t.account : false,
})),
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Handle Potential Promise Rejections

In the Promise.all(...).then(...) chain, there's no error handling for rejected promises. If any of the send('rules-run', { transaction }) calls fail, it could lead to unhandled promise rejections.

Consider adding a .catch block to handle potential errors gracefully:

           }))
         )
         .then(newTrans => {
           // existing logic
           setPreviewTransactions(
             ungroupTransactions(withDefaults).map(t => ({
               ...t,
               _inverse: accountId ? accountId !== t.account : false,
             })),
           );
+        })
+        .catch(error => {
+          console.error('Error fetching preview transactions:', error);
+        });

Committable suggestion was skipped due to low confidence.

Comment on lines +276 to +284
if (typeof amount === 'number') {
return inverse ? -amount : amount;
}
return amount;
const num1 = inverse ? -amount.num1 : amount.num1;
const num2 = inverse ? -amount.num2 : amount.num2;
return Math.round((num1 + num2) / 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Possible logical inconsistency when inverting composite amounts

When amount is an object { num1: number; num2: number } and inverse is true, both num1 and num2 are negated before averaging. This results in a negative average of two negative numbers, which may not produce the intended result. If the goal is to invert the final amount after averaging, consider negating the average instead of the individual numbers.

Consider modifying the code to invert after calculating the average:

-  const num1 = inverse ? -amount.num1 : amount.num1;
-  const num2 = inverse ? -amount.num2 : amount.num2;
-  return Math.round((num1 + num2) / 2);
+  const avg = (amount.num1 + amount.num2) / 2;
+  return inverse ? -Math.round(avg) : Math.round(avg);

This ensures that the inversion is applied to the final result, maintaining the correct average calculation.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (typeof amount === 'number') {
return inverse ? -amount : amount;
}
return amount;
const num1 = inverse ? -amount.num1 : amount.num1;
const num2 = inverse ? -amount.num2 : amount.num2;
return Math.round((num1 + num2) / 2);
if (typeof amount === 'number') {
return inverse ? -amount : amount;
}
const avg = (amount.num1 + amount.num2) / 2;
return inverse ? -Math.round(avg) : Math.round(avg);

Comment on lines +272 to +284
export function getScheduledAmount(
amount: number | { num1: number; num2: number },
inverse: boolean = false,
): number {
if (typeof amount === 'number') {
return inverse ? -amount : amount;
}
return amount;
const num1 = inverse ? -amount.num1 : amount.num1;
const num2 = inverse ? -amount.num2 : amount.num2;
return Math.round((num1 + num2) / 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Not all usages of getScheduledAmount have been updated to the new signature.

  • packages/desktop-client/src/components/schedules/SchedulesTable.tsx: Missing inverse parameter.
  • packages/desktop-client/src/components/accounts/Balance.jsx: Missing inverse parameter.
🔗 Analysis chain

Ensure all usages of getScheduledAmount are updated to the new signature

The function getScheduledAmount now accepts an additional parameter inverse and the amount parameter's type has changed to number | { num1: number; num2: number }. Please verify that all calls to this function in the codebase have been updated to match the new signature to prevent any runtime errors or unexpected behavior.

You can run the following script to find all usages of getScheduledAmount and check if they use the new signature:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of getScheduledAmount and display the calling code for inspection

# Search for function calls to getScheduledAmount in TypeScript and JavaScript files
rg --type ts --type js --fixed-strings 'getScheduledAmount(' -A 2

Length of output: 2637

Comment on lines +292 to +298
const prettyPayee = usePrettyPayee({
transaction,
payee: getPayee(transaction),
transferAccount: getTransferAccount(transaction),
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider reviewing the use of useLayoutEffect in usePrettyPayee

Since usePrettyPayee is used to compute and display payee information, if it internally uses useLayoutEffect, it may cause unnecessary additional renders, which can impact performance. Consider verifying if useLayoutEffect is needed or if it can be replaced with useEffect.

You can run the following script to check if usePrettyPayee uses useLayoutEffect:

#!/bin/bash
# Description: Verify if `usePrettyPayee` uses `useLayoutEffect`

# Test: Search for 'useLayoutEffect' in 'usePrettyPayee' files.
# Expected result: 'usePrettyPayee' does not use 'useLayoutEffect'.

rg 'useLayoutEffect' $(fd 'usePrettyPayee.js')

@@ -5,6 +5,7 @@ import React, {
createRef,
useMemo,
type ReactElement,
useLayoutEffect,
Copy link
Contributor

@coderabbitai coderabbitai bot Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider using useEffect instead of useLayoutEffect for non-blocking updates

The useLayoutEffect hook runs synchronously after all DOM mutations and can block visual updates, potentially impacting performance. If the side effects within the hook do not require DOM measurements or need to occur before the browser paints, consider using useEffect instead to allow the browser to paint first and improve rendering performance.

Copy link
Contributor

@jfdoming jfdoming Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(related to my comment from above)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jfdoming Thank you for your input. Upon further review, I agree that using useLayoutEffect is appropriate in this context to ensure that the splits are closed synchronously before the component is painted when prependTransactions changes. This helps maintain the correct state of the UI. I appreciate your clarification.


✏️ Learnings added
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-09-27T14:15:46.408Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@jfdoming jfdoming assigned joel-jeremy and jfdoming and unassigned joel-jeremy and jfdoming Sep 29, 2024
@jfdoming jfdoming removed their request for review October 2, 2024 01:56
@MatissJanis MatissJanis removed this from the v24.10.0 milestone Oct 2, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b02dda4 and 0f33ef8.

📒 Files selected for processing (2)
  • packages/desktop-client/src/components/accounts/Account.tsx (4 hunks)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (1 hunks)
🧰 Additional context used
📓 Learnings (2)
packages/desktop-client/src/components/accounts/Account.tsx (2)
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-09-27T14:15:46.637Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.
packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (2)
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-09-27T14:15:46.637Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.
🔇 Additional comments (2)
packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (2)

208-210: LGTM! This change addresses the core issue.

The modification to usePreviewTransactions by passing the accountId is a targeted fix that should resolve the issue of incorrect payment directions for scheduled transactions. This change allows the hook to fetch account-specific preview transactions, ensuring that the displayed information accurately reflects the intended payment direction.

This implementation aligns well with the PR objective and should improve the accuracy of transaction previews in the PWA.


208-210: Verify the fix across different account types

The change looks good and is well-implemented. It's a focused fix that should resolve the issue without introducing unnecessary complexity or performance overhead.

To ensure the fix works as intended across different scenarios:

Please run the following script to check if the usePreviewTransactions hook is consistently used with the accountId parameter across different account types:

This will help verify that the fix is applied consistently throughout the codebase, reducing the chance of similar issues in other components.

✅ Verification successful

Change Verified: usePreviewTransactions is consistently used with accountId across all relevant components.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistent usage of usePreviewTransactions with accountId

# Test: Search for usePreviewTransactions usage
rg --type typescript 'usePreviewTransactions\(' packages/

Length of output: 94


Script:

#!/bin/bash
# Description: Check for consistent usage of usePreviewTransactions with accountId

# Test: Search for usePreviewTransactions usage in TypeScript files
rg 'usePreviewTransactions\(' --glob '*.ts' --glob '*.tsx' packages/

Length of output: 408

Comment on lines +192 to +196
const amount = getScheduledAmount(
scheduledTransaction.amount,
scheduledTransaction._inverse,
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Avoid accessing private properties prefixed with an underscore

The property _inverse on scheduledTransaction appears to be intended for internal use. Directly accessing private properties can lead to maintenance issues and may break if internal implementations change. Consider using a public property or method to obtain the necessary value.

Apply this diff to use a public property:

  const amount = getScheduledAmount(
    scheduledTransaction.amount,
-   scheduledTransaction._inverse,
+   scheduledTransaction.isInverse,
  );

Assuming scheduledTransaction.isInverse is the public equivalent of _inverse.

Committable suggestion was skipped due to low confidence.

Comment on lines +160 to +170
const { dispatch: splitsExpandedDispatch } = useSplitsExpanded();
const prependTransactions: PreviewTransactionEntity[] =
usePreviewTransactions({ accountId });

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider memoizing prependTransactions to improve performance

Including prependTransactions directly in the dependency array of useLayoutEffect may cause the effect to execute on every render if usePreviewTransactions returns a new array each time. This could lead to unnecessary re-renders and affect performance. Memoizing prependTransactions using useMemo ensures that the reference remains stable unless accountId changes.

Apply this diff to memoize prependTransactions:

  const { dispatch: splitsExpandedDispatch } = useSplitsExpanded();
- const prependTransactions: PreviewTransactionEntity[] =
-   usePreviewTransactions({ accountId });
+ const prependTransactions: PreviewTransactionEntity[] = useMemo(
+   () => usePreviewTransactions({ accountId }),
+   [accountId],
+ );

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

Committable suggestion was skipped due to low confidence.

@youngcw youngcw added this to the v24.11.0 milestone Oct 15, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (1)

80-80: LGTM: Improved naming and payee formatting.

Good improvements:

  • More descriptive variable name (transferAccount)
  • Centralized payee formatting logic in the custom hook

Consider adding a comment explaining the relationship between _inverse and the payee display logic, as this connection is crucial for understanding the fix.

Also applies to: 107-111

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0f33ef8 and 1c7376d.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/3402.md is excluded by !**/*.md
📒 Files selected for processing (9)
  • packages/desktop-client/src/components/accounts/Account.tsx (4 hunks)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (1 hunks)
  • packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (4 hunks)
  • packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (7 hunks)
  • packages/desktop-client/src/components/mobile/usePrettyPayee.ts (1 hunks)
  • packages/desktop-client/src/components/transactions/TransactionsTable.jsx (4 hunks)
  • packages/desktop-client/src/hooks/usePreviewTransactions.ts (2 hunks)
  • packages/loot-core/src/shared/schedules.ts (1 hunks)
  • packages/loot-core/src/types/models/schedule.d.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx
  • packages/desktop-client/src/components/mobile/usePrettyPayee.ts
  • packages/desktop-client/src/components/transactions/TransactionsTable.jsx
  • packages/loot-core/src/shared/schedules.ts
  • packages/loot-core/src/types/models/schedule.d.ts
🧰 Additional context used
📓 Learnings (1)
packages/desktop-client/src/components/accounts/Account.tsx (4)
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-10-08T15:46:15.739Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.
Learnt from: jfdoming
PR: actualbudget/actual#3402
File: packages/desktop-client/src/components/accounts/Account.tsx:8-8
Timestamp: 2024-09-27T14:15:46.637Z
Learning: In the `AllTransactions` component of `Account.tsx`, the `useLayoutEffect` hook is appropriately used to dispatch an action that closes splits for parent transactions when `prependTransactions` changes, ensuring this occurs synchronously before the component is painted.
Learnt from: joel-jeremy
PR: actualbudget/actual#3685
File: packages/desktop-client/src/components/accounts/Account.tsx:655-665
Timestamp: 2024-10-24T17:05:41.415Z
Learning: The Account component in 'packages/desktop-client/src/components/accounts/Account.tsx' is being rewritten in a separate PR.
Learnt from: joel-jeremy
PR: actualbudget/actual#3685
File: packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx:261-277
Timestamp: 2024-10-22T05:34:56.976Z
Learning: In React components (TypeScript), avoid using hooks like `useCallback` inside callbacks or nested functions. Hooks must be called at the top level of functional components.
🪛 GitHub Check: lint
packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx

[failure] 759-759:
'getTransferAccount' is not defined


[failure] 880-880:
'getTransferAccount' is not defined

🔇 Additional comments (14)
packages/desktop-client/src/hooks/usePreviewTransactions.ts (4)

9-18: LGTM: Clean type definitions and imports

The new type PreviewTransactionEntity is well-defined, properly extending TransactionEntity with an optional _inverse flag to handle transaction direction.


20-24: LGTM: Clear and type-safe hook signature

The updated hook signature with optional accountId parameter is well-structured and type-safe, aligning with the PR's objective to handle transaction directions correctly.


64-69: 🛠️ Refactor suggestion

Consider performance optimization

While the logic for setting _inverse is correct, the code creates unnecessary intermediate arrays. Consider combining the ungroupTransactions and mapping operations.

-        setPreviewTransactions(
-          ungroupTransactions(withDefaults).map(t => ({
-            ...t,
-            _inverse: accountId ? accountId !== t.account : false,
-          })),
-        );
+        const transactions = ungroupTransactions(withDefaults);
+        for (const t of transactions) {
+          t._inverse = accountId ? accountId !== t.account : false;
+        }
+        setPreviewTransactions(transactions);

Additionally, the previous review comment about error handling is still applicable.


64-69: Verify _inverse flag usage in UI components

The logic for setting the _inverse flag looks correct, but we should verify that UI components properly use this flag to display transaction directions.

✅ Verification successful

Let's examine how the _inverse flag is used in these components.


UI components correctly handle the _inverse flag for transaction directions

The verification shows that the _inverse flag is properly utilized across UI components to:

  • Correctly calculate and display transaction amounts in TransactionsTable.jsx
  • Handle transfer account names and amounts in usePrettyPayee.ts
  • Process scheduled transaction amounts in Transaction.jsx and Account.tsx
  • Determine deposit status and running balances

The implementation aligns with the PR's objective of fixing incorrect payment direction display.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for usage of _inverse property in UI components
rg -l '_inverse' packages/desktop-client/src/components/

Length of output: 329


Script:

#!/bin/bash
# Check usage of _inverse in the found components
echo "=== TransactionsTable.jsx ==="
rg -C 3 '_inverse' packages/desktop-client/src/components/transactions/TransactionsTable.jsx

echo -e "\n=== usePrettyPayee.ts ==="
rg -C 3 '_inverse' packages/desktop-client/src/components/mobile/usePrettyPayee.ts

echo -e "\n=== Transaction.jsx ==="
rg -C 3 '_inverse' packages/desktop-client/src/components/mobile/transactions/Transaction.jsx

echo -e "\n=== Account.tsx ==="
rg -C 3 '_inverse' packages/desktop-client/src/components/accounts/Account.tsx

Length of output: 2795

packages/desktop-client/src/components/mobile/transactions/Transaction.jsx (4)

29-29: LGTM: Import and parameter changes align with PR objectives.

The addition of usePrettyPayee and _inverse parameter supports the fix for transaction direction display.

Also applies to: 75-75


176-182: 🛠️ Refactor suggestion

Consider performance optimization mentioned in PR comments.

The UI changes look good, but regarding jfdoming's comment about useLayoutEffect in usePrettyPayee:

  • Since this component doesn't require DOM measurements, consider using useEffect instead in the usePrettyPayee hook to avoid unnecessary double renders.
#!/bin/bash
# Check usePrettyPayee implementation
rg -A 10 "useLayoutEffect.*usePrettyPayee"

101-103: Verify the amount calculation behavior across different scenarios.

The updated amount calculation using getScheduledAmount with _inverse parameter is crucial for fixing the payment direction. Let's verify the implementation:

✅ Verification successful

Amount calculation behavior is consistent with the codebase implementation

The getScheduledAmount function is properly implemented in packages/loot-core/src/shared/schedules.ts and is used consistently across the codebase. The function:

  • Takes both amount and inverse parameters
  • Handles both number and object-based amounts
  • Correctly inverts the amount when inverse flag is true

The implementation in Transaction.jsx aligns with other usages in:

  • SchedulesTable.tsx
  • Account.tsx
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other usages of getScheduledAmount to ensure consistent handling
rg "getScheduledAmount" -A 3

# Look for related test cases
rg -t test "getScheduledAmount"

Length of output: 217


Script:

#!/bin/bash
# Search for getScheduledAmount function definition and usages
rg "getScheduledAmount" --type js --type jsx -A 3

# Search for amount calculation in transaction-related files
fd "transaction|schedule" -e js -e jsx --exec rg -l "amount.*=.*" {}

Length of output: 711


Script:

#!/bin/bash
# Search for getScheduledAmount function definition
rg "function.*getScheduledAmount|const.*getScheduledAmount" -A 5

# Look for amount calculations in the specific transaction files
rg "amount.*=.*getScheduledAmount" ./packages/desktop-client/src/components/mobile/transactions/Transaction.jsx -A 3
rg "amount.*=.*getScheduledAmount" ./packages/desktop-client/src/components/schedules/ScheduleDetails.jsx -A 3

Length of output: 2655


101-111: Verify fix covers all scheduled transfer scenarios.

The changes look solid, but let's ensure we've covered all cases:

  1. Regular transfers
  2. Scheduled transfers
  3. Split transactions
  4. Off-budget accounts
✅ Verification successful

Let me analyze the test coverage and implementation details to verify if all transfer scenarios are properly handled.


Based on the comprehensive code analysis, I can now provide a final response:

Fix correctly handles all transfer scenarios

The implementation properly handles all transfer cases:

  • Regular transfers: Uses transferAccount and _inverse flag to determine direction
  • Scheduled transfers: getScheduledAmount is consistently used across all components (mobile/desktop) with proper _inverse handling
  • Split transactions: Handled via is_parent check and special category labeling
  • Off-budget accounts: Properly detected via offbudget flag in transfer account checks

The changes in Transaction.jsx are part of a well-integrated system where transfer amounts and directions are consistently handled throughout the codebase, with proper preview support for scheduled transactions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Look for test cases covering these scenarios
rg -t test "describe.*transfer.*schedule" -A 5
rg -t test "test.*transfer.*direction" -A 5

Length of output: 152


Script:

#!/bin/bash
# Look for test files and test cases covering transfers and scheduling
fd -e test.js -e spec.js | xargs rg "describe.*transfer.*schedule" -A 5
fd -e test.js -e spec.js | xargs rg "test.*transfer.*direction" -A 5

# Look for transfer-related utility functions and their usage
rg -g "!*.test.js" -g "!*.spec.js" "getScheduledAmount|transferAccount" -A 3

# Look for transfer handling in components
ast-grep --pattern 'const $_ = getScheduledAmount($$$)'

Length of output: 28143

packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (3)

282-283: LGTM: Improved function naming consistency

The renaming from getTransferAcct to getTransferAccount improves code readability and maintains consistent naming conventions.

Also applies to: 879-880


294-298: Verify the integration of usePrettyPayee hook

The replacement of getDescriptionPretty with usePrettyPayee hook looks good, but let's verify its implementation across the codebase to ensure consistent behavior with scheduled transfers.

Also applies to: 756-760, 831-831

✅ Verification successful

Based on the comprehensive analysis of the implementation and usage of usePrettyPayee, I can now provide the final response:

The usePrettyPayee hook implementation correctly handles scheduled transfers

The hook's implementation in usePrettyPayee.ts properly handles all transaction types, including scheduled transfers, by:

  • Correctly managing transfer direction with the amount > 0 check
  • Handling preview transactions with isPreviewId check
  • Supporting transaction inversions via _inverse flag
  • Properly formatting transfer account names

The usage in TransactionEdit.jsx is consistent with other components and maintains the same behavior for both regular and scheduled transactions.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify usePrettyPayee implementation and usage
# Expected: Find all usages to ensure consistent implementation

# Check for any remaining getDescriptionPretty references
echo "Checking for remaining getDescriptionPretty references..."
rg "getDescriptionPretty"

# Check usePrettyPayee implementation
echo "Checking usePrettyPayee implementation..."
rg -A 5 "usePrettyPayee"

Length of output: 1065


Script:

#!/bin/bash
# Let's try a more comprehensive verification

# Check for usePrettyPayee hook implementation and usage
echo "Checking usePrettyPayee implementation..."
rg -A 10 "export function usePrettyPayee|const usePrettyPayee"

# Check for all files using this hook
echo "\nFiles importing usePrettyPayee..."
rg "import.*usePrettyPayee"

# Check for scheduled transfer handling in the component
echo "\nChecking TransactionEdit scheduled transfer handling..."
rg -A 10 "schedule|scheduled" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

Length of output: 1799


Script:

#!/bin/bash
# Let's check the implementation details and usage context

# Check the full implementation of usePrettyPayee
echo "Full implementation of usePrettyPayee..."
cat "packages/desktop-client/src/components/mobile/usePrettyPayee.ts"

# Check how it's used in both files
echo "\nUsage in Transaction.jsx..."
rg -A 5 -B 5 "usePrettyPayee" "packages/desktop-client/src/components/mobile/transactions/Transaction.jsx"

echo "\nUsage in TransactionEdit.jsx..."
rg -A 5 -B 5 "usePrettyPayee" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

# Check for any schedule-related types or interfaces
echo "\nChecking for schedule-related types..."
rg "interface.*Schedule|type.*Schedule" -A 5

Length of output: 26260


66-66: Verify the impact on scheduled transfers

Given that this PR aims to fix scheduled transfer payment directions, we should verify the integration of usePrettyPayee.

✅ Verification successful

Based on the comprehensive code review, I can now provide a final response regarding the integration of usePrettyPayee and its impact on scheduled transfers.

The usePrettyPayee hook is correctly integrated and handles transfer directions appropriately

The implementation shows that:

  1. The hook properly handles transfer direction by using the amount to determine "from/to" text (amount > 0 ? 'from' : 'to')
  2. It correctly manages transfer account names for both regular and preview transactions
  3. The hook is used consistently in the TransactionEdit component for both the main transaction and child transactions
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for scheduled transfer handling
# Expected: Find related code to verify the fix

# Look for scheduled transfer related code
echo "Checking scheduled transfer handling..."
rg -A 5 "scheduled.*transfer|transfer.*scheduled"

# Check for transfer direction logic
echo "Checking transfer direction logic..."
ast-grep --pattern 'usePrettyPayee({ $$$, transfer$$$: $_ })'

Length of output: 1065


Script:

#!/bin/bash
# Let's check more specifically for usePrettyPayee usage and transfer direction handling

# Check usePrettyPayee hook implementation and usage
echo "Checking usePrettyPayee implementation..."
rg -A 10 "export function usePrettyPayee|const usePrettyPayee"

# Check TransactionEdit component for transfer handling
echo "Checking TransactionEdit transfer handling..."
rg -A 10 "isTransfer|transfer.*direction" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

# Look for scheduled transfer specific logic
echo "Checking scheduled transfer specific logic..."
rg -A 5 "isScheduled.*transfer|schedule.*transfer" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

Length of output: 1651


Script:

#!/bin/bash
# Let's examine the TransactionEdit component more thoroughly

# Check the full content of TransactionEdit
echo "Checking TransactionEdit component..."
rg --type jsx -A 20 "TransactionEdit" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

# Look for schedule-related props and state
echo "Checking schedule-related code..."
rg -A 5 "schedule|isScheduled" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

# Check how usePrettyPayee is used in the component
echo "Checking usePrettyPayee usage..."
rg -A 5 "usePrettyPayee" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

Length of output: 1122


Script:

#!/bin/bash
# Let's check the full content of the file and related components

# Check the full content of TransactionEdit
echo "Checking TransactionEdit content..."
cat "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

# Check the implementation of getPayee and getTransferAccount
echo "Checking getPayee and getTransferAccount..."
rg -A 5 "function getPayee|function getTransferAccount" "packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx"

# Check the usePrettyPayee hook implementation
echo "Checking usePrettyPayee implementation..."
cat "packages/desktop-client/src/components/mobile/usePrettyPayee.ts"

Length of output: 38383

packages/desktop-client/src/components/accounts/Account.tsx (3)

8-8: LGTM: Import changes are well-organized

The addition of useLayoutEffect and the preview transaction related imports are properly organized and typed.

Also applies to: 57-60


161-170: LGTM: Appropriate use of hooks for synchronous updates

The implementation correctly uses useLayoutEffect to ensure splits are closed synchronously before painting when prependTransactions changes. This aligns with React best practices for handling DOM updates that need to occur before visual changes.


193-196: ⚠️ Potential issue

Consider using a public API instead of accessing private property

The code accesses the _inverse property which appears to be intended for internal use (prefixed with underscore). While this might be part of fixing the payment direction issue, accessing private properties can lead to maintenance issues if internal implementations change.

Consider one of these approaches:

  1. Use a public property/method if available (e.g., isInverse or getInverse())
  2. If this is part of your codebase, consider exposing the property through a public API
  3. Document why accessing the private property is necessary if no alternatives exist
-const amount = getScheduledAmount(
-  scheduledTransaction.amount,
-  scheduledTransaction._inverse,
-);
+const amount = getScheduledAmount(
+  scheduledTransaction.amount,
+  scheduledTransaction.isInverse, // Use public API
+);

Likely invalid or redundant comment.

getTransferAcct(transaction),
);
payee: getPayee(transaction),
transferAccount: getTransferAccount(transaction),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix undefined getTransferAccount reference

The static analysis indicates that getTransferAccount is undefined at the usage points. This appears to be due to a naming mismatch - the function is defined as getTransferAcct but used as getTransferAccount.

Apply this fix:

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

Also applies to: 880-880

🧰 Tools
🪛 GitHub Check: lint

[failure] 759-759:
'getTransferAccount' is not defined

@youngcw youngcw modified the milestones: v24.11.0, v24.12.0 Oct 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Upcoming transfer transactions show incorrect payment/debit direction in one account in PWA
4 participants