mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
feat: account drawer.
This commit is contained in:
@@ -13,6 +13,7 @@ import { useAccountsChartContext } from './AccountsChartProvider';
|
||||
|
||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||
|
||||
/**
|
||||
* Accounts data-table.
|
||||
@@ -23,6 +24,9 @@ function AccountsDataTable({
|
||||
|
||||
// #withDial
|
||||
openDialog,
|
||||
|
||||
// #withDrawerActions
|
||||
openDrawer,
|
||||
}) {
|
||||
const {
|
||||
isAccountsLoading,
|
||||
@@ -59,6 +63,11 @@ function AccountsDataTable({
|
||||
openDialog('account-form', { action: 'edit', id: account.id });
|
||||
};
|
||||
|
||||
// Handle view detail account.
|
||||
const handleViewDetailAccount = ({ id, name, code }) => {
|
||||
openDrawer('account-drawer', { accountId: id, title: `${name} ${code}` });
|
||||
};
|
||||
|
||||
// Handle new child button click.
|
||||
const handleNewChildAccount = (account) => {
|
||||
openDialog('account-form', {
|
||||
@@ -76,40 +85,38 @@ function AccountsDataTable({
|
||||
selectionColumn={true}
|
||||
expandable={true}
|
||||
sticky={true}
|
||||
|
||||
loading={isAccountsLoading}
|
||||
headerLoading={isAccountsLoading}
|
||||
progressBarLoading={isAccountsFetching}
|
||||
|
||||
rowClassNames={rowClassNames}
|
||||
|
||||
autoResetExpanded={false}
|
||||
autoResetSortBy={false}
|
||||
autoResetSelectedRows={false}
|
||||
|
||||
expandColumnSpace={1}
|
||||
expandToggleColumn={2}
|
||||
selectionColumnWidth={50}
|
||||
|
||||
TableCellRenderer={TableFastCell}
|
||||
TableRowsRenderer={TableVirtualizedListRows}
|
||||
TableLoadingRenderer={TableSkeletonRows}
|
||||
TableHeaderSkeletonRenderer={TableSkeletonHeader}
|
||||
ContextMenu={ActionsMenu}
|
||||
|
||||
// #TableVirtualizedListRows props.
|
||||
vListrowHeight={42}
|
||||
vListOverscanRowCount={0}
|
||||
|
||||
payload={{
|
||||
onEdit: handleEditAccount,
|
||||
onDelete: handleDeleteAccount,
|
||||
onActivate: handleActivateAccount,
|
||||
onInactivate: handleInactivateAccount,
|
||||
onNewChild: handleNewChildAccount
|
||||
onNewChild: handleNewChildAccount,
|
||||
onViewDetails: handleViewDetailAccount,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withAlertsActions, withDialogActions)(AccountsDataTable);
|
||||
export default compose(
|
||||
withAlertsActions,
|
||||
withDrawerActions,
|
||||
withDialogActions,
|
||||
)(AccountsDataTable);
|
||||
|
||||
@@ -27,6 +27,7 @@ export function ActionsMenu({
|
||||
onNewChild,
|
||||
onActivate,
|
||||
onInactivate,
|
||||
// onDrawer,
|
||||
},
|
||||
}) {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import React from 'react';
|
||||
import Icon from 'components/Icon';
|
||||
import { Button, Classes, NavbarGroup, Intent } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||
|
||||
import { safeCallback } from 'utils';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
/**
|
||||
* Account drawer action bar.
|
||||
*/
|
||||
function AccountDrawerActionBar({
|
||||
// #withDialog
|
||||
openDialog,
|
||||
|
||||
// #withAlertsDialog
|
||||
openAlert,
|
||||
|
||||
// #withDrawerActions
|
||||
closeDrawer,
|
||||
|
||||
// #ownProps
|
||||
account,
|
||||
}) {
|
||||
|
||||
|
||||
// Handle new child button click.
|
||||
const onNewChildAccount = () => {
|
||||
openDialog('account-form', {
|
||||
action: 'new_child',
|
||||
parentAccountId: account.id,
|
||||
accountType: account.account_type,
|
||||
});
|
||||
};
|
||||
|
||||
// Handle edit account action.
|
||||
const onEditAccount = () => {
|
||||
openDialog('account-form', { action: 'edit', id: account.id });
|
||||
};
|
||||
|
||||
// Handle delete action account.
|
||||
const onDeleteAccount = () => {
|
||||
if (account) {
|
||||
openAlert('account-delete', { accountId: account.id });
|
||||
closeDrawer('account-drawer');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="pen-18" />}
|
||||
text={<T id={'edit_account'} />}
|
||||
onClick={safeCallback(onEditAccount)}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="plus" />}
|
||||
text={<T id={'new_child_account'} />}
|
||||
onClick={safeCallback(onNewChildAccount)}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon style={{ color: 'red' }} icon="trash-18" iconSize={18} />}
|
||||
text={<T id={'delete'} />}
|
||||
// intent={Intent.DANGER}
|
||||
onClick={safeCallback(onDeleteAccount)}
|
||||
/>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
}
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withAlertsActions,
|
||||
withDrawerActions,
|
||||
)(AccountDrawerActionBar);
|
||||
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
import { AccountDrawerProvider } from './AccountDrawerProvider';
|
||||
import AccountDrawerDetails from './AccountDrawerDetails';
|
||||
|
||||
/**
|
||||
* Account drawer content.
|
||||
*/
|
||||
export default function AccountDrawerContent({
|
||||
// #ownProp
|
||||
accountId,
|
||||
}) {
|
||||
return (
|
||||
<AccountDrawerProvider accountId={accountId}>
|
||||
<AccountDrawerDetails />
|
||||
</AccountDrawerProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
import AccountDrawerActionBar from './AccountDrawerActionBar';
|
||||
import AccountDrawerHeader from './AccountDrawerHeader';
|
||||
import AccountDrawerTable from './AccountDrawerTable';
|
||||
import { useAccountDrawerContext } from './AccountDrawerProvider';
|
||||
|
||||
import 'style/components/Drawer/AccountDrawer.scss';
|
||||
|
||||
/**
|
||||
* Account view details.
|
||||
*/
|
||||
export default function AccountDrawerDetails() {
|
||||
const { account, accounts } = useAccountDrawerContext();
|
||||
|
||||
return (
|
||||
<div className={'account-drawer'}>
|
||||
<AccountDrawerActionBar account={account} />
|
||||
<AccountDrawerHeader account={account} />
|
||||
<AccountDrawerTable />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { If, Money } from 'components';
|
||||
|
||||
/**
|
||||
* Account drawer header.
|
||||
*/
|
||||
export default function AccountDrawerHeader({
|
||||
account: {
|
||||
account_normal,
|
||||
account_type_label,
|
||||
code,
|
||||
amount,
|
||||
currency_code,
|
||||
description,
|
||||
},
|
||||
}) {
|
||||
return (
|
||||
<div className={'account-drawer__content'}>
|
||||
<div>
|
||||
<span>Closing Balance</span>
|
||||
<p className={'balance'}>
|
||||
{<Money amount={amount} currency={currency_code} />}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<T id={'account_type'} />
|
||||
</span>
|
||||
<p>{account_type_label}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<T id={'account_normal'} />
|
||||
</span>
|
||||
<p> {account_normal}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<T id={'code'} />
|
||||
</span>
|
||||
<p>{code}</p>
|
||||
</div>
|
||||
<div>
|
||||
<span>
|
||||
<T id={'currency'} />
|
||||
</span>
|
||||
<p>{currency_code}</p>
|
||||
</div>
|
||||
|
||||
<p className={'account-drawer__content--desc'}>
|
||||
<If condition={description}>
|
||||
<b>
|
||||
<T id={'description'} />
|
||||
</b>
|
||||
: {description}
|
||||
</If>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import { useAccount, useAccountTransactions } from 'hooks/query';
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
|
||||
const AccountDrawerContext = React.createContext();
|
||||
|
||||
/**
|
||||
* Account drawer provider.
|
||||
*/
|
||||
function AccountDrawerProvider({ accountId, ...props }) {
|
||||
// Fetches the specific account details.
|
||||
const { data: account, isLoading: isAccountLoading } = useAccount(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
|
||||
// Load the specific account transactions.
|
||||
const {
|
||||
data: accounts,
|
||||
isLoading: isAccountsLoading,
|
||||
} = useAccountTransactions(accountId, {
|
||||
enabled: !!accountId,
|
||||
});
|
||||
|
||||
// provider.
|
||||
const provider = {
|
||||
accountId,
|
||||
account,
|
||||
accounts,
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardInsider loading={isAccountLoading || isAccountsLoading}>
|
||||
<AccountDrawerContext.Provider value={provider} {...props} />
|
||||
</DashboardInsider>
|
||||
);
|
||||
}
|
||||
|
||||
const useAccountDrawerContext = () => React.useContext(AccountDrawerContext);
|
||||
|
||||
export { AccountDrawerProvider, useAccountDrawerContext };
|
||||
@@ -0,0 +1,60 @@
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import { useAccountDrawerContext } from './AccountDrawerProvider';
|
||||
|
||||
import { formatMessage } from 'services/intl';
|
||||
import { DataTable, Money } from 'components';
|
||||
import { isBlank } from 'utils';
|
||||
|
||||
/**
|
||||
* account drawer table.
|
||||
*/
|
||||
export default function AccountDrawerTable() {
|
||||
const {
|
||||
account: { currency_code },
|
||||
accounts,
|
||||
} = useAccountDrawerContext();
|
||||
|
||||
const columns = React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: formatMessage({ id: 'transaction_date' }),
|
||||
accessor: ({ date }) => moment(date).format('YYYY MMM DD'),
|
||||
width: 110,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'transaction_type' }),
|
||||
accessor: 'reference_type_formatted',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'credit' }),
|
||||
accessor: ({ credit }) =>
|
||||
!isBlank(credit) && credit !== 0 ? (
|
||||
<Money amount={credit} currency={currency_code} />
|
||||
) : null,
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'debit' }),
|
||||
accessor: ({ debit }) =>
|
||||
!isBlank(debit) && debit !== 0 ? (
|
||||
<Money amount={debit} currency={currency_code} />
|
||||
) : null,
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
Header: formatMessage({ id: 'running_balance' }),
|
||||
accessor: 'balance',
|
||||
width: 110,
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={'account-drawer__table'}>
|
||||
<DataTable columns={columns} data={accounts} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
35
client/src/containers/Drawers/AccountDrawer/index.js
Normal file
35
client/src/containers/Drawers/AccountDrawer/index.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import React, { lazy } from 'react';
|
||||
import { Drawer, DrawerSuspense } from 'components';
|
||||
import withDrawers from 'containers/Drawer/withDrawers';
|
||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
const AccountDrawerContent = lazy(() => import('./AccountDrawerContent'));
|
||||
|
||||
/**
|
||||
* Account drawer.
|
||||
*/
|
||||
function AccountDrawer({
|
||||
name,
|
||||
//#withDrawer
|
||||
isOpen,
|
||||
payload: { accountId, title },
|
||||
|
||||
closeDrawer,
|
||||
}) {
|
||||
// Handle close drawer.
|
||||
const handleDrawerClose = () => {
|
||||
closeDrawer(name);
|
||||
};
|
||||
|
||||
return (
|
||||
<Drawer isOpen={isOpen} title={title} isClose={handleDrawerClose}>
|
||||
<DrawerSuspense>
|
||||
<AccountDrawerContent accountId={accountId} />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDrawers(), withDrawerActions)(AccountDrawer);
|
||||
Reference in New Issue
Block a user