Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/components/BankTransactionMobileList/BusinessForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,13 @@ export const BusinessForm = ({
<div className='Layer__bank-transaction-mobile-list-item__actions'>
{showReceiptUploads && (
<FileInput
onUpload={files => receiptsRef.current?.uploadReceipt(files[0])}
onUpload={(files) => {
const firstFile = files[0]

if (firstFile) {
receiptsRef.current?.uploadReceipt(firstFile)
}
}}
text='Upload receipt'
iconOnly={true}
icon={<PaperclipIcon />}
Expand Down
17 changes: 10 additions & 7 deletions src/components/BankTransactionMobileList/MatchForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,10 @@ export const MatchForm = ({
const { match: matchBankTransaction, isLoading } =
useBankTransactionsContext()

const [selectedMatchId, setSelectedMatchId] = useState<string | undefined>(
isAlreadyMatched(bankTransaction)
?? (bankTransaction.suggested_matches
&& bankTransaction.suggested_matches?.length > 0
? bankTransaction.suggested_matches[0].id
: undefined),
const [selectedMatchId, setSelectedMatchId] = useState<string | undefined>(() =>
isAlreadyMatched(bankTransaction) ?? (bankTransaction.suggested_matches?.[0]?.id),
)

const [formError, setFormError] = useState<string | undefined>()

const showRetry = Boolean(bankTransaction.error)
Expand Down Expand Up @@ -106,7 +103,13 @@ export const MatchForm = ({
<div className='Layer__bank-transaction-mobile-list-item__actions'>
{showReceiptUploads && (
<FileInput
onUpload={files => receiptsRef.current?.uploadReceipt(files[0])}
onUpload={(files) => {
const firstFile = files[0]

if (firstFile) {
receiptsRef.current?.uploadReceipt(firstFile)
}
}}
text='Upload receipt'
iconOnly={true}
icon={<PaperclipIcon />}
Expand Down
8 changes: 7 additions & 1 deletion src/components/BankTransactionMobileList/PersonalForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,13 @@ export const PersonalForm = ({
<div className='Layer__bank-transaction-mobile-list-item__actions'>
{showReceiptUploads && (
<FileInput
onUpload={files => receiptsRef.current?.uploadReceipt(files[0])}
onUpload={(files) => {
const firstFile = files[0]

if (firstFile) {
receiptsRef.current?.uploadReceipt(firstFile)
}
}}
text='Upload receipt'
iconOnly={true}
icon={<PaperclipIcon />}
Expand Down
47 changes: 37 additions & 10 deletions src/components/BankTransactionMobileList/SplitForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,11 @@ export const SplitForm = ({
return sum + amount
}, 0)
const remaining = bankTransaction.amount - splitTotal
newSplits[0].amount = remaining
newSplits[0].inputValue = formatMoney(remaining)

if (newSplits[0]) {
newSplits[0].amount = remaining
newSplits[0].inputValue = formatMoney(remaining)
}

updateRowState({
...rowState,
Expand All @@ -134,25 +137,42 @@ export const SplitForm = ({
return sum + amount
}, 0)
const remaining = bankTransaction.amount - splitTotal
rowState.splits[rowNumber].amount = newAmount
rowState.splits[rowNumber].inputValue = newDisplaying
rowState.splits[0].amount = remaining
rowState.splits[0].inputValue = formatMoney(remaining)

if (rowState.splits[rowNumber]) {
rowState.splits[rowNumber].amount = newAmount
rowState.splits[rowNumber].inputValue = newDisplaying
}
if (rowState.splits[0]) {
rowState.splits[0].amount = remaining
rowState.splits[0].inputValue = formatMoney(remaining)
}
Comment on lines +141 to +148
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: State mutations should be avoided. Consider creating a new state object instead of directly modifying rowState.splits

Suggested change
if (rowState.splits[rowNumber]) {
rowState.splits[rowNumber].amount = newAmount
rowState.splits[rowNumber].inputValue = newDisplaying
}
if (rowState.splits[0]) {
rowState.splits[0].amount = remaining
rowState.splits[0].inputValue = formatMoney(remaining)
}
const newSplits = [...rowState.splits]
if (newSplits[rowNumber]) {
newSplits[rowNumber] = {
...newSplits[rowNumber],
amount: newAmount,
inputValue: newDisplaying
}
}
if (newSplits[0]) {
newSplits[0] = {
...newSplits[0],
amount: remaining,
inputValue: formatMoney(remaining)
}
}


updateRowState({ ...rowState })
setFormError(undefined)
}

const onBlur = (event: React.FocusEvent<HTMLInputElement>) => {
if (event.target.value === '') {
const [_, index] = event.target.name.split('-')
rowState.splits[parseInt(index)].inputValue = '0.00'
if (!index) {
return
}

const parsedIndex = parseInt(index)

if (rowState.splits[parsedIndex]) {
rowState.splits[parsedIndex].inputValue = '0.00'
}

updateRowState({ ...rowState })
setFormError(undefined)
}
}

const changeCategory = (index: number, newValue: CategoryOption) => {
rowState.splits[index].category = newValue
if (rowState.splits[index]) {
rowState.splits[index].category = newValue
}
updateRowState({ ...rowState })
setFormError(undefined)
}
Expand Down Expand Up @@ -204,7 +224,7 @@ export const SplitForm = ({

await categorizeBankTransaction(
bankTransaction.id,
rowState.splits.length === 1 && rowState?.splits[0].category
rowState.splits.length === 1 && rowState?.splits[0]?.category
? ({
type: 'Category',
category: getCategorizePayload(rowState?.splits[0].category),
Expand Down Expand Up @@ -314,7 +334,14 @@ export const SplitForm = ({
<div className='Layer__bank-transaction-mobile-list-item__actions'>
{showReceiptUploads && (
<FileInput
onUpload={files => receiptsRef.current?.uploadReceipt(files[0])}
onUpload={(files) => {
const firstFile = files[0]
if (!firstFile) {
return
}

receiptsRef.current?.uploadReceipt(firstFile)
}}
text='Upload receipt'
iconOnly={true}
icon={<PaperclipIcon />}
Expand Down
9 changes: 5 additions & 4 deletions src/components/BankTransactionMobileList/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,11 @@ export const getAssignedValue = (
}

if (hasSuggestions(bankTransaction.categorization_flow)) {
const firstSuggestion = (
bankTransaction.categorization_flow
).suggestions[0]
return mapCategoryToOption(firstSuggestion)
const firstSuggestion = bankTransaction.categorization_flow.suggestions[0]

if (firstSuggestion) {
return mapCategoryToOption(firstSuggestion)
}
}

return
Expand Down
21 changes: 19 additions & 2 deletions src/components/BankTransactionReceipts/BankTransactionReceipts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,17 @@ const BankTransactionReceipts = forwardRef<
: null}
{!hideUploadButtons && (!receiptUrls || receiptUrls.length === 0)
? (
<FileInput onUpload={files => void uploadReceipt(files[0])} text='Upload receipt' />
<FileInput
onUpload={(files) => {
const firstFile = files[0]
if (!firstFile) {
return
}

void uploadReceipt(firstFile)
}}
text='Upload receipt'
/>
)
: null}
{receiptUrls.map((url, index) => (
Expand Down Expand Up @@ -132,7 +142,14 @@ const BankTransactionReceipts = forwardRef<
? (
<FileInput
secondary
onUpload={files => void uploadReceipt(files[0])}
onUpload={(files) => {
const firstFile = files[0]
if (!firstFile) {
return
}

void uploadReceipt(firstFile)
}}
text='Add next receipt'
/>
)
Expand Down
1 change: 1 addition & 0 deletions src/components/BankTransactionRow/BankTransactionRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export const getDefaultSelectedCategory = (
if (
hasSuggestions(bankTransaction.categorization_flow)
&& bankTransaction.categorization_flow.suggestions.length > 0
&& bankTransaction.categorization_flow.suggestions[0]
) {
return mapCategoryToOption(
bankTransaction.categorization_flow.suggestions[0],
Expand Down
2 changes: 1 addition & 1 deletion src/components/Bills/useBillsRecordPayment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const useBillsRecordPayment = ({ refetchAllBills }: { refetchAllBills?: (

setBillsToPay(prev => [
...prev.slice(0, index),
{ bill, amount: prev[index].amount },
{ bill, amount: prev?.[index]?.amount },
...prev.slice(index + 1),
])
}
Expand Down
12 changes: 7 additions & 5 deletions src/components/CategorySelect/CategorySelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -316,15 +316,17 @@ export const CategorySelect = ({

const selected = value
? value
: !excludeMatches
&& matchOptions?.length === 1
&& matchOptions[0].options.length === 1
: (
!excludeMatches
&& matchOptions?.[0]?.options.length === 1
)
? matchOptions[0].options[0]
: undefined

const matchOptionsCount = matchOptions?.[0]?.options.length ?? 0
const placeholder =
matchOptions?.length === 1 && matchOptions[0].options.length > 1
? `${matchOptions[0].options.length} possible matches...`
matchOptionsCount > 1
? `${matchOptionsCount} possible matches...`
: 'Categorize or match...'

if (asDrawer) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/CsvUpload/CopyTemplateHeadersButtonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ interface CopyTemplateHeadersButtonGroupProps {
export const CopyTemplateHeadersButtonGroup = ({ headers, className }: CopyTemplateHeadersButtonGroupProps) => {
return (
<HStack gap='3xs' className={classNames('Layer__csv-upload__copy-template-headers-button-group', className)}>
{Object.keys(headers).map(key => (
{Object.entries(headers).map(([key, header]) => (
<Button
key={key}
onClick={() => copyTextToClipboard(headers[key])}
onClick={() => copyTextToClipboard(header)}
rightIcon={<CopyIcon strokeWidth={1} size={12} />}
variant={ButtonVariant.secondary}
>
{headers[key]}
{header}
</Button>
))}
</HStack>
Expand Down
6 changes: 6 additions & 0 deletions src/components/CsvUpload/CsvUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ export const CsvUpload = ({ file, onFileSelected, replaceDropTarget = false }: C
return
}

if (!firstFile) {
onFileSelected(null)
setErrorMessage(undefined)
return
}

const maybeErrorMessage = validateCsvFile(firstFile)
if (!maybeErrorMessage) {
onFileSelected(firstFile)
Expand Down
5 changes: 5 additions & 0 deletions src/components/CsvUpload/ValidateCsvTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ export function ValidateCsvTable<T extends { [K in keyof T]: string | number }>(
/>
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
const row = rows[virtualRow.index]

if (!row) {
return null
}

return (
<ValidateCsvTableRow key={row.id} row={row} virtualRow={virtualRow} rowVirtualizer={rowVirtualizer} />
)
Expand Down
4 changes: 2 additions & 2 deletions src/components/ErrorBoundary/ErrorBoundary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class ErrorBoundary extends Component<
return { hasError: true }
}

componentDidCatch(error: Error, _info: ErrorInfo) {
override componentDidCatch(error: Error, _info: ErrorInfo) {
if (this.onError) {
this.onError({ type: 'render', payload: error })
}
Expand All @@ -36,7 +36,7 @@ export class ErrorBoundary extends Component<
}
}

render() {
override render() {
if (this.state.hasError) {
return <ErrorBoundaryMessage />
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,11 @@ const ExpandedBankTransactionRow = forwardRef<SaveHandle, Props>(
return sum + amount
}, 0)
const remaining = bankTransaction.amount - splitTotal
newSplits[0].amount = remaining
newSplits[0].inputValue = formatMoney(remaining)

if (newSplits[0]) {
newSplits[0].amount = remaining
newSplits[0].inputValue = formatMoney(remaining)
}

updateRowState({
...rowState,
Expand All @@ -222,7 +225,9 @@ const ExpandedBankTransactionRow = forwardRef<SaveHandle, Props>(

// Limit to two digits after the decimal point
if (parts.length === 2) {
sanitized = parts[0] + '.' + parts[1].slice(0, 2)
const secondPart = parts[1]?.slice(0, 2) ?? ''

sanitized = parts[0] + '.' + secondPart
}

return sanitized
Expand All @@ -240,18 +245,33 @@ const ExpandedBankTransactionRow = forwardRef<SaveHandle, Props>(
}, 0)

const remaining = bankTransaction.amount - splitTotal
rowState.splits[rowNumber].amount = newAmount
rowState.splits[rowNumber].inputValue = newDisplaying
rowState.splits[0].amount = remaining
rowState.splits[0].inputValue = formatMoney(remaining)

if (rowState.splits[rowNumber]) {
rowState.splits[rowNumber].amount = newAmount
rowState.splits[rowNumber].inputValue = newDisplaying
}
if (rowState.splits[0]) {
rowState.splits[0].amount = remaining
rowState.splits[0].inputValue = formatMoney(remaining)
}

updateRowState({ ...rowState })
setSplitFormError(undefined)
}

const onBlur = (event: React.FocusEvent<HTMLInputElement>) => {
if (event.target.value === '') {
const [_, index] = event.target.name.split('-')
rowState.splits[parseInt(index)].inputValue = '0.00'
if (!index) {
return
}

const parsedIndex = parseInt(index)

if (rowState.splits[parsedIndex]) {
rowState.splits[parsedIndex].inputValue = '0.00'
}

updateRowState({ ...rowState })
setSplitFormError(undefined)
}
Expand All @@ -268,7 +288,10 @@ const ExpandedBankTransactionRow = forwardRef<SaveHandle, Props>(
}

const changeCategory = (index: number, newValue: CategoryOption) => {
rowState.splits[index].category = newValue
if (rowState.splits[index]) {
rowState.splits[index].category = newValue
}

updateRowState({ ...rowState })
setSplitFormError(undefined)
}
Expand Down Expand Up @@ -302,12 +325,14 @@ const ExpandedBankTransactionRow = forwardRef<SaveHandle, Props>(
return
}

const firstCategory = rowState.splits[0]?.category

await categorizeBankTransaction(
bankTransaction.id,
rowState.splits.length === 1 && rowState?.splits[0].category
rowState.splits.length === 1 && firstCategory
? ({
type: 'Category',
category: getCategorizePayload(rowState?.splits[0].category),
category: getCategorizePayload(firstCategory),
} as SingleCategoryUpdate)
: ({
type: 'Split',
Expand Down
Loading