actual/packages/desktop-client/src/components/payees/ManagePayeesWithData.js
Tom French 9c0df36e16
Sort import in alphabetical order (#238)
* style: enforce sorting of imports

* style: alphabetize imports

* style: merge duplicated imports
2022-09-02 15:07:24 +01:00

157 lines
3.8 KiB
JavaScript

import React, { useState, useEffect, useRef } from 'react';
import { connect } from 'react-redux';
import * as actions from 'loot-core/src/client/actions';
import { send, listen } from 'loot-core/src/platform/client/fetch';
import * as undo from 'loot-core/src/platform/client/undo';
import { applyChanges } from 'loot-core/src/shared/util';
import { ManagePayees } from 'loot-design/src/components/payees';
function ManagePayeesWithData({
history,
modalProps,
initialSelectedIds,
lastUndoState,
initialPayees,
categoryGroups,
initiallyLoadPayees,
getPayees,
setLastUndoState,
pushModal
}) {
let [payees, setPayees] = useState(initialPayees);
let [ruleCounts, setRuleCounts] = useState({ value: new Map() });
let payeesRef = useRef();
async function refetchRuleCounts() {
let counts = await send('payees-get-rule-counts');
counts = new Map(Object.entries(counts));
setRuleCounts({ value: counts });
}
useEffect(() => {
async function loadData() {
let result = await initiallyLoadPayees();
// Wait a bit before setting the data. This lets the modal
// settle and makes for a smoother experience.
await new Promise(resolve => setTimeout(resolve, 100));
if (result) {
setPayees(result);
}
refetchRuleCounts();
}
loadData();
let unlisten = listen('sync-event', async ({ type, tables }) => {
if (type === 'applied') {
if (tables.includes('rules')) {
refetchRuleCounts();
}
}
});
undo.setUndoState('openModal', 'manage-payees');
return () => {
undo.setUndoState('openModal', null);
unlisten();
};
}, []);
async function onUndo({ tables, messages, meta, url }, scroll = false) {
if (
!tables.includes('payees') &&
!tables.includes('payee_mapping') &&
!tables.includes('payee_rules')
) {
return;
}
setPayees(await getPayees());
if (
(meta && meta.targetId) ||
messages.find(msg => msg.dataset === 'rules')
) {
refetchRuleCounts();
}
setLastUndoState(null);
}
useEffect(() => {
if (lastUndoState.current) {
onUndo(lastUndoState.current, true);
}
return listen('undo-event', onUndo);
}, []);
function onViewRules(id) {
pushModal('manage-rules', { payeeId: id });
}
function onCreateRule(id) {
let payee = payees.find(p => p.id === id);
let rule = {
id: null,
stage: null,
conditions: [
{
field: 'description',
op: 'is',
value: payee.id,
type: 'id'
}
],
actions: []
};
pushModal('edit-rule', { rule });
}
return (
<ManagePayees
ref={payeesRef}
modalProps={modalProps}
payees={payees}
ruleCounts={ruleCounts.value}
categoryGroups={categoryGroups}
initialSelectedIds={initialSelectedIds}
lastUndoState={lastUndoState}
onBatchChange={changes => {
send('payees-batch-change', changes);
setPayees(applyChanges(changes, payees));
}}
onMerge={async ([targetId, ...mergeIds]) => {
await send('payees-merge', { targetId, mergeIds });
let result = payees.filter(p => !mergeIds.includes(p.id));
mergeIds.forEach(id => {
let count = ruleCounts.value.get(id) || 0;
ruleCounts.value.set(
targetId,
(ruleCounts.value.get(targetId) || 0) + count
);
});
setPayees(result);
setRuleCounts({ value: ruleCounts.value });
}}
onViewRules={onViewRules}
onCreateRule={onCreateRule}
/>
);
}
export default connect(
state => ({
initialPayees: state.queries.payees,
lastUndoState: state.app.lastUndoState,
categoryGroups: state.queries.categories.grouped
}),
actions
)(ManagePayeesWithData);