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

♻️ (typescript) Refactor Accounts/Balances to tsx and Remove ts-strict-ignore from Accounts/Account #4047

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

Conversation

tlesicka
Copy link
Contributor

Refactoring Accounts component to strict typescript.

@actual-github-bot actual-github-bot bot changed the title ♻️ (typescript) Refactor Accounts/Balances to tsx and Remove ts-strict-ignore from Accounts/Account [WIP] ♻️ (typescript) Refactor Accounts/Balances to tsx and Remove ts-strict-ignore from Accounts/Account Dec 27, 2024
Copy link

netlify bot commented Dec 27, 2024

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit b80c9ef
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/6775d4a1d6d4bc000826b222
😎 Deploy Preview https://deploy-preview-4047.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.

Copy link
Contributor

github-actions bot commented Dec 27, 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
10 5.64 MB → 5.64 MB (+204 B) +0.00%
Changeset
File Δ Size
src/components/accounts/Balance.tsx 🆕 +5.34 kB 0 B → 5.34 kB
src/components/accounts/Account.tsx 📈 +250 B (+0.55%) 44.63 kB → 44.87 kB
src/components/accounts/Header.tsx 📈 +36 B (+0.19%) 18.58 kB → 18.61 kB
src/components/accounts/Balance.jsx 🔥 -5.42 kB (-100%) 5.42 kB → 0 B
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/wide.js 104.11 kB → 104.3 kB (+204 B) +0.19%

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/workbox-window.prod.es5.js 5.69 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/AppliedFilters.js 10.24 kB 0%
static/js/useAccountPreviewTransactions.js 1.63 kB 0%
static/js/narrow.js 83.36 kB 0%
static/js/ReportRouter.js 1.58 MB 0%
static/js/index.js 3.71 MB 0%

Copy link
Contributor

github-actions bot commented Dec 27, 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.33 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.js 1.33 MB 0%

@tlesicka tlesicka changed the title [WIP] ♻️ (typescript) Refactor Accounts/Balances to tsx and Remove ts-strict-ignore from Accounts/Account ♻️ (typescript) Refactor Accounts/Balances to tsx and Remove ts-strict-ignore from Accounts/Account Dec 27, 2024
Copy link
Contributor

coderabbitai bot commented Dec 27, 2024

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/desktop-client/src/components/accounts/Balance.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't find the plugin "eslint-plugin-eslint-plugin".

(The package "eslint-plugin-eslint-plugin" was not found when loaded as a Node module from the directory "/packages/eslint-plugin-actual".)

It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:

npm install eslint-plugin-eslint-plugin@latest --save-dev

The plugin "eslint-plugin-eslint-plugin" was referenced from the config file in "packages/eslint-plugin-actual/.eslintrc.js".

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

Walkthrough

The pull request introduces type safety improvements and state management refinements across multiple components in the desktop client, specifically focusing on the Account.tsx, Balance.tsx, Header.tsx, and spreadsheet/index.ts files. The changes primarily involve updating type annotations, making properties optional, and enhancing type definitions to prevent potential runtime errors. Key modifications include changing property signatures, adding type definitions, simplifying conditional logic, and ensuring more robust handling of potentially undefined or null values in components related to account management and balance tracking.

Possibly related issues

  • [Maintenance] TypeScript migration #1483 (TypeScript migration): These changes directly contribute to the ongoing TypeScript migration effort by improving type safety in the Account.tsx, Balance.tsx, and Header.tsx components, which were part of the remaining files to be converted.

Possibly related PRs

Suggested labels

type-safety, refactoring, typescript

Suggested reviewers

  • joel-jeremy
  • matt-fidd

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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

🧹 Nitpick comments (4)
packages/desktop-client/src/components/accounts/Header.tsx (1)

70-71: Optional reconcileAmount, canCalculateBalance, and filteredAmount

Changing these to optional parameters (including null for amounts) logically supports cases when certain details are unavailable or do not apply. Double-check that wherever these props are consumed, you consider their null or undefined states to avoid runtime errors.

Also applies to: 73-73

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

