diff --git a/packages/desktop-client/src/components/Modals.tsx b/packages/desktop-client/src/components/Modals.tsx index 5974ec0e2fb..5163c587f25 100644 --- a/packages/desktop-client/src/components/Modals.tsx +++ b/packages/desktop-client/src/components/Modals.tsx @@ -310,6 +310,7 @@ export function Modals() { modalProps={modalProps} id={options?.id || null} actions={actions} + transaction={options?.transaction || null} /> ); @@ -320,6 +321,8 @@ export function Modals() { modalProps={modalProps} actions={actions} transactionIds={options?.transactionIds} + getTransaction={options?.getTransaction} + pushModal={options?.pushModal} /> ); diff --git a/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx b/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx index 8459e937c03..85446055b92 100644 --- a/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx +++ b/packages/desktop-client/src/components/schedules/ScheduleDetails.jsx @@ -67,14 +67,14 @@ function updateScheduleConditions(schedule, fields) { }; } -export function ScheduleDetails({ modalProps, actions, id }) { +export function ScheduleDetails({ modalProps, actions, id, transaction }) { const adding = id == null; + const fromTrans = transaction != null; const payees = useCachedPayees({ idKey: true }); const globalDispatch = useDispatch(); const dateFormat = useSelector(state => { return state.prefs.local.dateFormat || 'MM/dd/yyyy'; }); - const [state, dispatch] = useReducer( (state, action) => { switch (action.type) { @@ -143,6 +143,11 @@ export function ScheduleDetails({ modalProps, actions, id }) { fields: { ...state.fields, ...fields }, }; case 'set-transactions': + if (fromTrans && action.transactions) { + action.transactions.sort(a => { + return transaction.id === a.id ? -1 : 1; + }); + } return { ...state, transactions: action.transactions }; case 'set-repeats': return { @@ -210,12 +215,30 @@ export function ScheduleDetails({ modalProps, actions, id }) { endOccurrences: '1', endDate: monthUtils.currentDay(), }; - const schedule = { - posts_transaction: false, - _date: date, - _conditions: [{ op: 'isapprox', field: 'date', value: date }], - _actions: [], - }; + + const schedule = fromTrans + ? { + posts_transaction: false, + _conditions: [{ op: 'isapprox', field: 'date', value: date }], + _actions: [], + _account: transaction.account, + _amount: transaction.amount, + _amountOp: 'is', + name: transaction.payee ? payees[transaction.payee].name : '', + _payee: transaction.payee ? transaction.payee : '', + _date: { + ...date, + frequency: 'monthly', + start: transaction.date, + patterns: [], + }, + } + : { + posts_transaction: false, + _date: date, + _conditions: [{ op: 'isapprox', field: 'date', value: date }], + _actions: [], + }; dispatch({ type: 'set-schedule', schedule }); } else { @@ -226,6 +249,7 @@ export function ScheduleDetails({ modalProps, actions, id }) { } } } + run(); }, []); @@ -321,7 +345,11 @@ export function ScheduleDetails({ modalProps, actions, id }) { }; }, [state.schedule, state.transactionsMode, state.fields]); - const selectedInst = useSelected('transactions', state.transactions, []); + const selectedInst = useSelected( + 'transactions', + state.transactions, + transaction ? [transaction.id] : [], + ); async function onSave() { dispatch({ type: 'form-error', error: null }); @@ -415,7 +443,6 @@ export function ScheduleDetails({ modalProps, actions, id }) { } const payee = payees ? payees[state.fields.payee] : null; - // This is derived from the date const repeats = state.fields.date ? !!state.fields.date.frequency : false; return ( diff --git a/packages/desktop-client/src/components/schedules/ScheduleLink.tsx b/packages/desktop-client/src/components/schedules/ScheduleLink.tsx index c6251c12aeb..ed924fca296 100644 --- a/packages/desktop-client/src/components/schedules/ScheduleLink.tsx +++ b/packages/desktop-client/src/components/schedules/ScheduleLink.tsx @@ -4,8 +4,11 @@ import React, { useCallback, useRef, useState } from 'react'; import { useSchedules } from 'loot-core/src/client/data-hooks/schedules'; import { send } from 'loot-core/src/platform/client/fetch'; import { type Query } from 'loot-core/src/shared/query'; +import { type TransactionEntity } from 'loot-core/src/types/models'; import { type BoundActions } from '../../hooks/useActions'; +import { SvgAdd } from '../../icons/v0'; +import { Button } from '../common/Button'; import { Modal } from '../common/Modal'; import { Search } from '../common/Search'; import { Text } from '../common/Text'; @@ -14,14 +17,23 @@ import { type CommonModalProps } from '../Modals'; import { ROW_HEIGHT, SchedulesTable } from './SchedulesTable'; +type ModalParams = { + id: string; + transaction: TransactionEntity; +}; + export function ScheduleLink({ modalProps, actions, transactionIds: ids, + getTransaction, + pushModal, }: { actions: BoundActions; modalProps?: CommonModalProps; transactionIds: string[]; + getTransaction: (transactionId: string) => TransactionEntity; + pushModal: (name: string, params: ModalParams) => void; }) { const [filter, setFilter] = useState(''); @@ -45,6 +57,14 @@ export function ScheduleLink({ actions.popModal(); } + async function onCreate() { + actions.popModal(); + pushModal('schedule-edit', { + id: null, + transaction: getTransaction(ids[0]), + }); + } + return ( + {ids.length === 1 && ( + + )}