);
diff --git a/client/src/components/Drawer/DrawerInsider.js b/client/src/components/Drawer/DrawerInsider.js
new file mode 100644
index 000000000..e63690a98
--- /dev/null
+++ b/client/src/components/Drawer/DrawerInsider.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import classnames from 'classnames';
+import LoadingIndicator from 'components/LoadingIndicator';
+
+/**
+ * Drawer inside.
+ */
+export function DrawerInsider({
+ loading,
+ children,
+ name,
+ mount = false,
+ className,
+}) {
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/client/src/components/Drawer/DrawerMainTabs.js b/client/src/components/Drawer/DrawerMainTabs.js
new file mode 100644
index 000000000..89ab0a52c
--- /dev/null
+++ b/client/src/components/Drawer/DrawerMainTabs.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import { Tabs } from '@blueprintjs/core';
+
+/**
+ * Drawer main tabs.
+ */
+export function DrawerMainTabs({ children, ...restProps }) {
+ return (
+
+ );
+}
diff --git a/client/src/components/DrawersContainer.js b/client/src/components/DrawersContainer.js
index 2803209e2..e56988bcb 100644
--- a/client/src/components/DrawersContainer.js
+++ b/client/src/components/DrawersContainer.js
@@ -1,7 +1,7 @@
import React from 'react';
-import EstimateDrawer from 'containers/Sales/Estimates/EstimateDetails/EstimateDrawer';
-import InvoiceDrawer from 'containers/Sales/Invoices/InvoiceDetails/InvoiceDrawer';
-import ReceiptDrawer from 'containers/Sales/Receipts/ReceiptDetails/ReceiptDrawer';
+// import EstimateDrawer from 'containers/Sales/Estimates/EstimateDetails/EstimateDrawer';
+// import InvoiceDrawer from 'containers/Sales/Invoices/InvoiceDetails/InvoiceDrawer';
+// import ReceiptDrawer from 'containers/Sales/Receipts/ReceiptDetails/ReceiptDrawer';
import PaymentReceiveDrawer from 'containers/Sales/PaymentReceives/PaymentDetails/PaymentReceiveDrawer';
import AccountDrawer from 'containers/Drawers/AccountDrawer';
import ManualJournalDrawer from 'containers/Drawers/ManualJournalDrawer';
@@ -23,9 +23,9 @@ import { DRAWERS } from 'common/drawers';
export default function DrawersContainer() {
return (
-
-
-
+ {/*
*/}
+ {/*
*/}
+ {/*
*/}
diff --git a/client/src/components/TotalLines/TotalLines.module.scss b/client/src/components/TotalLines/TotalLines.module.scss
new file mode 100644
index 000000000..5c92246b5
--- /dev/null
+++ b/client/src/components/TotalLines/TotalLines.module.scss
@@ -0,0 +1,12 @@
+.total_lines {}
+
+
+.total_line {
+ display: flex;
+ border-bottom: 1px solid #d2dde2;
+
+ :global .amount,
+ :global .title{
+ padding: 8px;
+ }
+}
\ No newline at end of file
diff --git a/client/src/components/TotalLines/index.js b/client/src/components/TotalLines/index.js
new file mode 100644
index 000000000..793f70c0d
--- /dev/null
+++ b/client/src/components/TotalLines/index.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import clsx from 'classnames';
+
+import TotalLinesCls from './TotalLines.module.scss';
+
+export function TotalLines({ children, className }) {
+ return (
+
+ {children}
+
+ );
+}
+
+export function TotalLine({ title, value, className }) {
+ return (
+
+ );
+}
diff --git a/client/src/components/Utils/Choose.js b/client/src/components/Utils/Choose.js
index fa13379bb..eb4fffc80 100644
--- a/client/src/components/Utils/Choose.js
+++ b/client/src/components/Utils/Choose.js
@@ -2,32 +2,32 @@ import React from 'react';
import PropTypes from 'prop-types';
import If from './If';
-const Choose = props => {
- let when = null;
- let otherwise = null;
+const Choose = (props) => {
+ let when = null;
+ let otherwise = null;
- React.Children.forEach(props.children, children => {
- if (children.props.condition === undefined) {
- otherwise = children;
- } else if (!when && children.props.condition === true) {
- when = children;
- }
- });
+ React.Children.forEach(props.children, (children) => {
+ if (children.props.condition === undefined) {
+ otherwise = children;
+ } else if (!when && children.props.condition === true) {
+ when = children;
+ }
+ });
- return when || otherwise;
+ return when || otherwise;
};
Choose.propTypes = {
- children: PropTypes.node
+ children: PropTypes.node,
};
Choose.When = If;
-Choose.Otherwise = ({render, children}) => render ? render() : children;
+Choose.Otherwise = ({ render, children }) => (render ? render() : children);
Choose.Otherwise.propTypes = {
children: PropTypes.node,
- render: PropTypes.func
+ render: PropTypes.func,
};
-export default Choose;
\ No newline at end of file
+export default Choose;
diff --git a/client/src/components/index.js b/client/src/components/index.js
index b55982615..064f67d02 100644
--- a/client/src/components/index.js
+++ b/client/src/components/index.js
@@ -69,6 +69,9 @@ export * from './Dashboard/DashboardRowsHeightButton';
export * from './UniversalSearch/UniversalSearch';
export * from './PdfPreview';
export * from './Details';
+export * from './Drawer/DrawerInsider';
+export * from './Drawer/DrawerMainTabs';
+export * from './TotalLines/index'
const Hint = FieldHint;
diff --git a/client/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js b/client/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js
new file mode 100644
index 000000000..e67562ccf
--- /dev/null
+++ b/client/src/containers/Drawers/BillDrawer/BillDetailActionsBar.js
@@ -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 (
+
+
+ }
+ text={}
+ onClick={safeCallback(onEditBill)}
+ />
+
+ }
+ text={}
+ intent={Intent.DANGER}
+ onClick={safeCallback(onDeleteBill)}
+ />
+
+
+ );
+}
+
+export default compose(
+ withDialogActions,
+ withDrawerActions,
+ withAlertsActions,
+)(BillDetailActionsBar);
diff --git a/client/src/containers/Drawers/BillDrawer/BillDetailFooter.js b/client/src/containers/Drawers/BillDrawer/BillDetailFooter.js
new file mode 100644
index 000000000..b4e761e2d
--- /dev/null
+++ b/client/src/containers/Drawers/BillDrawer/BillDetailFooter.js
@@ -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 (
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/BillDrawer/BillDetailHeader.js b/client/src/containers/Drawers/BillDrawer/BillDetailHeader.js
new file mode 100644
index 000000000..96af60a59
--- /dev/null
+++ b/client/src/containers/Drawers/BillDrawer/BillDetailHeader.js
@@ -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 (
+
+
+ {bill.formatted_amount}}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/BillDrawer/BillDetailTab.js b/client/src/containers/Drawers/BillDrawer/BillDetailTab.js
new file mode 100644
index 000000000..32466efd4
--- /dev/null
+++ b/client/src/containers/Drawers/BillDrawer/BillDetailTab.js
@@ -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 (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/BillDrawer/BillDetailTable.js b/client/src/containers/Drawers/BillDrawer/BillDetailTable.js
new file mode 100644
index 000000000..6ef30dd9d
--- /dev/null
+++ b/client/src/containers/Drawers/BillDrawer/BillDetailTable.js
@@ -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 (
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/BillDrawer/BillDrawerContent.js b/client/src/containers/Drawers/BillDrawer/BillDrawerContent.js
index b2f62ac72..abe8932fa 100644
--- a/client/src/containers/Drawers/BillDrawer/BillDrawerContent.js
+++ b/client/src/containers/Drawers/BillDrawer/BillDrawerContent.js
@@ -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 (
-
+
-
+ {/* */}
);
}
diff --git a/client/src/containers/Drawers/BillDrawer/BillDrawerDetails.js b/client/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
index d1ac37f33..60df54da1 100644
--- a/client/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
+++ b/client/src/containers/Drawers/BillDrawer/BillDrawerDetails.js
@@ -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 (
-
-
-
+
+
+ }
+ />
}
/>
-
+
);
}
-
-// 42 / fon-w 600
\ No newline at end of file
diff --git a/client/src/containers/Drawers/BillDrawer/BillDrawerProvider.js b/client/src/containers/Drawers/BillDrawer/BillDrawerProvider.js
index 12b11263c..b8d880fbf 100644
--- a/client/src/containers/Drawers/BillDrawer/BillDrawerProvider.js
+++ b/client/src/containers/Drawers/BillDrawer/BillDrawerProvider.js
@@ -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 (
-
+
+
-
+
);
diff --git a/client/src/containers/Drawers/BillDrawer/utils.js b/client/src/containers/Drawers/BillDrawer/utils.js
new file mode 100644
index 000000000..f59dafd10
--- /dev/null
+++ b/client/src/containers/Drawers/BillDrawer/utils.js
@@ -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
+ },
+ ],
+ [],
+);
\ No newline at end of file
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js
index eceb2f2bb..2de7affc9 100644
--- a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetail.js
@@ -1,21 +1,26 @@
import React from 'react';
-import { Tabs, Tab } from '@blueprintjs/core';
+import { Tab } from '@blueprintjs/core';
import intl from 'react-intl-universal';
-import EstimateDetailTab from './EstimateDetailTab';
+import { DrawerMainTabs } from 'components';
+
+import EstimateDetailPanel from './EstimateDetailPanel';
+import clsx from 'classnames';
+
+import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss';
/**
* Estimate view detail
*/
export default function EstimateDetail() {
return (
-
-
+
+
}
+ panel={}
/>
-
+
);
}
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTab.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js
similarity index 72%
rename from client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTab.js
rename to client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js
index 2de289201..fdf3d39cb 100644
--- a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTab.js
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailActionsBar.js
@@ -17,9 +17,12 @@ import withDrawerActions from 'containers/Drawer/withDrawerActions';
import { Icon, FormattedMessage as T } from 'components';
-import { safeCallback, compose } from 'utils';
+import { compose } from 'utils';
-function EstimateDetailTab({
+/**
+ * Estimate read-only details actions bar of the drawer.
+ */
+function EstimateDetailActionsBar({
// #withDialogActions
openDialog,
@@ -29,28 +32,24 @@ function EstimateDetailTab({
// #withDrawerActions
closeDrawer,
}) {
- const history = useHistory();
-
const { estimateId } = useEstimateDetailDrawerContext();
+ const history = useHistory();
+
// Handle edit sale estimate.
- const onEditEstimate = () => {
- return estimateId
- ? (history.push(`/estimates/${estimateId}/edit`),
- closeDrawer('estimate-detail-drawer'))
- : null;
+ const handleEditEstimate = () => {
+ history.push(`/estimates/${estimateId}/edit`);
+ closeDrawer('estimate-detail-drawer');
};
// Handle delete sale estimate.
- const onDeleteEstimate = () => {
- return estimateId
- ? (openAlert('estimate-delete', { estimateId }),
- closeDrawer('estimate-detail-drawer'))
- : null;
+ const handleDeleteEstimate = () => {
+ openAlert('estimate-delete', { estimateId });
+ closeDrawer('estimate-detail-drawer');
};
// Handle print estimate.
- const onPrintEstimate = () => {
+ const handlePrintEstimate = () => {
openDialog('estimate-pdf-preview', { estimateId });
};
@@ -61,21 +60,21 @@ function EstimateDetailTab({
className={Classes.MINIMAL}
icon={}
text={}
- onClick={safeCallback(onEditEstimate)}
+ onClick={handleEditEstimate}
/>
}
text={}
- onClick={safeCallback(onPrintEstimate)}
+ onClick={handleDeleteEstimate}
/>
}
text={}
intent={Intent.DANGER}
- onClick={safeCallback(onDeleteEstimate)}
+ onClick={handlePrintEstimate}
/>
@@ -86,4 +85,4 @@ export default compose(
withDialogActions,
withAlertsActions,
withDrawerActions,
-)(EstimateDetailTab);
+)(EstimateDetailActionsBar);
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js
index 6a08ede8b..8b3ecf215 100644
--- a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerContent.js
@@ -1,7 +1,5 @@
import React from 'react';
-import 'style/components/Drawers/ViewDetail/ViewDetail.scss';
-
import EstimateDetail from './EstimateDetail';
import { EstimateDetailDrawerProvider } from './EstimateDetailDrawerProvider';
@@ -10,10 +8,10 @@ import { EstimateDetailDrawerProvider } from './EstimateDetailDrawerProvider';
*/
export default function EstimateDetailDrawerContent({
// #ownProp
- estimate,
+ estimateId,
}) {
return (
-
+
);
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js
index f5caf34c2..646ba0fc3 100644
--- a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailDrawerProvider.js
@@ -1,6 +1,7 @@
import React from 'react';
import intl from 'react-intl-universal';
-import { DrawerHeaderContent, DashboardInsider } from 'components';
+import { useEstimate } from 'hooks/query';
+import { DrawerHeaderContent, DrawerInsider } from 'components';
const EstimateDetailDrawerContext = React.createContext();
@@ -8,19 +9,25 @@ const EstimateDetailDrawerContext = React.createContext();
* Estimate detail provider.
*/
function EstimateDetailDrawerProvider({ estimateId, ...props }) {
+ // Fetches the estimate by the given id.
+ const { data: estimate, isLoading: isEstimateLoading } = useEstimate(
+ estimateId,
+ { enabled: !!estimateId },
+ );
+
const provider = {
estimateId,
+ estimate,
};
return (
-
+
-
-
+
);
}
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailFooter.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailFooter.js
new file mode 100644
index 000000000..fae47b75e
--- /dev/null
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailFooter.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import clsx from 'classnames';
+
+import { TotalLines, TotalLine, If } from 'components';
+
+import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss';
+
+/**
+ * Estimate details panel footer content.
+ */
+export default function EstimateDetailFooter() {
+ return (
+
+ );
+}
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailHeader.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailHeader.js
new file mode 100644
index 000000000..7ec6709ae
--- /dev/null
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailHeader.js
@@ -0,0 +1,50 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+import { defaultTo } from 'lodash';
+import clsx from 'classnames';
+
+import { DetailsMenu, DetailItem } from 'components';
+import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider';
+
+import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss';
+
+/**
+ * Estimate read-only details drawer header.
+ */
+export default function EstimateDetailHeader() {
+ const { estimate } = useEstimateDetailDrawerContext();
+
+ return (
+
+
+
+ {estimate.formatted_amount}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailPanel.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailPanel.js
new file mode 100644
index 000000000..cb2c22ff1
--- /dev/null
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailPanel.js
@@ -0,0 +1,25 @@
+import React from 'react';
+import clsx from 'classnames';
+
+import { Card } from 'components';
+
+import EstimateDetailActionsBar from './EstimateDetailActionsBar';
+import EstimateDetailHeader from './EstimateDetailHeader';
+import EstimateDetailTable from './EstimateDetailTable';
+
+import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss';
+import EstimateDetailFooter from './EstimateDetailFooter';
+
+export default function EstimateDetailTab() {
+ return (
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTable.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTable.js
new file mode 100644
index 000000000..af5f6b6ba
--- /dev/null
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDetailTable.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import clsx from 'classnames';
+
+import { DataTable } from 'components';
+import { useEstimateDetailDrawerContext } from './EstimateDetailDrawerProvider';
+
+import { useEstimateReadonlyEntriesColumns } from './utils';
+
+import EstimateDetailsCls from 'style/components/Drawers/EstimateDetails.module.scss';
+
+/**
+ * Estimate detail table.
+ */
+export default function EstimateDetailTable() {
+ const {
+ estimate: { entries },
+ } = useEstimateDetailDrawerContext();
+
+ // Estimate entries table columns.
+ const columns = useEstimateReadonlyEntriesColumns();
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDrawerClasses.js b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDrawerClasses.js
new file mode 100644
index 000000000..bed0d9e1d
--- /dev/null
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/EstimateDrawerClasses.js
@@ -0,0 +1,32 @@
+const globalStateClassesMapping = {
+ active: 'active',
+ checked: 'checked',
+ completed: 'completed',
+ disabled: 'disabled',
+ error: 'error',
+ expanded: 'expanded',
+ focused: 'focused',
+ focusVisible: 'focusVisible',
+ required: 'required',
+ selected: 'selected',
+};
+
+function generateUtilityClass(componentName, slot) {
+ const globalStateClass = globalStateClassesMapping[slot];
+ return globalStateClass || `${componentName}__${slot}`;
+}
+
+function generateUtilityClasses(componentName, modifiers) {
+ const result = {
+ root: componentName,
+ };
+ modifiers.forEach((modifier) => {
+ result[modifier] = generateUtilityClass(componentName, modifier);
+ });
+
+ return result;
+}
+
+export const EstimateDrawerCls = generateUtilityClasses('estimate-drawer', [
+ 'content',
+]);
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/index.js b/client/src/containers/Drawers/EstimateDetailDrawer/index.js
index f7aee682d..b6201710d 100644
--- a/client/src/containers/Drawers/EstimateDetailDrawer/index.js
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/index.js
@@ -15,9 +15,14 @@ function EstimateDetailDrawer({
payload: { estimateId },
}) {
return (
-
+
-
+
);
diff --git a/client/src/containers/Drawers/EstimateDetailDrawer/utils.js b/client/src/containers/Drawers/EstimateDetailDrawer/utils.js
new file mode 100644
index 000000000..49722bc1e
--- /dev/null
+++ b/client/src/containers/Drawers/EstimateDetailDrawer/utils.js
@@ -0,0 +1,43 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+
+/**
+ * Retrieve table columns of estimate readonly entries details.
+ */
+export const useEstimateReadonlyEntriesColumns = () =>
+ React.useMemo(() => [
+ {
+ Header: intl.get('product_and_service'),
+ accessor: 'item.name',
+ width: 150,
+ className: 'name',
+ 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,
+ },
+ ], []);
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
index abd18f28c..e80b8b9bf 100644
--- a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetail.js
@@ -1,36 +1,36 @@
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 JournalEntriesTable from '../../JournalEntriesTable/JournalEntriesTable';
import InvoiceDetailTab from './InvoiceDetailTab';
import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+import InvoiceDrawerCls from 'style/components/Drawers/InvoiceDrawer.module.scss';
+
/**
* Invoice view detail.
*/
export default function InvoiceDetail() {
- const { transactions, invoiceId } = useInvoiceDetailDrawerContext();
+ const { transactions } = useInvoiceDetailDrawerContext();
return (
-
-
+
+
}
+ panel={}
/>
}
/>
-
+
);
}
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
new file mode 100644
index 000000000..558db7592
--- /dev/null
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailActionsBar.js
@@ -0,0 +1,90 @@
+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 { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+
+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 { compose } from 'utils';
+
+/**
+ * Invoice details action bar.
+ */
+function InvoiceDetailActionsBar({
+ // #withDialogActions
+ openDialog,
+
+ // #withAlertsActions
+ openAlert,
+
+ // #withDrawerActions
+ closeDrawer,
+}) {
+ const history = useHistory();
+
+ // Invoice detail drawer context.
+ const { invoiceId } = useInvoiceDetailDrawerContext();
+
+ // Handle edit sale invoice.
+ const handleEditInvoice = () => {
+ history.push(`/invoices/${invoiceId}/edit`);
+ closeDrawer('invoice-detail-drawer');
+ };
+
+ // Handle delete sale invoice.
+ const handleDeleteInvoice = () => {
+ openAlert('invoice-delete', { invoiceId });
+ closeDrawer('invoice-detail-drawer');
+ };
+
+ // Handle print invoices.
+ const handlePrintInvoice = () => {
+ openDialog('invoice-pdf-preview', { invoiceId });
+ };
+
+ return (
+
+
+ }
+ text={}
+ onClick={handleEditInvoice}
+ />
+
+ }
+ text={}
+ onClick={handlePrintInvoice}
+ />
+ }
+ text={}
+ intent={Intent.DANGER}
+ onClick={handleDeleteInvoice}
+ />
+
+
+ );
+}
+
+export default compose(
+ withDialogActions,
+ withDrawerActions,
+ withAlertsActions,
+)(InvoiceDetailActionsBar);
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerContent.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerContent.js
index 509f66dcb..9d2ff7991 100644
--- a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerContent.js
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerContent.js
@@ -10,10 +10,10 @@ import { InvoiceDetailDrawerProvider } from './InvoiceDetailDrawerProvider';
*/
export default function InvoiceDetailDrawerContent({
// #ownProp
- invoice,
+ invoiceId,
}) {
return (
-
+
);
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerProvider.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerProvider.js
index ac05e44dd..d19a5906e 100644
--- a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerProvider.js
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailDrawerProvider.js
@@ -1,7 +1,7 @@
import React from 'react';
import intl from 'react-intl-universal';
import { DrawerHeaderContent, DashboardInsider } from 'components';
-import { useTransactionsByReference } from 'hooks/query';
+import { useTransactionsByReference, useInvoice } from 'hooks/query';
const InvoiceDetailDrawerContext = React.createContext();
/**
@@ -20,13 +20,19 @@ function InvoiceDetailDrawerProvider({ invoiceId, ...props }) {
{ enabled: !!invoiceId },
);
+ // Fetch sale invoice details.
+ const { data: invoice, isLoading: isInvoiceLoading } = useInvoice(invoiceId, {
+ enabled: !!invoiceId,
+ });
+
//provider.
const provider = {
transactions,
invoiceId,
+ invoice,
};
return (
-
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailHeader.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailHeader.js
new file mode 100644
index 000000000..43ca39e3b
--- /dev/null
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailHeader.js
@@ -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 { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+
+import InvoiceDrawerCls from 'style/components/Drawers/InvoiceDrawer.module.scss';
+
+/**
+ * Invoice detail header.
+ */
+export default function InvoiceDetailHeader() {
+ const { invoice } = useInvoiceDetailDrawerContext();
+
+ return (
+
+
+
+ {invoice.formatted_amount}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTab.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTab.js
index 8dbaf7cec..5741f7674 100644
--- a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTab.js
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTab.js
@@ -1,89 +1,28 @@
import React from 'react';
-import { useHistory } from 'react-router-dom';
+import clsx from 'classnames';
-import {
- Button,
- NavbarGroup,
- Classes,
- NavbarDivider,
- Intent,
-} from '@blueprintjs/core';
-import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
+import { Card } from 'components';
-import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+import InvoiceDetailActionsBar from './InvoiceDetailActionsBar';
+import InvoiceDetailHeader from './InvoiceDetailHeader';
+import InvoiceDetailTable from './InvoiceDetailTable';
+import { InvoiceDetailFooter } from './InvoiceDetailFooter';
-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 InvoiceDetailTab({
- invoiceId,
- // #withDialogActions
- openDialog,
-
- // #withAlertsActions
- openAlert,
-
- // #withDrawerActions
- closeDrawer,
-}) {
- const history = useHistory();
-
- // Handle edit sale invoice.
- const onEditInvoice = () => {
- return invoiceId
- ? (history.push(`/invoices/${invoiceId}/edit`),
- closeDrawer('invoice-detail-drawer'))
- : null;
- };
-
- // Handle delete sale invoice.
- const onDeleteInvoice = () => {
- return invoiceId
- ? (openAlert('invoice-delete', { invoiceId }),
- closeDrawer('invoice-detail-drawer'))
- : null;
- };
-
- // Handle print invoices.
- const onPrintInvoice = () => {
- openDialog('invoice-pdf-preview', { invoiceId });
- };
+import InvoiceDrawerCls from 'style/components/Drawers/InvoiceDrawer.module.scss';
+/**
+ * Invoice readonly details tab panel.
+ */
+export default function InvoiceDetailTab() {
return (
-
-
- }
- text={}
- onClick={safeCallback(onEditInvoice)}
- />
-
- }
- text={}
- onClick={safeCallback(onPrintInvoice)}
- />
- }
- text={}
- intent={Intent.DANGER}
- onClick={safeCallback(onDeleteInvoice)}
- />
-
-
- );
-}
+
+
-export default compose(
- withDialogActions,
- withDrawerActions,
- withAlertsActions,
-)(InvoiceDetailTab);
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTable.js b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTable.js
new file mode 100644
index 000000000..95fa6d8a9
--- /dev/null
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/InvoiceDetailTable.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import clsx from 'classnames';
+
+import { DataTable } from 'components';
+
+import { useInvoiceReadonlyEntriesColumns } from './utils';
+import { useInvoiceDetailDrawerContext } from './InvoiceDetailDrawerProvider';
+
+import InvoiceDrawerCls from 'style/components/Drawers/InvoiceDrawer.module.scss';
+
+/**
+ * Invoice readonly details entries table columns.
+ */
+export default function InvoiceDetailTable() {
+ const columns = useInvoiceReadonlyEntriesColumns();
+
+ const {
+ invoice: { entries },
+ } = useInvoiceDetailDrawerContext();
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/index.js b/client/src/containers/Drawers/InvoiceDetailDrawer/index.js
index 35f1609ec..97c85d71e 100644
--- a/client/src/containers/Drawers/InvoiceDetailDrawer/index.js
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/index.js
@@ -18,9 +18,14 @@ function InvoiceDetailDrawer({
payload: { invoiceId },
}) {
return (
-
+
-
+
);
diff --git a/client/src/containers/Drawers/InvoiceDetailDrawer/utils.js b/client/src/containers/Drawers/InvoiceDetailDrawer/utils.js
new file mode 100644
index 000000000..b594ca38e
--- /dev/null
+++ b/client/src/containers/Drawers/InvoiceDetailDrawer/utils.js
@@ -0,0 +1,43 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+
+export const useInvoiceReadonlyEntriesColumns = () =>
+ React.useMemo(
+ () => [
+ {
+ Header: intl.get('product_and_service'),
+ accessor: 'item.name',
+ width: 150,
+ className: 'name',
+ 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,
+ },
+ ],
+ [],
+ );
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetail.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetail.js
index 0816976d2..2f7dfa695 100644
--- a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetail.js
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetail.js
@@ -1,31 +1,35 @@
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 JournalEntriesTable from '../../JournalEntriesTable/JournalEntriesTable';
import ReceiptDetailTab from './ReceiptDetailTab';
import { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider';
+import ReceiptDrawerCls from 'style/components/Drawers/ReceiptDrawer.module.scss';
+
/**
* Receipt view detail.
*/
export default function ReceiptDetail() {
- const { transactions, receiptId } = useReceiptDetailDrawerContext();
+ const { transactions } = useReceiptDetailDrawerContext();
return (
-
-
+
+
}
+ panel={}
/>
}
/>
-
+
);
}
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailActionBar.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailActionBar.js
new file mode 100644
index 000000000..eb2eae415
--- /dev/null
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailActionBar.js
@@ -0,0 +1,86 @@
+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 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 { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider';
+
+import { safeCallback, compose } from 'utils';
+
+function ReceiptDetailActionBar({
+ // #withDialogActions
+ openDialog,
+
+ // #withAlertsActions
+ openAlert,
+
+ // #withDrawerActions
+ closeDrawer,
+}) {
+ const history = useHistory();
+ const { receiptId } = useReceiptDetailDrawerContext();
+
+ // Handle edit sale receipt.
+ const onEditReceipt = () => {
+ return receiptId
+ ? (history.push(`/receipts/${receiptId}/edit`),
+ closeDrawer('receipt-detail-drawer'))
+ : null;
+ };
+
+ // Handle delete sale receipt.
+ const onDeleteReceipt = () => {
+ return receiptId
+ ? (openAlert('receipt-delete', { receiptId }),
+ closeDrawer('receipt-detail-drawer'))
+ : null;
+ };
+ // Handle print receipt.
+ const onPrintReceipt = () => {
+ openDialog('receipt-pdf-preview', { receiptId });
+ };
+ return (
+
+
+ }
+ text={}
+ onClick={safeCallback(onEditReceipt)}
+ />
+
+ }
+ text={}
+ onClick={safeCallback(onPrintReceipt)}
+ />
+ }
+ text={}
+ intent={Intent.DANGER}
+ onClick={safeCallback(onDeleteReceipt)}
+ />
+
+
+ );
+}
+
+export default compose(
+ withDialogActions,
+ withDrawerActions,
+ withAlertsActions,
+)(ReceiptDetailActionBar);
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerContent.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerContent.js
index cae135981..c01872156 100644
--- a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerContent.js
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerContent.js
@@ -10,10 +10,10 @@ import { ReceiptDetailDrawerProvider } from './ReceiptDetailDrawerProvider';
*/
export default function ReceiptDetailDrawerContent({
// #ownProp
- receipt,
+ receiptId,
}) {
return (
-
+
);
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerProvider.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerProvider.js
index 46f05ed01..57dfd8d43 100644
--- a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerProvider.js
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailDrawerProvider.js
@@ -1,7 +1,7 @@
import React from 'react';
import intl from 'react-intl-universal';
import { DrawerHeaderContent, DashboardInsider } from 'components';
-import { useTransactionsByReference } from 'hooks/query';
+import { useTransactionsByReference, useReceipt } from 'hooks/query';
// useTransactionsByReference
const ReceiptDetailDrawerContext = React.createContext();
@@ -10,6 +10,14 @@ const ReceiptDetailDrawerContext = React.createContext();
* Receipt detail provider.
*/
function ReceiptDetailDrawerProvider({ receiptId, ...props }) {
+ // Fetch sale receipt details.
+ const { data: receipt, isFetching: isReceiptLoading } = useReceipt(
+ receiptId,
+ {
+ enabled: !!receiptId,
+ },
+ );
+
// Handle fetch transaction by reference.
const {
data: { transactions },
@@ -26,10 +34,11 @@ function ReceiptDetailDrawerProvider({ receiptId, ...props }) {
const provider = {
transactions,
receiptId,
+ receipt,
};
return (
-
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailHeader.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailHeader.js
new file mode 100644
index 000000000..2d3ab8fda
--- /dev/null
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailHeader.js
@@ -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 { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider';
+
+import ReceiptDrawerCls from 'style/components/Drawers/ReceiptDrawer.module.scss';
+
+/**
+ * receipt detail content.
+ */
+export default function ReceiptDetailHeader() {
+ const { receipt } = useReceiptDetailDrawerContext();
+
+ return (
+
+
+
+ {receipt.formatted_amount}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTab.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTab.js
index 07e4b690a..34ef3e24f 100644
--- a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTab.js
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTab.js
@@ -1,85 +1,25 @@
import React from 'react';
-import { useHistory } from 'react-router-dom';
+import clsx from 'classnames';
-import {
- Button,
- NavbarGroup,
- Classes,
- NavbarDivider,
- Intent,
-} from '@blueprintjs/core';
-import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
+import { Card } from 'components';
-import withDialogActions from 'containers/Dialog/withDialogActions';
-import withAlertsActions from 'containers/Alert/withAlertActions';
-import withDrawerActions from 'containers/Drawer/withDrawerActions';
+import ReceiptDetailActionBar from './ReceiptDetailActionBar';
+import ReceiptDetailHeader from './ReceiptDetailHeader';
+import ReceiptDetailTable from './ReceiptDetailTable';
+import { ReceiptDetailFooter } from './ReceiptDetailFooter';
-import { Icon, FormattedMessage as T } from 'components';
+import ReceiptDrawerCls from 'style/components/Drawers/ReceiptDrawer.module.scss';
-import { safeCallback, compose } from 'utils';
-
-function ReceiptDetailTab({
- receiptId,
- // #withDialogActions
- openDialog,
-
- // #withAlertsActions
- openAlert,
-
- // #withDrawerActions
- closeDrawer,
-}) {
- const history = useHistory();
-
- // Handle edit sale receipt.
- const onEditReceipt = () => {
- return receiptId
- ? (history.push(`/receipts/${receiptId}/edit`),
- closeDrawer('receipt-detail-drawer'))
- : null;
- };
-
- // Handle delete sale receipt.
- const onDeleteReceipt = () => {
- return receiptId
- ? (openAlert('receipt-delete', { receiptId }),
- closeDrawer('receipt-detail-drawer'))
- : null;
- };
- // Handle print receipt.
- const onPrintReceipt = () => {
- openDialog('receipt-pdf-preview', { receiptId });
- };
+export default function ReceiptDetailTab() {
return (
-
-
- }
- text={}
- onClick={safeCallback(onEditReceipt)}
- />
-
- }
- text={}
- onClick={safeCallback(onPrintReceipt)}
- />
- }
- text={}
- intent={Intent.DANGER}
- onClick={safeCallback(onDeleteReceipt)}
- />
-
-
+
+
+
+
+
+
+
+
+
);
}
-
-export default compose(
- withDialogActions,
- withDrawerActions,
- withAlertsActions,
-)(ReceiptDetailTab);
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTable.js b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTable.js
new file mode 100644
index 000000000..21155a0c0
--- /dev/null
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/ReceiptDetailTable.js
@@ -0,0 +1,31 @@
+import React from 'react';
+import clsx from 'classnames';
+
+import { DataTable } from 'components';
+
+import { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider';
+import { useReceiptReadonlyEntriesTableColumns } from './utils';
+
+import ReceiptDrawerCls from 'style/components/Drawers/ReceiptDrawer.module.scss';
+
+/**
+ * Receipt readonly details table columns.
+ */
+export default function ReceiptDetailTable() {
+ const {
+ receipt: { entries },
+ } = useReceiptDetailDrawerContext();
+
+ // Receipt readonly entries table columns.
+ const columns = useReceiptReadonlyEntriesTableColumns();
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/index.js b/client/src/containers/Drawers/ReceiptDetailDrawer/index.js
index 3f982ee13..0a3da63d0 100644
--- a/client/src/containers/Drawers/ReceiptDetailDrawer/index.js
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/index.js
@@ -18,9 +18,14 @@ function ReceiptDetailDrawer({
payload: { receiptId },
}) {
return (
-
+
-
+
);
diff --git a/client/src/containers/Drawers/ReceiptDetailDrawer/utils.js b/client/src/containers/Drawers/ReceiptDetailDrawer/utils.js
new file mode 100644
index 000000000..5a37bc1bb
--- /dev/null
+++ b/client/src/containers/Drawers/ReceiptDetailDrawer/utils.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import intl from 'react-intl-universal';
+
+export const useReceiptReadonlyEntriesTableColumns = () => React.useMemo(() => [
+ {
+ Header: intl.get('product_and_service'),
+ accessor: 'item.name',
+ width: 150,
+ className: 'name',
+ 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
+ },
+ ], []);
+
\ No newline at end of file
diff --git a/client/src/containers/Purchases/Bills/BillUniversalSearch.js b/client/src/containers/Purchases/Bills/BillUniversalSearch.js
index 314590ec3..5d80bd6d0 100644
--- a/client/src/containers/Purchases/Bills/BillUniversalSearch.js
+++ b/client/src/containers/Purchases/Bills/BillUniversalSearch.js
@@ -15,12 +15,14 @@ function BillUniversalSearchSelectComponent({
// #ownProps
resourceType,
resourceId,
+ onAction,
// #withDrawerActions
openDrawer,
}) {
- if (resourceType === RESOURCES_TYPES.INVOICE) {
+ if (resourceType === RESOURCES_TYPES.BILL) {
openDrawer('bill-drawer', { billId: resourceId });
+ onAction && onAction();
}
return null;
}
@@ -103,6 +105,7 @@ export function BillUniversalSearchItem(
}
const billsToSearch = (bill) => ({
+ id: bill.id,
text: bill.vendor.display_name,
reference: bill,
});
diff --git a/client/src/containers/Sales/Estimates/EstimatesLanding/EstimateUniversalSearch.js b/client/src/containers/Sales/Estimates/EstimatesLanding/EstimateUniversalSearch.js
index 3e1c7f701..3d979a4c4 100644
--- a/client/src/containers/Sales/Estimates/EstimatesLanding/EstimateUniversalSearch.js
+++ b/client/src/containers/Sales/Estimates/EstimatesLanding/EstimateUniversalSearch.js
@@ -4,7 +4,7 @@ import intl from 'react-intl-universal';
import { Choose, T, Icon } from 'components';
-import { RESOURCES_TYPES } from "../../../../common/resourcesTypes";
+import { RESOURCES_TYPES } from "common/resourcesTypes";
import withDrawerActions from "../../../Drawer/withDrawerActions";
/**
@@ -19,7 +19,7 @@ function EstimateUniversalSearchSelectComponent({
openDrawer,
}) {
if (resourceType === RESOURCES_TYPES.ESTIMATE) {
- openDrawer('estimate-drawer', { estimateId: resourceId });
+ openDrawer('estimate-detail-drawer', { estimateId: resourceId });
}
return null;
}
@@ -69,6 +69,7 @@ export function EstimateUniversalSearchItem(
) {
return (