335-336: Definite assignment operator for rootQuery and currentQuery

Using the ! operator ensures these fields will be assigned before use, but confirm they’re actually set prior to any method calls referencing them. Otherwise, consider using constructor injection or lazy initialization for clarity.


680-686: Guard condition for computing balance

This short-circuits calculation if a search or filters are active. The logic is correct, but might be clearer with an explanatory comment or a standalone helper function named shouldCalculateBalance().


1405-1405: Another update to filterId.status

Again, consistent usage. Validate that these repeated updates do not cause performance overhead or complicated re-renders.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3f6068f and 57ab2a2.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/4047.md is excluded by !**/*.md
📒 Files selected for processing (4)
  • packages/desktop-client/src/components/accounts/Account.tsx (15 hunks)
  • packages/desktop-client/src/components/accounts/Balance.tsx (6 hunks)
  • packages/desktop-client/src/components/accounts/Header.tsx (4 hunks)
  • packages/desktop-client/src/components/spreadsheet/index.ts (1 hunks)
🧰 Additional context used
📓 Learnings (1)
packages/desktop-client/src/components/accounts/Account.tsx (1)
Learnt from: joel-jeremy
PR: actualbudget/actual#3685
File: packages/desktop-client/src/components/accounts/Account.tsx:655-665
Timestamp: 2024-11-10T16:45:31.225Z
Learning: The Account component in 'packages/desktop-client/src/components/accounts/Account.tsx' is being rewritten in a separate PR.
🔇 Additional comments (39)
packages/desktop-client/src/components/spreadsheet/index.ts (1)

72-74: Ensure consistency of newly introduced index signatures.

The new template-literal properties may require further validation to confirm that:

  1. They do not conflict with existing keys in the codebase.
  2. They correctly reflect all expected usage patterns (e.g., any scenario where values could be null or undefined).

Below is a script that searches for these property usages across the repo to verify correct usage:

✅ Verification successful

Template literal properties are used consistently and safely

Based on the search results, all three template literal properties are used consistently throughout the codebase:

  1. balance-query-${string}:

    • Defined in type system with number value
    • Used in Balance.tsx, Account.tsx, and Reconcile.tsx components
    • Always used with proper typing and query context
    • Includes variants like -cleared and -uncleared suffixes
  2. selected-transactions-${string}:

    • Defined with Array<{ id: string }> type
    • Used in Balance.tsx for tracking selected transaction rows
    • Properly typed when used with useSheetValue
  3. selected-balance-${string}:

    • Defined with number type
    • Used in Balance.tsx for sum calculations
    • Properly constructed from selected items

The usage patterns show:

  • No type conflicts or mismatches
  • Consistent value types matching the type definitions
  • Clear naming patterns and purpose for each key
  • No null/undefined handling issues as the types are properly constrained
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Searches for code references of the new template-literal properties

rg -A 3 "balance-query-"
rg -A 3 "selected-transactions-"
rg -A 3 "selected-balance-"

Length of output: 6387

packages/desktop-client/src/components/accounts/Balance.tsx (19)

8-8: Import usage validated.

The additional import from loot-core/src/shared/query looks good for typed usage in the code below.


10-10: AccountEntity import enhancement.

Importing AccountEntity for typed props will help ensure better type safety across the code.


19-19: Binding type import recognized.

Using Binding from ../spreadsheet aligns well with the new typed spreadsheet structure.


24-28: Typed props for DetailedBalance.

Defining DetailedBalanceProps provides clarity on which parameters are required, improving code readability and maintainability.


30-34: DetailedBalance function signature updated.

Using a typed props object rather than positional arguments enhances readability. The default value for isExactBalance is cleanly expressed.


57-60: SelectedBalanceProps type introduction.

Including typed property definitions for selectedItems and account clarifies usage and ensures stricter checking at compile time.


62-70: SelectedBalance function with typed props.

Defining component props with SelectedBalanceProps helps ensure consistency in how selectedItems and account are handled.


76-76: Safe usage of (rows || []).map(...).

The fallback to [] when rows is falsy prevents runtime issues. This is a good defensive pattern.


87-87: Initialize scheduleBalance with 0.

This default initialization is a clear and safe approach to avoid potential NaN or undefined behavior.


115-118: Conditional check for zero or undefined balances.

The logic gracefully returns null for no relevant balance, and otherwise combines the values. This ensures the component doesn't render unnecessary markup.


130-132: FilteredBalanceProps structured well.

Marking filteredAmount as optional and potentially null is appropriate for scenarios where the value might be absent or unknown.


134-140: FilteredBalance function.

Displaying a fallback of 0 when filteredAmount is not available is consistent with the approach used elsewhere and aligns with user expectations.


146-148: MoreBalancesProps typed for clearer usage.

Specifying the shape of balanceQuery clarifies how the query is consumed, reducing type ambiguity.


150-169: MoreBalances function clarifies cleared vs. uncleared queries.

Explicit calls to useSheetValue with template-literal string keys help ensure data alignment. The usage of separate cleared and uncleared queries is clean and handled well.


174-181: BalancesProps.

The new type for the Balances component properties ensures that each prop is well-documented, improving code maintainability.


190-190: Enhanced Balances function signature.

Using BalancesProps ensures consistent usage of balanceQuery, showExtraBalances, and other related props.


214-222: CellValue usage with typed binding.

Casting ...balanceQuery, value: 0 to Binding<'balance','balance-query-${string}-cleared'> is consistent with the template-literal property definition in Spreadsheets, ensuring strong type checking.


67-68: Verify usage for 'selected-transactions-${string}' binding.

Ensure that the name parameter (name as 'selected-transactions-${string}') is passed only where the template-literal structure is indeed correct and consistent with your data model.

Below is a script to confirm correct usage:

✅ Verification successful

Template literal type is correctly used and matches the data model

The verification shows that the template literal type selected-transactions-${string} is correctly defined in the data model (packages/desktop-client/src/components/spreadsheet/index.ts) and consistently used in the Balance component. The type is properly defined as a key in an interface where it maps to an array of objects with an id property, and its usage in Balance.tsx aligns with this type definition.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching for all references to selected-transactions
rg -A 3 "selected-transactions-"

Length of output: 920


79-80: Verify usage for 'selected-balance-${string}' binding.

Like the previous binding, confirm that the name parameter reflects all relevant usage patterns.

✅ Verification successful

The selected-balance-${string} binding is used consistently and correctly

The verification shows that the binding is used appropriately across the codebase:

  • It's properly typed in spreadsheet/index.ts as a key in an interface
  • In Balance.tsx, it's used in two related contexts:
    1. Base name construction: selected-balance-${[...selectedItems].join('-')}
    2. Sum variant: ${name}-sum which extends from the base name

The naming pattern is consistent and follows the expected usage pattern, with proper type assertions in place.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Searching for references to 'selected-balance-'
rg -A 3 "selected-balance-"

Length of output: 1308

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

57-57: Marking account as optional broadens applicability.

Allowing account to be potentially undefined makes the component more versatile, but ensure consumer components handle the absence of an account object in all usage scenarios.


446-448: Conditional invocation of canCalculateBalance

Nicely prevents runtime errors by verifying canCalculateBalance before calling. Confirm that fallbacks like the boolean literal false are correct for all usage contexts.


556-556: Aligning optional account in AccountNameFieldProps

Consistent with the changes above, marking account as optional allows for flexible usage. Assure that the component handles undefined account gracefully, especially in UI display logic.

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

386-386: Initialize focusId to null

This makes the variable’s default state explicit and avoids potential undefined references. Good practice.


538-538: Safe fallback for transactionCount

Using the nullish coalescing (??) ensures a value of 0 when paged?.totalCount is undefined, preventing runtime issues.


714-714: Use of this.props.accountId ?? ''

Using the nullish coalescing operator clarifies that accountId might be undefined, and provides a safe fallback string. Confirm all consumers properly handle the empty string as an ID.


723-723: Explicit casting of updated account

Casting to AccountEntity is acceptable if the type is guaranteed. Ideally, ensure that account is validated before the spread operator to solidify type safety.


921-923: Refined onReconcile to accept null

Permitting null supports skipping or clearing the existing reconcile amount. Ensure that all reconciliation call sites handle null values consistently, and that subsequent logic is not inadvertently triggered.


1302-1304: Setting filter operation states

Updating filterId.status to 'changed' clarifies the filter's new state. Make sure there's an accompanying flow that resets or finalizes status once changes are handled.


1311-1311: Reloading saved filters

Line 1311 introduces onReloadSavedFilter; line 1323 applies the new filter conditions. Check that calling this.applyFilters([...]) twice (once for “reload” and again for fallback) does not cause confusion or redundant re-renders.

Also applies to: 1323-1323


1351-1351: Marking filterId status as 'changed'

Reinforces the state-based approach to tracking filter modifications.


1368-1368: Consistent change tracking

Same pattern here, ensuring consistency in how filter states transition when filters are deleted.


1663-1667: isNameEditable logic

Explicitly excludes certain pseudo-IDs (onbudget, offbudget, uncategorized) from name editing. Looks correct, but re-check if future special-case IDs might need consideration.


1690-1690: Providing default for editingName

Ensures that a boolean is always passed to the child component.


1691-1691: Providing default for isNameEditable

Guarantees the prop is always defined, removing potential undefined checks.


1692-1692: Providing default for workingHard

Safeguards internal logic from missing or undefined states when dealing with spinner or loading states.


1701-1705: Optional booleans for display controls

Making these boolean props explicitly default to false clarifies the UI contract—no confusion between undefined vs. “off.”


1707-1707: Gracefully handling canCalculateBalance

Uses ?? undefined to avoid function calls if this.canCalculateBalance is falsy. This is consistent with optional usage across the codebase.


1709-1709: isFiltered default

A false fallback helps unify the prop's usage throughout the component tree, removing ambiguity once again.

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

🧹 Nitpick comments (3)
packages/desktop-client/src/components/accounts/Balance.tsx (2)

115-119: Simplify balance calculation logic

The balance calculation can be simplified using nullish coalescing.

-  if (!balance && !scheduleBalance) {
-    return null;
-  } else {
-    balance = (balance ?? 0) + scheduleBalance;
-  }
+  if (!balance && !scheduleBalance) return null;
+  balance = (balance ?? 0) + scheduleBalance;

214-222: Consider improving type safety of binding

The type assertion could be replaced with a more type-safe approach using proper generic constraints.

-          binding={
-            { ...balanceQuery, value: 0 } as Binding<
-              'balance',
-              `balance-query-${string}`
-            >
-          }
+          binding={
+            { ...balanceQuery, value: 0 } satisfies Binding<
+              'balance',
+              `balance-query-${string}`
+            >
+          }
packages/desktop-client/src/components/accounts/Header.tsx (1)

446-448: Simplify canShowBalances logic

The conditional logic can be simplified using optional chaining.

-                  canShowBalances={
-                    canCalculateBalance ? canCalculateBalance() : false
-                  }
+                  canShowBalances={canCalculateBalance?.() ?? false}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57ab2a2 and b904981.

📒 Files selected for processing (2)
  • packages/desktop-client/src/components/accounts/Balance.tsx (6 hunks)
  • packages/desktop-client/src/components/accounts/Header.tsx (6 hunks)
🔇 Additional comments (3)
packages/desktop-client/src/components/accounts/Balance.tsx (2)

24-28: Well-structured type definitions!

The type definitions are clear, properly typed, and follow TypeScript best practices. The optional properties are correctly marked, and the generic types are used appropriately for query-related props.

Also applies to: 57-60, 130-132, 146-148, 174-181


Line range hint 30-56: Clean and type-safe implementation!

The DetailedBalance component is well-implemented with proper type safety and good UX considerations for approximate values.

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

Line range hint 556-563: Well-structured props interface!

The AccountNameField props are well-defined with proper optional properties and clear naming conventions.

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.

1 participant