Skip to content

Commit

Permalink
Support type-checking on spreadsheet fields (part 2) (#3095)
Browse files Browse the repository at this point in the history
* Add rollover budget typing

* Fix lint

* Add release notes

* Fix strict typechecking
  • Loading branch information
jfdoming authored Aug 7, 2024
1 parent a2e434a commit 6532939
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import React, { type ComponentPropsWithoutRef } from 'react';
import { rolloverBudget } from 'loot-core/src/client/queries';

import { Menu } from '../../common/Menu';
import { useSheetValue } from '../../spreadsheet/useSheetValue';

import { useRolloverSheetValue } from './RolloverComponents';

type BalanceMenuProps = Omit<
ComponentPropsWithoutRef<typeof Menu>,
Expand All @@ -22,8 +23,10 @@ export function BalanceMenu({
onCover,
...props
}: BalanceMenuProps) {
const carryover = useSheetValue(rolloverBudget.catCarryover(categoryId));
const balance = useSheetValue(rolloverBudget.catBalance(categoryId));
const carryover = useRolloverSheetValue(
rolloverBudget.catCarryover(categoryId),
);
const balance = useRolloverSheetValue(rolloverBudget.catBalance(categoryId));
return (
<Menu
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import React, { useState } from 'react';

import { rolloverBudget } from 'loot-core/src/client/queries';

import { useSheetValue } from '../../spreadsheet/useSheetValue';

import { BalanceMenu } from './BalanceMenu';
import { CoverMenu } from './CoverMenu';
import { useRolloverSheetValue } from './RolloverComponents';
import { TransferMenu } from './TransferMenu';

type BalanceMovementMenuProps = {
Expand All @@ -21,7 +20,9 @@ export function BalanceMovementMenu({
onBudgetAction,
onClose = () => {},
}: BalanceMovementMenuProps) {
const catBalance = useSheetValue(rolloverBudget.catBalance(categoryId));
const catBalance = useRolloverSheetValue(
rolloverBudget.catBalance(categoryId),
);
const [menu, setMenu] = useState('menu');

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,44 @@ import { Button } from '../../common/Button2';
import { Popover } from '../../common/Popover';
import { Text } from '../../common/Text';
import { View } from '../../common/View';
import { CellValue } from '../../spreadsheet/CellValue';
import { type Binding, type SheetFields } from '../../spreadsheet';
import { CellValue, type CellValueProps } from '../../spreadsheet/CellValue';
import { useFormat } from '../../spreadsheet/useFormat';
import { Row, Field, SheetCell } from '../../table';
import { useSheetName } from '../../spreadsheet/useSheetName';
import { useSheetValue } from '../../spreadsheet/useSheetValue';
import { Row, Field, SheetCell, type SheetCellProps } from '../../table';
import { BalanceWithCarryover } from '../BalanceWithCarryover';
import { makeAmountGrey } from '../util';

import { BalanceMovementMenu } from './BalanceMovementMenu';
import { BudgetMenu } from './BudgetMenu';

export function useRolloverSheetName<
FieldName extends SheetFields<'rollover-budget'>,
>(binding: Binding<'rollover-budget', FieldName>) {
return useSheetName(binding);
}

export function useRolloverSheetValue<
FieldName extends SheetFields<'rollover-budget'>,
>(binding: Binding<'rollover-budget', FieldName>) {
return useSheetValue(binding);
}

export const RolloverCellValue = <
FieldName extends SheetFields<'rollover-budget'>,
>(
props: CellValueProps<'rollover-budget', FieldName>,
) => {
return <CellValue {...props} />;
};

const RolloverSheetCell = <FieldName extends SheetFields<'rollover-budget'>>(
props: SheetCellProps<'rollover-budget', FieldName>,
) => {
return <SheetCell {...props} />;
};

const headerLabelStyle: CSSProperties = {
flex: 1,
padding: '0 5px',
Expand All @@ -40,7 +69,7 @@ export const BudgetTotalsMonth = memo(function BudgetTotalsMonth() {
>
<View style={headerLabelStyle}>
<Text style={{ color: theme.tableHeaderText }}>Budgeted</Text>
<CellValue
<RolloverCellValue
binding={rolloverBudget.totalBudgeted}
type="financial"
style={{ color: theme.tableHeaderText, fontWeight: 600 }}
Expand All @@ -51,15 +80,15 @@ export const BudgetTotalsMonth = memo(function BudgetTotalsMonth() {
</View>
<View style={headerLabelStyle}>
<Text style={{ color: theme.tableHeaderText }}>Spent</Text>
<CellValue
<RolloverCellValue
binding={rolloverBudget.totalSpent}
type="financial"
style={{ color: theme.tableHeaderText, fontWeight: 600 }}
/>
</View>
<View style={headerLabelStyle}>
<Text style={{ color: theme.tableHeaderText }}>Balance</Text>
<CellValue
<RolloverCellValue
binding={rolloverBudget.totalBalance}
type="financial"
style={{ color: theme.tableHeaderText, fontWeight: 600 }}
Expand Down Expand Up @@ -93,7 +122,7 @@ export const ExpenseGroupMonth = memo(function ExpenseGroupMonth({

return (
<View style={{ flex: 1, flexDirection: 'row' }}>
<SheetCell
<RolloverSheetCell
name="budgeted"
width="flex"
textAlign="right"
Expand All @@ -103,7 +132,7 @@ export const ExpenseGroupMonth = memo(function ExpenseGroupMonth({
type: 'financial',
}}
/>
<SheetCell
<RolloverSheetCell
name="spent"
width="flex"
textAlign="right"
Expand All @@ -113,7 +142,7 @@ export const ExpenseGroupMonth = memo(function ExpenseGroupMonth({
type: 'financial',
}}
/>
<SheetCell
<RolloverSheetCell
name="balance"
width="flex"
textAlign="right"
Expand Down Expand Up @@ -249,7 +278,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
</Popover>
</View>
) : null}
<SheetCell
<RolloverSheetCell
name="budget"
exposed={editing}
focused={editing}
Expand Down Expand Up @@ -299,7 +328,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
data-testid="category-month-spent"
onClick={() => onShowActivity(category.id, month)}
>
<CellValue
<RolloverCellValue
binding={rolloverBudget.catSumAmount(category.id)}
type="financial"
getStyle={makeAmountGrey}
Expand Down Expand Up @@ -353,7 +382,7 @@ export const ExpenseCategoryMonth = memo(function ExpenseCategoryMonth({
export function IncomeGroupMonth() {
return (
<View style={{ flex: 1 }}>
<SheetCell
<RolloverSheetCell
name="received"
width="flex"
textAlign="right"
Expand Down Expand Up @@ -400,7 +429,7 @@ export function IncomeCategoryMonth({
}}
>
<span onClick={() => onShowActivity(category.id, month)}>
<CellValue
<RolloverCellValue
binding={rolloverBudget.catSumAmount(category.id)}
type="financial"
style={{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { rolloverBudget } from 'loot-core/src/client/queries';
import { type CSSProperties } from '../../../../style';
import { Popover } from '../../../common/Popover';
import { View } from '../../../common/View';
import { useSheetValue } from '../../../spreadsheet/useSheetValue';
import { CoverMenu } from '../CoverMenu';
import { HoldMenu } from '../HoldMenu';
import { useRolloverSheetValue } from '../RolloverComponents';
import { TransferMenu } from '../TransferMenu';

import { ToBudgetAmount } from './ToBudgetAmount';
Expand All @@ -31,11 +31,16 @@ export function ToBudget({
}: ToBudgetProps) {
const [menuOpen, setMenuOpen] = useState<string | null>(null);
const triggerRef = useRef(null);
const sheetValue = useSheetValue({
const sheetValue = useRolloverSheetValue({
name: rolloverBudget.toBudget,
value: 0,
});
const availableValue = parseInt(sheetValue);
const availableValue = sheetValue;
if (typeof availableValue !== 'number') {
throw new Error(
'Expected availableValue to be a number but got ' + availableValue,
);
}
const isMenuOpen = Boolean(menuOpen);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { Tooltip } from '../../../common/Tooltip';
import { View } from '../../../common/View';
import { PrivacyFilter } from '../../../PrivacyFilter';
import { useFormat } from '../../../spreadsheet/useFormat';
import { useSheetName } from '../../../spreadsheet/useSheetName';
import { useSheetValue } from '../../../spreadsheet/useSheetValue';
import {
useRolloverSheetName,
useRolloverSheetValue,
} from '../RolloverComponents';

import { TotalsList } from './TotalsList';

Expand All @@ -30,13 +32,18 @@ export function ToBudgetAmount({
onClick,
isTotalsListTooltipDisabled = false,
}: ToBudgetAmountProps) {
const sheetName = useSheetName(rolloverBudget.toBudget);
const sheetValue = useSheetValue({
const sheetName = useRolloverSheetName(rolloverBudget.toBudget);
const sheetValue = useRolloverSheetValue({
name: rolloverBudget.toBudget,
value: 0,
});
const format = useFormat();
const availableValue = parseInt(sheetValue);
const availableValue = sheetValue;
if (typeof availableValue !== 'number') {
throw new Error(
'Expected availableValue to be a number but got ' + availableValue,
);
}
const num = isNaN(availableValue) ? 0 : availableValue;
const isNegative = num < 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { type ComponentPropsWithoutRef } from 'react';
import { rolloverBudget } from 'loot-core/client/queries';

import { Menu } from '../../../common/Menu';
import { useSheetValue } from '../../../spreadsheet/useSheetValue';
import { useRolloverSheetValue } from '../RolloverComponents';

type ToBudgetMenuProps = Omit<
ComponentPropsWithoutRef<typeof Menu>,
Expand All @@ -21,8 +21,8 @@ export function ToBudgetMenu({
onResetHoldBuffer,
...props
}: ToBudgetMenuProps) {
const toBudget = useSheetValue(rolloverBudget.toBudget);
const forNextMonth = useSheetValue(rolloverBudget.forNextMonth);
const toBudget = useRolloverSheetValue(rolloverBudget.toBudget);
const forNextMonth = useRolloverSheetValue(rolloverBudget.forNextMonth);
const items = [
...(toBudget > 0
? [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { AlignedText } from '../../../common/AlignedText';
import { Block } from '../../../common/Block';
import { Tooltip } from '../../../common/Tooltip';
import { View } from '../../../common/View';
import { CellValue } from '../../../spreadsheet/CellValue';
import { useFormat } from '../../../spreadsheet/useFormat';
import { RolloverCellValue } from '../RolloverComponents';

type TotalsListProps = {
prevMonthName: string;
Expand Down Expand Up @@ -40,7 +40,7 @@ export function TotalsList({ prevMonthName, style }: TotalsListProps) {
<AlignedText
left="Income:"
right={
<CellValue
<RolloverCellValue
binding={rolloverBudget.totalIncome}
type="financial"
privacyFilter={false}
Expand All @@ -50,7 +50,7 @@ export function TotalsList({ prevMonthName, style }: TotalsListProps) {
<AlignedText
left="From Last Month:"
right={
<CellValue
<RolloverCellValue
binding={rolloverBudget.fromLastMonth}
type="financial"
privacyFilter={false}
Expand All @@ -61,14 +61,14 @@ export function TotalsList({ prevMonthName, style }: TotalsListProps) {
}
placement="bottom end"
>
<CellValue
<RolloverCellValue
binding={rolloverBudget.incomeAvailable}
type="financial"
style={{ fontWeight: 600 }}
/>
</Tooltip>

<CellValue
<RolloverCellValue
binding={rolloverBudget.lastMonthOverspent}
type="financial"
formatter={value => {
Expand All @@ -78,7 +78,7 @@ export function TotalsList({ prevMonthName, style }: TotalsListProps) {
style={{ fontWeight: 600, ...styles.tnum }}
/>

<CellValue
<RolloverCellValue
binding={rolloverBudget.totalBudgeted}
type="financial"
formatter={value => {
Expand All @@ -88,7 +88,7 @@ export function TotalsList({ prevMonthName, style }: TotalsListProps) {
style={{ fontWeight: 600, ...styles.tnum }}
/>

<CellValue
<RolloverCellValue
binding={rolloverBudget.forNextMonth}
type="financial"
formatter={value => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import React, { useState } from 'react';
import { rolloverBudget } from 'loot-core/client/queries';

import { styles } from '../../style';
import { useRolloverSheetValue } from '../budget/rollover/RolloverComponents';
import { Button } from '../common/Button2';
import { InitialFocus } from '../common/InitialFocus';
import { Modal, ModalCloseButton, ModalHeader } from '../common/Modal2';
import { View } from '../common/View';
import { FieldLabel } from '../mobile/MobileForms';
import { useSheetValue } from '../spreadsheet/useSheetValue';
import { AmountInput } from '../util/AmountInput';

type HoldBufferModalProps = {
Expand All @@ -17,7 +17,7 @@ type HoldBufferModalProps = {
};

export function HoldBufferModal({ onSubmit }: HoldBufferModalProps) {
const available = useSheetValue(rolloverBudget.toBudget);
const available = useRolloverSheetValue(rolloverBudget.toBudget);
const [amount, setAmount] = useState<number>(0);

const _onSubmit = (newAmount: number) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { amountToInteger, integerToAmount } from 'loot-core/shared/util';
import { useCategory } from '../../hooks/useCategory';
import { type CSSProperties, theme, styles } from '../../style';
import { BudgetMenu } from '../budget/rollover/BudgetMenu';
import { useRolloverSheetValue } from '../budget/rollover/RolloverComponents';
import {
Modal,
ModalCloseButton,
Expand All @@ -19,7 +20,6 @@ import {
import { Text } from '../common/Text';
import { View } from '../common/View';
import { FocusableAmountInput } from '../mobile/transactions/FocusableAmountInput';
import { useSheetValue } from '../spreadsheet/useSheetValue';

type RolloverBudgetMenuModalProps = ComponentPropsWithoutRef<
typeof BudgetMenu
Expand All @@ -42,7 +42,9 @@ export function RolloverBudgetMenuModal({
borderTop: `1px solid ${theme.pillBorder}`,
};

const budgeted = useSheetValue(rolloverBudget.catBudgeted(categoryId));
const budgeted = useRolloverSheetValue(
rolloverBudget.catBudgeted(categoryId),
);
const category = useCategory(categoryId);
const [amountFocused, setAmountFocused] = useState(false);

Expand Down
Loading

0 comments on commit 6532939

Please sign in to comment.