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

@@ -187,6 +187,7 @@ export function BankAccount({
type,
balance,
loading = false,
to
}) {
return (
<BankAccountWrap>

View File

@@ -189,10 +189,6 @@ export default [
},
],
},
{
text: <T id={'banking'} />,
children: [],
},
{
text: <T id={'cash_flow'} />,
children: [

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>
));
}

View File

@@ -221,7 +221,7 @@
"manual_journal": "Manual Journal",
"make_journal": "Make Journal",
"banking": "Banking",
"cash_flow": "Cash Flow",
"cash_flow": "Cash flow",
"sales": "Sales",
"purchases": "Purchases",
"financial_reports": "Financial Reports",

View File

@@ -766,7 +766,7 @@ export const getDashboardRoutes = () => [
},
// Cash flow
{
path: `/account/:id/transactions`,
path: `/cashflow-accounts/:id/transactions`,
component: lazy(() =>
import('containers/CashFlow/AccountTransactions/AccountTransactionsList'),
),

View File

@@ -481,7 +481,7 @@ export default {
},
'account-balance': {
path: [
'M6.5 10h-2v7h2v-7zm6 0h-2v7h2v-7zm8.5 9H2v2h19v-2zm-2.5-9h-2v7h2v-7zm-7-6.74L16.71 6H6.29l5.21-2.74m0-2.26L2 6v2h19V6l-9.5-5z'
'M6.5 10h-2v7h2v-7zm6 0h-2v7h2v-7zm8.5 9H2v2h19v-2zm-2.5-9h-2v7h2v-7zm-7-6.74L16.71 6H6.29l5.21-2.74m0-2.26L2 6v2h19V6l-9.5-5z',
],
viewBox: '0 0 24 24',
},
@@ -490,5 +490,17 @@ export default {
'M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z',
],
viewBox: '0 0 24 24',
},
'arrow-drop-down': {
path: ['M7 10l5 5 5-5H7z'],
viewBox: '0 0 24 24',
},
'arrow-downward': {
path: ['M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z'],
viewBox: '0 0 24 24',
},
'arrow-upward': {
path: ['M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z'],
viewBox: '0 0 24 24',
}
};

View File

@@ -1,6 +1,8 @@
.dashboard__insider--account-transactions {
.bigcapital-datatable {
.tbody {
}
position: relative;
top: -1px;
.tbody {}
}
}
}

View File

@@ -1,14 +1,17 @@
.dashboard__insider--cashflow-accounts {
.bigcapital-datatable {
.table {
.tbody {
.td.balance {
.cell-inner {
> span {
>span {
font-weight: 600;
}
}
}
.account_name {
.bp3-popover-wrapper--inactive-semafro {
margin-left: 8px;
@@ -16,9 +19,11 @@
float: right;
border: 0;
}
.bp3-popover-wrapper--account-desc {
border-bottom-color: #bbb;
}
.inactive-semafro {
height: 7px;
width: 7px;
@@ -30,4 +35,4 @@
}
}
}
}
}