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', EXPENSES: 'expenses',
CASHFLOW_ACCOUNTS: 'cashflow_accounts', CASHFLOW_ACCOUNTS: 'cashflow_accounts',
CASHFLOW_Transactions: 'cashflow_transactions', CASHFLOW_Transactions: 'cashflow_transactions',
UNCATEGORIZED_CASHFLOW_TRANSACTION: 'UNCATEGORIZED_CASHFLOW_TRANSACTION',
CREDIT_NOTES: 'credit_notes', CREDIT_NOTES: 'credit_notes',
VENDOR_CREDITS: 'vendor_credits', VENDOR_CREDITS: 'vendor_credits',
WAREHOUSE_TRANSFERS: 'warehouse_transfers', 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 { useMemorizedColumnsWidths } from '@/hooks';
import { useAccountTransactionsColumns, ActionsMenu } from './components'; import { useAccountTransactionsColumns, ActionsMenu } from './components';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
import { handleCashFlowTransactionType } from './utils'; import { handleCashFlowTransactionType } from './utils';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { useAccountTransactionsAllContext } from './AccountTransactionsAllBoot';
/** /**
* Account transactions data table. * Account transactions data table.
@@ -41,7 +41,7 @@ function AccountTransactionsDataTable({
// Retrieve list context. // Retrieve list context.
const { cashflowTransactions, isCashFlowTransactionsLoading } = const { cashflowTransactions, isCashFlowTransactionsLoading } =
useAccountTransactionsContext(); useAccountTransactionsAllContext();
// Local storage memorizing columns widths. // Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] = const [initialColumnsWidths, , handleColumnResizing] =
@@ -51,11 +51,10 @@ function AccountTransactionsDataTable({
const handleDeleteTransaction = ({ reference_id }) => { const handleDeleteTransaction = ({ reference_id }) => {
openAlert('account-transaction-delete', { referenceId: reference_id }); openAlert('account-transaction-delete', { referenceId: reference_id });
}; };
// Handle view details action.
const handleViewDetailCashflowTransaction = (referenceType) => { const handleViewDetailCashflowTransaction = (referenceType) => {
handleCashFlowTransactionType(referenceType, openDrawer); handleCashFlowTransactionType(referenceType, openDrawer);
}; };
// Handle cell click. // Handle cell click.
const handleCellClick = (cell, event) => { const handleCellClick = (cell, event) => {
const referenceType = cell.row.original; const referenceType = cell.row.original;

View File

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

View File

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

View File

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

View File

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