mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: add view detail cash flow transaction.
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import Icon from 'components/Icon';
|
||||
import { Button, Classes, NavbarGroup, Intent } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
import { useCashflowTransactionDrawerContext } from './CashflowTransactionDrawerProvider';
|
||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
/**
|
||||
* Cashflow transaction drawer action bar.
|
||||
*/
|
||||
function CashflowTransactionDrawerActionBar({
|
||||
// #withAlertsDialog
|
||||
openAlert,
|
||||
}) {
|
||||
const { referenceId } = useCashflowTransactionDrawerContext();
|
||||
|
||||
// Handle cashflow transaction delete action.
|
||||
const handleDeleteCashflowTransaction = () => {
|
||||
openAlert('account-transaction-delete', { referenceId });
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||
text={<T id={'delete'} />}
|
||||
intent={Intent.DANGER}
|
||||
onClick={handleDeleteCashflowTransaction}
|
||||
/>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
}
|
||||
export default compose(withAlertsActions)(CashflowTransactionDrawerActionBar);
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
import 'style/components/Drawers/CashflowTransactionDrawer.scss';
|
||||
|
||||
import { DrawerBody } from 'components';
|
||||
import { CashflowTransactionDrawerProvider } from './CashflowTransactionDrawerProvider';
|
||||
import CashflowTransactionDrawerDetails from './CashflowTransactionDrawerDetails';
|
||||
|
||||
/**
|
||||
* Cash flow transction drawer content.
|
||||
*/
|
||||
export default function CashflowTransactionDrawerContent({
|
||||
// #ownProp
|
||||
referenceId,
|
||||
}) {
|
||||
return (
|
||||
<CashflowTransactionDrawerProvider referenceId={referenceId}>
|
||||
<DrawerBody>
|
||||
<CashflowTransactionDrawerDetails />
|
||||
</DrawerBody>
|
||||
</CashflowTransactionDrawerProvider>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Card } from 'components';
|
||||
|
||||
import CashflowTransactionDrawerActionBar from './CashflowTransactionDrawerActionBar';
|
||||
import CashflowTransactionDrawerHeader from './CashflowTransactionDrawerHeader';
|
||||
import CashflowTransactionDrawerTable from './CashflowTransactionDrawerTable';
|
||||
import CashflowTransactionDrawerFooter from './CashflowTransactionDrawerFooter';
|
||||
/**
|
||||
* Cashflow transaction view details.
|
||||
*/
|
||||
export default function CashflowTransactionDrawerDetails() {
|
||||
return (
|
||||
<div className={'cashflow-drawer'}>
|
||||
<CashflowTransactionDrawerActionBar />
|
||||
<div className="cashflow-drawer__content">
|
||||
<Card>
|
||||
<CashflowTransactionDrawerHeader />
|
||||
<CashflowTransactionDrawerTable />
|
||||
<CashflowTransactionDrawerFooter />
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
import { useCashflowTransactionDrawerContext } from './CashflowTransactionDrawerProvider';
|
||||
import { T, FormatNumber } from '../../../components';
|
||||
|
||||
export default function CashflowTransactionDrawerFooter() {
|
||||
const {
|
||||
cashflowTransaction: { amount },
|
||||
} = useCashflowTransactionDrawerContext();
|
||||
|
||||
return (
|
||||
<div className="cashflow-drawer__content-footer">
|
||||
<div class="total-lines">
|
||||
<div class="total-lines__line total-lines__line--subtotal">
|
||||
<div class="title">
|
||||
<T id={'manual_journal.details.subtotal'} />
|
||||
</div>
|
||||
<div class="debit">
|
||||
<FormatNumber value={amount} />
|
||||
</div>
|
||||
<div class="credit">
|
||||
<FormatNumber value={amount} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="total-lines__line total-lines__line--total">
|
||||
<div class="title">
|
||||
<T id={'manual_journal.details.total'} />
|
||||
</div>
|
||||
<div class="debit">{amount}</div>
|
||||
<div class="credit">{amount}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import React from 'react';
|
||||
import { defaultTo } from 'lodash';
|
||||
import {
|
||||
DetailsMenu,
|
||||
DetailItem,
|
||||
FormatDate,
|
||||
FormattedMessage as T,
|
||||
} from 'components';
|
||||
import { useCashflowTransactionDrawerContext } from './CashflowTransactionDrawerProvider';
|
||||
|
||||
/**
|
||||
* Cashlflow transaction drawer detail Header.
|
||||
*/
|
||||
export default function CashflowTransactionDrawerHeader() {
|
||||
const {
|
||||
cashflowTransaction: {
|
||||
amount,
|
||||
transaction_type,
|
||||
transaction_number,
|
||||
reference_no,
|
||||
date,
|
||||
description,
|
||||
},
|
||||
} = useCashflowTransactionDrawerContext();
|
||||
|
||||
return (
|
||||
<div className={'cashflow-drawer__content-header'}>
|
||||
<DetailsMenu>
|
||||
<DetailItem name={'total'} label={<T id={'total'} />}>
|
||||
<h3 class="amount">{amount}</h3>
|
||||
</DetailItem>
|
||||
|
||||
<DetailItem
|
||||
name={'transaction_type'}
|
||||
label={<T id={'cash_flow_drawer.label_transaction_type'} />}
|
||||
>
|
||||
{transaction_type}
|
||||
</DetailItem>
|
||||
|
||||
<DetailItem
|
||||
name={'transaction_number'}
|
||||
label={<T id={'cash_flow.drawer.label_transaction_no'} />}
|
||||
>
|
||||
{transaction_number}
|
||||
</DetailItem>
|
||||
<DetailItem
|
||||
label={<T id={'date'} />}
|
||||
children={<FormatDate value={date} />}
|
||||
/>
|
||||
<DetailItem name={'reference-no'} label={<T id={'reference_no'} />}>
|
||||
{defaultTo(reference_no, '-')}
|
||||
</DetailItem>
|
||||
</DetailsMenu>
|
||||
|
||||
<div class="cashflow-drawer__content-description">
|
||||
<b class="title">
|
||||
<T id={'description'} />
|
||||
</b>
|
||||
: {defaultTo(description, '—')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { useCashflowTransaction } from 'hooks/query';
|
||||
|
||||
import { DrawerLoading, DrawerHeaderContent } from 'components';
|
||||
|
||||
const CashflowTransactionDrawerContext = React.createContext();
|
||||
|
||||
/**
|
||||
* Cashflow transaction drawer provider.
|
||||
*/
|
||||
function CashflowTransactionDrawerProvider({ referenceId, ...props }) {
|
||||
// Fetch the specific cashflow transaction details.
|
||||
const {
|
||||
data: cashflowTransaction,
|
||||
isLoading: isCashflowTransactionLoading,
|
||||
isFetching: isCashflowTransactionFetching,
|
||||
} = useCashflowTransaction(referenceId, {
|
||||
enabled: !!referenceId,
|
||||
});
|
||||
|
||||
// Provider.
|
||||
const provider = {
|
||||
referenceId,
|
||||
cashflowTransaction,
|
||||
|
||||
isCashflowTransactionFetching,
|
||||
isCashflowTransactionLoading,
|
||||
};
|
||||
|
||||
return (
|
||||
<DrawerLoading loading={isCashflowTransactionLoading}>
|
||||
<DrawerHeaderContent
|
||||
name={'cashflow-transaction-drawer'}
|
||||
title={intl.get('cash_flow.drawer.label_transaction', {
|
||||
number: cashflowTransaction?.transaction_number,
|
||||
})}
|
||||
/>
|
||||
<CashflowTransactionDrawerContext.Provider value={provider} {...props} />
|
||||
</DrawerLoading>
|
||||
);
|
||||
}
|
||||
|
||||
const useCashflowTransactionDrawerContext = () =>
|
||||
React.useContext(CashflowTransactionDrawerContext);
|
||||
|
||||
export {
|
||||
CashflowTransactionDrawerProvider,
|
||||
useCashflowTransactionDrawerContext,
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
|
||||
import { DataTable, If, FormattedMessage as T } from 'components';
|
||||
|
||||
import { useCashflowTransactionColumns } from './utils';
|
||||
import { useCashflowTransactionDrawerContext } from './CashflowTransactionDrawerProvider';
|
||||
|
||||
/**
|
||||
* Cashflow transaction drawer table.
|
||||
*/
|
||||
export default function CashflowTransactionDrawerTable() {
|
||||
const columns = useCashflowTransactionColumns();
|
||||
const {
|
||||
cashflowTransaction: { transactions },
|
||||
} = useCashflowTransactionDrawerContext();
|
||||
|
||||
return (
|
||||
<div className="cashflow-drawer__content-table">
|
||||
<DataTable columns={columns} data={transactions} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Drawer, DrawerSuspense } from 'components';
|
||||
import withDrawers from 'containers/Drawer/withDrawers';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
const CashFlowTransactionDrawerContent = React.lazy(() =>
|
||||
import('./CashflowTransactionDrawerContent'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Cash flow transaction drawer
|
||||
*/
|
||||
function CashflowTransactionDetailDrawer({
|
||||
name,
|
||||
// #withDrawer
|
||||
isOpen,
|
||||
payload: { referenceId },
|
||||
}) {
|
||||
return (
|
||||
<Drawer
|
||||
isOpen={isOpen}
|
||||
name={name}
|
||||
size={'65%'}
|
||||
style={{ minWidth: '700px', maxWidth: '900px' }}
|
||||
>
|
||||
<DrawerSuspense>
|
||||
<CashFlowTransactionDrawerContent referenceId={referenceId} />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDrawers())(CashflowTransactionDetailDrawer);
|
||||
@@ -0,0 +1,76 @@
|
||||
import intl from 'react-intl-universal';
|
||||
import React from 'react';
|
||||
import { Classes, Tooltip, Position } from '@blueprintjs/core';
|
||||
|
||||
import { FormatNumberCell, If, Icon } from '../../../components';
|
||||
|
||||
/**
|
||||
* Note column accessor.
|
||||
*/
|
||||
export function NoteAccessor(row) {
|
||||
return (
|
||||
<If condition={row.note}>
|
||||
<Tooltip
|
||||
className={Classes.TOOLTIP_INDICATOR}
|
||||
content={row.note}
|
||||
position={Position.LEFT_TOP}
|
||||
hoverOpenDelay={50}
|
||||
>
|
||||
<Icon icon={'file-alt'} iconSize={16} />
|
||||
</Tooltip>
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve cashflow transaction entries columns.
|
||||
*/
|
||||
export const useCashflowTransactionColumns = () =>
|
||||
React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: intl.get('account_name'),
|
||||
accessor: 'account.name',
|
||||
width: 130,
|
||||
disableSortBy: true,
|
||||
className: 'account',
|
||||
},
|
||||
{
|
||||
Header: intl.get('contact'),
|
||||
accessor: 'contact.display_name',
|
||||
width: 130,
|
||||
disableSortBy: true,
|
||||
className: 'contact',
|
||||
},
|
||||
{
|
||||
Header: intl.get('note'),
|
||||
accessor: NoteAccessor,
|
||||
width: 80,
|
||||
disableSortBy: true,
|
||||
className: 'note',
|
||||
},
|
||||
{
|
||||
Header: intl.get('credit'),
|
||||
accessor: 'credit',
|
||||
Cell: FormatNumberCell,
|
||||
width: 100,
|
||||
disableResizable: true,
|
||||
disableSortBy: true,
|
||||
formatNumber: { noZero: true },
|
||||
className: 'credit',
|
||||
align: 'right',
|
||||
},
|
||||
{
|
||||
Header: intl.get('debit'),
|
||||
accessor: 'debit',
|
||||
Cell: FormatNumberCell,
|
||||
width: 100,
|
||||
disableResizable: true,
|
||||
disableSortBy: true,
|
||||
formatNumber: { noZero: true },
|
||||
className: 'debit',
|
||||
align: 'right',
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
Reference in New Issue
Block a user