diff --git a/packages/webapp/src/components/AppShell/AppContentShell/AppContentShell.tsx b/packages/webapp/src/components/AppShell/AppContentShell/AppContentShell.tsx
index da442eb6e..83299110a 100644
--- a/packages/webapp/src/components/AppShell/AppContentShell/AppContentShell.tsx
+++ b/packages/webapp/src/components/AppShell/AppContentShell/AppContentShell.tsx
@@ -1,5 +1,9 @@
-import React from 'react';
-import { AppShellProvider, useAppShellContext } from './AppContentShellProvider';
+// @ts-nocheck
+import React, { forwardRef, Ref } from 'react';
+import {
+ AppShellProvider,
+ useAppShellContext,
+} from './AppContentShellProvider';
import { Box, BoxProps } from '../../Layout';
import styles from './AppContentShell.module.scss';
@@ -12,50 +16,73 @@ interface AppContentShellProps {
hideMain?: boolean;
}
-export function AppContentShell({
- asideProps,
- mainProps,
- topbarOffset = 0,
- hideAside = false,
- hideMain = false,
- ...restProps
-}: AppContentShellProps) {
- return (
-
-
-
- );
-}
+export const AppContentShell = forwardRef(
+ (
+ {
+ asideProps,
+ mainProps,
+ topbarOffset = 0,
+ hideAside = false,
+ hideMain = false,
+ ...restProps
+ }: AppContentShellProps,
+ ref: Ref,
+ ) => {
+ return (
+
+
+
+ );
+ },
+);
+AppContentShell.displayName = 'AppContentShell';
interface AppContentShellMainProps extends BoxProps {}
-function AppContentShellMain({ ...props }: AppContentShellMainProps) {
- const { hideMain } = useAppShellContext();
+/**
+ * Main content of the app shell.
+ * @param {AppContentShellMainProps} props -
+ * @returns {React.ReactNode}
+ */
+const AppContentShellMain = forwardRef(
+ ({ ...props }: AppContentShellMainProps, ref: Ref) => {
+ const { hideMain } = useAppShellContext();
- if (hideMain === true) {
- return null;
- }
- return ;
-}
+ if (hideMain === true) {
+ return null;
+ }
+ return ;
+ },
+);
+
+AppContentShellMain.displayName = 'AppContentShellMain';
interface AppContentShellAsideProps extends BoxProps {
children: React.ReactNode;
}
-function AppContentShellAside({ ...props }: AppContentShellAsideProps) {
- const { hideAside } = useAppShellContext();
+/**
+ * Aside content of the app shell.
+ * @param {AppContentShellAsideProps} props
+ * @returns {React.ReactNode}
+ */
+const AppContentShellAside = forwardRef(
+ ({ ...props }: AppContentShellAsideProps, ref: Ref) => {
+ const { hideAside } = useAppShellContext();
- if (hideAside === true) {
- return null;
- }
- return ;
-}
+ if (hideAside === true) {
+ return null;
+ }
+ return ;
+ },
+);
+AppContentShellAside.displayName = 'AppContentShellAside';
AppContentShell.Main = AppContentShellMain;
AppContentShell.Aside = AppContentShellAside;
diff --git a/packages/webapp/src/components/Datatable/TableVirtualizedRows.tsx b/packages/webapp/src/components/Datatable/TableVirtualizedRows.tsx
index 563575b12..ab2bc35b3 100644
--- a/packages/webapp/src/components/Datatable/TableVirtualizedRows.tsx
+++ b/packages/webapp/src/components/Datatable/TableVirtualizedRows.tsx
@@ -25,14 +25,13 @@ function TableVirtualizedListRow({ index, isScrolling, isVisible, style }) {
export function TableVirtualizedListRows() {
const {
table: { page },
- props: { vListrowHeight, vListOverscanRowCount },
+ props: { vListrowHeight, vListOverscanRowCount, windowScrollerProps },
} = useContext(TableContext);
// Dashboard content pane.
- const dashboardContentPane = React.useMemo(
- () => document.querySelector(`.${CLASSES.DASHBOARD_CONTENT_PANE}`),
- [],
- );
+ const scrollElement =
+ windowScrollerProps?.scrollElement ||
+ document.querySelector(`.${CLASSES.DASHBOARD_CONTENT_PANE}`);
const rowRenderer = React.useCallback(
({ key, ...args }) => ,
@@ -40,7 +39,7 @@ export function TableVirtualizedListRows() {
);
return (
-
+
{({ height, isScrolling, onChildScroll, scrollTop }) => (
{({ width }) => (
diff --git a/packages/webapp/src/components/Layout/Box/Box.tsx b/packages/webapp/src/components/Layout/Box/Box.tsx
index 15acc305b..9d104cf58 100644
--- a/packages/webapp/src/components/Layout/Box/Box.tsx
+++ b/packages/webapp/src/components/Layout/Box/Box.tsx
@@ -1,12 +1,15 @@
-import React from 'react';
+import React, { forwardRef, Ref } from 'react';
import { HTMLDivProps, Props } from '@blueprintjs/core';
export interface BoxProps extends Props, HTMLDivProps {
className?: string;
}
-export function Box({ className, ...rest }: BoxProps) {
- const Element = 'div';
+export const Box = forwardRef(
+ ({ className, ...rest }: BoxProps, ref: Ref) => {
+ const Element = 'div';
- return ;
-}
+ return ;
+ },
+);
+Box.displayName = '@bigcapital/Box';
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx
index 671747706..c5a8fed62 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsList.tsx
@@ -29,28 +29,41 @@ function AccountTransactionsListRoot({
return (
-
-
-
-
-
-
-
-
- }>
-
-
-
-
-
-
-
-
+
+
);
}
+function AccountTransactionsMain() {
+ const { setScrollableRef } = useAccountTransactionsContext();
+
+ return (
+ setScrollableRef(e)}>
+
+
+
+
+
+
+
+ }>
+
+
+
+
+ );
+}
+
+function AccountTransactionsAside() {
+ return (
+
+
+
+ );
+}
+
export default R.compose(
withBanking(
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.tsx
index ba4447c69..4266fae1c 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/AccountTransactionsProvider.tsx
@@ -1,5 +1,5 @@
// @ts-nocheck
-import React from 'react';
+import React, { useRef, useState } from 'react';
import { useParams } from 'react-router-dom';
import { DashboardInsider } from '@/components';
import { useCashflowAccounts, useAccount } from '@/hooks/query';
@@ -41,6 +41,8 @@ function AccountTransactionsProvider({ query, ...props }) {
isLoading: isBankAccountMetaSummaryLoading,
} = useGetBankAccountSummaryMeta(accountId);
+ const [scrollableRef, setScrollableRef] = useState();
+
// Provider payload.
const provider = {
accountId,
@@ -56,6 +58,9 @@ function AccountTransactionsProvider({ query, ...props }) {
filterTab,
setFilterTab,
+
+ scrollableRef,
+ setScrollableRef
};
return (
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/ExcludedTransactionsTable.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/ExcludedTransactionsTable.tsx
index 90fa018f1..c84ec27aa 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/ExcludedTransactionsTable.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/ExcludedTransactionsTable.tsx
@@ -16,6 +16,7 @@ import { TABLES } from '@/constants/tables';
import { useMemorizedColumnsWidths } from '@/hooks';
import { useExcludedTransactionsColumns } from './_utils';
import { useExcludedTransactionsBoot } from './ExcludedTransactionsTableBoot';
+import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
import { ActionsMenu } from './_components';
import { useUnexcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
@@ -37,6 +38,8 @@ function ExcludedTransactionsTableRoot({
const { mutateAsync: unexcludeBankTransaction } =
useUnexcludeUncategorizedTransaction();
+ const { scrollableRef } = useAccountTransactionsContext();
+
// Retrieve table columns.
const columns = useExcludedTransactionsColumns();
@@ -97,6 +100,7 @@ function ExcludedTransactionsTableRoot({
className="table-constrant"
selectionColumn={true}
onSelectedRowsChange={handleSelectedRowsChange}
+ windowScrollerProps={{ scrollElement: scrollableRef }}
payload={{
onRestore: handleRestoreClick,
}}
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/RecognizedTransactions/RecognizedTransactionsTable.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/RecognizedTransactions/RecognizedTransactionsTable.tsx
index a3732eb6e..bfdf90d2e 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/RecognizedTransactions/RecognizedTransactionsTable.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/RecognizedTransactions/RecognizedTransactionsTable.tsx
@@ -20,6 +20,7 @@ import { useRecognizedTransactionsBoot } from './RecognizedTransactionsTableBoot
import { ActionsMenu } from './_components';
import { compose } from '@/utils';
+import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
import { useExcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
import {
WithBankingActionsProps,
@@ -49,6 +50,8 @@ function RecognizedTransactionsTableRoot({
const [initialColumnsWidths, , handleColumnResizing] =
useMemorizedColumnsWidths(TABLES.UNCATEGORIZED_ACCOUNT_TRANSACTIONS);
+ const { scrollableRef } = useAccountTransactionsContext();
+
// Handle cell click.
const handleCellClick = (cell, event) => {
setUncategorizedTransactionIdForMatching(
@@ -102,6 +105,7 @@ function RecognizedTransactionsTableRoot({
vListOverscanRowCount={0}
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}
+ windowScrollerProps={{ scrollElement: scrollableRef }}
noResults={}
className="table-constrant"
payload={{
diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/UncategorizedTransactions/AccountTransactionsUncategorizedTable.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/UncategorizedTransactions/AccountTransactionsUncategorizedTable.tsx
index f2bd264bd..bd586adb4 100644
--- a/packages/webapp/src/containers/CashFlow/AccountTransactions/UncategorizedTransactions/AccountTransactionsUncategorizedTable.tsx
+++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/UncategorizedTransactions/AccountTransactionsUncategorizedTable.tsx
@@ -22,6 +22,7 @@ import { useMemorizedColumnsWidths } from '@/hooks';
import { useAccountUncategorizedTransactionsContext } from '../AllTransactionsUncategorizedBoot';
import { useExcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
import { useAccountUncategorizedTransactionsColumns } from './hooks';
+import { useAccountTransactionsContext } from '../AccountTransactionsProvider';
import { compose } from '@/utils';
import { withBanking } from '../../withBanking';
@@ -48,6 +49,8 @@ function AccountTransactionsDataTable({
// Retrieve table columns.
const columns = useAccountUncategorizedTransactionsColumns();
+ const { scrollableRef } = useAccountTransactionsContext();
+
// Retrieve list context.
const { uncategorizedTransactions, isUncategorizedTransactionsLoading } =
useAccountUncategorizedTransactionsContext();
@@ -124,6 +127,7 @@ function AccountTransactionsDataTable({
onCategorize: handleCategorizeBtnClick,
}}
onSelectedRowsChange={handleSelectedRowsChange}
+ windowScrollerProps={{ scrollElement: scrollableRef }}
className={clsx('table-constrant', styles.table, {
[styles.showCategorizeColumn]: enableMultipleCategorization,
})}