diff --git a/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.js b/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx similarity index 95% rename from packages/desktop-client/src/components/autocomplete/AccountAutocomplete.js rename to packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx index b1e0c50ae0c..dbd7f67e7ef 100644 --- a/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.js +++ b/packages/desktop-client/src/components/autocomplete/AccountAutocomplete.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { type ComponentProps } from 'react'; import { css } from 'glamor'; @@ -108,13 +108,20 @@ function AccountList({ ); } +type AutoCompleteProps = { + embedded?: boolean; + includeClosedAccounts: boolean; + groupHeaderStyle?: boolean; + closeOnBlur?: boolean; +} & ComponentProps; + export default function AccountAutocomplete({ embedded, includeClosedAccounts = true, groupHeaderStyle, closeOnBlur, ...props -}) { +}: AutoCompleteProps) { let accounts = useCachedAccounts() || []; //remove closed accounts if needed diff --git a/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx b/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx index 32ec5f2d78c..16491a6fd2c 100644 --- a/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx +++ b/packages/desktop-client/src/components/autocomplete/Autocomplete.tsx @@ -147,7 +147,9 @@ type SingleAutocompleteProps = { embedded?: boolean; containerProps?: HTMLProps; labelProps?: { id?: string }; - inputProps?: ComponentProps; + inputProps?: Omit, 'onChange'> & { + onChange?: (value: string) => void; + }; suggestions?: unknown[]; tooltipStyle?: CSSProperties; tooltipProps?: ComponentProps; @@ -158,7 +160,7 @@ type SingleAutocompleteProps = { idx: number, value?: unknown, ) => ReactNode; - itemToString?: (item: unknown) => string; + itemToString?: (item) => string; shouldSaveFromKey?: (e: KeyboardEvent) => boolean; filterSuggestions?: (suggestions, value: string) => unknown[]; openOnFocus?: boolean; @@ -169,7 +171,7 @@ type SingleAutocompleteProps = { onSelect: (id: unknown, value: string) => void; tableBehavior?: boolean; closeOnBlur?: boolean; - value: unknown[]; + value: unknown[] | string; isMulti?: boolean; }; function SingleAutocomplete({ @@ -482,7 +484,6 @@ function SingleAutocomplete({ }, onChange: (e: ChangeEvent) => { const { onChange } = inputProps || {}; - // @ts-expect-error unsure if onChange needs an event or a string onChange?.(e.target.value); }, }), @@ -679,13 +680,31 @@ export function AutocompleteFooter({ ); } -type AutocompleteProps = ComponentProps & { - multi?: boolean; -}; -export default function Autocomplete({ multi, ...props }: AutocompleteProps) { - if (multi) { +type AutocompleteProps = + | ComponentProps + | ComponentProps; + +function isMultiAutocomplete( + props: AutocompleteProps, + multi?: boolean, +): props is ComponentProps { + return multi; +} + +function isSingleAutocomplete( + props: AutocompleteProps, + multi?: boolean, +): props is ComponentProps { + return !multi; +} + +export default function Autocomplete({ + multi, + ...props +}: AutocompleteProps & { multi?: boolean }) { + if (isMultiAutocomplete(props, multi)) { return ; - } else { + } else if (isSingleAutocomplete(props, multi)) { return ; } } diff --git a/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx b/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx index af3ec707491..bd3d6289635 100644 --- a/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx +++ b/packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx @@ -3,6 +3,7 @@ import React, { Fragment, useMemo, type ReactNode, + type CSSProperties, } from 'react'; import { css } from 'glamor'; @@ -166,9 +167,10 @@ function CategoryList({ type CategoryAutocompleteProps = ComponentProps & { categoryGroups: Array; showSplitOption?: boolean; - groupHeaderStyle?: object; + groupHeaderStyle?: CSSProperties; showHiddenItems?: boolean; }; + export default function CategoryAutocomplete({ categoryGroups, showSplitOption, diff --git a/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.js b/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx similarity index 93% rename from packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.js rename to packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx index 050c07cc916..a1ff9db9985 100644 --- a/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.js +++ b/packages/desktop-client/src/components/autocomplete/PayeeAutocomplete.tsx @@ -1,4 +1,10 @@ -import React, { Fragment, useState, useMemo } from 'react'; +import React, { + Fragment, + useState, + useMemo, + type ComponentProps, + type CSSProperties, +} from 'react'; import { useDispatch } from 'react-redux'; import { css } from 'glamor'; @@ -7,6 +13,10 @@ import { createPayee } from 'loot-core/src/client/actions/queries'; import { useCachedAccounts } from 'loot-core/src/client/data-hooks/accounts'; import { useCachedPayees } from 'loot-core/src/client/data-hooks/payees'; import { getActivePayees } from 'loot-core/src/client/reducers/queries'; +import { + type AccountEntity, + type PayeeEntity, +} from 'loot-core/src/types/models'; import Add from '../../icons/v1/Add'; import { useResponsive } from '../../ResponsiveProvider'; @@ -202,6 +212,22 @@ function PayeeList({ ); } +type PayeeAutocompleteProps = { + value: ComponentProps['value']; + inputProps: ComponentProps['inputProps']; + showMakeTransfer?: boolean; + showManagePayees?: boolean; + tableBehavior: ComponentProps['tableBehavior']; + embedded?: boolean; + closeOnBlur: ComponentProps['closeOnBlur']; + onUpdate?: (value: string) => void; + onSelect?: (value: string) => void; + onManagePayees: () => void; + groupHeaderStyle: CSSProperties; + accounts?: AccountEntity[]; + payees?: PayeeEntity[]; +}; + export default function PayeeAutocomplete({ value, inputProps, @@ -217,7 +243,7 @@ export default function PayeeAutocomplete({ accounts, payees, ...props -}) { +}: PayeeAutocompleteProps) { let cachedPayees = useCachedPayees(); if (!payees) { payees = cachedPayees; diff --git a/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.js b/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx similarity index 73% rename from packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.js rename to packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx index 2ba4b1fb393..71646b65f5a 100644 --- a/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.js +++ b/packages/desktop-client/src/components/autocomplete/SavedFilterAutocomplete.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { type ComponentProps } from 'react'; import { useFilters } from 'loot-core/src/client/data-hooks/filters'; @@ -7,7 +7,19 @@ import View from '../common/View'; import Autocomplete from './Autocomplete'; -function FilterList({ items, getItemProps, highlightedIndex, embedded }) { +type FilterListProps = { + items: { id: string; name: string }[]; + getItemProps: (arg: { item: unknown }) => ComponentProps; + highlightedIndex: number; + embedded?: boolean; +}; + +function FilterList({ + items, + getItemProps, + highlightedIndex, + embedded, +}: FilterListProps) { return ( ; + +export default function SavedFilterAutocomplete({ + embedded, + ...props +}: SavedFilterAutocompleteProps) { let filters = useFilters() || []; return ( diff --git a/packages/desktop-client/src/components/common/Button.tsx b/packages/desktop-client/src/components/common/Button.tsx index e568196b4dd..a421059aed9 100644 --- a/packages/desktop-client/src/components/common/Button.tsx +++ b/packages/desktop-client/src/components/common/Button.tsx @@ -22,7 +22,13 @@ type ButtonProps = HTMLProps & { as?: ElementType; }; -type ButtonType = 'normal' | 'primary' | 'bare' | 'link'; +type ButtonType = + | 'normal' + | 'primary' + | 'bare' + | 'link' + | 'menu' + | 'menuSelected'; const backgroundColor = { normal: theme.buttonNormalBackground, diff --git a/packages/desktop-client/src/components/modals/CloseAccount.js b/packages/desktop-client/src/components/modals/CloseAccount.tsx similarity index 91% rename from packages/desktop-client/src/components/modals/CloseAccount.js rename to packages/desktop-client/src/components/modals/CloseAccount.tsx index ea8e35ab973..48f63a61ff7 100644 --- a/packages/desktop-client/src/components/modals/CloseAccount.js +++ b/packages/desktop-client/src/components/modals/CloseAccount.tsx @@ -1,8 +1,14 @@ import React, { useState } from 'react'; import { integerToCurrency } from 'loot-core/src/shared/util'; +import { + type AccountEntity, + type CategoryGroupEntity, +} from 'loot-core/src/types/models'; +import { type BoundActions } from '../../hooks/useActions'; import { theme } from '../../style'; +import { type CommonModalProps } from '../../types/modals'; import AccountAutocomplete from '../autocomplete/AccountAutocomplete'; import CategoryAutocomplete from '../autocomplete/CategoryAutocomplete'; import Button from '../common/Button'; @@ -13,7 +19,11 @@ import Paragraph from '../common/Paragraph'; import Text from '../common/Text'; import View from '../common/View'; -function needsCategory(account, currentTransfer, accounts) { +function needsCategory( + account: AccountEntity, + currentTransfer: string, + accounts: AccountEntity[], +) { const acct = accounts.find(a => a.id === currentTransfer); const isOffBudget = acct && acct.offbudget === 1; @@ -22,6 +32,16 @@ function needsCategory(account, currentTransfer, accounts) { return account.offbudget === 0 && isOffBudget; } +type CloseAccountProps = { + account: AccountEntity; + accounts: AccountEntity[]; + categoryGroups: CategoryGroupEntity[]; + balance: number; + canDelete: boolean; + actions: BoundActions; + modalProps: CommonModalProps; +}; + function CloseAccount({ account, accounts, @@ -30,7 +50,7 @@ function CloseAccount({ canDelete, actions, modalProps, -}) { +}: CloseAccountProps) { let [loading, setLoading] = useState(false); let [transfer, setTransfer] = useState(''); let [category, setCategory] = useState(''); @@ -95,7 +115,6 @@ function CloseAccount({ { await send('account-close', { id: accountId, diff --git a/upcoming-release-notes/1923.md b/upcoming-release-notes/1923.md new file mode 100644 index 00000000000..1f31105245a --- /dev/null +++ b/upcoming-release-notes/1923.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [MikesGlitch] +--- + +Convert CloseAccount, AccountAutocomplete, SavedFilterAutocomplete, PayeeAutocomplete components to Typescript.