mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: merge the boot provider of categorize and matching forms
This commit is contained in:
@@ -189,7 +189,7 @@ export function useAccountUncategorizedTransactionsColumns() {
|
||||
{
|
||||
id: 'deposit',
|
||||
Header: intl.get('cash_flow.label.deposit'),
|
||||
accessor: 'formattet_deposit_amount',
|
||||
accessor: 'formatted_deposit_amount',
|
||||
width: 40,
|
||||
className: 'deposit',
|
||||
textOverview: true,
|
||||
|
||||
@@ -2,20 +2,34 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { first } from 'lodash';
|
||||
import { DrawerLoading } from '@/components';
|
||||
import {
|
||||
useAccounts,
|
||||
useBranches,
|
||||
useUncategorizedTransaction,
|
||||
} from '@/hooks/query';
|
||||
import { useAccounts, useBranches } from '@/hooks/query';
|
||||
import { useFeatureCan } from '@/hooks/state';
|
||||
import { Features } from '@/constants';
|
||||
import { Spinner } from '@blueprintjs/core';
|
||||
|
||||
const CategorizeTransactionBootContext = React.createContext();
|
||||
interface CategorizeTransactionBootProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
interface CategorizeTransactionBootValue {
|
||||
branches: any;
|
||||
accounts: any;
|
||||
isBranchesLoading: boolean;
|
||||
isAccountsLoading: boolean;
|
||||
primaryBranch: any;
|
||||
}
|
||||
|
||||
const CategorizeTransactionBootContext =
|
||||
React.createContext<CategorizeTransactionBootValue>(
|
||||
{} as CategorizeTransactionBootValue,
|
||||
);
|
||||
|
||||
/**
|
||||
* Categorize transcation boot.
|
||||
*/
|
||||
function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
||||
function CategorizeTransactionBoot({
|
||||
...props
|
||||
}: CategorizeTransactionBootProps) {
|
||||
// Detarmines whether the feature is enabled.
|
||||
const { featureCan } = useFeatureCan();
|
||||
const isBranchFeatureCan = featureCan(Features.Branches);
|
||||
@@ -28,12 +42,6 @@ function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
||||
{},
|
||||
{ enabled: isBranchFeatureCan },
|
||||
);
|
||||
// Retrieves the uncategorized transaction.
|
||||
const {
|
||||
data: uncategorizedTransaction,
|
||||
isLoading: isUncategorizedTransactionLoading,
|
||||
} = useUncategorizedTransaction(uncategorizedTransactionId);
|
||||
|
||||
// Retrieves the primary branch.
|
||||
const primaryBranch = useMemo(
|
||||
() => branches?.find((b) => b.primary) || first(branches),
|
||||
@@ -41,18 +49,17 @@ function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
||||
);
|
||||
|
||||
const provider = {
|
||||
uncategorizedTransactionId,
|
||||
uncategorizedTransaction,
|
||||
isUncategorizedTransactionLoading,
|
||||
branches,
|
||||
accounts,
|
||||
isBranchesLoading,
|
||||
isAccountsLoading,
|
||||
primaryBranch,
|
||||
};
|
||||
const isLoading =
|
||||
isBranchesLoading || isUncategorizedTransactionLoading || isAccountsLoading;
|
||||
const isLoading = isBranchesLoading || isAccountsLoading;
|
||||
|
||||
if (isLoading) {
|
||||
<Spinner size={30} />;
|
||||
}
|
||||
return (
|
||||
<DrawerLoading loading={isLoading}>
|
||||
<CategorizeTransactionBootContext.Provider value={provider} {...props} />
|
||||
@@ -61,6 +68,8 @@ function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
||||
}
|
||||
|
||||
const useCategorizeTransactionBoot = () =>
|
||||
React.useContext(CategorizeTransactionBootContext);
|
||||
React.useContext<CategorizeTransactionBootValue>(
|
||||
CategorizeTransactionBootContext,
|
||||
);
|
||||
|
||||
export { CategorizeTransactionBoot, useCategorizeTransactionBoot };
|
||||
|
||||
@@ -3,9 +3,10 @@ import styled from 'styled-components';
|
||||
import { DrawerBody } from '@/components';
|
||||
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
||||
import { useCategorizeTransactionTabsBoot } from '@/containers/CashFlow/CategorizeTransactionAside/CategorizeTransactionTabsBoot';
|
||||
|
||||
export function CategorizeTransactionContent({}) {
|
||||
const uncategorizedTransactionId = 4;
|
||||
const { uncategorizedTransactionId } = useCategorizeTransactionTabsBoot();
|
||||
|
||||
return (
|
||||
<CategorizeTransactionBoot
|
||||
|
||||
@@ -16,6 +16,7 @@ import { compose } from '@/utils';
|
||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||
import { AppToaster } from '@/components';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { useCategorizeTransactionTabsBoot } from '@/containers/CashFlow/CategorizeTransactionAside/CategorizeTransactionTabsBoot';
|
||||
|
||||
/**
|
||||
* Categorize cashflow transaction form dialog content.
|
||||
@@ -24,11 +25,9 @@ function CategorizeTransactionFormRoot({
|
||||
// #withDrawerActions
|
||||
closeDrawer,
|
||||
}) {
|
||||
const {
|
||||
uncategorizedTransactionId,
|
||||
uncategorizedTransaction,
|
||||
primaryBranch,
|
||||
} = useCategorizeTransactionBoot();
|
||||
const { uncategorizedTransactionId, uncategorizedTransaction } =
|
||||
useCategorizeTransactionTabsBoot();
|
||||
const { primaryBranch } = useCategorizeTransactionBoot();
|
||||
const { mutateAsync: categorizeTransaction } = useCategorizeTransaction();
|
||||
|
||||
// Callbacks handles form submit.
|
||||
|
||||
@@ -5,7 +5,7 @@ import { FormGroup } from '@blueprintjs/core';
|
||||
import { FFormGroup, FSelect, } from '@/components';
|
||||
import { getAddMoneyInOptions, getAddMoneyOutOptions } from '@/constants';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { useCategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||
import { useCategorizeTransactionTabsBoot } from '@/containers/CashFlow/CategorizeTransactionAside/CategorizeTransactionTabsBoot';
|
||||
|
||||
// Retrieves the add money in button options.
|
||||
const MoneyInOptions = getAddMoneyInOptions();
|
||||
@@ -18,7 +18,7 @@ const Title = styled('h3')`
|
||||
`;
|
||||
|
||||
export function CategorizeTransactionFormContent() {
|
||||
const { uncategorizedTransaction } = useCategorizeTransactionBoot();
|
||||
const { uncategorizedTransaction } = useCategorizeTransactionTabsBoot();
|
||||
|
||||
const transactionTypes = uncategorizedTransaction?.is_deposit_transaction
|
||||
? MoneyInOptions
|
||||
|
||||
@@ -3,18 +3,17 @@ import * as R from 'ramda';
|
||||
import { Button, Classes, Intent } from '@blueprintjs/core';
|
||||
import { useFormikContext } from 'formik';
|
||||
import styled from 'styled-components';
|
||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
import { Group } from '@/components';
|
||||
import { withBankingActions } from '@/containers/CashFlow/withBankingActions';
|
||||
|
||||
function CategorizeTransactionFormFooterRoot({
|
||||
// #withDrawerActions
|
||||
closeDrawer,
|
||||
// #withBankingActions
|
||||
closeMatchingTransactionAside,
|
||||
}) {
|
||||
const { isSubmitting } = useFormikContext();
|
||||
|
||||
const handleClose = () => {
|
||||
closeDrawer(DRAWERS.CATEGORIZE_TRANSACTION);
|
||||
closeMatchingTransactionAside();
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -23,8 +22,8 @@ function CategorizeTransactionFormFooterRoot({
|
||||
<Group spacing={10}>
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
loading={isSubmitting}
|
||||
style={{ minWidth: '75px' }}
|
||||
loading={isSubmitting}
|
||||
type="submit"
|
||||
>
|
||||
Save
|
||||
@@ -43,7 +42,7 @@ function CategorizeTransactionFormFooterRoot({
|
||||
);
|
||||
}
|
||||
|
||||
export const CategorizeTransactionFormFooter = R.compose(withDrawerActions)(
|
||||
export const CategorizeTransactionFormFooter = R.compose(withBankingActions)(
|
||||
CategorizeTransactionFormFooterRoot,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import * as R from 'ramda';
|
||||
import { Aside } from '@/components/Aside/Aside';
|
||||
import { CategorizeTransactionTabs } from './CategorizeTransactionTabs';
|
||||
@@ -5,24 +6,40 @@ import {
|
||||
WithBankingActionsProps,
|
||||
withBankingActions,
|
||||
} from '../withBankingActions';
|
||||
import { CategorizeTransactionTabsBoot } from './CategorizeTransactionTabsBoot';
|
||||
import { withBanking } from '../withBanking';
|
||||
|
||||
interface CategorizeTransactionAsideProps extends WithBankingActionsProps {}
|
||||
|
||||
function CategorizeTransactionAsideRoot({
|
||||
// #withBankingActions
|
||||
closeMatchingTransactionAside,
|
||||
|
||||
// #withBanking
|
||||
selectedUncategorizedTransactionId,
|
||||
}: CategorizeTransactionAsideProps) {
|
||||
const handleClose = () => {
|
||||
closeMatchingTransactionAside();
|
||||
};
|
||||
const uncategorizedTransactionId = selectedUncategorizedTransactionId;
|
||||
|
||||
if (!selectedUncategorizedTransactionId) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<Aside title={'Categorize Bank Transaction'} onClose={handleClose}>
|
||||
<CategorizeTransactionTabs />
|
||||
<CategorizeTransactionTabsBoot
|
||||
uncategorizedTransactionId={uncategorizedTransactionId}
|
||||
>
|
||||
<CategorizeTransactionTabs />
|
||||
</CategorizeTransactionTabsBoot>
|
||||
</Aside>
|
||||
);
|
||||
}
|
||||
|
||||
export const CategorizeTransactionAside = R.compose(withBankingActions)(
|
||||
CategorizeTransactionAsideRoot,
|
||||
);
|
||||
export const CategorizeTransactionAside = R.compose(
|
||||
withBankingActions,
|
||||
withBanking(({ selectedUncategorizedTransactionId }) => ({
|
||||
selectedUncategorizedTransactionId,
|
||||
})),
|
||||
)(CategorizeTransactionAsideRoot);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { CategorizeTransactionContent } from '../CategorizeTransaction/drawers/C
|
||||
|
||||
export function CategorizeTransactionTabs() {
|
||||
return (
|
||||
<Tabs large className={styles.tabs}>
|
||||
<Tabs large renderActiveTabPanelOnly className={styles.tabs}>
|
||||
<Tab
|
||||
id="categorize"
|
||||
title="Categorize Transaction"
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Spinner } from '@blueprintjs/core';
|
||||
import { useUncategorizedTransaction } from '@/hooks/query';
|
||||
|
||||
interface CategorizeTransactionTabsValue {
|
||||
uncategorizedTransactionId: number;
|
||||
isUncategorizedTransactionLoading: boolean;
|
||||
uncategorizedTransaction: any;
|
||||
}
|
||||
|
||||
interface CategorizeTransactionTabsBootProps {
|
||||
uncategorizedTransactionId: number;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
const CategorizeTransactionTabsBootContext =
|
||||
React.createContext<CategorizeTransactionTabsValue>(
|
||||
{} as CategorizeTransactionTabsValue,
|
||||
);
|
||||
|
||||
/**
|
||||
* Categorize transcation tabs boot.
|
||||
*/
|
||||
export function CategorizeTransactionTabsBoot({
|
||||
uncategorizedTransactionId,
|
||||
children,
|
||||
}: CategorizeTransactionTabsBootProps) {
|
||||
const {
|
||||
data: uncategorizedTransaction,
|
||||
isLoading: isUncategorizedTransactionLoading,
|
||||
} = useUncategorizedTransaction(uncategorizedTransactionId);
|
||||
|
||||
const provider = {
|
||||
uncategorizedTransactionId,
|
||||
uncategorizedTransaction,
|
||||
isUncategorizedTransactionLoading,
|
||||
};
|
||||
const isLoading = isUncategorizedTransactionLoading;
|
||||
|
||||
// Use a key prop to force re-render of children when uncategorizedTransactionId changes
|
||||
const childrenPerKey = React.useMemo(() => {
|
||||
return React.Children.map(children, (child) =>
|
||||
React.cloneElement(child, { key: uncategorizedTransactionId }),
|
||||
);
|
||||
}, [children, uncategorizedTransactionId]);
|
||||
|
||||
if (isLoading) {
|
||||
return <Spinner size={30} />;
|
||||
}
|
||||
return (
|
||||
<CategorizeTransactionTabsBootContext.Provider value={provider}>
|
||||
{childrenPerKey}
|
||||
</CategorizeTransactionTabsBootContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export const useCategorizeTransactionTabsBoot = () =>
|
||||
React.useContext<CategorizeTransactionTabsValue>(
|
||||
CategorizeTransactionTabsBootContext,
|
||||
);
|
||||
@@ -13,6 +13,7 @@ import { FastField, FastFieldProps, Form, Formik } from 'formik';
|
||||
import { useMatchTransaction } from '@/hooks/query/bank-rules';
|
||||
import { MatchingTransactionFormValues } from './types';
|
||||
import { transformToReq, useGetPendingAmountMatched } from './utils';
|
||||
import { useCategorizeTransactionTabsBoot } from './CategorizeTransactionTabsBoot';
|
||||
import {
|
||||
WithBankingActionsProps,
|
||||
withBankingActions,
|
||||
@@ -23,7 +24,7 @@ const initialValues = {
|
||||
};
|
||||
|
||||
export function MatchingBankTransaction() {
|
||||
const uncategorizedTransactionId = 4;
|
||||
const { uncategorizedTransactionId } = useCategorizeTransactionTabsBoot();
|
||||
const { mutateAsync: matchTransaction } = useMatchTransaction();
|
||||
|
||||
// Handles the form submitting.
|
||||
@@ -191,7 +192,6 @@ const MatchTransactionFooter = R.compose(withBankingActions)(
|
||||
const handleCancelBtnClick = () => {
|
||||
closeMatchingTransactionAside();
|
||||
};
|
||||
|
||||
const totalPending = useGetPendingAmountMatched();
|
||||
|
||||
return (
|
||||
@@ -202,7 +202,7 @@ const MatchTransactionFooter = R.compose(withBankingActions)(
|
||||
Add Reconcile Transaction +
|
||||
</AnchorButton>
|
||||
|
||||
<Text style={{ fontSize: 13 }} tagName='span'>
|
||||
<Text style={{ fontSize: 13 }} tagName="span">
|
||||
Pending <FormatNumber value={totalPending} currency={'USD'} />
|
||||
</Text>
|
||||
</Group>
|
||||
|
||||
Reference in New Issue
Block a user