From bc04a8cbec0a0a5ec8a50abb016e20fe049fbd45 Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins Date: Wed, 4 Sep 2024 20:15:27 +0100 Subject: [PATCH] :recycle: (typescript) migrate reconcile file to TS (#3355) --- .../accounts/{Reconcile.jsx => Reconcile.tsx} | 57 +++++++++++-------- .../src/components/spreadsheet/index.ts | 9 +++ packages/loot-core/src/client/queries.ts | 43 +++++--------- upcoming-release-notes/3355.md | 6 ++ 4 files changed, 63 insertions(+), 52 deletions(-) rename packages/desktop-client/src/components/accounts/{Reconcile.jsx => Reconcile.tsx} (72%) create mode 100644 upcoming-release-notes/3355.md diff --git a/packages/desktop-client/src/components/accounts/Reconcile.jsx b/packages/desktop-client/src/components/accounts/Reconcile.tsx similarity index 72% rename from packages/desktop-client/src/components/accounts/Reconcile.jsx rename to packages/desktop-client/src/components/accounts/Reconcile.tsx index 0a4ac13b16c..77e0dc14592 100644 --- a/packages/desktop-client/src/components/accounts/Reconcile.jsx +++ b/packages/desktop-client/src/components/accounts/Reconcile.tsx @@ -2,7 +2,9 @@ import React, { useState } from 'react'; import { Trans } from 'react-i18next'; import * as queries from 'loot-core/src/client/queries'; +import { type Query } from 'loot-core/src/shared/query'; import { currencyToInteger } from 'loot-core/src/shared/util'; +import { type AccountEntity } from 'loot-core/types/models'; import { SvgCheckCircle1 } from '../../icons/v2'; import { styles, theme } from '../../style'; @@ -14,20 +16,32 @@ import { View } from '../common/View'; import { useFormat } from '../spreadsheet/useFormat'; import { useSheetValue } from '../spreadsheet/useSheetValue'; +type ReconcilingMessageProps = { + balanceQuery: { name: `balance-query-${string}`; query: Query }; + targetBalance: number; + onDone: () => void; + onCreateTransaction: (targetDiff: number) => void; +}; + export function ReconcilingMessage({ balanceQuery, targetBalance, onDone, onCreateTransaction, -}) { - const cleared = useSheetValue({ - name: balanceQuery.name + '-cleared', +}: ReconcilingMessageProps) { + const cleared = useSheetValue<'balance', `balance-query-${string}-cleared`>({ + name: (balanceQuery.name + '-cleared') as `balance-query-${string}-cleared`, value: 0, query: balanceQuery.query.filter({ cleared: true }), }); const format = useFormat(); const targetDiff = targetBalance - cleared; + const clearedBalance = format(cleared, 'financial'); + const bankBalance = format(targetBalance, 'financial'); + const difference = + (targetDiff > 0 ? '+' : '') + format(targetDiff, 'financial'); + return ( - Your cleared balance{' '} - - {{ clearedBalance: format(cleared, 'financial') }} - {' '} - needs{' '} - - {{ - difference: - (targetDiff > 0 ? '+' : '') + - format(targetDiff, 'financial'), - }} - {' '} - to match + Your cleared balance {clearedBalance} needs{' '} + {difference} to match
your bank's balance of{' '} - - {{ bankBalance: format(targetBalance, 'financial') }} - + {bankBalance}
@@ -104,15 +105,25 @@ export function ReconcilingMessage({ ); } -export function ReconcileMenu({ account, onReconcile, onClose }) { +type ReconcileMenuProps = { + account: AccountEntity; + onReconcile: (amount: number | null) => void; + onClose: () => void; +}; + +export function ReconcileMenu({ + account, + onReconcile, + onClose, +}: ReconcileMenuProps) { const balanceQuery = queries.accountBalance(account); - const clearedBalance = useSheetValue({ - name: balanceQuery.name + '-cleared', + const clearedBalance = useSheetValue<'account', `balance-${string}-cleared`>({ + name: (balanceQuery.name + '-cleared') as `balance-${string}-cleared`, value: null, query: balanceQuery.query.filter({ cleared: true }), }); const format = useFormat(); - const [inputValue, setInputValue] = useState(null); + const [inputValue, setInputValue] = useState(null); const [inputFocused, setInputFocused] = useState(false); function onSubmit() { diff --git a/packages/desktop-client/src/components/spreadsheet/index.ts b/packages/desktop-client/src/components/spreadsheet/index.ts index e9ff3d7aa7a..38b6b27afee 100644 --- a/packages/desktop-client/src/components/spreadsheet/index.ts +++ b/packages/desktop-client/src/components/spreadsheet/index.ts @@ -8,6 +8,7 @@ export type Spreadsheets = { // Account fields balance: number; + [key: `balance-${string}-cleared`]: number | null; 'accounts-balance': number; 'budgeted-accounts-balance': number; 'offbudget-accounts-balance': number; @@ -62,6 +63,14 @@ export type Spreadsheets = { goal: number; 'long-goal': number; }; + [`balance`]: { + // Common fields + 'uncategorized-amount': number; + 'uncategorized-balance': number; + + // Balance fields + [key: `balance-query-${string}-cleared`]: number; + }; }; export type SheetNames = keyof Spreadsheets & string; diff --git a/packages/loot-core/src/client/queries.ts b/packages/loot-core/src/client/queries.ts index 807ee0eca21..590e5e9a687 100644 --- a/packages/loot-core/src/client/queries.ts +++ b/packages/loot-core/src/client/queries.ts @@ -115,73 +115,61 @@ export function makeTransactionSearchQuery( }); } -export function accountBalance( - acct: AccountEntity, -): Binding<'account', 'balance'> { +export function accountBalance(acct: AccountEntity) { return { name: accountParametrizedField('balance')(acct.id), query: q('transactions') .filter({ account: acct.id }) .options({ splits: 'none' }) .calculate({ $sum: '$amount' }), - }; + } satisfies Binding<'account', 'balance'>; } -export function accountBalanceCleared( - acct: AccountEntity, -): Binding<'account', 'balanceCleared'> { +export function accountBalanceCleared(acct: AccountEntity) { return { name: accountParametrizedField('balanceCleared')(acct.id), query: q('transactions') .filter({ account: acct.id, cleared: true }) .options({ splits: 'none' }) .calculate({ $sum: '$amount' }), - }; + } satisfies Binding<'account', 'balanceCleared'>; } -export function accountBalanceUncleared( - acct: AccountEntity, -): Binding<'account', 'balanceUncleared'> { +export function accountBalanceUncleared(acct: AccountEntity) { return { name: accountParametrizedField('balanceUncleared')(acct.id), query: q('transactions') .filter({ account: acct.id, cleared: false }) .options({ splits: 'none' }) .calculate({ $sum: '$amount' }), - }; + } satisfies Binding<'account', 'balanceUncleared'>; } -export function allAccountBalance(): Binding<'account', 'accounts-balance'> { +export function allAccountBalance() { return { query: q('transactions') .filter({ 'account.closed': false }) .calculate({ $sum: '$amount' }), name: 'accounts-balance', - }; + } satisfies Binding<'account', 'accounts-balance'>; } -export function budgetedAccountBalance(): Binding< - 'account', - 'budgeted-accounts-balance' -> { +export function budgetedAccountBalance() { return { name: `budgeted-accounts-balance`, query: q('transactions') .filter({ 'account.offbudget': false, 'account.closed': false }) .calculate({ $sum: '$amount' }), - }; + } satisfies Binding<'account', 'budgeted-accounts-balance'>; } -export function offbudgetAccountBalance(): Binding< - 'account', - 'offbudget-accounts-balance' -> { +export function offbudgetAccountBalance() { return { name: `offbudget-accounts-balance`, query: q('transactions') .filter({ 'account.offbudget': true, 'account.closed': false }) .calculate({ $sum: '$amount' }), - }; + } satisfies Binding<'account', 'offbudget-accounts-balance'>; } export function categoryBalance(category: CategoryEntity, month: string) { @@ -249,14 +237,11 @@ export function uncategorizedBalance() { }; } -export function uncategorizedCount(): Binding< - SheetName, - 'uncategorized-amount' -> { +export function uncategorizedCount() { return { name: 'uncategorized-amount', query: uncategorizedQuery.calculate({ $count: '$id' }), - }; + } satisfies Binding; } export const rolloverBudget = { diff --git a/upcoming-release-notes/3355.md b/upcoming-release-notes/3355.md new file mode 100644 index 00000000000..d74e4039f1d --- /dev/null +++ b/upcoming-release-notes/3355.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MatissJanis] +--- + +TypeScript: migrate Reconcile file.