mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +00:00
feat: wip invoice customizer
This commit is contained in:
@@ -25,6 +25,7 @@ import CategorizeTransactionDrawer from '@/containers/CashFlow/CategorizeTransac
|
||||
import ChangeSubscriptionPlanDrawer from '@/containers/Subscriptions/drawers/ChangeSubscriptionPlanDrawer/ChangeSubscriptionPlanDrawer';
|
||||
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
import { InvoiceCustomizeDrawer } from '@/containers/Sales/Invoices/InvoiceCustomize/InvoiceCustomizeDrawer';
|
||||
|
||||
/**
|
||||
* Drawers container of the dashboard.
|
||||
@@ -65,6 +66,7 @@ export default function DrawersContainer() {
|
||||
<TaxRateDetailsDrawer name={DRAWERS.TAX_RATE_DETAILS} />
|
||||
<CategorizeTransactionDrawer name={DRAWERS.CATEGORIZE_TRANSACTION} />
|
||||
<ChangeSubscriptionPlanDrawer name={DRAWERS.CHANGE_SUBSCARIPTION_PLAN} />
|
||||
<InvoiceCustomizeDrawer name={DRAWERS.INVOICE_CUSTOMIZE} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,5 +24,9 @@ export enum DRAWERS {
|
||||
WAREHOUSE_TRANSFER_DETAILS = 'warehouse-transfer-detail-drawer',
|
||||
TAX_RATE_DETAILS = 'tax-rate-detail-drawer',
|
||||
CATEGORIZE_TRANSACTION = 'categorize-transaction',
|
||||
CHANGE_SUBSCARIPTION_PLAN = 'change-subscription-plan'
|
||||
CHANGE_SUBSCARIPTION_PLAN = 'change-subscription-plan',
|
||||
INVOICE_CUSTOMIZE = 'INVOICE_CUSTOMIZE',
|
||||
ESTIMATE_CUSTOMIZE = 'ESTIMATE_CUSTOMIZE',
|
||||
PAYMENT_RECEIPT_CUSTOMIZE = 'PAYMENT_RECEIPT_CUSTOMIZE',
|
||||
RECEIPT_CUSTOMIZE = 'RECEIPT_CUSTOMIZE',
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
.field{
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.colorPicker{
|
||||
background-color: rgb(103, 114, 229);
|
||||
border-radius: 3px;
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
InputGroup,
|
||||
Popover,
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import { useState } from 'react';
|
||||
import { HexColorPicker } from 'react-colorful';
|
||||
import styles from './ColorField.module.scss';
|
||||
|
||||
export function ColorField() {
|
||||
const [color, setColor] = useState('#aabbcc');
|
||||
|
||||
return (
|
||||
<Popover
|
||||
content={<HexColorPicker color={color} onChange={setColor} />}
|
||||
position={Position.BOTTOM}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
modifiers={{
|
||||
offset: { offset: '0, 4' },
|
||||
}}
|
||||
minimal
|
||||
>
|
||||
<InputGroup
|
||||
leftElement={<div className={styles.colorPicker}></div>}
|
||||
className={styles.field}
|
||||
/>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ColorField } from './ColorField';
|
||||
|
||||
interface FColorFieldProps {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export function FColorField({ name }: FColorFieldProps) {
|
||||
return <ColorField />;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Box, Group } from '@/components';
|
||||
import { InvoiceCustomizePreview } from './InvoiceCustomizePreview';
|
||||
import { InvoiceCustomizeFields } from './InvoiceCustomizeFields';
|
||||
import { InvoiceCustomizeForm } from './InvoiceCustomizerForm';
|
||||
import { Classes } from '@blueprintjs/core';
|
||||
import { InvoiceCustomizeTabsControllerProvider } from './InvoiceCustomizeTabsController';
|
||||
|
||||
export default function InvoiceCustomizeContent() {
|
||||
return (
|
||||
<Box className={Classes.DRAWER_BODY}>
|
||||
<InvoiceCustomizeForm>
|
||||
<Group spacing={0} align="flex-start">
|
||||
<InvoiceCustomizeTabsControllerProvider>
|
||||
<InvoiceCustomizeFields />
|
||||
<InvoiceCustomizePreview />
|
||||
</InvoiceCustomizeTabsControllerProvider>
|
||||
</Group>
|
||||
</InvoiceCustomizeForm>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import * as R from 'ramda';
|
||||
|
||||
import { Drawer, DrawerSuspense } from '@/components';
|
||||
import withDrawers from '@/containers/Drawer/withDrawers';
|
||||
|
||||
const InvoiceCustomizeContent = React.lazy(
|
||||
() => import('./InvoiceCustomizeContent'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Refund credit note detail.
|
||||
* @returns
|
||||
*/
|
||||
function InvoiceCustomizeDrawerRoot({
|
||||
name,
|
||||
// #withDrawer
|
||||
isOpen,
|
||||
payload: {},
|
||||
}) {
|
||||
return (
|
||||
<Drawer
|
||||
isOpen={isOpen}
|
||||
name={name}
|
||||
size={'100%'}
|
||||
>
|
||||
<DrawerSuspense>
|
||||
<InvoiceCustomizeContent />
|
||||
</DrawerSuspense>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
|
||||
export const InvoiceCustomizeDrawer = R.compose(withDrawers())(
|
||||
InvoiceCustomizeDrawerRoot,
|
||||
);
|
||||
@@ -0,0 +1,7 @@
|
||||
.root {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mainFields{
|
||||
flex: 1;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Box, Group } from '@/components';
|
||||
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader';
|
||||
import { InvoiceCustomizeTabs } from './InvoiceCustomizeTabs';
|
||||
import styles from './InvoiceCustomizeFields.module.scss';
|
||||
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
|
||||
import { useInvoiceCustomizeTabsController } from './InvoiceCustomizeTabsController';
|
||||
|
||||
export function InvoiceCustomizeFields() {
|
||||
return (
|
||||
<Group spacing={0} align={'stretch'} className={styles.root}>
|
||||
<InvoiceCustomizeTabs />
|
||||
<InvoiceCustomizeFieldsMain />
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
export function InvoiceCustomizeFieldsMain() {
|
||||
const { currentTabId } = useInvoiceCustomizeTabsController();
|
||||
return (
|
||||
<Box className={styles.mainFields}>
|
||||
<InvoiceCustomizeHeader label={'Customize'} />
|
||||
|
||||
{currentTabId === 'general' && <InvoiceCustomizeGeneralField />}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Box, FFormGroup } from '@/components';
|
||||
import { FColorField } from './FColorField';
|
||||
|
||||
export function InvoiceCustomizeGeneralField() {
|
||||
return (
|
||||
<Box>
|
||||
<FFormGroup name={'primaryColor'} label={'Primary Color'} inline>
|
||||
<FColorField name={'primaryColor'} />
|
||||
</FFormGroup>
|
||||
|
||||
<FFormGroup name={'secondaryColor'} label={'Secondary Color'} inline>
|
||||
<FColorField name={'secondaryColor'} />
|
||||
</FFormGroup>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
.root {
|
||||
align-items: center;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 1px 0 rgba(17, 20, 24, .15);
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
min-height: 40px;
|
||||
padding: 5px 5px 5px 20px;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.title{
|
||||
margin: 0;
|
||||
font-size: 19px;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Group, Icon } from '@/components';
|
||||
import styles from './InvoiceCustomizeHeader.module.scss';
|
||||
import { Button, Classes } from '@blueprintjs/core';
|
||||
|
||||
interface InvoiceCustomizeHeaderProps {
|
||||
label?: string;
|
||||
children?: React.ReactNode;
|
||||
closeButton?: boolean;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
export function InvoiceCustomizeHeader({
|
||||
label,
|
||||
closeButton,
|
||||
onClose,
|
||||
children,
|
||||
}: InvoiceCustomizeHeaderProps) {
|
||||
const handleClose = () => {
|
||||
onClose && onClose();
|
||||
};
|
||||
return (
|
||||
<Group className={styles.root}>
|
||||
{label && <h1 className={styles.title}>{label}</h1>}
|
||||
{closeButton && (
|
||||
<Button
|
||||
aria-label="Close"
|
||||
className={Classes.DIALOG_CLOSE_BUTTON}
|
||||
icon={<Icon icon={'smallCross'} color={'#000'} />}
|
||||
minimal={true}
|
||||
onClick={handleClose}
|
||||
style={{ marginLeft: 'auto' }}
|
||||
/>
|
||||
)}
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Stack } from '@/components';
|
||||
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader';
|
||||
import { InvoiceCustomizePreviewContent } from './InvoiceCustomizePreviewContent';
|
||||
|
||||
export function InvoiceCustomizePreview() {
|
||||
return (
|
||||
<Stack spacing={0} style={{ borderLeft: '1px solid #D9D9D9' }}>
|
||||
<InvoiceCustomizeHeader label={'Preview'} closeButton />
|
||||
<InvoiceCustomizePreviewContent />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { Box } from '@/components';
|
||||
import { PaperTemplate } from './PaperTemplate';
|
||||
|
||||
export function InvoiceCustomizePreviewContent() {
|
||||
return (
|
||||
<Box style={{ padding: 20, backgroundColor: '#F5F5F5' }}>
|
||||
<PaperTemplate />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
.root {
|
||||
flex: 1;
|
||||
min-width: 165px;
|
||||
max-width: 185px;
|
||||
}
|
||||
|
||||
.content{
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.tabsList{
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Box } from '@/components';
|
||||
import { Tab, Tabs } from '@blueprintjs/core';
|
||||
import { InvoiceCustomizeHeader } from './InvoiceCustomizeHeader';
|
||||
import styles from './InvoiceCustomizeTabs.module.scss';
|
||||
import {
|
||||
InvoiceCustomizeTabsEnum,
|
||||
useInvoiceCustomizeTabsController,
|
||||
} from './InvoiceCustomizeTabsController';
|
||||
|
||||
export function InvoiceCustomizeTabs() {
|
||||
const { setCurrentTabId } = useInvoiceCustomizeTabsController();
|
||||
|
||||
const handleChange = (value: InvoiceCustomizeTabsEnum) => {
|
||||
setCurrentTabId(value);
|
||||
};
|
||||
return (
|
||||
<Box className={styles.root}>
|
||||
<InvoiceCustomizeHeader label={''} />
|
||||
|
||||
<Box className={styles.content}>
|
||||
<Tabs vertical fill onChange={handleChange} className={styles.tabsList}>
|
||||
<Tab id="general" title="General" />
|
||||
<Tab id="content" title="Content" />
|
||||
<Tab id="total" title="Total" />
|
||||
</Tabs>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
|
||||
export enum InvoiceCustomizeTabsEnum {
|
||||
General = 'general',
|
||||
Items = 'items',
|
||||
Totals = 'totals'
|
||||
}
|
||||
|
||||
const DEFAULT_TAB_ID = InvoiceCustomizeTabsEnum.General;
|
||||
|
||||
interface InvoiceCustomizeTabsControllerValue {
|
||||
currentTabId: InvoiceCustomizeTabsEnum;
|
||||
setCurrentTabId: React.Dispatch<
|
||||
React.SetStateAction<InvoiceCustomizeTabsEnum>
|
||||
>;
|
||||
}
|
||||
|
||||
const InvoiceCustomizeTabsController = createContext(
|
||||
{} as InvoiceCustomizeTabsControllerValue,
|
||||
);
|
||||
|
||||
export const useInvoiceCustomizeTabsController = () => {
|
||||
return useContext(InvoiceCustomizeTabsController);
|
||||
};
|
||||
|
||||
interface InvoiceCustomizeTabsControllerProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const InvoiceCustomizeTabsControllerProvider = ({
|
||||
children,
|
||||
}: InvoiceCustomizeTabsControllerProps) => {
|
||||
const [currentTabId, setCurrentTabId] =
|
||||
useState<InvoiceCustomizeTabsEnum>(DEFAULT_TAB_ID);
|
||||
|
||||
const value = {
|
||||
currentTabId,
|
||||
setCurrentTabId,
|
||||
};
|
||||
|
||||
return (
|
||||
<InvoiceCustomizeTabsController.Provider value={value}>
|
||||
{children}
|
||||
</InvoiceCustomizeTabsController.Provider>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Formik, Form } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import React from 'react';
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
invoiceNumber: Yup.string().required('Invoice number is required'),
|
||||
customerName: Yup.string().required('Customer name is required'),
|
||||
amount: Yup.number()
|
||||
.required('Amount is required')
|
||||
.positive('Amount must be positive'),
|
||||
});
|
||||
|
||||
interface InvoiceCustomizeFormProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function InvoiceCustomizeForm({ children }: InvoiceCustomizeFormProps) {
|
||||
return (
|
||||
<Formik
|
||||
initialValues={{ invoiceNumber: '', customerName: '', amount: '' }}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={(values) => {}}
|
||||
>
|
||||
<Form>{children}</Form>
|
||||
</Formik>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
.root {
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
box-shadow: inset 0 4px 0px 0 #002762, 0 10px 15px rgba(0, 0, 0, 0.15);
|
||||
padding: 22px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bigTitle{
|
||||
font-size: 60px;
|
||||
margin: 0;
|
||||
LINE-HEIGHT: 1;
|
||||
MARGIN-BOTTOM: 20px;
|
||||
}
|
||||
|
||||
.details {
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.detail {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
}
|
||||
.detailLabel {
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.addressRoot{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.addressBillTo{
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.addressFrom{
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.table :global {
|
||||
margin-top: 40px;
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
text-align: left;
|
||||
|
||||
thead th{
|
||||
font-weight: 400;
|
||||
border-bottom: 1px solid #000;
|
||||
}
|
||||
|
||||
tbody{
|
||||
|
||||
tr {
|
||||
|
||||
}
|
||||
td{
|
||||
border: 1px solid #F6F6F6;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.totals{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 40px;
|
||||
margin-left: auto;
|
||||
}
|
||||
.totalsItem{
|
||||
display: flex;
|
||||
padding: 6px 0;
|
||||
}
|
||||
.totalsItemLabel{
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.logoWrap{
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
top: 20px;
|
||||
|
||||
img{
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.footer{
|
||||
|
||||
}
|
||||
|
||||
.paragraph{
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.paragraphLabel{
|
||||
color: #333333;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
import styles from './PaperTemplate.module.scss';
|
||||
|
||||
export function PaperTemplate() {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div>
|
||||
<h1 className={styles.bigTitle}>Invoice</h1>
|
||||
|
||||
<div className={styles.logoWrap}>
|
||||
<img alt="" src="https://cdn-development.mercury.com/demo-assets/avatars/mercury-demo-dark.png" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.details}>
|
||||
<div className={styles.detail}>
|
||||
<div className={styles.detailLabel}>Invoice number</div>
|
||||
<div>346D3D40-0001</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.detail}>
|
||||
<div className={styles.detailLabel}>Date of issue</div>
|
||||
<div>September 3, 2024</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.detail}>
|
||||
<div className={styles.detailLabel}>Date due</div>
|
||||
<div>October 3, 2024</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.addressRoot}>
|
||||
<div className={styles.addressBillTo}>
|
||||
Bigcapital Technology, Inc. <br />
|
||||
131 Continental Dr Suite 305 Newark,
|
||||
<br />
|
||||
Delaware 19713
|
||||
<br />
|
||||
United States
|
||||
<br />
|
||||
+1 762-339-5634
|
||||
<br />
|
||||
ahmed@bigcapital.app
|
||||
</div>
|
||||
|
||||
<div className={styles.addressFrom}>
|
||||
Billed To <br />
|
||||
Bigcapital Technology, Inc. <br />
|
||||
131 Continental Dr Suite 305 Newark,
|
||||
<br />
|
||||
Delaware 19713
|
||||
<br />
|
||||
United States
|
||||
<br />
|
||||
+1 762-339-5634
|
||||
<br />
|
||||
ahmed@bigcapital.app
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table className={styles.table}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Item</th>
|
||||
<th>Description</th>
|
||||
<th>Rate</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Simply dummy text</td>
|
||||
<td>Simply dummy text of the printing and typesetting</td>
|
||||
<td>1 X $100,00</td>
|
||||
<td>$100,00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style={{ display: 'flex' }}>
|
||||
<div className={styles.totals}>
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Sub Total</div>
|
||||
<div>630.00</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Discount</div>
|
||||
<div>0.00</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Sample Tax1 (4.70%)</div>
|
||||
<div>11.75</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Sample Tax2 (7.00%)</div>
|
||||
<div>21.00</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Total</div>
|
||||
<div>$662.75</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Payment Made</div>
|
||||
<div>100.00</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.totalsItem}>
|
||||
<div className={styles.totalsItemLabel}>Balance Due</div>
|
||||
<div className={styles.totalsItemLabel}>$562.75</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.paragraph}>
|
||||
<div className={styles.paragraphLabel}>Terms & Conditions</div>
|
||||
<div>
|
||||
It is a long established fact that a reader will be distracted by the
|
||||
readable content of a page when looking at its layout.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={styles.paragraph}>
|
||||
<div className={styles.paragraphLabel}>Statement</div>
|
||||
<div>
|
||||
It is a long established fact that a reader will be distracted by the
|
||||
readable content of a page when looking at its layout.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -7,6 +7,11 @@ import {
|
||||
NavbarGroup,
|
||||
Intent,
|
||||
Alignment,
|
||||
Menu,
|
||||
MenuItem,
|
||||
Popover,
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import {
|
||||
@@ -32,6 +37,8 @@ import withSettingsActions from '@/containers/Settings/withSettingsActions';
|
||||
import { compose } from '@/utils';
|
||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||
import { DialogsName } from '@/constants/dialogs';
|
||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||
import { DRAWERS } from '@/constants/drawers';
|
||||
|
||||
/**
|
||||
* Invoices table actions bar.
|
||||
@@ -51,6 +58,9 @@ function InvoiceActionsBar({
|
||||
|
||||
// #withDialogsActions
|
||||
openDialog,
|
||||
|
||||
// #withDrawerActions
|
||||
openDrawer,
|
||||
}) {
|
||||
const history = useHistory();
|
||||
|
||||
@@ -97,6 +107,11 @@ function InvoiceActionsBar({
|
||||
downloadExportPdf({ resource: 'SaleInvoice' });
|
||||
};
|
||||
|
||||
// Handles the invoice customize button click.
|
||||
const handleCustomizeBtnClick = () => {
|
||||
openDrawer(DRAWERS.INVOICE_CUSTOMIZE);
|
||||
};
|
||||
|
||||
return (
|
||||
<DashboardActionsBar>
|
||||
<NavbarGroup>
|
||||
@@ -164,6 +179,25 @@ function InvoiceActionsBar({
|
||||
<NavbarDivider />
|
||||
</NavbarGroup>
|
||||
<NavbarGroup align={Alignment.RIGHT}>
|
||||
<Popover
|
||||
minimal={true}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
position={Position.BOTTOM_RIGHT}
|
||||
modifiers={{
|
||||
offset: { offset: '0, 4' },
|
||||
}}
|
||||
content={
|
||||
<Menu>
|
||||
<MenuItem
|
||||
onClick={handleCustomizeBtnClick}
|
||||
text={'Customize Invoice'}
|
||||
/>
|
||||
</Menu>
|
||||
}
|
||||
>
|
||||
<Button icon={<Icon icon="cog-16" iconSize={16} />} minimal={true} />
|
||||
</Popover>
|
||||
<NavbarDivider />
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="refresh-16" iconSize={14} />}
|
||||
@@ -184,4 +218,5 @@ export default compose(
|
||||
invoicesTableSize: invoiceSettings?.tableSize,
|
||||
})),
|
||||
withDialogActions,
|
||||
withDrawerActions,
|
||||
)(InvoiceActionsBar);
|
||||
|
||||
Reference in New Issue
Block a user