Skip to content

Commit

Permalink
Merge branch 'master' into fix-exhaustive-deps-useSheetValue
Browse files Browse the repository at this point in the history
  • Loading branch information
joel-jeremy authored Feb 21, 2025
2 parents c5aa5dc + 5a79bea commit 3bfa2ca
Show file tree
Hide file tree
Showing 27 changed files with 1,354 additions and 1,173 deletions.
1 change: 0 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,6 @@ export default [
'packages/desktop-client/src/components/select/DateSelect.tsx',
'packages/desktop-client/src/components/sidebar/Tools.tsx',
'packages/desktop-client/src/components/sort.tsx',
'packages/desktop-client/src/components/transactions/TransactionList.jsx',
],

rules: {
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
"vite": "^5.2.14",
"vite-plugin-pwa": "^0.20.0",
"vite-tsconfig-paths": "^4.3.2",
"vitest": "^1.6.0",
"vitest": "^1.6.1",
"webpack-bundle-analyzer": "^4.10.1",
"xml2js": "^0.6.2"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function AccountSyncCheck() {
setOpen(false);

if (acc.account_id) {
authorizeBank(dispatch, { upgradingAccountId: acc.account_id });
authorizeBank(dispatch);
}
},
[dispatch],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ export function CreateAccountModal({ upgradingAccountId }: CreateAccountProps) {
if (upgradingAccountId == null) {
authorizeBank(dispatch);
} else {
authorizeBank(dispatch, {
upgradingAccountId,
});
authorizeBank(dispatch);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,59 +100,84 @@ export function TransactionList({
onMakeAsNonSplitTransactions,
}) {
const dispatch = useDispatch();
const transactionsLatest = useRef();
const navigate = useNavigate();
const [learnCategories = 'true'] = useSyncedPref('learn-categories');
const isLearnCategoriesEnabled = String(learnCategories) === 'true';

const transactionsLatest = useRef();
useLayoutEffect(() => {
transactionsLatest.current = transactions;
}, [transactions]);

const onAdd = useCallback(async newTransactions => {
newTransactions = realizeTempTransactions(newTransactions);
const onAdd = useCallback(
async newTransactions => {
newTransactions = realizeTempTransactions(newTransactions);

await saveDiff({ added: newTransactions }, isLearnCategoriesEnabled);
onRefetch();
}, []);
await saveDiff({ added: newTransactions }, isLearnCategoriesEnabled);
onRefetch();
},
[isLearnCategoriesEnabled, onRefetch],
);

const onSave = useCallback(async transaction => {
const changes = updateTransaction(transactionsLatest.current, transaction);
transactionsLatest.current = changes.data;
const onSave = useCallback(
async transaction => {
const changes = updateTransaction(
transactionsLatest.current,
transaction,
);
transactionsLatest.current = changes.data;

if (changes.diff.updated.length > 0) {
const dateChanged = !!changes.diff.updated[0].date;
if (dateChanged) {
// Make sure it stays at the top of the list of transactions
// for that date
changes.diff.updated[0].sort_order = Date.now();
await saveDiff(changes.diff, isLearnCategoriesEnabled);
onRefetch();
} else {
onChange(changes.newTransaction, changes.data);
saveDiffAndApply(
changes.diff,
changes,
onChange,
isLearnCategoriesEnabled,
);
if (changes.diff.updated.length > 0) {
const dateChanged = !!changes.diff.updated[0].date;
if (dateChanged) {
// Make sure it stays at the top of the list of transactions
// for that date
changes.diff.updated[0].sort_order = Date.now();
await saveDiff(changes.diff, isLearnCategoriesEnabled);
onRefetch();
} else {
onChange(changes.newTransaction, changes.data);
saveDiffAndApply(
changes.diff,
changes,
onChange,
isLearnCategoriesEnabled,
);
}
}
}
}, []);
},
[isLearnCategoriesEnabled, onChange, onRefetch],
);

const onAddSplit = useCallback(id => {
const changes = addSplitTransaction(transactionsLatest.current, id);
onChange(changes.newTransaction, changes.data);
saveDiffAndApply(changes.diff, changes, onChange, isLearnCategoriesEnabled);
return changes.diff.added[0].id;
}, []);
const onAddSplit = useCallback(
id => {
const changes = addSplitTransaction(transactionsLatest.current, id);
onChange(changes.newTransaction, changes.data);
saveDiffAndApply(
changes.diff,
changes,
onChange,
isLearnCategoriesEnabled,
);
return changes.diff.added[0].id;
},
[isLearnCategoriesEnabled, onChange],
);

const onSplit = useCallback(id => {
const changes = splitTransaction(transactionsLatest.current, id);
onChange(changes.newTransaction, changes.data);
saveDiffAndApply(changes.diff, changes, onChange, isLearnCategoriesEnabled);
return changes.diff.added[0].id;
}, []);
const onSplit = useCallback(
id => {
const changes = splitTransaction(transactionsLatest.current, id);
onChange(changes.newTransaction, changes.data);
saveDiffAndApply(
changes.diff,
changes,
onChange,
isLearnCategoriesEnabled,
);
return changes.diff.added[0].id;
},
[isLearnCategoriesEnabled, onChange],
);

const onApplyRules = useCallback(
async (transaction, updatedFieldName = null) => {
Expand Down Expand Up @@ -193,26 +218,38 @@ export function TransactionList({
[],
);

const onManagePayees = useCallback(id => {
navigate('/payees', { state: { selectedPayee: id } });
});
const onManagePayees = useCallback(
id => {
navigate('/payees', { state: { selectedPayee: id } });
},
[navigate],
);

const onNavigateToTransferAccount = useCallback(accountId => {
navigate(`/accounts/${accountId}`);
});
const onNavigateToTransferAccount = useCallback(
accountId => {
navigate(`/accounts/${accountId}`);
},
[navigate],
);

const onNavigateToSchedule = useCallback(scheduleId => {
dispatch(pushModal('schedule-edit', { id: scheduleId }));
});
const onNavigateToSchedule = useCallback(
scheduleId => {
dispatch(pushModal('schedule-edit', { id: scheduleId }));
},
[dispatch],
);

const onNotesTagClick = useCallback(tag => {
onApplyFilter({
field: 'notes',
op: 'hasTags',
value: tag,
type: 'string',
});
});
const onNotesTagClick = useCallback(
tag => {
onApplyFilter({
field: 'notes',
op: 'hasTags',
value: tag,
type: 'string',
});
},
[onApplyFilter],
);

return (
<TransactionTable
Expand Down
11 changes: 2 additions & 9 deletions packages/desktop-client/src/gocardless.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { type GoCardlessToken } from 'loot-core/types/models';

function _authorize(
dispatch: AppDispatch,
upgradingAccountId: string | undefined,
{
onSuccess,
onClose,
Expand All @@ -18,7 +17,6 @@ function _authorize(
pushModal('gocardless-external-msg', {
onMoveExternal: async ({ institutionId }) => {
const resp = await send('gocardless-create-web-token', {
upgradingAccountId,
institutionId,
accessValidForDays: 90,
});
Expand All @@ -28,7 +26,6 @@ function _authorize(
window.Actual.openURLInBrowser(link);

return send('gocardless-poll-web-token', {
upgradingAccountId,
requisitionId,
});
},
Expand All @@ -39,17 +36,13 @@ function _authorize(
);
}

export async function authorizeBank(
dispatch: AppDispatch,
{ upgradingAccountId }: { upgradingAccountId?: string } = {},
) {
_authorize(dispatch, upgradingAccountId, {
export async function authorizeBank(dispatch: AppDispatch) {
_authorize(dispatch, {
onSuccess: async data => {
dispatch(
pushModal('select-linked-accounts', {
accounts: data.accounts,
requisitionId: data.id,
upgradingAccountId,
syncSource: 'goCardless',
}),
);
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-actual/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"eslint-plugin-eslint-plugin": "^5.5.1",
"eslint-plugin-node": "^11.1.0",
"eslint-vitest-rule-tester": "^0.7.1",
"vitest": "^1.6.0"
"vitest": "^1.6.1"
},
"peerDependencies": {
"eslint": ">=7"
Expand Down
41 changes: 17 additions & 24 deletions packages/loot-core/src/client/accounts/accountsSlice.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';

import { send } from '../../platform/client/fetch';
import { type AccountEntity, type TransactionEntity } from '../../types/models';
import { type SyncResponseWithErrors } from '../../server/accounts/app';
import {
type SyncServerGoCardlessAccount,
type AccountEntity,
type TransactionEntity,
type SyncServerSimpleFinAccount,
} from '../../types/models';
import { addNotification } from '../actions';
import {
getAccounts,
Expand Down Expand Up @@ -80,9 +86,9 @@ export const unlinkAccount = createAppAsyncThunk(

type LinkAccountPayload = {
requisitionId: string;
account: unknown;
upgradingId?: AccountEntity['id'];
offBudget?: boolean;
account: SyncServerGoCardlessAccount;
upgradingId?: AccountEntity['id'] | undefined;
offBudget?: boolean | undefined;
};

export const linkAccount = createAppAsyncThunk(
Expand All @@ -103,9 +109,9 @@ export const linkAccount = createAppAsyncThunk(
);

type LinkAccountSimpleFinPayload = {
externalAccount: unknown;
upgradingId?: AccountEntity['id'];
offBudget?: boolean;
externalAccount: SyncServerSimpleFinAccount;
upgradingId?: AccountEntity['id'] | undefined;
offBudget?: boolean | undefined;
};

export const linkAccountSimpleFin = createAppAsyncThunk(
Expand All @@ -124,22 +130,9 @@ export const linkAccountSimpleFin = createAppAsyncThunk(
},
);

type SyncResponse = {
errors: Array<{
type: string;
category: string;
code: string;
message: string;
internal?: string;
}>;
newTransactions: Array<TransactionEntity['id']>;
matchedTransactions: Array<TransactionEntity['id']>;
updatedAccounts: Array<AccountEntity['id']>;
};

function handleSyncResponse(
accountId: AccountEntity['id'],
res: SyncResponse,
res: SyncResponseWithErrors,
dispatch: AppDispatch,
resNewTransactions: Array<TransactionEntity['id']>,
resMatchedTransactions: Array<TransactionEntity['id']>,
Expand All @@ -153,7 +146,7 @@ function handleSyncResponse(
if (error) {
// We only want to mark the account as having problem if it
// was a real syncing error.
if (error.type === 'SyncError') {
if ('type' in error && error.type === 'SyncError') {
dispatch(
markAccountFailed({
id: accountId,
Expand All @@ -168,7 +161,7 @@ function handleSyncResponse(

// Dispatch errors (if any)
errors.forEach(error => {
if (error.type === 'SyncError') {
if ('type' in error && error.type === 'SyncError') {
dispatch(
addNotification({
type: 'error',
Expand All @@ -180,7 +173,7 @@ function handleSyncResponse(
addNotification({
type: 'error',
message: error.message,
internal: error.internal,
internal: 'internal' in error ? error.internal : undefined,
}),
);
}
Expand Down
Loading

0 comments on commit 3bfa2ca

Please sign in to comment.