Merge pull request #587 from bigcapitalhq/big-244-uncategorize-bank-transactions-in-bulk

feat: Uncategorize bank transactions in bulk
This commit is contained in:
Ahmed Bouhuolia
2024-08-12 10:11:55 +02:00
committed by GitHub
11 changed files with 323 additions and 6 deletions

View File

@@ -64,6 +64,7 @@ function AccountTransactionsActionsBar({
uncategorizedTransationsIdsSelected,
excludedTransactionsIdsSelected,
openMatchingTransactionAside,
categorizedTransactionsSelected,
// #withBankingActions
enableMultipleCategorization,
@@ -194,7 +195,7 @@ function AccountTransactionsActionsBar({
// Handle multi select transactions for categorization or matching.
const handleMultipleCategorizingSwitch = (event) => {
enableMultipleCategorization(event.currentTarget.checked);
}
};
// Handle resume bank feeds syncing.
const handleResumeFeedsSyncing = () => {
openAlert('resume-feeds-syncing-bank-accounnt', {
@@ -208,6 +209,13 @@ function AccountTransactionsActionsBar({
});
};
// Handles uncategorize the categorized transactions in bulk.
const handleUncategorizeCategorizedBulkBtnClick = () => {
openAlert('uncategorize-transactions-bulk', {
uncategorizeTransactionsIds: categorizedTransactionsSelected,
});
};
return (
<DashboardActionsBar>
<NavbarGroup>
@@ -297,6 +305,14 @@ function AccountTransactionsActionsBar({
disabled={isUnexcludingLoading}
/>
)}
{!isEmpty(categorizedTransactionsSelected) && (
<Button
text={'Uncategorize'}
onClick={handleUncategorizeCategorizedBulkBtnClick}
intent={Intent.DANGER}
minimal
/>
)}
</NavbarGroup>
<NavbarGroup align={Alignment.RIGHT}>
@@ -379,10 +395,12 @@ export default compose(
uncategorizedTransationsIdsSelected,
excludedTransactionsIdsSelected,
openMatchingTransactionAside,
categorizedTransactionsSelected,
}) => ({
uncategorizedTransationsIdsSelected,
excludedTransactionsIdsSelected,
openMatchingTransactionAside,
categorizedTransactionsSelected,
}),
),
withBankingActions,

View File

@@ -22,10 +22,11 @@ import { useMemorizedColumnsWidths } from '@/hooks';
import { useAccountTransactionsColumns, ActionsMenu } from './components';
import { useAccountTransactionsAllContext } from './AccountTransactionsAllBoot';
import { useUnmatchMatchedUncategorizedTransaction } from '@/hooks/query/bank-rules';
import { useUncategorizeTransaction } from '@/hooks/query';
import { handleCashFlowTransactionType } from './utils';
import { compose } from '@/utils';
import { useUncategorizeTransaction } from '@/hooks/query';
import { withBankingActions } from '../withBankingActions';
/**
* Account transactions data table.
@@ -39,6 +40,9 @@ function AccountTransactionsDataTable({
// #withDrawerActions
openDrawer,
// #withBankingActions
setCategorizedTransactionsSelected,
}) {
// Retrieve table columns.
const columns = useAccountTransactionsColumns();
@@ -97,6 +101,15 @@ function AccountTransactionsDataTable({
});
};
// Handle selected rows change.
const handleSelectedRowsChange = (selected) => {
const selectedIds = selected
?.filter((row) => row.original.uncategorized_transaction_id)
?.map((row) => row.original.uncategorized_transaction_id);
setCategorizedTransactionsSelected(selectedIds);
};
return (
<CashflowTransactionsTable
noInitialFetch={true}
@@ -119,6 +132,8 @@ function AccountTransactionsDataTable({
vListOverscanRowCount={0}
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}
selectionColumn={true}
onSelectedRowsChange={handleSelectedRowsChange}
noResults={<T id={'cash_flow.account_transactions.no_results'} />}
className="table-constrant"
payload={{
@@ -136,6 +151,7 @@ export default compose(
})),
withAlertsActions,
withDrawerActions,
withBankingActions,
)(AccountTransactionsDataTable);
const DashboardConstrantTable = styled(DataTable)`

View File

@@ -0,0 +1,69 @@
// @ts-nocheck
import React from 'react';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster, FormattedMessage as T } from '@/components';
import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect';
import withAlertActions from '@/containers/Alert/withAlertActions';
import { useUncategorizeTransactionsBulkAction } from '@/hooks/query/bank-transactions';
import { compose } from '@/utils';
/**
* Uncategorize bank account transactions in build alert.
*/
function UncategorizeBankTransactionsBulkAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { uncategorizeTransactionsIds },
// #withAlertActions
closeAlert,
}) {
const { mutateAsync: uncategorizeTransactions, isLoading } =
useUncategorizeTransactionsBulkAction();
// Handle activate item alert cancel.
const handleCancelActivateItem = () => {
closeAlert(name);
};
// Handle confirm item activated.
const handleConfirmItemActivate = () => {
uncategorizeTransactions({ ids: uncategorizeTransactionsIds })
.then(() => {
AppToaster.show({
message: 'The bank feeds of the bank account has been resumed.',
intent: Intent.SUCCESS,
});
})
.catch((error) => {})
.finally(() => {
closeAlert(name);
});
};
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={'Uncategorize Transactions'}
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelActivateItem}
loading={isLoading}
onConfirm={handleConfirmItemActivate}
>
<p>
Are you sure want to uncategorize the selected bank transactions, this
action is not reversible but you can always categorize them again?
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
)(UncategorizeBankTransactionsBulkAlert);

View File

@@ -9,6 +9,10 @@ const PauseFeedsBankAccountAlert = React.lazy(
() => import('./PauseFeedsBankAccount'),
);
const UncategorizeTransactionsBulkAlert = React.lazy(
() => import('./UncategorizeBankTransactionsBulkAlert'),
);
/**
* Bank account alerts.
*/
@@ -21,4 +25,8 @@ export const BankAccountAlerts = [
name: 'pause-feeds-syncing-bank-accounnt',
component: PauseFeedsBankAccountAlert,
},
{
name: 'uncategorize-transactions-bulk',
component: UncategorizeTransactionsBulkAlert,
},
];

