@@ -4,6 +4,7 @@ import React, {
4
4
useMemo ,
5
5
useRef ,
6
6
useState ,
7
+ type CSSProperties ,
7
8
} from 'react' ;
8
9
import { ListBox , Section , Header , Collection } from 'react-aria-components' ;
9
10
import { useTranslation } from 'react-i18next' ;
@@ -12,6 +13,7 @@ import { setNotificationInset } from 'loot-core/client/actions';
12
13
import { groupById , integerToCurrency } from 'loot-core/shared/util' ;
13
14
import * as monthUtils from 'loot-core/src/shared/months' ;
14
15
import { isPreviewId } from 'loot-core/src/shared/transactions' ;
16
+ import { type TransactionEntity } from 'loot-core/types/models/transaction' ;
15
17
16
18
import { useAccounts } from '../../../hooks/useAccounts' ;
17
19
import { useCategories } from '../../../hooks/useCategories' ;
@@ -29,7 +31,7 @@ import { SvgDotsHorizontalTriple } from '../../../icons/v1';
29
31
import { useDispatch } from '../../../redux' ;
30
32
import { styles , theme } from '../../../style' ;
31
33
import { Button } from '../../common/Button2' ;
32
- import { Menu } from '../../common/Menu' ;
34
+ import { Menu , type MenuItemObject } from '../../common/Menu' ;
33
35
import { Popover } from '../../common/Popover' ;
34
36
import { Text } from '../../common/Text' ;
35
37
import { View } from '../../common/View' ;
@@ -40,7 +42,12 @@ import { TransactionListItem } from './TransactionListItem';
40
42
41
43
const NOTIFICATION_BOTTOM_INSET = 75 ;
42
44
43
- function Loading ( { style, 'aria-label' : ariaLabel } ) {
45
+ type LoadingProps = {
46
+ style ?: CSSProperties ;
47
+ 'aria-label' : string ;
48
+ } ;
49
+
50
+ function Loading ( { style, 'aria-label' : ariaLabel } : LoadingProps ) {
44
51
return (
45
52
< View
46
53
aria-label = { ariaLabel || 'Loading...' }
@@ -57,17 +64,29 @@ function Loading({ style, 'aria-label': ariaLabel }) {
57
64
) ;
58
65
}
59
66
67
+ type TransactionListProps = {
68
+ isLoading : boolean ;
69
+ transactions : readonly TransactionEntity [ ] ;
70
+ onOpenTransaction ?: ( transaction : TransactionEntity ) => void ;
71
+ isLoadingMore : boolean ;
72
+ onLoadMore : ( ) => void ;
73
+ } ;
74
+
60
75
export function TransactionList ( {
61
76
isLoading,
62
77
transactions,
63
78
onOpenTransaction,
64
79
isLoadingMore,
65
80
onLoadMore,
66
- } ) {
81
+ } : TransactionListProps ) {
67
82
const { t } = useTranslation ( ) ;
68
83
const sections = useMemo ( ( ) => {
69
84
// Group by date. We can assume transactions is ordered
70
- const sections = [ ] ;
85
+ const sections : {
86
+ id : string ;
87
+ date : TransactionEntity [ 'date' ] ;
88
+ transactions : TransactionEntity [ ] ;
89
+ } [ ] = [ ] ;
71
90
transactions . forEach ( transaction => {
72
91
if (
73
92
sections . length === 0 ||
@@ -88,13 +107,16 @@ export function TransactionList({
88
107
const dispatchSelected = useSelectedDispatch ( ) ;
89
108
const selectedTransactions = useSelectedItems ( ) ;
90
109
91
- const onTransactionPress = useCallback (
110
+ const onTransactionPress : (
111
+ transaction : TransactionEntity ,
112
+ isLongPress ?: boolean ,
113
+ ) => void = useCallback (
92
114
( transaction , isLongPress = false ) => {
93
115
const isPreview = isPreviewId ( transaction . id ) ;
94
116
if ( ! isPreview && ( isLongPress || selectedTransactions . size > 0 ) ) {
95
117
dispatchSelected ( { type : 'select' , id : transaction . id } ) ;
96
118
} else {
97
- onOpenTransaction ( transaction ) ;
119
+ onOpenTransaction ?. ( transaction ) ;
98
120
}
99
121
} ,
100
122
[ dispatchSelected , onOpenTransaction , selectedTransactions ] ,
@@ -185,13 +207,21 @@ export function TransactionList({
185
207
) ;
186
208
}
187
209
188
- function SelectedTransactionsFloatingActionBar ( { transactions, style } ) {
210
+ type SelectedTransactionsFloatingActionBarProps = {
211
+ transactions : readonly TransactionEntity [ ] ;
212
+ style ?: CSSProperties ;
213
+ } ;
214
+
215
+ function SelectedTransactionsFloatingActionBar ( {
216
+ transactions,
217
+ style = { } ,
218
+ } : SelectedTransactionsFloatingActionBarProps ) {
189
219
const editMenuTriggerRef = useRef ( null ) ;
190
220
const [ isEditMenuOpen , setIsEditMenuOpen ] = useState ( false ) ;
191
221
const moreOptionsMenuTriggerRef = useRef ( null ) ;
192
222
const [ isMoreOptionsMenuOpen , setIsMoreOptionsMenuOpen ] = useState ( false ) ;
193
223
const getMenuItemStyle = useCallback (
194
- item => ( {
224
+ < T extends string > ( item : MenuItemObject < T > ) => ( {
195
225
...styles . mobileMenuItem ,
196
226
color : theme . mobileHeaderText ,
197
227
...( item . name === 'delete' && { color : theme . errorTextMenu } ) ,
@@ -326,16 +356,20 @@ function SelectedTransactionsFloatingActionBar({ transactions, style }) {
326
356
let displayValue = value ;
327
357
switch ( name ) {
328
358
case 'account' :
329
- displayValue = accountsById [ value ] ?. name ?? value ;
359
+ displayValue =
360
+ accountsById [ String ( value ) ] ?. name ?? value ;
330
361
break ;
331
362
case 'category' :
332
- displayValue = categoriesById [ value ] ?. name ?? value ;
363
+ displayValue =
364
+ categoriesById [ String ( value ) ] ?. name ?? value ;
333
365
break ;
334
366
case 'payee' :
335
- displayValue = payeesById [ value ] ?. name ?? value ;
367
+ displayValue = payeesById [ String ( value ) ] ?. name ?? value ;
336
368
break ;
337
369
case 'amount' :
338
- displayValue = integerToCurrency ( value ) ;
370
+ displayValue = Number . isNaN ( Number ( value ) )
371
+ ? value
372
+ : integerToCurrency ( Number ( value ) ) ;
339
373
break ;
340
374
case 'notes' :
341
375
displayValue = `${ mode } with ${ value } ` ;
0 commit comments