feat: abstract the uncategorized and all transactions boot wrappers

This commit is contained in:
Ahmed Bouhuolia
2024-03-07 14:31:59 +02:00
parent 62d3e386dd
commit b9a00418fa
9 changed files with 193 additions and 130 deletions

View File

@@ -15,6 +15,7 @@ export const TABLES = {
EXPENSES: 'expenses',
CASHFLOW_ACCOUNTS: 'cashflow_accounts',
CASHFLOW_Transactions: 'cashflow_transactions',
UNCATEGORIZED_CASHFLOW_TRANSACTION: 'UNCATEGORIZED_CASHFLOW_TRANSACTION',
CREDIT_NOTES: 'credit_notes',
VENDOR_CREDITS: 'vendor_credits',
WAREHOUSE_TRANSFERS: 'warehouse_transfers',

View File

@@ -0,0 +1,78 @@
// @ts-nocheck
import React from 'react';
import { flatten, map } from 'lodash';
import { IntersectionObserver } from '@/components';
import { useAccountTransactionsInfinity } from '@/hooks/query';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
const AccountTransactionsAllBootContext = React.createContext();
function flattenInfinityPages(data) {
return flatten(map(data.pages, (page) => page.transactions));
}
interface AccountTransactionsAllPoviderProps {
children: React.ReactNode;
}
/**
* Account transctions all provider.
*/
function AccountTransactionsAllProvider({
children,
}: AccountTransactionsAllPoviderProps) {
const { accountId } = useAccountTransactionsContext();
// Fetch cashflow account transactions list
const {
data: cashflowTransactionsPages,
isFetching: isCashFlowTransactionsFetching,
isLoading: isCashFlowTransactionsLoading,
isSuccess: isCashflowTransactionsSuccess,
fetchNextPage: fetchNextTransactionsPage,
isFetchingNextPage: isCashflowTransactionsFetchingNextPage,
hasNextPage: hasCashflowTransactionsNextPgae,
} = useAccountTransactionsInfinity(accountId, {
page_size: 50,
account_id: accountId,
});
// Memorized the cashflow account transactions.
const cashflowTransactions = React.useMemo(
() =>
isCashflowTransactionsSuccess
? flattenInfinityPages(cashflowTransactionsPages)
: [],
[cashflowTransactionsPages, isCashflowTransactionsSuccess],
);
// Handle the observer ineraction.
const handleObserverInteract = React.useCallback(() => {
if (!isCashFlowTransactionsFetching && hasCashflowTransactionsNextPgae) {
fetchNextTransactionsPage();
}
}, [
isCashFlowTransactionsFetching,
hasCashflowTransactionsNextPgae,
fetchNextTransactionsPage,
]);
// Provider payload.
const provider = {
cashflowTransactions,
isCashFlowTransactionsFetching,
isCashFlowTransactionsLoading,
};
return (
<AccountTransactionsAllBootContext.Provider value={provider}>
{children}
<IntersectionObserver
onIntersect={handleObserverInteract}
enabled={!isCashflowTransactionsFetchingNextPage}
/>
</AccountTransactionsAllBootContext.Provider>
);
}
const useAccountTransactionsAllContext = () =>
React.useContext(AccountTransactionsAllBootContext);
export { AccountTransactionsAllProvider, useAccountTransactionsAllContext };

View File

@@ -18,10 +18,10 @@ import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useMemorizedColumnsWidths } from '@/hooks';
import { useAccountTransactionsColumns, ActionsMenu } from './components';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
import { handleCashFlowTransactionType } from './utils';
import { compose } from '@/utils';
import { useAccountTransactionsAllContext } from './AccountTransactionsAllBoot';
/**
* Account transactions data table.
@@ -41,7 +41,7 @@ function AccountTransactionsDataTable({
// Retrieve list context.
const { cashflowTransactions, isCashFlowTransactionsLoading } =
useAccountTransactionsContext();
useAccountTransactionsAllContext();
// Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] =
@@ -51,11 +51,10 @@ function AccountTransactionsDataTable({
const handleDeleteTransaction = ({ reference_id }) => {
openAlert('account-transaction-delete', { referenceId: reference_id });
};
// Handle view details action.
const handleViewDetailCashflowTransaction = (referenceType) => {
handleCashFlowTransactionType(referenceType, openDrawer);
};
// Handle cell click.
const handleCellClick = (cell, event) => {
const referenceType = cell.row.original;

View File

@@ -1,26 +1,12 @@
// @ts-nocheck
import React from 'react';
import { useParams } from 'react-router-dom';
import { flatten, map } from 'lodash';
import { IntersectionObserver, DashboardInsider } from '@/components';
import {
useAccountTransactionsInfinity,
useCashflowAccounts,
useAccount,
useAccountUncategorizedTransactionsInfinity,
} from '@/hooks/query';
import { DashboardInsider } from '@/components';
import { useCashflowAccounts, useAccount } from '@/hooks/query';
import { useAppQueryString } from '@/hooks';
const AccountTransactionsContext = React.createContext();
function flattenInfinityPages(data) {
return flatten(map(data.pages, (page) => page.transactions));
}
function flattenInfinityPagesData(data) {
return flatten(map(data.pages, (page) => page.data));
}
/**
* Account transctions provider.
*/
@@ -31,64 +17,9 @@ function AccountTransactionsProvider({ query, ...props }) {
const [locationQuery, setLocationQuery] = useAppQueryString();
const filterTab = locationQuery?.filter || 'all';
const setFilterTab = (value: stirng) => {
const setFilterTab = (value: string) => {
setLocationQuery({ filter: value });
};
// Fetch cashflow account transactions list
const {
data: cashflowTransactionsPages,
isFetching: isCashFlowTransactionsFetching,
isLoading: isCashFlowTransactionsLoading,
isSuccess: isCashflowTransactionsSuccess,
fetchNextPage: fetchNextTransactionsPage,
isFetchingNextPage,
hasNextPage,
} = useAccountTransactionsInfinity(
accountId,
{
page_size: 50,
account_id: accountId,
},
{
enabled: filterTab === 'all' || filterTab === 'dashboard',
},
);
const {
data: uncategorizedTransactionsPage,
isFetching: isUncategorizedTransactionFetching,
isLoading: isUncategorizedTransactionsLoading,
isSuccess: isUncategorizedTransactionsSuccess,
fetchNextPage: fetchNextUncategorizedTransactionsPage,
} = useAccountUncategorizedTransactionsInfinity(
accountId,
{
page_size: 50,
},
{
enabled: filterTab === 'uncategorized',
},
);
// Memorized the cashflow account transactions.
const cashflowTransactions = React.useMemo(
() =>
isCashflowTransactionsSuccess
? flattenInfinityPages(cashflowTransactionsPages)
: [],
[cashflowTransactionsPages, isCashflowTransactionsSuccess],
);
// Memorized the cashflow account transactions.
const uncategorizedTransactions = React.useMemo(
() =>
isUncategorizedTransactionsSuccess
? flattenInfinityPagesData(uncategorizedTransactionsPage)
: [],
[uncategorizedTransactionsPage, isUncategorizedTransactionsSuccess],
);
// Fetch cashflow accounts.
const {
data: cashflowAccounts,
@@ -97,27 +28,19 @@ function AccountTransactionsProvider({ query, ...props }) {
} = useCashflowAccounts(query, { keepPreviousData: true });
// Retrieve specific account details.
const {
data: currentAccount,
isFetching: isCurrentAccountFetching,
isLoading: isCurrentAccountLoading,
} = useAccount(accountId, { keepPreviousData: true });
// Handle the observer ineraction.
const handleObserverInteract = React.useCallback(() => {
if (!isFetchingNextPage && hasNextPage) {
fetchNextTransactionsPage();
}
}, [isFetchingNextPage, hasNextPage, fetchNextTransactionsPage]);
// Provider payload.
const provider = {
accountId,
cashflowTransactions,
cashflowAccounts,
currentAccount,
isCashFlowTransactionsFetching,
isCashFlowTransactionsLoading,
isCashFlowAccountsFetching,
isCashFlowAccountsLoading,
isCurrentAccountFetching,
@@ -125,18 +48,11 @@ function AccountTransactionsProvider({ query, ...props }) {
filterTab,
setFilterTab,
uncategorizedTransactions,
isUncategorizedTransactionFetching
};
return (
<DashboardInsider name={'account-transactions'}>
<AccountTransactionsContext.Provider value={provider} {...props} />
<IntersectionObserver
onIntersect={handleObserverInteract}
enabled={!isFetchingNextPage}
/>
</DashboardInsider>
);
}

View File

@@ -13,7 +13,6 @@ import {
import { TABLES } from '@/constants/tables';
import withSettings from '@/containers/Settings/withSettings';
import withAlertsActions from '@/containers/Alert/withAlertActions';
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
import { useMemorizedColumnsWidths } from '@/hooks';
@@ -21,8 +20,7 @@ import {
ActionsMenu,
useAccountUncategorizedTransactionsColumns,
} from './components';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
import { handleCashFlowTransactionType } from './utils';
import { useAccountUncategorizedTransactionsContext } from './AllTransactionsUncategorizedBoot';
import { compose } from '@/utils';
import { DRAWERS } from '@/constants/drawers';
@@ -34,9 +32,6 @@ function AccountTransactionsDataTable({
// #withSettings
cashflowTansactionsTableSize,
// #withAlertsActions
openAlert,
// #withDrawerActions
openDrawer,
}) {
@@ -44,17 +39,12 @@ function AccountTransactionsDataTable({
const columns = useAccountUncategorizedTransactionsColumns();
// Retrieve list context.
const { uncategorizedTransactions, isCashFlowTransactionsLoading } =
useAccountTransactionsContext();
const { uncategorizedTransactions, isUncategorizedTransactionsLoading } =
useAccountUncategorizedTransactionsContext();
// Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] =
useMemorizedColumnsWidths(TABLES.CASHFLOW_Transactions);
// handle delete transaction
const handleDeleteTransaction = ({ reference_id }) => {};
const handleViewDetailCashflowTransaction = (referenceType) => {};
useMemorizedColumnsWidths(TABLES.UNCATEGORIZED_CASHFLOW_TRANSACTION);
// Handle cell click.
const handleCellClick = (cell, event) => {
@@ -69,8 +59,8 @@ function AccountTransactionsDataTable({
columns={columns}
data={uncategorizedTransactions || []}
sticky={true}
loading={isCashFlowTransactionsLoading}
headerLoading={isCashFlowTransactionsLoading}
loading={isUncategorizedTransactionsLoading}
headerLoading={isUncategorizedTransactionsLoading}
expandColumnSpace={1}
expandToggleColumn={2}
selectionColumnWidth={45}
@@ -81,16 +71,12 @@ function AccountTransactionsDataTable({
ContextMenu={ActionsMenu}
onCellClick={handleCellClick}
// #TableVirtualizedListRows props.
vListrowHeight={cashflowTansactionsTableSize == 'small' ? 32 : 40}
vListrowHeight={cashflowTansactionsTableSize === 'small' ? 32 : 40}
vListOverscanRowCount={0}
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}
noResults={<T id={'cash_flow.account_transactions.no_results'} />}
className="table-constrant"
payload={{
onViewDetails: handleViewDetailCashflowTransaction,
onDelete: handleDeleteTransaction,
}}
/>
);
}
@@ -99,7 +85,6 @@ export default compose(
withSettings(({ cashflowTransactionsSettings }) => ({
cashflowTansactionsTableSize: cashflowTransactionsSettings?.tableSize,
})),
withAlertsActions,
withDrawerActions,
)(AccountTransactionsDataTable);

View File

@@ -5,6 +5,7 @@ import '@/style/pages/CashFlow/AccountTransactions/List.scss';
import AccountTransactionsDataTable from './AccountTransactionsDataTable';
import { AccountTransactionsUncategorizeFilter } from './AccountTransactionsUncategorizeFilter';
import { AccountTransactionsAllProvider } from './AccountTransactionsAllBoot';
const Box = styled.div`
margin: 30px 15px;
@@ -20,12 +21,14 @@ const CashflowTransactionsTableCard = styled.div`
export default function AccountTransactionsAll() {
return (
<Box>
<AccountTransactionsUncategorizeFilter />
<AccountTransactionsAllProvider>
<Box>
<AccountTransactionsUncategorizeFilter />
<CashflowTransactionsTableCard>
<AccountTransactionsDataTable />
</CashflowTransactionsTableCard>
</Box>
<CashflowTransactionsTableCard>
<AccountTransactionsDataTable />
</CashflowTransactionsTableCard>
</Box>
</AccountTransactionsAllProvider>
);
}

View File

@@ -4,6 +4,7 @@ import styled from 'styled-components';
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
import AccountTransactionsUncategorizedTable from './AccountTransactionsUncategorizedTable';
import { AccountUncategorizedTransactionsBoot } from './AllTransactionsUncategorizedBoot';
const Box = styled.div`
margin: 30px 15px;
@@ -15,15 +16,16 @@ const CashflowTransactionsTableCard = styled.div`
padding: 30px 18px;
background: #fff;
flex: 0 1;
`
`;
export default function AllTransactionsUncategorized() {
return (
<Box>
<CashflowTransactionsTableCard>
<AccountTransactionsUncategorizedTable />
</CashflowTransactionsTableCard>
</Box>
)
}
<AccountUncategorizedTransactionsBoot>
<Box>
<CashflowTransactionsTableCard>
<AccountTransactionsUncategorizedTable />
</CashflowTransactionsTableCard>
</Box>
</AccountUncategorizedTransactionsBoot>
);
}

View File

@@ -0,0 +1,78 @@
// @ts-nocheck
import React from 'react';
import { flatten, map } from 'lodash';
import { IntersectionObserver } from '@/components';
import { useAccountUncategorizedTransactionsInfinity } from '@/hooks/query';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
const AccountUncategorizedTransactionsContext = React.createContext();
function flattenInfinityPagesData(data) {
return flatten(map(data.pages, (page) => page.data));
}
/**
* Account uncategorized transctions provider.
*/
function AccountUncategorizedTransactionsBoot({ children }) {
const { accountId } = useAccountTransactionsContext();
// Fetches the uncategorized transactions.
const {
data: uncategorizedTransactionsPage,
isFetching: isUncategorizedTransactionFetching,
isLoading: isUncategorizedTransactionsLoading,
isSuccess: isUncategorizedTransactionsSuccess,
isFetchingNextPage: isUncategorizedTransactionFetchNextPage,
fetchNextPage: fetchNextUncategorizedTransactionsPage,
hasNextPage: hasUncategorizedTransactionsNextPage,
} = useAccountUncategorizedTransactionsInfinity(accountId, {
page_size: 50,
});
// Memorized the cashflow account transactions.
const uncategorizedTransactions = React.useMemo(
() =>
isUncategorizedTransactionsSuccess
? flattenInfinityPagesData(uncategorizedTransactionsPage)
: [],
[uncategorizedTransactionsPage, isUncategorizedTransactionsSuccess],
);
// Handle the observer ineraction.
const handleObserverInteract = React.useCallback(() => {
if (
!isUncategorizedTransactionFetching &&
hasUncategorizedTransactionsNextPage
) {
fetchNextUncategorizedTransactionsPage();
}
}, [
isUncategorizedTransactionFetching,
hasUncategorizedTransactionsNextPage,
fetchNextUncategorizedTransactionsPage,
]);
// Provider payload.
const provider = {
uncategorizedTransactions,
isUncategorizedTransactionFetching,
isUncategorizedTransactionsLoading,
};
return (
<AccountUncategorizedTransactionsContext.Provider value={provider}>
{children}
<IntersectionObserver
onIntersect={handleObserverInteract}
enabled={!isUncategorizedTransactionFetchNextPage}
/>
</AccountUncategorizedTransactionsContext.Provider>
);
}
const useAccountUncategorizedTransactionsContext = () =>
React.useContext(AccountUncategorizedTransactionsContext);
export {
AccountUncategorizedTransactionsBoot,
useAccountUncategorizedTransactionsContext,
};

View File

@@ -39,6 +39,7 @@ export function ActionsMenu({
</Menu>
);
}
/**
* Retrieve account transctions table columns.
*/