View File

@@ -22,6 +22,9 @@ export const withBanking = (mapState) => {
transactionsToCategorizeIdsSelected:
state.plaid.transactionsToCategorizeSelected,
categorizedTransactionsSelected:
state.plaid.categorizedTransactionsSelected,
};
return mapState ? mapState(mapped, state, props) : mapped;
};

View File

@@ -13,6 +13,8 @@ import {
enableMultipleCategorization,
addTransactionsToCategorizeSelected,
removeTransactionsToCategorizeSelected,
setCategorizedTransactionsSelected,
resetCategorizedTransactionsSelected,
} from '@/store/banking/banking.reducer';
export interface WithBankingActionsProps {
@@ -35,6 +37,9 @@ export interface WithBankingActionsProps {
resetTransactionsToCategorizeSelected: () => void;
enableMultipleCategorization: (enable: boolean) => void;
setCategorizedTransactionsSelected: (ids: Array<string | number>) => void;
resetCategorizedTransactionsSelected: () => void;
}
const mapDipatchToProps = (dispatch: any): WithBankingActionsProps => ({
@@ -120,6 +125,19 @@ const mapDipatchToProps = (dispatch: any): WithBankingActionsProps => ({
*/
enableMultipleCategorization: (enable: boolean) =>
dispatch(enableMultipleCategorization({ enable })),
/**
* Sets the selected ids of the categorized transactions.
* @param {Array<string | number>} ids
*/
setCategorizedTransactionsSelected: (ids: Array<string | number>) =>
dispatch(setCategorizedTransactionsSelected({ ids })),
/**
* Resets the selected categorized transcations.
*/
resetCategorizedTransactionsSelected: () =>
dispatch(resetCategorizedTransactionsSelected()),
});
export const withBankingActions = connect<