mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 13:50:31 +00:00
Merge remote-tracking branch 'origin/feature/Detail'
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import {
|
||||
Button,
|
||||
NavbarGroup,
|
||||
Classes,
|
||||
NavbarDivider,
|
||||
Intent,
|
||||
} from '@blueprintjs/core';
|
||||
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
|
||||
|
||||
import { useBillDrawerContext } from './BillDrawerProvider';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||
|
||||
import { Icon, FormattedMessage as T } from 'components';
|
||||
|
||||
import { safeCallback, compose } from 'utils';
|
||||
|
||||
function BillDetailActionsBar({
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withAlertsActions
|
||||
openAlert,
|
||||
|
||||
// #withDrawerActions
|
||||
closeDrawer,
|
||||
}) {
|
||||
const history = useHistory();
|
||||
|
||||
const { billId } = useBillDrawerContext();
|
||||
|
||||
// Handle edit bill.
|
||||
const onEditBill = () => {
|
||||
return billId
|
||||
? (history.push(`/bills/${billId}/edit`), closeDrawer('bill-drawer'))
|
||||
: null;
|
||||
};
|
||||
|
||||
// Handle delete bill.
|
||||
const onDeleteBill = () => {
|
||||
return billId
|
||||
? (openAlert('bill-delete', { billId }), closeDrawer('bill-drawer'))
|
||||
: null;
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="pen-18" />}
|
||||
text={<T id={'edit_bill'} />}
|
||||
onClick={safeCallback(onEditBill)}
|
||||
/>
|
||||
<NavbarDivider />
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon={'trash-16'} iconSize={16} />}
|
||||
text={<T id={'delete'} />}
|
||||
intent={Intent.DANGER}
|
||||
onClick={safeCallback(onDeleteBill)}
|
||||
/>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withDrawerActions,
|
||||
withAlertsActions,
|
||||
)(BillDetailActionsBar);
|
||||
37
client/src/containers/Drawers/BillDrawer/BillDetailFooter.js
Normal file
37
client/src/containers/Drawers/BillDrawer/BillDetailFooter.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
import clsx from 'classnames';
|
||||
|
||||
import { TotalLines, TotalLine } from 'components';
|
||||
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
|
||||
import { useBillDrawerContext } from './BillDrawerProvider';
|
||||
|
||||
export function BillDetailFooter() {
|
||||
const { bill } = useBillDrawerContext();
|
||||
|
||||
return (
|
||||
<div className={clsx(BillDrawerCls.detail_panel_footer)}>
|
||||
<TotalLines>
|
||||
<TotalLine
|
||||
title={'Subtotal'}
|
||||
value={bill.amount}
|
||||
className={BillDrawerCls.total_line_subtotal}
|
||||
/>
|
||||
<TotalLine
|
||||
title={'TOTAL'}
|
||||
value={bill.amount}
|
||||
className={BillDrawerCls.total_line_total}
|
||||
/>
|
||||
<TotalLine
|
||||
title={'Payment made'}
|
||||
value={bill.payment_amount}
|
||||
className={BillDrawerCls.total_line_payment}
|
||||
/>
|
||||
<TotalLine
|
||||
title={'Due amount'}
|
||||
value={bill.formatted_due_amount}
|
||||
className={BillDrawerCls.total_line_dueAmount}
|
||||
/>
|
||||
</TotalLines>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
55
client/src/containers/Drawers/BillDrawer/BillDetailHeader.js
Normal file
55
client/src/containers/Drawers/BillDrawer/BillDetailHeader.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { defaultTo } from 'lodash';
|
||||
import clsx from 'classnames';
|
||||
|
||||
import { DetailsMenu, DetailItem } from 'components';
|
||||
|
||||
import { useBillDrawerContext } from './BillDrawerProvider';
|
||||
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
|
||||
|
||||
/**
|
||||
* Bill detail header.
|
||||
*/
|
||||
export default function BillDetailHeader() {
|
||||
const { bill } = useBillDrawerContext();
|
||||
|
||||
return (
|
||||
<div className={clsx(BillDrawerCls.detail_panel_header)}>
|
||||
<DetailsMenu>
|
||||
<DetailItem
|
||||
label={intl.get('amount')}
|
||||
children={<h3 class="big-number">{bill.formatted_amount}</h3>}
|
||||
/>
|
||||
<DetailItem
|
||||
label={intl.get('bill_number')}
|
||||
children={defaultTo(bill.bill_number, '-')}
|
||||
/>
|
||||
<DetailItem
|
||||
label={intl.get('bill_date')}
|
||||
children={bill.formatted_bill_date}
|
||||
/>
|
||||
<DetailItem
|
||||
label={intl.get('vendor_name')}
|
||||
children={bill.vendor?.display_name}
|
||||
/>
|
||||
<DetailItem
|
||||
label={intl.get('due_date')}
|
||||
children={bill.formatted_due_date}
|
||||
/>
|
||||
</DetailsMenu>
|
||||
|
||||
<DetailsMenu direction={'horizantal'} minLabelSize={'140px'}>
|
||||
<DetailItem
|
||||
label={intl.get('due_amount')}
|
||||
children={bill.formatted_due_amount}
|
||||
/>
|
||||
<DetailItem
|
||||
label={intl.get('reference')}
|
||||
children={defaultTo(bill.reference_no, '--')}
|
||||
/>
|
||||
<DetailItem label={'Created at'} children={'2020 Ang 21'} />
|
||||
</DetailsMenu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
29
client/src/containers/Drawers/BillDrawer/BillDetailTab.js
Normal file
29
client/src/containers/Drawers/BillDrawer/BillDetailTab.js
Normal file
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import clsx from 'classnames';
|
||||
|
||||
import { Card } from 'components';
|
||||
|
||||
import BillDetailActionsBar from './BillDetailActionsBar';
|
||||
import BillDetailHeader from './BillDetailHeader';
|
||||
import BillDetailTable from './BillDetailTable';
|
||||
import { BillDetailFooter } from './BillDetailFooter'
|
||||
|
||||
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
|
||||
|
||||
|
||||
/**
|
||||
* Bill detail panel tab.
|
||||
*/
|
||||
export default function BillDetailTab() {
|
||||
return (
|
||||
<div className={clsx(BillDrawerCls.detail_panel)}>
|
||||
<BillDetailActionsBar />
|
||||
|
||||
<Card>
|
||||
<BillDetailHeader />
|
||||
<BillDetailTable />
|
||||
<BillDetailFooter />
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
26
client/src/containers/Drawers/BillDrawer/BillDetailTable.js
Normal file
26
client/src/containers/Drawers/BillDrawer/BillDetailTable.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
import clsx from 'classnames';
|
||||
|
||||
import { DataTable } from 'components';
|
||||
|
||||
import { useBillDrawerContext } from './BillDrawerProvider';
|
||||
import { useBillReadonlyEntriesTableColumns } from './utils';
|
||||
|
||||
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
|
||||
|
||||
export default function BillDetailTable() {
|
||||
const { bill: { entries } } = useBillDrawerContext();
|
||||
|
||||
// Retrieve bill readonly entries table columns.
|
||||
const columns = useBillReadonlyEntriesTableColumns();
|
||||
|
||||
return (
|
||||
<div className={clsx(BillDrawerCls.detail_panel_table)}>
|
||||
<DataTable
|
||||
columns={columns}
|
||||
data={entries}
|
||||
className={'table-constrant'}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -4,19 +4,19 @@ import 'style/components/Drawers/ViewDetail/ViewDetail.scss';
|
||||
|
||||
import { BillDrawerProvider } from './BillDrawerProvider';
|
||||
import BillDrawerDetails from './BillDrawerDetails';
|
||||
import BillDrawerAlerts from './BillDrawerAlerts';
|
||||
// import BillDrawerAlerts from './BillDrawerAlerts';
|
||||
|
||||
/**
|
||||
* Bill drawer content.
|
||||
*/
|
||||
export default function BillDrawerContent({
|
||||
// #ownProp
|
||||
bill,
|
||||
billId,
|
||||
}) {
|
||||
return (
|
||||
<BillDrawerProvider billId={bill}>
|
||||
<BillDrawerProvider billId={billId}>
|
||||
<BillDrawerDetails />
|
||||
<BillDrawerAlerts />
|
||||
{/* <BillDrawerAlerts /> */}
|
||||
</BillDrawerProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
import React from 'react';
|
||||
import { Tabs, Tab } from '@blueprintjs/core';
|
||||
import { Tab } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import clsx from 'classnames';
|
||||
|
||||
import { DrawerMainTabs } from 'components';
|
||||
|
||||
import BillDetailTab from './BillDetailTab';
|
||||
import LocatedLandedCostTable from './LocatedLandedCostTable';
|
||||
import JournalEntriesTable from '../../JournalEntriesTable/JournalEntriesTable';
|
||||
import { useBillDrawerContext } from './BillDrawerProvider';
|
||||
|
||||
import BillDrawerCls from 'style/components/Drawers/BillDrawer.module.scss';
|
||||
|
||||
/**
|
||||
* Bill view details.
|
||||
*/
|
||||
@@ -15,9 +21,13 @@ export default function BillDrawerDetails() {
|
||||
} = useBillDrawerContext();
|
||||
|
||||
return (
|
||||
<div className="view-detail-drawer">
|
||||
<Tabs animate={true} large={true} defaultSelectedTabId="journal_entries">
|
||||
<Tab title={intl.get('details')} id={'details'} disabled={true} />
|
||||
<div className={clsx(BillDrawerCls.root)}>
|
||||
<DrawerMainTabs defaultSelectedTabId="details">
|
||||
<Tab
|
||||
title={intl.get('details')}
|
||||
id={'details'}
|
||||
panel={<BillDetailTab />}
|
||||
/>
|
||||
<Tab
|
||||
title={intl.get('journal_entries')}
|
||||
id={'journal_entries'}
|
||||
@@ -28,9 +38,7 @@ export default function BillDrawerDetails() {
|
||||
id={'landed_cost'}
|
||||
panel={<LocatedLandedCostTable />}
|
||||
/>
|
||||
</Tabs>
|
||||
</DrawerMainTabs>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// 42 / fon-w 600
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { DrawerHeaderContent, DashboardInsider } from 'components';
|
||||
import { useBillLocatedLandedCost } from 'hooks/query';
|
||||
import { useTransactionsByReference } from 'hooks/query';
|
||||
import {
|
||||
useBill,
|
||||
useTransactionsByReference,
|
||||
useBillLocatedLandedCost,
|
||||
} from 'hooks/query';
|
||||
|
||||
const BillDrawerContext = React.createContext();
|
||||
|
||||
@@ -10,7 +13,11 @@ const BillDrawerContext = React.createContext();
|
||||
* Bill drawer provider.
|
||||
*/
|
||||
function BillDrawerProvider({ billId, ...props }) {
|
||||
|
||||
// Handle fetch bill details.
|
||||
const { isLoading: isBillLoading, data: bill } = useBill(billId, {
|
||||
enabled: !!billId,
|
||||
});
|
||||
|
||||
// Handle fetch transaction by reference.
|
||||
const { data, isLoading: isTransactionLoading } = useTransactionsByReference(
|
||||
{
|
||||
@@ -31,10 +38,13 @@ function BillDrawerProvider({ billId, ...props }) {
|
||||
transactions,
|
||||
billId,
|
||||
data,
|
||||
bill,
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardInsider loading={isLandedCostLoading || isTransactionLoading}>
|
||||
<DashboardInsider
|
||||
loading={isLandedCostLoading || isTransactionLoading || isBillLoading}
|
||||
>
|
||||
<DrawerHeaderContent
|
||||
name="bill-drawer"
|
||||
title={intl.get('bill_details')}
|
||||
|
||||
@@ -16,9 +16,14 @@ function BillDrawer({
|
||||
payload: { billId },
|
||||
}) {
|
||||
return (
|
||||
<Drawer isOpen={isOpen} name={name} size={'750px'}>
|
||||
<Drawer
|
||||
isOpen={isOpen}
|
||||
name={name}
|
||||
style={{ minWidth: '700px', maxWidth: '900px' }}
|
||||
size={'65%'}
|
||||
>
|
||||
<DrawerSuspense>
|
||||
<BillDrawerContent bill={billId} />
|
||||
<BillDrawerContent billId={billId} />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
|
||||
43
client/src/containers/Drawers/BillDrawer/utils.js
Normal file
43
client/src/containers/Drawers/BillDrawer/utils.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
|
||||
export const useBillReadonlyEntriesTableColumns = () =>
|
||||
React.useMemo(
|
||||
() => [
|
||||
{
|
||||
Header: intl.get('product_and_service'),
|
||||
accessor: 'item.name',
|
||||
width: 150,
|
||||
className: 'item',
|
||||
disableSortBy: true
|
||||
},
|
||||
{
|
||||
Header: intl.get('description'),
|
||||
accessor: 'description',
|
||||
className: 'description',
|
||||
disableSortBy: true
|
||||
},
|
||||
{
|
||||
Header: intl.get('quantity'),
|
||||
accessor: 'quantity',
|
||||
width: 100,
|
||||
className: 'quantity',
|
||||
disableSortBy: true
|
||||
},
|
||||
{
|
||||
Header: intl.get('rate'),
|
||||
accessor: 'rate',
|
||||
width: 100,
|
||||
className: 'rate',
|
||||
disableSortBy: true
|
||||
},
|
||||
{
|
||||
Header: intl.get('amount'),
|
||||
accessor: 'amount',
|
||||
width: 100,
|
||||
className: 'amount',
|
||||
disableSortBy: true
|
||||
},
|
||||
],
|
||||
[],
|
||||
);
|
||||
Reference in New Issue
Block a user