mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +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 ManualJournalDrawer from 'containers/Drawers/ManualJournalDrawer';
|
||||
import ExpenseDrawer from 'containers/Drawers/ExpenseDrawer';
|
||||
import BillDrawer from 'containers/Drawers/BillDrawer';
|
||||
|
||||
export default function DrawersContainer() {
|
||||
return (
|
||||
@@ -17,6 +18,7 @@ export default function DrawersContainer() {
|
||||
<AccountDrawer name={'account-drawer'} />
|
||||
<ManualJournalDrawer name={'journal-drawer'} />
|
||||
<ExpenseDrawer name={'expense-drawer'} />
|
||||
<BillDrawer name={'bill-drawer'} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,30 @@ export default function AllocateLandedCostEntriesTable({
|
||||
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',
|
||||
},
|
||||
{
|
||||
item_id: 'ITEM',
|
||||
quantity: '30000',
|
||||
rate: '100000',
|
||||
amount: '400',
|
||||
},
|
||||
];
|
||||
|
||||
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 withAlertsActions from 'containers/Alert/withAlertActions';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withDrawerActions from 'containers/Drawer/withDrawerActions';
|
||||
import { useBillsTableColumns, ActionsMenu } from './components';
|
||||
import { useBillsListContext } from './BillsListProvider';
|
||||
|
||||
@@ -32,6 +33,9 @@ function BillsDataTable({
|
||||
|
||||
// #withDialogActions
|
||||
openDialog,
|
||||
|
||||
// #withDrawerActions
|
||||
openDrawer,
|
||||
}) {
|
||||
// Bills list context.
|
||||
const { bills, pagination, isBillsLoading, isBillsFetching, isEmptyStatus } =
|
||||
@@ -78,6 +82,11 @@ function BillsDataTable({
|
||||
openDialog('allocate-landed-cost', { billId: id });
|
||||
};
|
||||
|
||||
// Handle view detail bill.
|
||||
const handleViewDetailBill = ({ id }) => {
|
||||
openDrawer('bill-drawer', { billId: id });
|
||||
};
|
||||
|
||||
if (isEmptyStatus) {
|
||||
return <BillsEmptyStatus />;
|
||||
}
|
||||
@@ -106,6 +115,7 @@ function BillsDataTable({
|
||||
onOpen: handleOpenBill,
|
||||
onQuick: handleQuickPaymentMade,
|
||||
onAllocateLandedCost: handleAllocateLandedCost,
|
||||
onViewDetails: handleViewDetailBill,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -115,6 +125,7 @@ export default compose(
|
||||
withBills(({ billsTableState }) => ({ billsTableState })),
|
||||
withBillActions,
|
||||
withAlertsActions,
|
||||
withDrawerActions,
|
||||
withDialogActions,
|
||||
withSettings(({ organizationSettings }) => ({
|
||||
baseCurrency: organizationSettings?.baseCurrency,
|
||||
|
||||
@@ -20,7 +20,14 @@ import moment from 'moment';
|
||||
* Actions menu.
|
||||
*/
|
||||
export function ActionsMenu({
|
||||
payload: { onEdit, onOpen, onDelete, onQuick, onAllocateLandedCost },
|
||||
payload: {
|
||||
onEdit,
|
||||
onOpen,
|
||||
onDelete,
|
||||
onQuick,
|
||||
onViewDetails,
|
||||
onAllocateLandedCost,
|
||||
},
|
||||
row: { original },
|
||||
}) {
|
||||
return (
|
||||
@@ -28,6 +35,7 @@ export function ActionsMenu({
|
||||
<MenuItem
|
||||
icon={<Icon icon="reader-18" />}
|
||||
text={intl.get('view_details')}
|
||||
onClick={safeCallback(onViewDetails, original)}
|
||||
/>
|
||||
<MenuDivider />
|
||||
<MenuItem
|
||||
|
||||
@@ -1133,5 +1133,8 @@
|
||||
"transaction_line":"Transaction line",
|
||||
"allocation_method":"Allocation method",
|
||||
"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 {
|
||||
.table {
|
||||
max-height: 300px;
|
||||
// max-height: 300px;
|
||||
border: 1px solid #d1dee2;
|
||||
min-width: auto;
|
||||
|
||||
.tbody,
|
||||
.tbody-inner {
|
||||
height: auto;
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
||||
Reference in New Issue
Block a user