mirror of
https://github.com/actualbudget/actual.git
synced 2026-10-11 22:49:59 +00:00
[AI] Fix clearing the payee when editing a transaction on mobile (#8926)
The mobile payee selector only allowed picking a payee, so once one was selected there was no way to leave the transaction without a payee. Add a "No payee" option to the payee autocomplete modal, mirroring the category modal's "Uncategorized" button, and show it while editing a transaction that already has a payee.
This commit is contained in:
@@ -79,6 +79,36 @@ test.describe('Mobile Transactions', () => {
|
||||
- textbox [disabled]: just a note`);
|
||||
});
|
||||
|
||||
test('removes the payee from a new transaction', async () => {
|
||||
const accountsPage = await navigation.goToAccountsPage();
|
||||
const accountPage = await accountsPage.openNthAccount(2);
|
||||
const transactionEntryPage = await accountPage.clickCreateTransaction();
|
||||
|
||||
await transactionEntryPage.fillAmount('12.34');
|
||||
// Click anywhere to cancel active edit.
|
||||
await transactionEntryPage.header.click();
|
||||
await transactionEntryPage.fillField(
|
||||
page.getByTestId('payee-field'),
|
||||
'Kroger',
|
||||
);
|
||||
await expect(page.getByTestId('payee-field')).toContainText('Kroger');
|
||||
|
||||
// Reopen the payee selector and clear it with the "No payee" option.
|
||||
await page.getByTestId('payee-field').click();
|
||||
await page.getByRole('button', { name: 'No payee' }).click();
|
||||
await expect(page.getByTestId('payee-field')).not.toContainText('Kroger');
|
||||
|
||||
await transactionEntryPage.fillField(
|
||||
page.getByTestId('category-field'),
|
||||
'Clothing',
|
||||
);
|
||||
await transactionEntryPage.createTransaction();
|
||||
|
||||
await expect(accountPage.transactions.nth(0)).toHaveText(
|
||||
'(No payee)Clothing-12.34',
|
||||
);
|
||||
});
|
||||
|
||||
test('creates a transaction from `/accounts/:id` page', async () => {
|
||||
const accountsPage = await navigation.goToAccountsPage();
|
||||
const accountPage = await accountsPage.openNthAccount(2);
|
||||
|
||||
@@ -994,6 +994,7 @@ const TransactionEditInner = memo<TransactionEditInnerProps>(
|
||||
modal: {
|
||||
name: 'payee-autocomplete',
|
||||
options: {
|
||||
showNoneOption: !!transactionToEdit.payee,
|
||||
onSelect: payeeId => {
|
||||
void onUpdateInner(transactionToEdit, name, payeeId);
|
||||
},
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Trans, useTranslation } from 'react-i18next';
|
||||
|
||||
import { Button } from '@actual-app/components/button';
|
||||
import { useResponsive } from '@actual-app/components/hooks/useResponsive';
|
||||
import { theme } from '@actual-app/components/theme';
|
||||
import { View } from '@actual-app/components/view';
|
||||
|
||||
import { PayeeAutocomplete } from '#components/autocomplete/PayeeAutocomplete';
|
||||
import {
|
||||
@@ -23,6 +25,7 @@ type PayeeAutocompleteModalProps = Extract<
|
||||
|
||||
export function PayeeAutocompleteModal({
|
||||
onSelect,
|
||||
showNoneOption,
|
||||
onClose,
|
||||
}: PayeeAutocompleteModalProps) {
|
||||
const { t } = useTranslation();
|
||||
@@ -69,20 +72,37 @@ export function PayeeAutocompleteModal({
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<PayeeAutocomplete
|
||||
payees={payees}
|
||||
accounts={accounts}
|
||||
focused
|
||||
embedded
|
||||
closeOnBlur={false}
|
||||
onClose={() => state.close()}
|
||||
onManagePayees={onManagePayees}
|
||||
showManagePayees={!isNarrowWidth}
|
||||
showMakeTransfer={!isNarrowWidth}
|
||||
{...defaultAutocompleteProps}
|
||||
onSelect={onSelect}
|
||||
value={null}
|
||||
/>
|
||||
<View>
|
||||
<View style={{ flex: 1 }}>
|
||||
<PayeeAutocomplete
|
||||
payees={payees}
|
||||
accounts={accounts}
|
||||
focused
|
||||
embedded
|
||||
closeOnBlur={false}
|
||||
onClose={() => state.close()}
|
||||
onManagePayees={onManagePayees}
|
||||
showManagePayees={!isNarrowWidth}
|
||||
showMakeTransfer={!isNarrowWidth}
|
||||
{...defaultAutocompleteProps}
|
||||
onSelect={onSelect}
|
||||
value={null}
|
||||
/>
|
||||
</View>
|
||||
{showNoneOption && (
|
||||
<View style={{ flexShrink: 0, padding: 5 }}>
|
||||
<Button
|
||||
variant="menu"
|
||||
onPress={() => {
|
||||
onSelect(null);
|
||||
state.close();
|
||||
}}
|
||||
>
|
||||
<Trans>No payee</Trans>
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</>
|
||||
)}
|
||||
</Modal>
|
||||
|
||||
@@ -695,7 +695,7 @@ function PayeeCell({
|
||||
modal: {
|
||||
name: 'payee-autocomplete',
|
||||
options: {
|
||||
onSelect: (payeeId: PayeeEntity['id']) => {
|
||||
onSelect: (payeeId: PayeeEntity['id'] | null) => {
|
||||
onUpdate('payee', payeeId);
|
||||
},
|
||||
},
|
||||
|
||||
@@ -170,6 +170,9 @@ export const GenericInput = ({
|
||||
name: 'payee-autocomplete',
|
||||
options: {
|
||||
onSelect: newValue => {
|
||||
if (newValue === null) {
|
||||
return;
|
||||
}
|
||||
if (props.multi === true) {
|
||||
props.onChange([...props.value, newValue]);
|
||||
return;
|
||||
|
||||
@@ -316,7 +316,8 @@ export type Modal =
|
||||
| {
|
||||
name: 'payee-autocomplete';
|
||||
options: {
|
||||
onSelect: (payeeId: string) => void;
|
||||
onSelect: (payeeId: string | null) => void;
|
||||
showNoneOption?: boolean;
|
||||
onClose?: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Bugfix
|
||||
authors: [danielnieto]
|
||||
---
|
||||
|
||||
Fix clearing the payee when editing a transaction on mobile
|
||||
Reference in New Issue
Block a user