Skip to content

Commit

Permalink
AmountInput component on split transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
joel-jeremy committed Dec 12, 2023
1 parent e28c31c commit e100317
Showing 1 changed file with 55 additions and 103 deletions.
158 changes: 55 additions & 103 deletions packages/desktop-client/src/components/transactions/MobileTransaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import {
} from '../mobile/MobileForms';
import MobileBackButton from '../MobileBackButton';
import { Page } from '../Page';
import { AmountInput } from '../util/AmountInput';
const zIndices = { SECTION_HEADING: 10 };

const getPayeesById = memoizeOne(payees => groupById(payees));
Expand Down Expand Up @@ -171,13 +172,6 @@ function Status({ status }) {
}

class TransactionEditInner extends PureComponent {
constructor(props) {
super(props);
this.state = {
transactions: props.transactions,
};
}

serializeTransactions = memoizeOne(transactions => {
return transactions.map(t =>
serializeTransaction(t, this.props.dateFormat),
Expand All @@ -190,19 +184,13 @@ class TransactionEditInner extends PureComponent {
}
}

componentWillUnmount() {
document
.querySelector('meta[name="theme-color"]')
.setAttribute('content', '#ffffff');
}

onAdd = () => {
this.onSave();
};

onSave = async () => {
const onConfirmSave = async () => {
let { transactions } = this.state;
let { transactions } = this.props;
const [transaction, ..._childTransactions] = transactions;
const { account: accountId } = transaction;
const account = getAccountsById(this.props.accounts)[accountId];
Expand All @@ -213,15 +201,6 @@ class TransactionEditInner extends PureComponent {
return;
}

// Since we don't own the state, we have to handle the case where
// the user saves while editing an input. We won't have the
// updated value so we "apply" a queued change. Maybe there's a
// better way to do this (lift the state?)
if (this._queuedChange) {
const [transaction, name, value] = this._queuedChange;
transactions = await this.onEdit(transaction, name, value);
}

if (this.props.adding) {
transactions = realizeTempTransactions(transactions);
}
Expand All @@ -230,7 +209,7 @@ class TransactionEditInner extends PureComponent {
this.props.navigate(`/accounts/${account.id}`, { replace: true });
};

const { transactions } = this.state;
const { transactions } = this.props;
const [transaction] = transactions;

if (transaction.reconciled) {
Expand All @@ -248,30 +227,10 @@ class TransactionEditInner extends PureComponent {
};

onEdit = async (transaction, name, value) => {
const { transactions } = this.state;

let newTransaction = { ...transaction, [name]: value };
const newTransaction = { ...transaction, [name]: value };
if (this.props.onEdit) {
newTransaction = await this.props.onEdit(newTransaction);
await this.props.onEdit(newTransaction);
}

const { data: newTransactions } = updateTransaction(
transactions,
deserializeTransaction(newTransaction, null, this.props.dateFormat),
);

this._queuedChange = null;
this.setState({ transactions: newTransactions });
return newTransactions;
};

onQueueChange = (transaction, name, value) => {
// This is an ugly hack to solve the problem that input's blur
// events are not fired when unmounting. If the user has focused
// an input and swipes back, it should still save, but because the
// blur event is not fired we need to manually track the latest
// change and apply it ourselves when unmounting
this._queuedChange = [transaction, name, value];
};

onClick = (transactionId, name) => {
Expand All @@ -280,7 +239,7 @@ class TransactionEditInner extends PureComponent {
this.props.pushModal('edit-field', {
name,
onSubmit: (name, value) => {
const { transactions } = this.state;
const { transactions } = this.props;
const transaction = transactions.find(t => t.id === transactionId);
// This is a deficiency of this API, need to fix. It
// assumes that it receives a serialized transaction,
Expand All @@ -292,15 +251,12 @@ class TransactionEditInner extends PureComponent {

onDelete = id => {
const onConfirmDelete = () => {
const { transactions } = this.state;
const { transactions } = this.props;

this.props.onDelete(id);

const [transaction, ..._childTransactions] = transactions;
if (transaction.id !== id) {
// Only the child transaction was deleted.
const changes = deleteTransaction(transactions, id);
this.setState({ transactions: changes.data });
return;
}

Expand All @@ -312,7 +268,7 @@ class TransactionEditInner extends PureComponent {
}
};

const { transactions } = this.state;
const { transactions } = this.props;
const [transaction] = transactions;

if (transaction.reconciled) {
Expand All @@ -326,22 +282,22 @@ class TransactionEditInner extends PureComponent {
};

onAddSplit = id => {
const changes = addSplitTransaction(this.state.transactions, id);
this.setState({ transactions: changes.data });
this.props.onAddSplit(id);
};

onSplit = id => {
const changes = splitTransaction(this.state.transactions, id);
this.setState({ transactions: changes.data });
this.props.onSplit(id);
};

render() {
const { adding, categories, accounts, payees } = this.props;
const transactions = this.serializeTransactions(
this.state.transactions || [],
);
const {
adding,
categories,
accounts,
payees,
transactions: originalTransactions,
} = this.props;
const transactions = this.serializeTransactions(originalTransactions || []);
const [transaction, ..._childTransactions] = transactions;

// Child transactions should always default to the signage
Expand Down Expand Up @@ -426,7 +382,7 @@ class TransactionEditInner extends PureComponent {
{transaction.error?.type === 'SplitTransactionError' ? (
<Button
style={{ height: 40 }}
onPointerUp={() =>
onClick={() =>
_childTransactions.length === 0
? this.onSplit(transaction.id)
: this.onAddSplit(transaction.id)
Expand Down Expand Up @@ -455,7 +411,7 @@ class TransactionEditInner extends PureComponent {
</Text>
</Button>
) : adding ? (
<Button style={{ height: 40 }} onPointerUp={() => this.onAdd()}>
<Button style={{ height: 40 }} onClick={() => this.onAdd()}>
<Add
width={17}
height={17}
Expand All @@ -472,7 +428,7 @@ class TransactionEditInner extends PureComponent {
</Text>
</Button>
) : (
<Button style={{ height: 40 }} onPointerUp={() => this.onSave()}>
<Button style={{ height: 40 }} onClick={() => this.onSave()}>
<PencilWriteAlternate
width={16}
height={16}
Expand Down Expand Up @@ -513,9 +469,6 @@ class TransactionEditInner extends PureComponent {
onBlur={value =>
this.onEdit(transaction, 'amount', value.toString())
}
onChange={value =>
this.onQueueChange(transaction, 'amount', value)
}
style={{ transform: [] }}
focusedStyle={{
width: 'auto',
Expand Down Expand Up @@ -575,32 +528,28 @@ class TransactionEditInner extends PureComponent {
}}
>
<View style={{ flexDirection: 'row' }}>
<View style={{ flexBasis: '70%' }}>
<View style={{ flexBasis: '75%' }}>
<FieldLabel title="Payee" />
<TapField
value={getPrettyPayee(childTrans)}
onClick={() => this.onClick(childTrans.id, 'payee')}
data-testid={`payee-field-${childTrans.id}`}
/>
</View>
<View style={{ flexBasis: '30%' }}>
<View style={{ flexBasis: '25%' }}>
<FieldLabel title="Amount" />
<InputField
defaultValue={childTrans.amount}
onUpdate={value => this.onEdit(childTrans, 'amount', value)}
onChange={e =>
this.onQueueChange(childTrans, 'amount', e.target.value)
<AmountInput
initialValue={amountToInteger(childTrans.amount)}
zeroSign="-"
textStyle={{ ...styles.smallText, textAlign: 'right' }}
onChange={value =>
this.onEdit(
childTrans,
'amount',
integerToCurrency(value),
)
}
/>
{/* <AmountInput
initialValue={amountToInteger(trans.amount)}
zeroSign="-"
textStyle={{ ...styles.smallText }}
onChange={value =>
this.onQueueChange(trans.amount, 'amount', value)
}
onBlur={() => this.onEdit(trans.amount, 'amount', trans.amount)}
/> */}
</View>
</View>

Expand Down Expand Up @@ -670,7 +619,7 @@ class TransactionEditInner extends PureComponent {
marginTop: 10,
backgroundColor: 'transparent',
}}
onClick={() => this.onSplit(transaction.id)}
onPointerUp={() => this.onSplit(transaction.id)}
type="bare"
>
<Split
Expand Down Expand Up @@ -716,13 +665,6 @@ class TransactionEditInner extends PureComponent {
formatDate(parseISO(value), this.props.dateFormat),
)
}
onChange={e =>
this.onQueueChange(
transaction,
'date',
formatDate(parseISO(e.target.value), this.props.dateFormat),
)
}
/>
</View>
{transaction.reconciled ? (
Expand Down Expand Up @@ -761,9 +703,6 @@ class TransactionEditInner extends PureComponent {
<InputField
defaultValue={transaction.notes}
onUpdate={value => this.onEdit(transaction, 'notes', value)}
onChange={e =>
this.onQueueChange(transaction, 'notes', e.target.value)
}
/>
</View>

Expand Down Expand Up @@ -825,6 +764,7 @@ function TransactionEditUnconnected(props) {
const { id: accountId, transactionId } = useParams();
const navigate = useNavigate();
const [transactions, setTransactions] = useState([]);
const [fetchedTransactions, setFetchedTransactions] = useState([]);
const adding = useRef(false);
const deleted = useRef(false);
useSetThemeColor(theme.mobileViewTheme);
Expand All @@ -851,7 +791,7 @@ function TransactionEditUnconnected(props) {
.select('*')
.options({ splits: 'grouped' }),
);
setTransactions(ungroupTransactions(data));
setFetchedTransactions(ungroupTransactions(data));
}
if (transactionId) {
fetchTransaction();
Expand All @@ -860,6 +800,10 @@ function TransactionEditUnconnected(props) {
}
}, [transactionId]);

useEffect(() => {
setTransactions(fetchedTransactions);
}, [fetchedTransactions]);

useEffect(() => {
if (adding.current) {
setTransactions(
Expand All @@ -880,32 +824,36 @@ function TransactionEditUnconnected(props) {
}

const onEdit = async transaction => {
let newTransaction = transaction;
// Run the rules to auto-fill in any data. Right now we only do
// this on new transactions because that's how desktop works.
if (isTemporary(transaction)) {
const afterRules = await send('rules-run', { transaction });
const diff = getChangedValues(transaction, afterRules);

const newTransaction = { ...transaction };
newTransaction = { ...transaction };
if (diff) {
Object.keys(diff).forEach(field => {
if (newTransaction[field] == null) {
newTransaction[field] = diff[field];
}
});
}
return newTransaction;
}

return transaction;
const { data: newTransactions } = updateTransaction(
transactions,
deserializeTransaction(newTransaction, null, dateFormat),
);
setTransactions(newTransactions);
};

const onSave = async newTransactions => {
if (deleted.current) {
return;
}

const changes = diffItems(transactions || [], newTransactions);
const changes = diffItems(fetchedTransactions || [], newTransactions);
if (
changes.added.length > 0 ||
changes.updated.length > 0 ||
Expand Down Expand Up @@ -933,18 +881,22 @@ function TransactionEditUnconnected(props) {
};

const onDelete = async id => {
const changes = deleteTransaction(transactions, id);

if (adding.current) {
// Adding a new transactions, this disables saving when the component unmounts
deleted.current = true;
} else {
const changes = {
deleted: transactions.filter(t => t.id === id),
};
const _remoteUpdates = await send('transactions-batch-update', changes);
const _remoteUpdates = await send('transactions-batch-update', {
deleted: changes.diff.deleted,
});

// if (onTransactionsChange) {
// onTransactionsChange({ ...changes, updated: remoteUpdates });
// }
}

setTransactions(changes.data);
};

const onAddSplit = id => {
Expand All @@ -956,7 +908,7 @@ function TransactionEditUnconnected(props) {
const onSplit = id => {
const changes = splitTransaction(transactions, id);
setTransactions(changes.data);
// this.props.onSave(changes.data);
// onSave(changes.data);
};

return (
Expand Down

0 comments on commit e100317

Please sign in to comment.