feart: optimize cashflow account transactions page.

This commit is contained in:
a.bouhuolia
2021-10-20 19:04:01 +02:00
parent 0bb1e57061
commit c7013caf12
16 changed files with 300 additions and 38 deletions

View File

@@ -1,5 +1,11 @@
import React from 'react';
import { Button, NavbarGroup, Classes, NavbarDivider } from '@blueprintjs/core';
import {
Button,
NavbarGroup,
Classes,
NavbarDivider,
Alignment,
} from '@blueprintjs/core';
import {
Icon,
DashboardRowsHeightButton,
@@ -23,6 +29,7 @@ function AccountTransactionsActionsBar({
// #withSettings
cashflowTansactionsTableSize,
// #withSettingsActions
addSetting,
}) {
@@ -32,7 +39,7 @@ function AccountTransactionsActionsBar({
};
const { accountId } = useAccountTransactionsContext();
//Handle money in form
// Handle money in form
const handleMoneyInFormTransaction = (value) => {
openDialog('money-in', {
account_type: value.type,
@@ -40,13 +47,16 @@ function AccountTransactionsActionsBar({
});
};
//Handle money out form
// Handle money out form
const handlMoneyOutFormTransaction = (value) => {
openDialog('money-out', {
account_type: value.type,
account_id: accountId,
});
};
const handleRefreshBtnClick = () => {};
return (
<DashboardActionsBar>
<NavbarGroup>
@@ -54,13 +64,18 @@ function AccountTransactionsActionsBar({
items={addMoneyIn}
onItemSelect={handleMoneyInFormTransaction}
text={<T id={'cash_flow.label.add_money_in'} />}
buttonProps={{
icon: <Icon icon={'arrow-downward'} iconSize={20} />,
}}
/>
<CashFlowMenuItems
items={addMoneyOut}
onItemSelect={handlMoneyOutFormTransaction}
text={<T id={'cash_flow.label.add_money_out'} />}
buttonProps={{
icon: <Icon icon={'arrow-upward'} iconSize={20} />,
}}
/>
<NavbarDivider />
<Button
className={Classes.MINIMAL}
@@ -84,6 +99,14 @@ function AccountTransactionsActionsBar({
/>
<NavbarDivider />
</NavbarGroup>
<NavbarGroup align={Alignment.RIGHT}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon="refresh-16" iconSize={14} />}
onClick={handleRefreshBtnClick}
/>
</NavbarGroup>
</DashboardActionsBar>
);
}

View File

@@ -40,7 +40,6 @@ function AccountTransactionsDataTable({
noInitialFetch={true}
columns={columns}
data={cashflowTransactions}
selectionColumn={true}
sticky={true}
loading={isCashFlowTransactionsLoading}
headerLoading={isCashFlowTransactionsLoading}
@@ -59,6 +58,9 @@ function AccountTransactionsDataTable({
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}
size={cashflowTansactionsTableSize}
noResults={'There is deposit/withdrawal transactions on the current account.'}
className="table-constrant"
/>
);
}

View File

@@ -0,0 +1,182 @@
import React from 'react';
import styled from 'styled-components';
import {
Popover,
Menu,
Position,
Button,
MenuItem,
Classes,
} from '@blueprintjs/core';
import { useHistory } from 'react-router-dom';
import { curry } from 'lodash/fp';
import { Icon } from '../../../components';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
function AccountSwitchButton() {
const { currentAccount } = useAccountTransactionsContext();
return (
<AccountSwitchButtonBase
minimal={true}
rightIcon={<Icon icon={'arrow-drop-down'} iconSize={24} />}
>
<AccountSwitchText>{currentAccount.name}</AccountSwitchText>
</AccountSwitchButtonBase>
);
}
function AccountSwitchItem() {
const { push } = useHistory();
const { cashflowAccounts } = useAccountTransactionsContext();
// Handle item click.
const handleItemClick = curry((account, event) => {
push(`/cashflow-accounts/${account.id}/transactions`);
});
const items = cashflowAccounts.map((account) => (
<AccountSwitchMenuItem
name={account.name}
onClick={handleItemClick(account)}
/>
));
return (
<Popover
content={<Menu>{items}</Menu>}
position={Position.BOTTOM_LEFT}
minimal={true}
>
<AccountSwitchButton />
</Popover>
);
}
function AccountBalanceItem() {
const { currentAccount } = useAccountTransactionsContext();
return (
<AccountBalanceItemWrap>
Balance in Bigcapital{' '}
<AccountBalanceAmount>
{currentAccount.formatted_amount}
</AccountBalanceAmount>
</AccountBalanceItemWrap>
);
}
function AccountTransactionsDetailsBarSkeleton() {
return (
<React.Fragment>
<DetailsBarSkeletonBase className={Classes.SKELETON}>
X
</DetailsBarSkeletonBase>
<DetailsBarSkeletonBase className={Classes.SKELETON}>
X
</DetailsBarSkeletonBase>
</React.Fragment>
);
}
function AccountTransactionsDetailsContent() {
return (
<React.Fragment>
<AccountSwitchItem />
<AccountBalanceItem />
</React.Fragment>
);
}
export function AccountTransactionsDetailsBar() {
const { isCurrentAccountLoading } = useAccountTransactionsContext();
return (
<AccountTransactionDetailsWrap>
{isCurrentAccountLoading ? (
<AccountTransactionsDetailsBarSkeleton />
) : (
<AccountTransactionsDetailsContent />
)}
</AccountTransactionDetailsWrap>
);
}
function AccountSwitchMenuItem({
name,
balance,
transactionsNumber,
...restProps
}) {
return (
<MenuItem
label={'LYD100,000'}
text={
<React.Fragment>
<AccountSwitchItemName>{name}</AccountSwitchItemName>
<AccountSwitchItemTranscations>
25 Transactions
</AccountSwitchItemTranscations>
<AccountSwitchItemUpdatedAt>
Updated before 2 days
</AccountSwitchItemUpdatedAt>
</React.Fragment>
}
{...restProps}
/>
);
}
const DetailsBarSkeletonBase = styled.div`
letter-spacing: 10px;
margin-right: 10px;
margin-left: 10px;
font-size: 8px;
width: 140px;
`;
const AccountBalanceItemWrap = styled.div`
margin-left: 18px;
color: #5f6d86;
`;
const AccountTransactionDetailsWrap = styled.div`
display: flex;
background: #fff;
border-bottom: 1px solid #d2dce2;
padding: 0 22px;
height: 42px;
align-items: center;
`;
const AccountSwitchText = styled.div`
font-weight: 600;
font-size: 14px;
`;
const AccountBalanceAmount = styled.span`
font-weight: 600;
display: inline-block;
margin-left: 10px;
color: rgb(31, 50, 85);
`;
const AccountSwitchItemName = styled.div`
font-weight: 600;
`;
const AccountSwitchItemTranscations = styled.div`
font-size: 12px;
opacity: 0.7;
`;
const AccountSwitchItemUpdatedAt = styled.div`
font-size: 12px;
opacity: 0.5;
`;
const AccountSwitchButtonBase = styled(Button)`
.bp3-button-text {
margin-right: 5px;
}
`;

View File

@@ -5,9 +5,11 @@ import 'style/pages/CashFlow/AccountTransactions/List.scss';
import { DashboardPageContent, DashboardContentTable } from 'components';
import { AccountTransactionsProvider } from './AccountTransactionsProvider';
import AccountTransactionsActionsBar from './AccountTransactionsActionsBar';
import AccountTransactionsDataTable from './AccountTransactionsDataTable';
import { AccountTransactionsDetailsBar } from './AccountTransactionsDetailsBar';
import { AccountTransactionsProgressBar } from './components';
/**
* Account transactions list.
@@ -16,6 +18,9 @@ function AccountTransactionsList() {
return (
<AccountTransactionsProvider>
<AccountTransactionsActionsBar />
<AccountTransactionsDetailsBar />
<AccountTransactionsProgressBar />
<DashboardPageContent>
<DashboardContentTable>
<AccountTransactionsDataTable />

View File

@@ -1,8 +1,11 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useCashflowTransactions } from 'hooks/query';
import {
useCashflowTransactions,
useCashflowAccounts,
useAccount,
} from 'hooks/query';
const AccountTransactionsContext = React.createContext();
@@ -22,12 +25,31 @@ function AccountTransactionsProvider({ query, ...props }) {
enabled: !!accountId,
});
// Fetch cashflow accounts .
const {
data: cashflowAccounts,
isFetching: isCashFlowAccountsFetching,
isLoading: isCashFlowAccountsLoading,
} = useCashflowAccounts(query, { keepPreviousData: true });
const {
data: currentAccount,
isFetching: isCurrentAccountFetching,
isLoading: isCurrentAccountLoading,
} = useAccount(accountId, { keepPreviousData: true });
// Provider payload.
const provider = {
accountId,
cashflowTransactions,
cashflowAccounts,
currentAccount,
isCashFlowTransactionsFetching,
isCashFlowTransactionsLoading,
isCashFlowAccountsFetching,
isCashFlowAccountsLoading,
isCurrentAccountFetching,
isCurrentAccountLoading,
};
return (

View File

@@ -1,7 +1,8 @@
import React from 'react';
import intl from 'react-intl-universal';
import { MaterialProgressBar } from 'components';
import { FormatDateCell } from 'components';
import { useAccountTransactionsContext } from './AccountTransactionsProvider';
/**
* Retrieve account transctions table columns.
@@ -60,3 +61,12 @@ export function useAccountTransactionsColumns() {
[],
);
}
/**
* Account transactions progress bar.
*/
export function AccountTransactionsProgressBar() {
const { isCashFlowTransactionsLoading } = useAccountTransactionsContext();
return isCashFlowTransactionsLoading ? <MaterialProgressBar /> : null;
}

View File

@@ -1,18 +1,20 @@
import React from 'react';
import classNames from 'classnames';
import {
Button,
PopoverInteractionKind,
MenuItem,
Classes,
Position,
} from '@blueprintjs/core';
import { Select } from '@blueprintjs/select';
import { Icon } from 'components';
export const CashFlowMenuItems = ({ text, items, onItemSelect }) => {
export const CashFlowMenuItems = ({
text,
items,
onItemSelect,
buttonProps,
}) => {
// Menu items renderer.
const itemsRenderer = (item, { handleClick, modifiers, query }) => (
<MenuItem text={item.name} label={item.label} onClick={handleClick} />
@@ -40,9 +42,8 @@ export const CashFlowMenuItems = ({ text, items, onItemSelect }) => {
<Button
text={text}
icon={<Icon icon={'plus-24'} iconSize={20} />}
// rightIcon={'caret-down'}
// className={classNames(Classes.MINIMAL, 'button--table-views')}
minimal={true}
{...buttonProps}
/>
</Select>
);

View File

@@ -33,12 +33,13 @@ function CashFlowAccountsDataTable({
// Local storage memorizing columns widths.
const [initialColumnsWidths, , handleColumnResizing] =
useMemorizedColumnsWidths(TABLES.CASHFLOW_ACCOUNTS);
return (
<DataTable
noInitialFetch={true}
columns={columns}
data={cashflowAccounts}
selectionColumn={true}
selectionColumn={false}
sticky={true}
loading={isCashFlowAccountsLoading}
headerLoading={isCashFlowAccountsLoading}
@@ -47,11 +48,8 @@ function CashFlowAccountsDataTable({
expandToggleColumn={2}
selectionColumnWidth={45}
TableCellRenderer={TableFastCell}
TableRowsRenderer={TableVirtualizedListRows}
TableLoadingRenderer={TableSkeletonRows}
// #TableVirtualizedListRows props.
vListrowHeight={cashflowTableSize == 'small' ? 40 : 42}
vListOverscanRowCount={0}
TableHeaderSkeletonRenderer={TableSkeletonHeader}
initialColumnsWidths={initialColumnsWidths}
onColumnResizing={handleColumnResizing}

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { isNull } from 'lodash';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
import { BankAccountsList, BankAccount } from '../../../components';
import { useCashFlowAccountsContext } from './CashFlowAccountsProvider';
@@ -23,12 +24,14 @@ function CashflowAccountsSkeleton() {
function CashflowAccountsGridItems({ accounts }) {
return accounts.map((account) => (
<BankAccount
title={account.name}
code={account.code}
balance={!isNull(account.amount) ? account.formattedAmount : '-'}
type={'cash'}
/>
<Link to={`/cashflow-accounts/${account.id}/transactions`}>
<BankAccount
title={account.name}
code={account.code}
balance={!isNull(account.amount) ? account.formattedAmount : '-'}
type={'cash'}
/>
</Link>
));
}