mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-21 15:20:34 +00:00
feat(webapp): send mail notification dialogs
This commit is contained in:
@@ -47,6 +47,10 @@ import ProjectInvoicingFormDialog from '@/containers/Projects/containers/Project
|
|||||||
import ProjectBillableEntriesFormDialog from '@/containers/Projects/containers/ProjectBillableEntriesFormDialog';
|
import ProjectBillableEntriesFormDialog from '@/containers/Projects/containers/ProjectBillableEntriesFormDialog';
|
||||||
import TaxRateFormDialog from '@/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialog';
|
import TaxRateFormDialog from '@/containers/TaxRates/dialogs/TaxRateFormDialog/TaxRateFormDialog';
|
||||||
import { DialogsName } from '@/constants/dialogs';
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
import InvoiceMailDialog from '@/containers/Sales/Invoices/InvoiceMailDialog/InvoiceMailDialog';
|
||||||
|
import EstimateMailDialog from '@/containers/Sales/Estimates/EstimateMailDialog/EstimateMailDialog';
|
||||||
|
import ReceiptMailDialog from '@/containers/Sales/Receipts/ReceiptMailDialog/ReceiptMailDialog';
|
||||||
|
import PaymentMailDialog from '@/containers/Sales/PaymentReceives/PaymentMailDialog/PaymentMailDialog';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialogs container.
|
* Dialogs container.
|
||||||
@@ -137,6 +141,10 @@ export default function DialogsContainer() {
|
|||||||
dialogName={DialogsName.ProjectBillableEntriesForm}
|
dialogName={DialogsName.ProjectBillableEntriesForm}
|
||||||
/>
|
/>
|
||||||
<TaxRateFormDialog dialogName={DialogsName.TaxRateForm} />
|
<TaxRateFormDialog dialogName={DialogsName.TaxRateForm} />
|
||||||
|
<InvoiceMailDialog dialogName={DialogsName.InvoiceMail} />
|
||||||
|
<EstimateMailDialog dialogName={DialogsName.EstimateMail} />
|
||||||
|
<ReceiptMailDialog dialogName={DialogsName.ReceiptMail} />
|
||||||
|
<PaymentMailDialog dialogName={DialogsName.PaymentMail} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,4 +48,8 @@ export enum DialogsName {
|
|||||||
ProjectBillableEntriesForm = 'project-billable-entries',
|
ProjectBillableEntriesForm = 'project-billable-entries',
|
||||||
InvoiceNumberSettings = 'InvoiceNumberSettings',
|
InvoiceNumberSettings = 'InvoiceNumberSettings',
|
||||||
TaxRateForm = 'tax-rate-form',
|
TaxRateForm = 'tax-rate-form',
|
||||||
|
InvoiceMail = 'invoice-mail',
|
||||||
|
EstimateMail = 'estimate-mail',
|
||||||
|
ReceiptMail = 'receipt-mail',
|
||||||
|
PaymentMail = 'payment-mail',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estimate read-only details actions bar of the drawer.
|
* Estimate read-only details actions bar of the drawer.
|
||||||
@@ -65,6 +66,10 @@ function EstimateDetailActionsBar({
|
|||||||
const handleNotifyViaSMS = () => {
|
const handleNotifyViaSMS = () => {
|
||||||
openDialog('notify-estimate-via-sms', { estimateId });
|
openDialog('notify-estimate-via-sms', { estimateId });
|
||||||
};
|
};
|
||||||
|
// Handles the estimate mail dialog.
|
||||||
|
const handleMailEstimate = () => {
|
||||||
|
openDialog(DialogsName.EstimateMail, { estimateId });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerActionsBar>
|
<DrawerActionsBar>
|
||||||
@@ -86,6 +91,15 @@ function EstimateDetailActionsBar({
|
|||||||
onClick={handlePrintEstimate}
|
onClick={handlePrintEstimate}
|
||||||
/>
|
/>
|
||||||
</Can>
|
</Can>
|
||||||
|
|
||||||
|
<Can I={SaleEstimateAction.View} a={AbilitySubject.Estimate}>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
text={'Mail'}
|
||||||
|
onClick={handleMailEstimate}
|
||||||
|
/>
|
||||||
|
<NavbarDivider />
|
||||||
|
</Can>
|
||||||
<Can I={SaleEstimateAction.Delete} a={AbilitySubject.Estimate}>
|
<Can I={SaleEstimateAction.Delete} a={AbilitySubject.Estimate}>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import {
|
|||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { BadDebtMenuItem } from './utils';
|
import { BadDebtMenuItem } from './utils';
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoice details action bar.
|
* Invoice details action bar.
|
||||||
@@ -93,6 +94,10 @@ function InvoiceDetailActionsBar({
|
|||||||
openAlert('cancel-bad-debt', { invoiceId });
|
openAlert('cancel-bad-debt', { invoiceId });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMailInvoice = () => {
|
||||||
|
openDialog(DialogsName.InvoiceMail, { invoiceId });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerActionsBar>
|
<DrawerActionsBar>
|
||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
@@ -116,6 +121,13 @@ function InvoiceDetailActionsBar({
|
|||||||
</If>
|
</If>
|
||||||
<NavbarDivider />
|
<NavbarDivider />
|
||||||
</Can>
|
</Can>
|
||||||
|
<Can I={SaleInvoiceAction.View} a={AbilitySubject.Invoice}>
|
||||||
|
<Button
|
||||||
|
text={'Mail'}
|
||||||
|
onClick={handleMailInvoice}
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
/>
|
||||||
|
</Can>
|
||||||
<Can I={SaleInvoiceAction.View} a={AbilitySubject.Invoice}>
|
<Can I={SaleInvoiceAction.View} a={AbilitySubject.Invoice}>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import {
|
|||||||
|
|
||||||
import { compose } from '@/utils';
|
import { compose } from '@/utils';
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Payment receive actions bar.
|
* Payment receive actions bar.
|
||||||
@@ -68,6 +69,10 @@ function PaymentReceiveActionsBar({
|
|||||||
openDialog('payment-pdf-preview', { paymentReceiveId });
|
openDialog('payment-pdf-preview', { paymentReceiveId });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMailPaymentReceive = () => {
|
||||||
|
openDialog(DialogsName.PaymentMail, { paymentReceiveId });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerActionsBar>
|
<DrawerActionsBar>
|
||||||
<NavbarGroup>
|
<NavbarGroup>
|
||||||
@@ -88,6 +93,13 @@ function PaymentReceiveActionsBar({
|
|||||||
onClick={handlePrintPaymentReceive}
|
onClick={handlePrintPaymentReceive}
|
||||||
/>
|
/>
|
||||||
</Can>
|
</Can>
|
||||||
|
<Can I={PaymentReceiveAction.View} a={AbilitySubject.PaymentReceive}>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
text={'Mail'}
|
||||||
|
onClick={handleMailPaymentReceive}
|
||||||
|
/>
|
||||||
|
</Can>
|
||||||
<Can I={PaymentReceiveAction.Delete} a={AbilitySubject.PaymentReceive}>
|
<Can I={PaymentReceiveAction.Delete} a={AbilitySubject.PaymentReceive}>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { useReceiptDetailDrawerContext } from './ReceiptDetailDrawerProvider';
|
|||||||
import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption';
|
import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption';
|
||||||
import { safeCallback, compose } from '@/utils';
|
import { safeCallback, compose } from '@/utils';
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
import { DialogsName } from '@/constants/dialogs';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receipt details actions bar.
|
* Receipt details actions bar.
|
||||||
@@ -60,6 +61,9 @@ function ReceiptDetailActionBar({
|
|||||||
const handleNotifyViaSMS = () => {
|
const handleNotifyViaSMS = () => {
|
||||||
openDialog('notify-receipt-via-sms', { receiptId });
|
openDialog('notify-receipt-via-sms', { receiptId });
|
||||||
};
|
};
|
||||||
|
const handleReceiptMail = () => {
|
||||||
|
openDialog(DialogsName.ReceiptMail, { receiptId });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DrawerActionsBar>
|
<DrawerActionsBar>
|
||||||
@@ -81,6 +85,13 @@ function ReceiptDetailActionBar({
|
|||||||
onClick={safeCallback(onPrintReceipt)}
|
onClick={safeCallback(onPrintReceipt)}
|
||||||
/>
|
/>
|
||||||
</Can>
|
</Can>
|
||||||
|
<Can I={SaleReceiptAction.View} a={AbilitySubject.Receipt}>
|
||||||
|
<Button
|
||||||
|
className={Classes.MINIMAL}
|
||||||
|
text={'Mail'}
|
||||||
|
onClick={handleReceiptMail}
|
||||||
|
/>
|
||||||
|
</Can>
|
||||||
<Can I={SaleReceiptAction.Delete} a={AbilitySubject.Receipt}>
|
<Can I={SaleReceiptAction.Delete} a={AbilitySubject.Receipt}>
|
||||||
<Button
|
<Button
|
||||||
className={Classes.MINIMAL}
|
className={Classes.MINIMAL}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const EstimateMailDialogContent = React.lazy(
|
||||||
|
() => import('./EstimateMailDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice mail dialog.
|
||||||
|
*/
|
||||||
|
function EstimateMailDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { estimateId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Estiomate Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={true}
|
||||||
|
autoFocus={true}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<EstimateMailDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
estimateId={estimateId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(withDialogRedux())(EstimateMailDialog);
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { createContext } from 'react';
|
||||||
|
import { useSaleEstimateDefaultOptions } from '@/hooks/query';
|
||||||
|
import { DialogContent } from '@/components';
|
||||||
|
|
||||||
|
interface EstimateMailDialogBootValues {
|
||||||
|
estimateId: number;
|
||||||
|
mailOptions: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EstimateMailDialagBoot = createContext<EstimateMailDialogBootValues>();
|
||||||
|
|
||||||
|
interface EstimateMailDialogBootProps {
|
||||||
|
estimateId: number;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimate mail dialog boot provider.
|
||||||
|
*/
|
||||||
|
function EstimateMailDialogBoot({
|
||||||
|
estimateId,
|
||||||
|
...props
|
||||||
|
}: EstimateMailDialogBootProps) {
|
||||||
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
|
useSaleEstimateDefaultOptions(estimateId);
|
||||||
|
|
||||||
|
const provider = {
|
||||||
|
mailOptions,
|
||||||
|
isMailOptionsLoading,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={isMailOptionsLoading}>
|
||||||
|
<EstimateMailDialagBoot.Provider value={provider} {...props} />
|
||||||
|
</DialogContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useEstimateMailDialogBoot = () =>
|
||||||
|
React.useContext<EstimateMailDialogBootValues>(EstimateMailDialagBoot);
|
||||||
|
|
||||||
|
export { EstimateMailDialogBoot, useEstimateMailDialogBoot };
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { EstimateMailDialogBoot } from './EstimateMailDialogBoot';
|
||||||
|
import { EstimateMailDialogForm } from './EstimateMailDialogForm';
|
||||||
|
|
||||||
|
interface EstimateMailDialogContentProps {
|
||||||
|
dialogName: string;
|
||||||
|
estimateId: number;
|
||||||
|
}
|
||||||
|
export default function EstimateMailDialogContent({
|
||||||
|
dialogName,
|
||||||
|
estimateId,
|
||||||
|
}: EstimateMailDialogContentProps) {
|
||||||
|
return (
|
||||||
|
<EstimateMailDialogBoot estimateId={estimateId}>
|
||||||
|
<EstimateMailDialogForm />
|
||||||
|
</EstimateMailDialogBoot>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { Formik } from 'formik';
|
||||||
|
import { useEstimateMailDialogBoot } from './EstimateMailDialogBoot';
|
||||||
|
import { transformToForm } from '@/utils';
|
||||||
|
import { SendMailNotificationForm } from '@/containers/SendMailNotification';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
|
|
||||||
|
const initialFormValues = {
|
||||||
|
from: [],
|
||||||
|
to: [],
|
||||||
|
subject: '',
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function EstimateMailDialogForm() {
|
||||||
|
const { mailOptions } = useEstimateMailDialogBoot();
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
...initialFormValues,
|
||||||
|
...transformToForm(mailOptions, initialFormValues),
|
||||||
|
from: mailOptions.from ? castArray(mailOptions.from) : [],
|
||||||
|
to: mailOptions.to ? castArray(mailOptions.to) : [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||||
|
<SendMailNotificationForm />
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './EstimateMailDialog';
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const InvoiceMailDialogContent = React.lazy(
|
||||||
|
() => import('./InvoiceMailDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice mail dialog.
|
||||||
|
*/
|
||||||
|
function InvoiceMailDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { invoiceId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Invoice Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={true}
|
||||||
|
autoFocus={true}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<InvoiceMailDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
invoiceId={invoiceId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(withDialogRedux())(InvoiceMailDialog);
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { createContext } from 'react';
|
||||||
|
import { useSaleInvoiceDefaultOptions } from '@/hooks/query';
|
||||||
|
import { DialogContent } from '@/components';
|
||||||
|
|
||||||
|
interface InvoiceMailDialogBootValues {
|
||||||
|
invoiceId: number;
|
||||||
|
mailOptions: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const InvoiceMailDialagBoot = createContext<InvoiceMailDialogBootValues>();
|
||||||
|
|
||||||
|
interface InvoiceMailDialogBootProps {
|
||||||
|
invoiceId: number;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice mail dialog boot provider.
|
||||||
|
*/
|
||||||
|
function InvoiceMailDialogBoot({
|
||||||
|
invoiceId,
|
||||||
|
...props
|
||||||
|
}: InvoiceMailDialogBootProps) {
|
||||||
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
|
useSaleInvoiceDefaultOptions(invoiceId);
|
||||||
|
|
||||||
|
const provider = {
|
||||||
|
mailOptions,
|
||||||
|
isMailOptionsLoading,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={isMailOptionsLoading}>
|
||||||
|
<InvoiceMailDialagBoot.Provider value={provider} {...props} />
|
||||||
|
</DialogContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useInvoiceMailDialogBoot = () =>
|
||||||
|
React.useContext<InvoiceMailDialogBootValues>(InvoiceMailDialagBoot);
|
||||||
|
|
||||||
|
export { InvoiceMailDialogBoot, useInvoiceMailDialogBoot };
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { InvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
|
||||||
|
import { InvoiceMailDialogForm } from './InvoiceMailDialogForm';
|
||||||
|
|
||||||
|
interface InvoiceMailDialogContentProps {
|
||||||
|
dialogName: string;
|
||||||
|
invoiceId: number;
|
||||||
|
}
|
||||||
|
export default function InvoiceMailDialogContent({
|
||||||
|
dialogName,
|
||||||
|
invoiceId,
|
||||||
|
}: InvoiceMailDialogContentProps) {
|
||||||
|
return (
|
||||||
|
<InvoiceMailDialogBoot invoiceId={invoiceId}>
|
||||||
|
<InvoiceMailDialogForm />
|
||||||
|
</InvoiceMailDialogBoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Formik } from 'formik';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
|
import { SendMailNotificationForm } from '@/containers/SendMailNotification';
|
||||||
|
import { useInvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
|
||||||
|
import { transformToForm } from '@/utils';
|
||||||
|
|
||||||
|
const initialFormValues = {
|
||||||
|
from: [],
|
||||||
|
to: [],
|
||||||
|
subject: '',
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
export function InvoiceMailDialogForm() {
|
||||||
|
const { mailOptions } = useInvoiceMailDialogBoot();
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
...initialFormValues,
|
||||||
|
...transformToForm(mailOptions, initialFormValues),
|
||||||
|
from: mailOptions.from ? castArray(mailOptions.from) : [],
|
||||||
|
to: mailOptions.to ? castArray(mailOptions.to) : [],
|
||||||
|
};
|
||||||
|
const handleSubmit = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||||
|
<SendMailNotificationForm />
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './InvoiceMailDialog';
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const PaymentMailDialogContent = React.lazy(
|
||||||
|
() => import('./PaymentMailDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment mail dialog.
|
||||||
|
*/
|
||||||
|
function PaymentMailDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { paymentReceiveId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Payment Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={true}
|
||||||
|
autoFocus={true}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<PaymentMailDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
paymentReceiveId={paymentReceiveId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(withDialogRedux())(PaymentMailDialog);
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { createContext } from 'react';
|
||||||
|
import { usePaymentReceiveDefaultOptions } from '@/hooks/query';
|
||||||
|
import { DialogContent } from '@/components';
|
||||||
|
|
||||||
|
interface PaymentMailDialogBootValues {
|
||||||
|
paymentReceiveId: number;
|
||||||
|
mailOptions: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PaymentMailDialogBootContext =
|
||||||
|
createContext<PaymentMailDialogBootValues>();
|
||||||
|
|
||||||
|
interface PaymentMailDialogBootProps {
|
||||||
|
paymentReceiveId: number;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payment mail dialog boot provider.
|
||||||
|
*/
|
||||||
|
function PaymentMailDialogBoot({
|
||||||
|
paymentReceiveId,
|
||||||
|
...props
|
||||||
|
}: PaymentMailDialogBootProps) {
|
||||||
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
|
usePaymentReceiveDefaultOptions(paymentReceiveId);
|
||||||
|
|
||||||
|
const provider = {
|
||||||
|
mailOptions,
|
||||||
|
isMailOptionsLoading,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={isMailOptionsLoading}>
|
||||||
|
<PaymentMailDialogBootContext.Provider value={provider} {...props} />
|
||||||
|
</DialogContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const usePaymentMailDialogBoot = () =>
|
||||||
|
React.useContext<PaymentMailDialogBootValues>(PaymentMailDialogBootContext);
|
||||||
|
|
||||||
|
export { PaymentMailDialogBoot, usePaymentMailDialogBoot };
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { PaymentMailDialogBoot } from './PaymentMailDialogBoot';
|
||||||
|
import { PaymentMailDialogForm } from './PaymentMailDialogForm';
|
||||||
|
|
||||||
|
interface PaymentMailDialogContentProps {
|
||||||
|
dialogName: string;
|
||||||
|
paymentReceiveId: number;
|
||||||
|
}
|
||||||
|
export default function PaymentMailDialogContent({
|
||||||
|
dialogName,
|
||||||
|
paymentReceiveId,
|
||||||
|
}: PaymentMailDialogContentProps) {
|
||||||
|
return (
|
||||||
|
<PaymentMailDialogBoot paymentReceiveId={paymentReceiveId}>
|
||||||
|
<PaymentMailDialogForm />
|
||||||
|
</PaymentMailDialogBoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Formik } from 'formik';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
|
import { SendMailNotificationForm } from '@/containers/SendMailNotification';
|
||||||
|
import { usePaymentMailDialogBoot } from './PaymentMailDialogBoot';
|
||||||
|
import { transformToForm } from '@/utils';
|
||||||
|
|
||||||
|
const initialFormValues = {
|
||||||
|
from: [],
|
||||||
|
to: [],
|
||||||
|
subject: '',
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
export function PaymentMailDialogForm() {
|
||||||
|
const { mailOptions } = usePaymentMailDialogBoot();
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
...initialFormValues,
|
||||||
|
...transformToForm(mailOptions, initialFormValues),
|
||||||
|
from: mailOptions.from ? castArray(mailOptions.from) : [],
|
||||||
|
to: mailOptions.to ? castArray(mailOptions.to) : [],
|
||||||
|
};
|
||||||
|
const handleSubmit = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||||
|
<SendMailNotificationForm />
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './PaymentMailDialog';
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import { Dialog, DialogSuspense } from '@/components';
|
||||||
|
import withDialogRedux from '@/components/DialogReduxConnect';
|
||||||
|
import { compose } from '@/utils';
|
||||||
|
|
||||||
|
const ReceiptMailDialogContent = React.lazy(
|
||||||
|
() => import('./ReceiptMailDialogContent'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice mail dialog.
|
||||||
|
*/
|
||||||
|
function ReceiptMailDialog({
|
||||||
|
dialogName,
|
||||||
|
payload: { receiptId = null },
|
||||||
|
isOpen,
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
name={dialogName}
|
||||||
|
title={'Receipt Mail'}
|
||||||
|
isOpen={isOpen}
|
||||||
|
canEscapeJeyClose={true}
|
||||||
|
autoFocus={true}
|
||||||
|
>
|
||||||
|
<DialogSuspense>
|
||||||
|
<ReceiptMailDialogContent
|
||||||
|
dialogName={dialogName}
|
||||||
|
receiptId={receiptId}
|
||||||
|
/>
|
||||||
|
</DialogSuspense>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default compose(withDialogRedux())(ReceiptMailDialog);
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React, { createContext } from 'react';
|
||||||
|
import { useSaleReceiptDefaultOptions } from '@/hooks/query';
|
||||||
|
import { DialogContent } from '@/components';
|
||||||
|
|
||||||
|
interface ReceiptMailDialogBootValues {
|
||||||
|
receiptId: number;
|
||||||
|
mailOptions: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReceiptMailDialogBootContext =
|
||||||
|
createContext<ReceiptMailDialogBootValues>();
|
||||||
|
|
||||||
|
interface ReceiptMailDialogBootProps {
|
||||||
|
receiptId: number;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receipt mail dialog boot provider.
|
||||||
|
*/
|
||||||
|
function ReceiptMailDialogBoot({
|
||||||
|
receiptId,
|
||||||
|
...props
|
||||||
|
}: ReceiptMailDialogBootProps) {
|
||||||
|
const { data: mailOptions, isLoading: isMailOptionsLoading } =
|
||||||
|
useSaleReceiptDefaultOptions(receiptId);
|
||||||
|
|
||||||
|
const provider = {
|
||||||
|
mailOptions,
|
||||||
|
isMailOptionsLoading,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DialogContent isLoading={isMailOptionsLoading}>
|
||||||
|
<ReceiptMailDialogBootContext.Provider value={provider} {...props} />
|
||||||
|
</DialogContent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useReceiptMailDialogBoot = () =>
|
||||||
|
React.useContext<ReceiptMailDialogBootValues>(ReceiptMailDialogBootContext);
|
||||||
|
|
||||||
|
export { ReceiptMailDialogBoot, useReceiptMailDialogBoot };
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { ReceiptMailDialogBoot } from './ReceiptMailDialogBoot';
|
||||||
|
import { ReceiptMailDialogForm } from './ReceiptMailDialogForm';
|
||||||
|
|
||||||
|
interface ReceiptMailDialogContentProps {
|
||||||
|
dialogName: string
|
||||||
|
receiptId: number;
|
||||||
|
}
|
||||||
|
export default function ReceiptMailDialogContent({
|
||||||
|
dialogName,
|
||||||
|
receiptId,
|
||||||
|
}: ReceiptMailDialogContentProps) {
|
||||||
|
return (
|
||||||
|
<ReceiptMailDialogBoot receiptId={receiptId}>
|
||||||
|
<ReceiptMailDialogForm />
|
||||||
|
</ReceiptMailDialogBoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
import { Formik } from 'formik';
|
||||||
|
import { castArray } from 'lodash';
|
||||||
|
import { SendMailNotificationForm } from '@/containers/SendMailNotification';
|
||||||
|
import { useReceiptMailDialogBoot } from './ReceiptMailDialogBoot';
|
||||||
|
import { transformToForm } from '@/utils';
|
||||||
|
|
||||||
|
const initialFormValues = {
|
||||||
|
from: [],
|
||||||
|
to: [],
|
||||||
|
subject: '',
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
export function ReceiptMailDialogForm() {
|
||||||
|
const { mailOptions } = useReceiptMailDialogBoot();
|
||||||
|
|
||||||
|
const initialValues = {
|
||||||
|
...initialFormValues,
|
||||||
|
...transformToForm(mailOptions, initialFormValues),
|
||||||
|
from: mailOptions.from ? castArray(mailOptions.from) : [],
|
||||||
|
to: mailOptions.to ? castArray(mailOptions.to) : [],
|
||||||
|
};
|
||||||
|
const handleSubmit = () => {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
|
||||||
|
<SendMailNotificationForm />
|
||||||
|
</Formik>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './ReceiptMailDialog';
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import { Form } from 'formik';
|
||||||
|
import { FFormGroup, FInputGroup, FMultiSelect } from '@/components';
|
||||||
|
|
||||||
|
export function SendMailNotificationForm() {
|
||||||
|
return (
|
||||||
|
<Form>
|
||||||
|
<FFormGroup label={'From'} name={'from'} inline={true} fastField={true}>
|
||||||
|
<FMultiSelect
|
||||||
|
items={[]}
|
||||||
|
name={'from'}
|
||||||
|
placeholder=""
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup label={'To'} name={'to'} inline={true} fastField={true}>
|
||||||
|
<FMultiSelect
|
||||||
|
items={[]}
|
||||||
|
name={'to'}
|
||||||
|
placeholder=""
|
||||||
|
popoverProps={{ minimal: true }}
|
||||||
|
/>
|
||||||
|
</FFormGroup>
|
||||||
|
|
||||||
|
<FFormGroup
|
||||||
|
label={'Subject'}
|
||||||
|
name={'subject'}
|
||||||
|
inline={true}
|
||||||
|
fastField={true}
|
||||||
|
>
|
||||||
|
<FInputGroup name={'subject'} />
|
||||||
|
</FFormGroup>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export * from './SendMailNotificationForm';
|
||||||
@@ -239,3 +239,33 @@ export function useEstimateSMSDetail(estimateId, props, requestProps) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useSendSaleEstimateMail(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
([id, values]) => apiRequest.post(`sales/estimates/${id}/mail`, values),
|
||||||
|
{
|
||||||
|
onSuccess: (res, [id, values]) => {
|
||||||
|
// Common invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSaleEstimateDefaultOptions(estimateId, props) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SALE_ESTIMATE_MAIL_OPTIONS, estimateId],
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
url: `sales/estimates/${estimateId}/mail`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (res) => res.data.data,
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -306,3 +306,34 @@ export function useInvoicePaymentTransactions(invoiceId, props) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useSendSaleInvoiceMail(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
([id, values]) => apiRequest.post(`sales/invoices/${id}/mail`, values),
|
||||||
|
{
|
||||||
|
onSuccess: (res, [id, values]) => {
|
||||||
|
// Common invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSaleInvoiceDefaultOptions(invoiceId, props) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SALE_INVOICE_DEFAULT_OPTIONS, invoiceId],
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
url: `sales/invoices/${invoiceId}/mail`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (res) => res.data.data,
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -234,3 +234,34 @@ export function usePaymentReceiveSMSDetail(
|
|||||||
export function usePdfPaymentReceive(paymentReceiveId) {
|
export function usePdfPaymentReceive(paymentReceiveId) {
|
||||||
return useRequestPdf(`sales/payment_receives/${paymentReceiveId}`);
|
return useRequestPdf(`sales/payment_receives/${paymentReceiveId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useSendPaymentReceiveMail(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
([id, values]) =>
|
||||||
|
apiRequest.post(`sales/payment_receives/${id}/mail`, values),
|
||||||
|
{
|
||||||
|
onSuccess: (res, [id, values]) => {
|
||||||
|
// Common invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function usePaymentReceiveDefaultOptions(paymentReceiveId, props) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.PAYMENT_RECEIVE_MAIL_OPTIONS, paymentReceiveId],
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
url: `sales/payment_receives/${paymentReceiveId}/mail`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (res) => res.data.data,
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -207,3 +207,36 @@ export function useReceiptSMSDetail(receiptId, props, requestProps) {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function useSendSaleReceiptMail(props) {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
return useMutation(
|
||||||
|
(id, values) => apiRequest.post(`sales/receipts/${id}/mail`, values),
|
||||||
|
{
|
||||||
|
onSuccess: () => {
|
||||||
|
// Invalidate queries.
|
||||||
|
commonInvalidateQueries(queryClient);
|
||||||
|
},
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSaleReceiptDefaultOptions(invoiceId, props) {
|
||||||
|
return useRequestQuery(
|
||||||
|
[t.SALE_RECEIPT_MAIL_OPTIONS, invoiceId],
|
||||||
|
{
|
||||||
|
method: 'get',
|
||||||
|
url: `sales/receipts/${invoiceId}/mail`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
select: (res) => res.data.data,
|
||||||
|
...props,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ const SALE_ESTIMATES = {
|
|||||||
SALE_ESTIMATE: 'SALE_ESTIMATE',
|
SALE_ESTIMATE: 'SALE_ESTIMATE',
|
||||||
SALE_ESTIMATE_SMS_DETAIL: 'SALE_ESTIMATE_SMS_DETAIL',
|
SALE_ESTIMATE_SMS_DETAIL: 'SALE_ESTIMATE_SMS_DETAIL',
|
||||||
NOTIFY_SALE_ESTIMATE_BY_SMS: 'NOTIFY_SALE_ESTIMATE_BY_SMS',
|
NOTIFY_SALE_ESTIMATE_BY_SMS: 'NOTIFY_SALE_ESTIMATE_BY_SMS',
|
||||||
|
SALE_ESTIMATE_MAIL_OPTIONS: 'SALE_ESTIMATE_MAIL_OPTIONS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SALE_RECEIPTS = {
|
const SALE_RECEIPTS = {
|
||||||
@@ -76,6 +77,7 @@ const SALE_RECEIPTS = {
|
|||||||
SALE_RECEIPT: 'SALE_RECEIPT',
|
SALE_RECEIPT: 'SALE_RECEIPT',
|
||||||
SALE_RECEIPT_SMS_DETAIL: 'SALE_RECEIPT_SMS_DETAIL',
|
SALE_RECEIPT_SMS_DETAIL: 'SALE_RECEIPT_SMS_DETAIL',
|
||||||
NOTIFY_SALE_RECEIPT_BY_SMS: 'NOTIFY_SALE_RECEIPT_BY_SMS',
|
NOTIFY_SALE_RECEIPT_BY_SMS: 'NOTIFY_SALE_RECEIPT_BY_SMS',
|
||||||
|
SALE_RECEIPT_MAIL_OPTIONS: 'SALE_RECEIPT_MAIL_OPTIONS'
|
||||||
};
|
};
|
||||||
|
|
||||||
const INVENTORY_ADJUSTMENTS = {
|
const INVENTORY_ADJUSTMENTS = {
|
||||||
@@ -101,6 +103,7 @@ const PAYMENT_RECEIVES = {
|
|||||||
PAYMENT_RECEIVE_EDIT_PAGE: 'PAYMENT_RECEIVE_EDIT_PAGE',
|
PAYMENT_RECEIVE_EDIT_PAGE: 'PAYMENT_RECEIVE_EDIT_PAGE',
|
||||||
PAYMENT_RECEIVE_SMS_DETAIL: 'PAYMENT_RECEIVE_SMS_DETAIL',
|
PAYMENT_RECEIVE_SMS_DETAIL: 'PAYMENT_RECEIVE_SMS_DETAIL',
|
||||||
NOTIFY_PAYMENT_RECEIVE_BY_SMS: 'NOTIFY_PAYMENT_RECEIVE_BY_SMS',
|
NOTIFY_PAYMENT_RECEIVE_BY_SMS: 'NOTIFY_PAYMENT_RECEIVE_BY_SMS',
|
||||||
|
PAYMENT_RECEIVE_MAIL_OPTIONS: 'PAYMENT_RECEIVE_MAIL_OPTIONS',
|
||||||
};
|
};
|
||||||
|
|
||||||
const SALE_INVOICES = {
|
const SALE_INVOICES = {
|
||||||
@@ -112,6 +115,7 @@ const SALE_INVOICES = {
|
|||||||
BAD_DEBT: 'BAD_DEBT',
|
BAD_DEBT: 'BAD_DEBT',
|
||||||
CANCEL_BAD_DEBT: 'CANCEL_BAD_DEBT',
|
CANCEL_BAD_DEBT: 'CANCEL_BAD_DEBT',
|
||||||
SALE_INVOICE_PAYMENT_TRANSACTIONS: 'SALE_INVOICE_PAYMENT_TRANSACTIONS',
|
SALE_INVOICE_PAYMENT_TRANSACTIONS: 'SALE_INVOICE_PAYMENT_TRANSACTIONS',
|
||||||
|
SALE_INVOICE_DEFAULT_OPTIONS: 'SALE_INVOICE_DEFAULT_OPTIONS'
|
||||||
};
|
};
|
||||||
|
|
||||||
const USERS = {
|
const USERS = {
|
||||||
|
|||||||
Reference in New Issue
Block a user