From 4bc82443fe22bf48bfad6aa106c90864f6d66793 Mon Sep 17 00:00:00 2001 From: Jed Fox <git@jedfox.com> Date: Wed, 1 Feb 2023 14:15:36 -0500 Subject: [PATCH] Improve handling of schedules that are missing a date (#601) * Fix adding date back to a schedule that lost its date * Propagate errors when searching matching transactions * Make the error more visible * Block removing the date field on schedule-linked rules --- .../accounts/SimpleTransactionsTable.js | 2 ++ .../src/components/modals/EditRule.js | 11 ++++++++- .../src/components/schedules/EditSchedule.js | 23 ++++++++++++++++++- .../loot-core/src/server/schedules/app.js | 4 ++-- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js b/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js index ca04a19ff..189289b4c 100644 --- a/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js +++ b/packages/desktop-client/src/components/accounts/SimpleTransactionsTable.js @@ -146,6 +146,7 @@ const TransactionRow = React.memo(function TransactionRow({ export default function SimpleTransactionsTable({ transactions, schedules, + renderEmpty, fields = ['date', 'payee', 'amount'], style }) { @@ -185,6 +186,7 @@ export default function SimpleTransactionsTable({ <Table style={style} items={serializedTransactions} + renderEmpty={renderEmpty} headers={ <> <SelectCell diff --git a/packages/desktop-client/src/components/modals/EditRule.js b/packages/desktop-client/src/components/modals/EditRule.js index e31d429d0..25b86c621 100644 --- a/packages/desktop-client/src/components/modals/EditRule.js +++ b/packages/desktop-client/src/components/modals/EditRule.js @@ -172,6 +172,7 @@ export function ConditionEditor({ ops, condition, editorStyle, + isSchedule, onChange, onDelete, onAdd @@ -214,7 +215,10 @@ export function ConditionEditor({ <View style={{ flex: 1 }}>{valueEditor}</View> <Stack direction="row"> - <EditorButtons onAdd={onAdd} onDelete={onDelete} /> + <EditorButtons + onAdd={onAdd} + onDelete={isSchedule && field === 'date' ? null : onDelete} + /> </Stack> </Editor> ); @@ -395,6 +399,7 @@ export function ConditionsList({ conditions, conditionFields, editorStyle, + isSchedule, onChangeConditions }) { function addCondition(index) { @@ -523,6 +528,7 @@ export function ConditionsList({ editorStyle={editorStyle} ops={ops} condition={cond} + isSchedule={isSchedule} onChange={(name, value) => { updateCondition(cond, name, value); }} @@ -567,6 +573,8 @@ export default function EditRule({ let dispatch = useDispatch(); let scrollableEl = useRef(); + let isSchedule = actions.some(action => action.op === 'link-schedule'); + useEffect(() => { dispatch(initiallyLoadPayees()); @@ -769,6 +777,7 @@ export default function EditRule({ conditions={conditions} conditionFields={conditionFields} editorStyle={editorStyle} + isSchedule={isSchedule} onChangeConditions={conds => setConditions(conds)} /> </View> diff --git a/packages/desktop-client/src/components/schedules/EditSchedule.js b/packages/desktop-client/src/components/schedules/EditSchedule.js index 79cd94673..064e56ea8 100644 --- a/packages/desktop-client/src/components/schedules/EditSchedule.js +++ b/packages/desktop-client/src/components/schedules/EditSchedule.js @@ -290,13 +290,18 @@ export default function ScheduleDetails() { let unsubscribe; if (state.schedule && state.transactionsMode === 'matched') { - let { conditions } = updateScheduleConditions( + let { error, conditions } = updateScheduleConditions( state.schedule, state.fields ); dispatch({ type: 'set-transactions', transactions: [] }); + if (error) { + dispatch({ type: 'form-error', error }); + return; + } + // *Extremely* gross hack because the rules are not mapped to // public names automatically. We really should be doing that // at the database layer @@ -695,6 +700,22 @@ export default function ScheduleDetails() { )} <SimpleTransactionsTable + renderEmpty={ + state.transactionsMode === 'matched' && + (() => ( + <View + style={{ padding: 20, color: colors.n4, textAlign: 'center' }} + > + {state.error ? ( + <Text style={{ color: colors.r4 }}> + Could not search: {state.error} + </Text> + ) : ( + 'No transactions found' + )} + </View> + )) + } transactions={state.transactions} fields={['date', 'payee', 'amount']} style={{ diff --git a/packages/loot-core/src/server/schedules/app.js b/packages/loot-core/src/server/schedules/app.js index 513f49ef9..a75edbe9b 100644 --- a/packages/loot-core/src/server/schedules/app.js +++ b/packages/loot-core/src/server/schedules/app.js @@ -268,8 +268,8 @@ export async function updateSchedule({ schedule, conditions, resetNextDate }) { oldConditions.find(c => c.field === 'account') ) || !deepEqual( - stripType(oldConditions.find(c => c.field === 'date')), - stripType(newConditions.find(c => c.field === 'date')) + stripType(oldConditions.find(c => c.field === 'date') || {}), + stripType(newConditions.find(c => c.field === 'date') || {}) ) ) { await setNextDate({ -- GitLab