mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: toggle banking matching aside
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { AppShellProvider } from './AppShellProvider';
|
||||
import { AppShellProvider, useAppShellContext } from './AppShellProvider';
|
||||
import { Box } from '../Layout';
|
||||
import styles from './AppShell.module.scss';
|
||||
|
||||
@@ -8,16 +8,26 @@ interface AppShellProps {
|
||||
mainProps: any;
|
||||
asideProps: any;
|
||||
children: React.ReactNode;
|
||||
hideAside?: boolean;
|
||||
hideMain?: boolean;
|
||||
}
|
||||
|
||||
export function AppShell({
|
||||
asideProps,
|
||||
mainProps,
|
||||
topbarOffset = 0,
|
||||
hideAside = false,
|
||||
hideMain = false,
|
||||
...restProps
|
||||
}: AppShellProps) {
|
||||
return (
|
||||
<AppShellProvider mainProps={mainProps} asideProps={asideProps} topbarOffset={topbarOffset}>
|
||||
<AppShellProvider
|
||||
mainProps={mainProps}
|
||||
asideProps={asideProps}
|
||||
topbarOffset={topbarOffset}
|
||||
hideAside={hideAside}
|
||||
hideMain={hideMain}
|
||||
>
|
||||
<Box {...restProps} className={styles.root} />
|
||||
</AppShellProvider>
|
||||
);
|
||||
@@ -27,6 +37,12 @@ AppShell.Main = AppShellMain;
|
||||
AppShell.Aside = AppShellAside;
|
||||
|
||||
function AppShellMain({ ...props }) {
|
||||
const { hideMain } = useAppShellContext();
|
||||
|
||||
if (hideMain === true) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Box {...props} className={styles.main} />;
|
||||
}
|
||||
|
||||
@@ -35,5 +51,11 @@ interface AppShellAsideProps {
|
||||
}
|
||||
|
||||
function AppShellAside({ ...props }: AppShellAsideProps) {
|
||||
const { hideAside } = useAppShellContext();
|
||||
|
||||
console.log(hideAside, 'hideAsidehideAsidehideAsidehideAside');
|
||||
if (hideAside === true) {
|
||||
return null;
|
||||
}
|
||||
return <Box {...props} className={styles.aside} />;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,37 @@
|
||||
// @ts-nocheck
|
||||
import React, { createContext } from 'react';
|
||||
|
||||
interface AppShellContextValue {
|
||||
topbarOffset: number
|
||||
interface ContentShellCommonValue {
|
||||
mainProps: any;
|
||||
asideProps: any;
|
||||
topbarOffset: number;
|
||||
hideAside: boolean;
|
||||
hideMain: boolean;
|
||||
}
|
||||
|
||||
interface AppShellContextValue extends ContentShellCommonValue {
|
||||
topbarOffset: number;
|
||||
}
|
||||
|
||||
const AppShellContext = createContext<AppShellContextValue>(
|
||||
{} as AppShellContextValue,
|
||||
);
|
||||
|
||||
interface AppShellProviderProps {
|
||||
interface AppShellProviderProps extends ContentShellCommonValue {
|
||||
children: React.ReactNode;
|
||||
mainProps: any;
|
||||
asideProps: any;
|
||||
topbarOffset: number;
|
||||
}
|
||||
|
||||
export function AppShellProvider({ topbarOffset, ...props }: AppShellProviderProps) {
|
||||
const provider = { topbarOffset } as AppShellContextValue;
|
||||
export function AppShellProvider({
|
||||
topbarOffset,
|
||||
hideAside,
|
||||
hideMain,
|
||||
...props
|
||||
}: AppShellProviderProps) {
|
||||
const provider = {
|
||||
topbarOffset,
|
||||
hideAside,
|
||||
hideMain,
|
||||
} as AppShellContextValue;
|
||||
|
||||
return <AppShellContext.Provider value={provider} {...props} />;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-nocheck
|
||||
import React, { Suspense } from 'react';
|
||||
import * as R from 'ramda';
|
||||
import { Spinner } from '@blueprintjs/core';
|
||||
|
||||
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
|
||||
@@ -16,14 +17,18 @@ import { AccountTransactionsProgressBar } from './components';
|
||||
import { AccountTransactionsFilterTabs } from './AccountTransactionsFilterTabs';
|
||||
import { AppShell } from '@/components/AppShell/AppShell';
|
||||
import { CategorizeTransactionAside } from '../CategorizeTransactionAside/CategorizeTransactionAside';
|
||||
import { withBanking } from '../withBanking';
|
||||
|
||||
/**
|
||||
* Account transactions list.
|
||||
*/
|
||||
function AccountTransactionsList() {
|
||||
function AccountTransactionsListRoot({
|
||||
// #withBanking
|
||||
openMatchingTransactionAside,
|
||||
}) {
|
||||
return (
|
||||
<AccountTransactionsProvider>
|
||||
<AppShell>
|
||||
<AppShell hideAside={!openMatchingTransactionAside}>
|
||||
<AppShell.Main>
|
||||
<AccountTransactionsActionsBar />
|
||||
<AccountTransactionsDetailsBar />
|
||||
@@ -46,7 +51,14 @@ function AccountTransactionsList() {
|
||||
);
|
||||
}
|
||||
|
||||
export default AccountTransactionsList;
|
||||
export default R.compose(
|
||||
withBanking(
|
||||
({ selectedUncategorizedTransactionId, openMatchingTransactionAside }) => ({
|
||||
selectedUncategorizedTransactionId,
|
||||
openMatchingTransactionAside,
|
||||
}),
|
||||
),
|
||||
)(AccountTransactionsListRoot);
|
||||
|
||||
const AccountsTransactionsAll = React.lazy(
|
||||
() => import('./AccountsTransactionsAll'),
|
||||
|
||||
@@ -15,6 +15,7 @@ import { TABLES } from '@/constants/tables';
|
||||
|
||||
import withSettings from '@/containers/Settings/withSettings';
|
||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||
import { withBankingActions } from '../withBankingActions';
|
||||
|
||||
import { useMemorizedColumnsWidths } from '@/hooks';
|
||||
import {
|
||||
@@ -24,7 +25,6 @@ import {
|
||||
import { useAccountUncategorizedTransactionsContext } from './AllTransactionsUncategorizedBoot';
|
||||
|
||||
import { compose } from '@/utils';
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
import { useExcludeUncategorizedTransaction } from '@/hooks/query/bank-rules';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
|
||||
@@ -35,6 +35,9 @@ function AccountTransactionsDataTable({
|
||||
// #withSettings
|
||||
cashflowTansactionsTableSize,
|
||||
|
||||
// #withBankingActions
|
||||
setUncategorizedTransactionIdForMatching,
|
||||
|
||||
// #withDrawerActions
|
||||
openDrawer,
|
||||
}) {
|
||||
@@ -53,10 +56,8 @@ function AccountTransactionsDataTable({
|
||||
useMemorizedColumnsWidths(TABLES.UNCATEGORIZED_CASHFLOW_TRANSACTION);
|
||||
|
||||
// Handle cell click.
|
||||
const handleCellClick = (cell, event) => {
|
||||
openDrawer(DRAWERS.CATEGORIZE_TRANSACTION, {
|
||||
uncategorizedTransactionId: cell.row.original.id,
|
||||
});
|
||||
const handleCellClick = (cell) => {
|
||||
setUncategorizedTransactionIdForMatching(cell.row.original.id);
|
||||
};
|
||||
// Handle exclude transaction.
|
||||
const handleExcludeTransaction = (transaction) => {
|
||||
@@ -111,6 +112,7 @@ export default compose(
|
||||
cashflowTansactionsTableSize: cashflowTransactionsSettings?.tableSize,
|
||||
})),
|
||||
withDrawerActions,
|
||||
withBankingActions,
|
||||
)(AccountTransactionsDataTable);
|
||||
|
||||
const DashboardConstrantTable = styled(DataTable)`
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
// @ts-nocheck
|
||||
import styled from 'styled-components';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import '@/style/pages/CashFlow/AccountTransactions/List.scss';
|
||||
|
||||
import AccountTransactionsUncategorizedTable from './AccountTransactionsUncategorizedTable';
|
||||
import { AccountUncategorizedTransactionsBoot } from './AllTransactionsUncategorizedBoot';
|
||||
import {
|
||||
WithBankingActionsProps,
|
||||
withBankingActions,
|
||||
} from '../withBankingActions';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const Box = styled.div`
|
||||
margin: 30px 15px;
|
||||
@@ -18,7 +24,18 @@ const CashflowTransactionsTableCard = styled.div`
|
||||
flex: 0 1;
|
||||
`;
|
||||
|
||||
export default function AllTransactionsUncategorized() {
|
||||
interface AllTransactionsUncategorizedProps extends WithBankingActionsProps {}
|
||||
|
||||
function AllTransactionsUncategorizedRoot({
|
||||
// #withBankingActions
|
||||
closeMatchingTransactionAside,
|
||||
}: AllTransactionsUncategorizedProps) {
|
||||
useEffect(
|
||||
() => () => {
|
||||
closeMatchingTransactionAside();
|
||||
},
|
||||
[closeMatchingTransactionAside],
|
||||
);
|
||||
return (
|
||||
<AccountUncategorizedTransactionsBoot>
|
||||
<Box>
|
||||
@@ -29,3 +46,5 @@ export default function AllTransactionsUncategorized() {
|
||||
</AccountUncategorizedTransactionsBoot>
|
||||
);
|
||||
}
|
||||
|
||||
export default R.compose(withBankingActions)(AllTransactionsUncategorizedRoot);
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// @ts-nocheck
|
||||
import React, { useMemo } from 'react';
|
||||
import { first } from 'lodash';
|
||||
import { DrawerHeaderContent, DrawerLoading } from '@/components';
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
import { DrawerLoading } from '@/components';
|
||||
import {
|
||||
useAccounts,
|
||||
useBranches,
|
||||
@@ -56,10 +55,6 @@ function CategorizeTransactionBoot({ uncategorizedTransactionId, ...props }) {
|
||||
|
||||
return (
|
||||
<DrawerLoading loading={isLoading}>
|
||||
<DrawerHeaderContent
|
||||
name={DRAWERS.CATEGORIZE_TRANSACTION}
|
||||
title={'Categorize Transaction'}
|
||||
/>
|
||||
<CategorizeTransactionBootContext.Provider value={provider} {...props} />
|
||||
</DrawerLoading>
|
||||
);
|
||||
|
||||
@@ -4,9 +4,9 @@ import { DrawerBody } from '@/components';
|
||||
import { CategorizeTransactionBoot } from './CategorizeTransactionBoot';
|
||||
import { CategorizeTransactionForm } from './CategorizeTransactionForm';
|
||||
|
||||
export default function CategorizeTransactionContent({
|
||||
uncategorizedTransactionId,
|
||||
}) {
|
||||
export function CategorizeTransactionContent({}) {
|
||||
const uncategorizedTransactionId = 4;
|
||||
|
||||
return (
|
||||
<CategorizeTransactionBoot
|
||||
uncategorizedTransactionId={uncategorizedTransactionId}
|
||||
@@ -18,7 +18,7 @@ export default function CategorizeTransactionContent({
|
||||
);
|
||||
}
|
||||
|
||||
export const CategorizeTransactionDrawerBody = styled(DrawerBody)`
|
||||
const CategorizeTransactionDrawerBody = styled(DrawerBody)`
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
`;
|
||||
|
||||
@@ -48,9 +48,9 @@ export const CategorizeTransactionFormFooter = R.compose(withDrawerActions)(
|
||||
);
|
||||
|
||||
const Root = styled.div`
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #fff;
|
||||
// position: absolute;
|
||||
// bottom: 0;
|
||||
// left: 0;
|
||||
// right: 0;
|
||||
// background: #fff;
|
||||
`;
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
import * as R from 'ramda';
|
||||
import { Aside } from '@/components/Aside/Aside';
|
||||
import { CategorizeTransactionTabs } from './CategorizeTransactionTabs';
|
||||
import {
|
||||
WithBankingActionsProps,
|
||||
withBankingActions,
|
||||
} from '../withBankingActions';
|
||||
|
||||
interface CategorizeTransactionAsideProps extends WithBankingActionsProps {}
|
||||
|
||||
function CategorizeTransactionAsideRoot({
|
||||
// #withBankingActions
|
||||
closeMatchingTransactionAside,
|
||||
}: CategorizeTransactionAsideProps) {
|
||||
const handleClose = () => {
|
||||
closeMatchingTransactionAside();
|
||||
};
|
||||
|
||||
export function CategorizeTransactionAside() {
|
||||
return (
|
||||
<Aside title={'Categorize Bank Transaction'}>
|
||||
<Aside title={'Categorize Bank Transaction'} onClose={handleClose}>
|
||||
<CategorizeTransactionTabs />
|
||||
</Aside>
|
||||
);
|
||||
}
|
||||
|
||||
export const CategorizeTransactionAside = R.compose(withBankingActions)(
|
||||
CategorizeTransactionAsideRoot,
|
||||
);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Tab, Tabs } from '@blueprintjs/core';
|
||||
import {
|
||||
CategorizeBankTransactionContent,
|
||||
MatchingBankTransaction,
|
||||
} from './MatchingTransaction';
|
||||
import { MatchingBankTransaction } from './MatchingTransaction';
|
||||
import styles from './CategorizeTransactionTabs.module.scss';
|
||||
import { CategorizeTransactionContent } from '../CategorizeTransaction/drawers/CategorizeTransactionDrawer/CategorizeTransactionContent';
|
||||
|
||||
export function CategorizeTransactionTabs() {
|
||||
return (
|
||||
@@ -11,7 +9,7 @@ export function CategorizeTransactionTabs() {
|
||||
<Tab
|
||||
id="categorize"
|
||||
title="Categorize Transaction"
|
||||
panel={<CategorizeBankTransactionContent />}
|
||||
panel={<CategorizeTransactionContent />}
|
||||
/>
|
||||
<Tab
|
||||
id="matching"
|
||||
|
||||
15
packages/webapp/src/containers/CashFlow/withBanking.ts
Normal file
15
packages/webapp/src/containers/CashFlow/withBanking.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
// @ts-nocheck
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
export const withBanking = (mapState) => {
|
||||
const mapStateToProps = (state, props) => {
|
||||
const mapped = {
|
||||
openMatchingTransactionAside: state.plaid.openMatchingTransactionAside,
|
||||
selectedUncategorizedTransactionId:
|
||||
state.plaid.uncategorizedTransactionIdForMatching,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
return connect(mapStateToProps);
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
import { connect } from 'react-redux';
|
||||
import {
|
||||
closeMatchingTransactionAside,
|
||||
setUncategorizedTransactionIdForMatching,
|
||||
} from '@/store/banking/banking.reducer';
|
||||
|
||||
export interface WithBankingActionsProps {
|
||||
closeMatchingTransactionAside: () => void;
|
||||
setUncategorizedTransactionIdForMatching: (
|
||||
uncategorizedTransactionId: number,
|
||||
) => void;
|
||||
}
|
||||
|
||||
const mapDipatchToProps = (dispatch: any): WithBankingActionsProps => ({
|
||||
closeMatchingTransactionAside: () =>
|
||||
dispatch(closeMatchingTransactionAside()),
|
||||
setUncategorizedTransactionIdForMatching: (
|
||||
uncategorizedTransactionId: number,
|
||||
) =>
|
||||
dispatch(
|
||||
setUncategorizedTransactionIdForMatching(uncategorizedTransactionId),
|
||||
),
|
||||
});
|
||||
|
||||
export const withBankingActions = connect<
|
||||
null,
|
||||
WithBankingActionsProps,
|
||||
{},
|
||||
any
|
||||
>(null, mapDipatchToProps);
|
||||
21
packages/webapp/src/store/banking/banking.actions.ts
Normal file
21
packages/webapp/src/store/banking/banking.actions.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
// @ts-nocheck
|
||||
import t from '@/store/types';
|
||||
|
||||
/**
|
||||
* Sets global table state of the table.
|
||||
* @param {object} queries
|
||||
*/
|
||||
export const setUncategorizedTransactionIdForMatching = (
|
||||
uncategorizedTransactionId: number,
|
||||
) => {
|
||||
return {
|
||||
type: 'setUncategorizedTransactionIdForMatching',
|
||||
payload: uncategorizedTransactionId,
|
||||
};
|
||||
};
|
||||
|
||||
export const closeMatchingTransactionAside = () => {
|
||||
return {
|
||||
type: 'closeMatchingTransactionAside',
|
||||
};
|
||||
};
|
||||
@@ -2,22 +2,46 @@ import { PayloadAction, createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
interface StorePlaidState {
|
||||
plaidToken: string;
|
||||
openMatchingTransactionAside: boolean;
|
||||
uncategorizedTransactionIdForMatching: number | null;
|
||||
}
|
||||
|
||||
export const PlaidSlice = createSlice({
|
||||
name: 'plaid',
|
||||
initialState: {
|
||||
plaidToken: '',
|
||||
openMatchingTransactionAside: false,
|
||||
uncategorizedTransactionIdForMatching: null,
|
||||
} as StorePlaidState,
|
||||
reducers: {
|
||||
setPlaidId: (state: StorePlaidState, action: PayloadAction<string>) => {
|
||||
state.plaidToken = action.payload;
|
||||
},
|
||||
|
||||
resetPlaidId: (state: StorePlaidState) => {
|
||||
state.plaidToken = '';
|
||||
}
|
||||
},
|
||||
|
||||
setUncategorizedTransactionIdForMatching: (
|
||||
state: StorePlaidState,
|
||||
action: PayloadAction<number>,
|
||||
) => {
|
||||
state.openMatchingTransactionAside = true;
|
||||
state.uncategorizedTransactionIdForMatching = action.payload;
|
||||
},
|
||||
|
||||
closeMatchingTransactionAside: (state: StorePlaidState) => {
|
||||
state.openMatchingTransactionAside = false;
|
||||
state.uncategorizedTransactionIdForMatching = null;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setPlaidId, resetPlaidId } = PlaidSlice.actions;
|
||||
export const getPlaidToken = (state: any) => state.plaid.plaidToken;
|
||||
export const {
|
||||
setPlaidId,
|
||||
resetPlaidId,
|
||||
setUncategorizedTransactionIdForMatching,
|
||||
closeMatchingTransactionAside,
|
||||
} = PlaidSlice.actions;
|
||||
|
||||
export const getPlaidToken = (state: any) => state.plaid.plaidToken;
|
||||
|
||||
Reference in New Issue
Block a user