mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: bulk categorizing bank transactions
This commit is contained in:
@@ -9,10 +9,15 @@ import {
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
Tooltip,
|
||||
Checkbox,
|
||||
} from '@blueprintjs/core';
|
||||
import { Box, FormatDateCell, Icon, MaterialProgressBar } from '@/components';
|
||||
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
|
||||
import { safeCallback } from '@/utils';
|
||||
import {
|
||||
useAddTransactionsToCategorizeSelected,
|
||||
useRemoveTransactionsToCategorizeSelected,
|
||||
} from '@/hooks/state/banking';
|
||||
|
||||
export function ActionsMenu({
|
||||
payload: { onUncategorize, onUnmatch },
|
||||
@@ -183,6 +188,20 @@ function statusAccessor(transaction) {
|
||||
* Retrieve account uncategorized transctions table columns.
|
||||
*/
|
||||
export function useAccountUncategorizedTransactionsColumns() {
|
||||
const addTransactionsToCategorizeSelected =
|
||||
useAddTransactionsToCategorizeSelected();
|
||||
|
||||
const removeTransactionsToCategorizeSelected =
|
||||
useRemoveTransactionsToCategorizeSelected();
|
||||
|
||||
const handleChange = (value) => (event) => {
|
||||
if (event.currentTarget.checked) {
|
||||
addTransactionsToCategorizeSelected(value.id);
|
||||
} else {
|
||||
removeTransactionsToCategorizeSelected(value.id);
|
||||
}
|
||||
};
|
||||
|
||||
return React.useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -242,6 +261,15 @@ export function useAccountUncategorizedTransactionsColumns() {
|
||||
align: 'right',
|
||||
clickable: true,
|
||||
},
|
||||
{
|
||||
id: 'categorize_include',
|
||||
Header: 'Include',
|
||||
accessor: (value) => <Checkbox large onChange={handleChange(value)} />,
|
||||
width: 10,
|
||||
minWidth: 10,
|
||||
maxWidth: 10,
|
||||
align: 'right',
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
resetUncategorizedTransactionsSelected,
|
||||
resetExcludedTransactionsSelected,
|
||||
setExcludedTransactionsSelected,
|
||||
resetTransactionsToCategorizeSelected,
|
||||
setTransactionsToCategorizeSelected,
|
||||
} from '@/store/banking/banking.reducer';
|
||||
|
||||
export interface WithBankingActionsProps {
|
||||
@@ -23,6 +25,9 @@ export interface WithBankingActionsProps {
|
||||
|
||||
setExcludedTransactionsSelected: (ids: Array<string | number>) => void;
|
||||
resetExcludedTransactionsSelected: () => void;
|
||||
|
||||
setTransactionsToCategorizeSelected: (ids: Array<string | number>) => void;
|
||||
resetTransactionsToCategorizeSelected: () => void;
|
||||
}
|
||||
|
||||
const mapDipatchToProps = (dispatch: any): WithBankingActionsProps => ({
|
||||
@@ -56,6 +61,11 @@ const mapDipatchToProps = (dispatch: any): WithBankingActionsProps => ({
|
||||
),
|
||||
resetExcludedTransactionsSelected: () =>
|
||||
dispatch(resetExcludedTransactionsSelected()),
|
||||
|
||||
setTransactionsToCategorizeSelected: (ids: Array<string | number>) =>
|
||||
dispatch(setTransactionsToCategorizeSelected({ ids })),
|
||||
resetTransactionsToCategorizeSelected: () =>
|
||||
dispatch(resetTransactionsToCategorizeSelected()),
|
||||
});
|
||||
|
||||
export const withBankingActions = connect<
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import {
|
||||
getPlaidToken,
|
||||
setPlaidId,
|
||||
resetPlaidId,
|
||||
setTransactionsToCategorizeSelected,
|
||||
resetTransactionsToCategorizeSelected,
|
||||
getTransactionsToCategorizeSelected,
|
||||
addTransactionsToCategorizeSelected,
|
||||
removeTransactionsToCategorizeSelected,
|
||||
} from '@/store/banking/banking.reducer';
|
||||
import { useCallback } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
export const useSetBankingPlaidToken = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -30,3 +35,50 @@ export const useResetBankingPlaidToken = () => {
|
||||
dispatch(resetPlaidId());
|
||||
}, [dispatch]);
|
||||
};
|
||||
|
||||
export const useGetTransactionsToCategorizeSelected = () => {
|
||||
const selectedTransactions = useSelector(getTransactionsToCategorizeSelected);
|
||||
|
||||
return useMemo(() => selectedTransactions, [selectedTransactions]);
|
||||
};
|
||||
|
||||
export const useSetTransactionsToCategorizeSelected = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return useCallback(
|
||||
(ids: Array<string | number>) => {
|
||||
return dispatch(setTransactionsToCategorizeSelected({ ids }));
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
};
|
||||
|
||||
export const useAddTransactionsToCategorizeSelected = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return useCallback(
|
||||
(id: string | number) => {
|
||||
return dispatch(addTransactionsToCategorizeSelected({ id }));
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
};
|
||||
|
||||
export const useRemoveTransactionsToCategorizeSelected = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return useCallback(
|
||||
(id: string | number) => {
|
||||
return dispatch(removeTransactionsToCategorizeSelected({ id }));
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
};
|
||||
|
||||
export const useResetTransactionsToCategorizeSelected = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return useCallback(() => {
|
||||
dispatch(resetTransactionsToCategorizeSelected());
|
||||
}, [dispatch]);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { uniq } from 'lodash';
|
||||
import { PayloadAction, createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
interface StorePlaidState {
|
||||
@@ -8,6 +9,7 @@ interface StorePlaidState {
|
||||
|
||||
uncategorizedTransactionsSelected: Array<number | string>;
|
||||
excludedTransactionsSelected: Array<number | string>;
|
||||
transactionsToCategorizeSelected: Array<number | string>;
|
||||
}
|
||||
|
||||
export const PlaidSlice = createSlice({
|
||||
@@ -22,6 +24,7 @@ export const PlaidSlice = createSlice({
|
||||
},
|
||||
uncategorizedTransactionsSelected: [],
|
||||
excludedTransactionsSelected: [],
|
||||
transactionsToCategorizeSelected: [],
|
||||
} as StorePlaidState,
|
||||
reducers: {
|
||||
setPlaidId: (state: StorePlaidState, action: PayloadAction<string>) => {
|
||||
@@ -79,6 +82,37 @@ export const PlaidSlice = createSlice({
|
||||
resetExcludedTransactionsSelected: (state: StorePlaidState) => {
|
||||
state.excludedTransactionsSelected = [];
|
||||
},
|
||||
|
||||
setTransactionsToCategorizeSelected: (
|
||||
state: StorePlaidState,
|
||||
action: PayloadAction<{ ids: Array<string | number> }>,
|
||||
) => {
|
||||
state.transactionsToCategorizeSelected = action.payload.ids;
|
||||
},
|
||||
|
||||
addTransactionsToCategorizeSelected: (
|
||||
state: StorePlaidState,
|
||||
action: PayloadAction<{ id: string | number }>,
|
||||
) => {
|
||||
state.transactionsToCategorizeSelected = uniq([
|
||||
...state.transactionsToCategorizeSelected,
|
||||
action.payload.id,
|
||||
]);
|
||||
},
|
||||
|
||||
removeTransactionsToCategorizeSelected: (
|
||||
state: StorePlaidState,
|
||||
action: PayloadAction<{ id: string | number }>,
|
||||
) => {
|
||||
state.transactionsToCategorizeSelected =
|
||||
state.transactionsToCategorizeSelected.filter(
|
||||
(t) => t !== action.payload.id,
|
||||
);
|
||||
},
|
||||
|
||||
resetTransactionsToCategorizeSelected: (state: StorePlaidState) => {
|
||||
state.transactionsToCategorizeSelected = [];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -93,6 +127,12 @@ export const {
|
||||
resetUncategorizedTransactionsSelected,
|
||||
setExcludedTransactionsSelected,
|
||||
resetExcludedTransactionsSelected,
|
||||
setTransactionsToCategorizeSelected,
|
||||
addTransactionsToCategorizeSelected,
|
||||
removeTransactionsToCategorizeSelected,
|
||||
resetTransactionsToCategorizeSelected,
|
||||
} = PlaidSlice.actions;
|
||||
|
||||
export const getPlaidToken = (state: any) => state.plaid.plaidToken;
|
||||
export const getTransactionsToCategorizeSelected = (state: any) =>
|
||||
state.plaid.transactionsToCategorizeSelected;
|
||||
|
||||
Reference in New Issue
Block a user