mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 07:10:33 +00:00
feat: Bill drawer.
This commit is contained in:
@@ -6,6 +6,7 @@ import PaymentReceiveDrawer from 'containers/Sales/PaymentReceives/PaymentDetail
|
|||||||
import AccountDrawer from 'containers/Drawers/AccountDrawer';
|
import AccountDrawer from 'containers/Drawers/AccountDrawer';
|
||||||
import ManualJournalDrawer from 'containers/Drawers/ManualJournalDrawer';
|
import ManualJournalDrawer from 'containers/Drawers/ManualJournalDrawer';
|
||||||
import ExpenseDrawer from 'containers/Drawers/ExpenseDrawer';
|
import ExpenseDrawer from 'containers/Drawers/ExpenseDrawer';
|
||||||
|
import BillDrawer from 'containers/Drawers/BillDrawer';
|
||||||
|
|
||||||
export default function DrawersContainer() {
|
export default function DrawersContainer() {
|
||||||
return (
|
return (
|
||||||
@@ -17,6 +18,7 @@ export default function DrawersContainer() {
|
|||||||
<AccountDrawer name={'account-drawer'} />
|
<AccountDrawer name={'account-drawer'} />
|
||||||
<ManualJournalDrawer name={'journal-drawer'} />
|
<ManualJournalDrawer name={'journal-drawer'} />
|
||||||
<ExpenseDrawer name={'expense-drawer'} />
|
<ExpenseDrawer name={'expense-drawer'} />
|
||||||
|
<BillDrawer name={'bill-drawer'} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,30 @@ export default function AllocateLandedCostEntriesTable({
|
|||||||
rate: '100000',
|
rate: '100000',
|
||||||
amount: '400',
|
amount: '400',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
item_id: 'ITEM',
|
||||||
|
quantity: '30000',
|
||||||
|
rate: '100000',
|
||||||
|
amount: '400',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item_id: 'ITEM',
|
||||||
|
quantity: '30000',
|
||||||
|
rate: '100000',
|
||||||
|
amount: '400',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item_id: 'ITEM',
|
||||||
|
quantity: '30000',
|
||||||
|
rate: '100000',
|
||||||
|
amount: '400',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
item_id: 'ITEM',
|
||||||
|
quantity: '30000',
|
||||||
|
rate: '100000',
|
||||||
|
amount: '400',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return <DataTableEditable columns={columns} data={LL} />;
|
return <DataTableEditable columns={columns} data={LL} />;
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { BillDrawerProvider } from './BillDrawerProvider';
|
||||||
|
import BillDrawerDetails from './BillDrawerDetails';
|
||||||
|
/**
|
||||||
|
* Bill drawer content.
|
||||||
|
*/
|
||||||
|
export default function BillDrawerContent({
|
||||||
|
// #ownProp
|
||||||
|
billId,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<BillDrawerProvider billId={billId}>
|
||||||
|
<BillDrawerDetails />
|
||||||
|
</BillDrawerProvider>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Tabs, Tab } from '@blueprintjs/core';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
|
||||||
|
import LocatedLandedCostTable from './LocatedLandedCostTable';
|
||||||
|
|
||||||
|
import 'style/components/Drawer/BillDrawer.scss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill view details.
|
||||||
|
*/
|
||||||
|
export default function BillDrawerDetails() {
|
||||||
|
return (
|
||||||
|
<div className="bill-drawer">
|
||||||
|
<Tabs animate={true} large={true} selectedTabId="landed_cost">
|
||||||
|
<Tab title={intl.get('details')} id={'details'} disabled={true} />
|
||||||
|
<Tab
|
||||||
|
title={intl.get('located_landed_cost')}
|
||||||
|
id={'landed_cost'}
|
||||||
|
panel={<LocatedLandedCostTable />}
|
||||||
|
/>
|
||||||
|
</Tabs>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { DrawerHeaderContent, DashboardInsider } from 'components';
|
||||||
|
|
||||||
|
const BillDrawerContext = React.createContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill drawer provider.
|
||||||
|
*/
|
||||||
|
function BillDrawerProvider({ billId, ...props }) {
|
||||||
|
//provider.
|
||||||
|
const provider = {};
|
||||||
|
return (
|
||||||
|
<DashboardInsider>
|
||||||
|
<DrawerHeaderContent
|
||||||
|
name="bill-drawer"
|
||||||
|
title={intl.get('bill_details')}
|
||||||
|
/>
|
||||||
|
<BillDrawerContext.Provider value={provider} {...props} />
|
||||||
|
</DashboardInsider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useBillDrawerContext = () => React.useContext(BillDrawerContext);
|
||||||
|
|
||||||
|
export { BillDrawerProvider, useBillDrawerContext };
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { DataTable } from 'components';
|
||||||
|
import { useLocatedLandedCostColumns, ActionsMenu } from './components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Located landed cost table.
|
||||||
|
*/
|
||||||
|
function LocatedLandedCostTable() {
|
||||||
|
const columns = useLocatedLandedCostColumns();
|
||||||
|
|
||||||
|
const DATA = [
|
||||||
|
{
|
||||||
|
name: 'INV-1000',
|
||||||
|
amount: '10.000.000',
|
||||||
|
allocation_method: 'Bill',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
return <DataTable columns={columns} data={DATA} ContextMenu={ActionsMenu} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default LocatedLandedCostTable;
|
||||||
41
client/src/containers/Drawers/BillDrawer/components.js
Normal file
41
client/src/containers/Drawers/BillDrawer/components.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import intl from 'react-intl-universal';
|
||||||
|
import { Intent, MenuItem, Menu } from '@blueprintjs/core';
|
||||||
|
import { safeCallback } from 'utils';
|
||||||
|
import { Icon } from 'components';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions menu.
|
||||||
|
*/
|
||||||
|
export function ActionsMenu({ row: { original }, payload: { onDelete } }) {
|
||||||
|
return (
|
||||||
|
<Menu>
|
||||||
|
<MenuItem
|
||||||
|
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||||
|
text={intl.get('delete_transaction')}
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
// onClick={safeCallback(onDelete, original)}
|
||||||
|
/>
|
||||||
|
</Menu>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useLocatedLandedCostColumns() {
|
||||||
|
return React.useMemo(() => [
|
||||||
|
{
|
||||||
|
Header: intl.get('name'),
|
||||||
|
accessor: 'name',
|
||||||
|
width: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: intl.get('amount'),
|
||||||
|
accessor: 'amount',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: intl.get('allocation_method'),
|
||||||
|
accessor: 'allocation_method',
|
||||||
|
width: 100,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
27
client/src/containers/Drawers/BillDrawer/index.js
Normal file
27
client/src/containers/Drawers/BillDrawer/index.js
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Drawer, DrawerSuspense } from 'components';
|
||||||
|
import withDrawers from 'containers/Drawer/withDrawers';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
const BillDrawerContent = React.lazy(() => import('./BillDrawerContent'));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bill drawer.
|
||||||
|
*/
|
||||||
|
function BillDrawer({
|
||||||
|
name,
|
||||||
|
// #withDrawer
|
||||||
|
isOpen,
|
||||||
|
payload: { billId },
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Drawer isOpen={isOpen} name={name} size={'750px'}>
|
||||||
|
<DrawerSuspense>
|
||||||
|
<BillDrawerContent bill={billId} />
|
||||||
|
</DrawerSuspense>
|
||||||
|
</Drawer>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(withDrawers())(BillDrawer);
|
||||||
@@ -14,6 +14,7 @@ import withBillActions from './withBillsActions';
|
|||||||
import withSettings from 'containers/Settings/withSettings';
|
import withSettings from 'containers/Settings/withSettings';
|
||||||
import withAlertsActions from 'containers/Alert/withAlertActions';
|
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||||
|
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||||
import { useBillsTableColumns, ActionsMenu } from './components';
|
import { useBillsTableColumns, ActionsMenu } from './components';
|
||||||
import { useBillsListContext } from './BillsListProvider';
|
import { useBillsListContext } from './BillsListProvider';
|
||||||
|
|
||||||
@@ -32,6 +33,9 @@ function BillsDataTable({
|
|||||||
|
|
||||||
// #withDialogActions
|
// #withDialogActions
|
||||||
openDialog,
|
openDialog,
|
||||||
|
|
||||||
|
// #withDrawerActions
|
||||||
|
openDrawer,
|
||||||
}) {
|
}) {
|
||||||
// Bills list context.
|
// Bills list context.
|
||||||
const { bills, pagination, isBillsLoading, isBillsFetching, isEmptyStatus } =
|
const { bills, pagination, isBillsLoading, isBillsFetching, isEmptyStatus } =
|
||||||
@@ -78,6 +82,11 @@ function BillsDataTable({
|
|||||||
openDialog('allocate-landed-cost', { billId: id });
|
openDialog('allocate-landed-cost', { billId: id });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle view detail bill.
|
||||||
|
const handleViewDetailBill = ({ id }) => {
|
||||||
|
openDrawer('bill-drawer', { billId: id });
|
||||||
|
};
|
||||||
|
|
||||||
if (isEmptyStatus) {
|
if (isEmptyStatus) {
|
||||||
return <BillsEmptyStatus />;
|
return <BillsEmptyStatus />;
|
||||||
}
|
}
|
||||||
@@ -106,6 +115,7 @@ function BillsDataTable({
|
|||||||
onOpen: handleOpenBill,
|
onOpen: handleOpenBill,
|
||||||
onQuick: handleQuickPaymentMade,
|
onQuick: handleQuickPaymentMade,
|
||||||
onAllocateLandedCost: handleAllocateLandedCost,
|
onAllocateLandedCost: handleAllocateLandedCost,
|
||||||
|
onViewDetails: handleViewDetailBill,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -115,6 +125,7 @@ export default compose(
|
|||||||
withBills(({ billsTableState }) => ({ billsTableState })),
|
withBills(({ billsTableState }) => ({ billsTableState })),
|
||||||
withBillActions,
|
withBillActions,
|
||||||
withAlertsActions,
|
withAlertsActions,
|
||||||
|
withDrawerActions,
|
||||||
withDialogActions,
|
withDialogActions,
|
||||||
withSettings(({ organizationSettings }) => ({
|
withSettings(({ organizationSettings }) => ({
|
||||||
baseCurrency: organizationSettings?.baseCurrency,
|
baseCurrency: organizationSettings?.baseCurrency,
|
||||||
|
|||||||
@@ -20,7 +20,14 @@ import moment from 'moment';
|
|||||||
* Actions menu.
|
* Actions menu.
|
||||||
*/
|
*/
|
||||||
export function ActionsMenu({
|
export function ActionsMenu({
|
||||||
payload: { onEdit, onOpen, onDelete, onQuick, onAllocateLandedCost },
|
payload: {
|
||||||
|
onEdit,
|
||||||
|
onOpen,
|
||||||
|
onDelete,
|
||||||
|
onQuick,
|
||||||
|
onViewDetails,
|
||||||
|
onAllocateLandedCost,
|
||||||
|
},
|
||||||
row: { original },
|
row: { original },
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -28,6 +35,7 @@ export function ActionsMenu({
|
|||||||
<MenuItem
|
<MenuItem
|
||||||
icon={<Icon icon="reader-18" />}
|
icon={<Icon icon="reader-18" />}
|
||||||
text={intl.get('view_details')}
|
text={intl.get('view_details')}
|
||||||
|
onClick={safeCallback(onViewDetails, original)}
|
||||||
/>
|
/>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
@@ -1133,5 +1133,8 @@
|
|||||||
"transaction_line":"Transaction line",
|
"transaction_line":"Transaction line",
|
||||||
"allocation_method":"Allocation method",
|
"allocation_method":"Allocation method",
|
||||||
"valuation":"Valuation",
|
"valuation":"Valuation",
|
||||||
"select_transaction":"Select transaction account"
|
"select_transaction":"Select transaction account",
|
||||||
|
"details":"Details",
|
||||||
|
"located_landed_cost":"Located Landed Cost",
|
||||||
|
"delete_transaction":"Delete transaction"
|
||||||
}
|
}
|
||||||
81
client/src/style/components/Drawer/BillDrawer.scss
Normal file
81
client/src/style/components/Drawer/BillDrawer.scss
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
@import '../../Base.scss';
|
||||||
|
|
||||||
|
.bill-drawer {
|
||||||
|
.bp3-tabs {
|
||||||
|
.bp3-tab-list {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> *:not(:last-child) {
|
||||||
|
margin-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bp3-large > .bp3-tab {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #555;
|
||||||
|
margin: 0 0.8rem;
|
||||||
|
|
||||||
|
&[aria-selected='true'],
|
||||||
|
&:not([aria-disabled='true']):hover {
|
||||||
|
color: $pt-link-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bigcapital-datatable {
|
||||||
|
.table {
|
||||||
|
max-height: 500px;
|
||||||
|
border: 1px solid #d1dee2;
|
||||||
|
min-width: auto;
|
||||||
|
margin: 12px;
|
||||||
|
|
||||||
|
.tbody,
|
||||||
|
.tbody-inner {
|
||||||
|
height: auto;
|
||||||
|
scrollbar-width: none;
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tbody {
|
||||||
|
.tr .td {
|
||||||
|
padding: 0.8rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-drawer.bp3-position-right {
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
overflow: auto;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
scrollbar-width: none;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bp3-drawer-header {
|
||||||
|
margin-bottom: 2px;
|
||||||
|
box-shadow: (0, 0, 0);
|
||||||
|
background-color: #6a7993;
|
||||||
|
|
||||||
|
.bp3-heading,
|
||||||
|
.bp3-icon {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,12 +19,13 @@
|
|||||||
|
|
||||||
.bigcapital-datatable {
|
.bigcapital-datatable {
|
||||||
.table {
|
.table {
|
||||||
max-height: 300px;
|
// max-height: 300px;
|
||||||
border: 1px solid #d1dee2;
|
border: 1px solid #d1dee2;
|
||||||
min-width: auto;
|
min-width: auto;
|
||||||
|
|
||||||
.tbody,
|
.tbody,
|
||||||
.tbody-inner {
|
.tbody-inner {
|
||||||
|
height: auto;
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
&::-webkit-scrollbar {
|
&::-webkit-scrollbar {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
Reference in New Issue
Block a user