feat(webapp): showing up mail popup once saving invoice, receipt and estimate

This commit is contained in:
Ahmed Bouhuolia
2024-01-25 21:56:18 +02:00
parent 760dbc6cfc
commit 63708ae839
29 changed files with 482 additions and 138 deletions

View File

@@ -0,0 +1,39 @@
// @ts-nocheck
import React from 'react';
import { Dialog, DialogSuspense } from '@/components';
import withDialogRedux from '@/components/DialogReduxConnect';
import { compose } from '@/utils';
const InvoiceFormMailDeliverDialogContent = React.lazy(
() => import('./InvoiceFormMailDeliverDialogContent'),
);
/**
* Invoice mail dialog.
*/
function InvoiceFormMailDeliverDialog({
dialogName,
payload: { invoiceId = null },
isOpen,
}) {
return (
<Dialog
name={dialogName}
title={'Invoice Mail'}
isOpen={isOpen}
canEscapeJeyClose={false}
isCloseButtonShown={false}
autoFocus={true}
style={{ width: 600 }}
>
<DialogSuspense>
<InvoiceFormMailDeliverDialogContent
dialogName={dialogName}
invoiceId={invoiceId}
/>
</DialogSuspense>
</Dialog>
);
}
export default compose(withDialogRedux())(InvoiceFormMailDeliverDialog);

View File

@@ -0,0 +1,40 @@
// @ts-nocheck
import * as R from 'ramda';
import { useHistory } from 'react-router-dom';
import InvoiceMailDialogContent from '../../../InvoiceMailDialog/InvoiceMailDialogContent';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import { DialogsName } from '@/constants/dialogs';
interface InvoiceFormDeliverDialogContent {
invoiceId: number;
}
function InvoiceFormDeliverDialogContentRoot({
invoiceId,
// #withDialogActions
closeDialog,
}: InvoiceFormDeliverDialogContent) {
const history = useHistory();
const handleSubmit = () => {
history.push('/invoices');
closeDialog(DialogsName.InvoiceFormMailDeliver);
};
const handleCancel = () => {
history.push('/invoices');
closeDialog(DialogsName.InvoiceFormMailDeliver);
};
return (
<InvoiceMailDialogContent
invoiceId={invoiceId}
onFormSubmit={handleSubmit}
onCancelClick={handleCancel}
/>
);
}
export default R.compose(withDialogActions)(
InvoiceFormDeliverDialogContentRoot,
);

View File

@@ -30,19 +30,19 @@ export default function InvoiceFloatingActions() {
const { setSubmitPayload, invoice } = useInvoiceFormContext();
// Handle submit & deliver button click.
const handleSubmitDeliverBtnClick = (event) => {
setSubmitPayload({ redirect: true, deliver: true });
const handleSubmitDeliverBtnClick = () => {
setSubmitPayload({ redirectToEdit: true, deliverViaMail: true });
submitForm();
};
// Handle submit, deliver & new button click.
const handleSubmitDeliverAndNewBtnClick = (event) => {
const handleSubmitDeliverAndNewBtnClick = () => {
setSubmitPayload({ redirect: false, deliver: true, resetForm: true });
submitForm();
};
// Handle submit, deliver & continue editing button click.
const handleSubmitDeliverContinueEditingBtnClick = (event) => {
const handleSubmitDeliverContinueEditingBtnClick = () => {
setSubmitPayload({ redirect: false, deliver: true });
submitForm();
};

View File

@@ -34,12 +34,20 @@ import {
transformValueToRequest,
resetFormState,
} from './utils';
import { InvoiceExchangeRateSync, InvoiceNoSyncSettingsToForm } from './components';
import {
InvoiceExchangeRateSync,
InvoiceNoSyncSettingsToForm,
} from './components';
import { DialogsName } from '@/constants/dialogs';
import withDialogActions from '@/containers/Dialog/withDialogActions';
/**
* Invoice form.
*/
function InvoiceForm({
// #withDialogActions
openDialog,
// #withSettings
invoiceNextNumber,
invoiceNumberPrefix,
@@ -111,7 +119,7 @@ function InvoiceForm({
from_estimate_id: estimateId,
};
// Handle the request success.
const onSuccess = () => {
const onSuccess = (res) => {
AppToaster.show({
message: intl.get(
isNewMode
@@ -123,6 +131,11 @@ function InvoiceForm({
});
setSubmitting(false);
if (submitPayload.deliverViaMail) {
openDialog(DialogsName.InvoiceFormMailDeliver, {
invoiceId: res.data.id,
});
}
if (submitPayload.redirect) {
history.push('/invoices');
}
@@ -201,4 +214,5 @@ export default compose(
invoiceTermsConditions: invoiceSettings?.termsConditions,
})),
withCurrentOrganization(),
withDialogActions,
)(InvoiceForm);

View File

@@ -1,8 +1,8 @@
// @ts-nocheck
import React from 'react';
import { useFormikContext } from 'formik';
import InvoiceNumberDialog from '@/containers/Dialogs/InvoiceNumberDialog';
import { DialogsName } from '@/constants/dialogs';
import InvoiceFormMailDeliverDialog from './Dialogs/InvoiceFormMailDeliverDialog/InvoiceFormMailDeliverDialog';
/**
* Invoice form dialogs.
@@ -23,9 +23,14 @@ export default function InvoiceFormDialogs() {
};
return (
<InvoiceNumberDialog
dialogName={DialogsName.InvoiceNumberSettings}
onConfirm={handleInvoiceNumberFormConfirm}
/>
<>
<InvoiceNumberDialog
dialogName={DialogsName.InvoiceNumberSettings}
onConfirm={handleInvoiceNumberFormConfirm}
/>
<InvoiceFormMailDeliverDialog
dialogName={DialogsName.InvoiceFormMailDeliver}
/>
</>
);
}

View File

@@ -4,8 +4,8 @@ import { Dialog, DialogSuspense } from '@/components';
import withDialogRedux from '@/components/DialogReduxConnect';
import { compose } from '@/utils';
const InvoiceMailDialogContent = React.lazy(
() => import('./InvoiceMailDialogContent'),
const InvoiceMailDialogBody = React.lazy(
() => import('./InvoiceMailDialogBody'),
);
/**
@@ -13,12 +13,7 @@ const InvoiceMailDialogContent = React.lazy(
*/
function InvoiceMailDialog({
dialogName,
payload: {
invoiceId = null,
// Redirects to the invoices list.
redirectToInvoicesList = false,
},
payload: { invoiceId = null },
isOpen,
}) {
return (
@@ -26,16 +21,13 @@ function InvoiceMailDialog({
name={dialogName}
title={'Invoice Mail'}
isOpen={isOpen}
canEscapeJeyClose={true}
canEscapeJeyClose={false}
isCloseButtonShown={false}
autoFocus={true}
style={{ width: 600 }}
>
<DialogSuspense>
<InvoiceMailDialogContent
dialogName={dialogName}
invoiceId={invoiceId}
redirectToInvoicesList={redirectToInvoicesList}
/>
<InvoiceMailDialogBody invoiceId={invoiceId} />
</DialogSuspense>
</Dialog>
);

View File

@@ -0,0 +1,36 @@
// @ts-nocheck
import * as R from 'ramda';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import InvoiceMailDialogContent, {
InvoiceMailDialogContentProps,
} from './InvoiceMailDialogContent';
import { DialogsName } from '@/constants/dialogs';
export interface InvoiceMailDialogBodyProps
extends InvoiceMailDialogContentProps {}
function InvoiceMailDialogBodyRoot({
invoiceId,
onCancelClick,
onFormSubmit,
// #withDialogActions
closeDialog,
}: InvoiceMailDialogBodyProps) {
const handleCancelClick = () => {
closeDialog(DialogsName.InvoiceMail);
};
const handleSubmitClick = () => {
closeDialog(DialogsName.InvoiceMail);
};
return (
<InvoiceMailDialogContent
invoiceId={invoiceId}
onCancelClick={handleCancelClick}
onFormSubmit={handleSubmitClick}
/>
);
}
export default R.compose(withDialogActions)(InvoiceMailDialogBodyRoot);

View File

@@ -1,24 +1,22 @@
import { InvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
import { InvoiceMailDialogForm } from './InvoiceMailDialogForm';
interface InvoiceMailDialogContentProps {
dialogName: string;
export interface InvoiceMailDialogContentProps {
invoiceId: number;
// Redirect to invoices list after submitting the message.
redirectToInvoicesList?: boolean;
onFormSubmit?: () => void;
onCancelClick?: () => void;
}
export default function InvoiceMailDialogContent({
dialogName,
invoiceId,
redirectToInvoicesList,
onFormSubmit,
onCancelClick,
}: InvoiceMailDialogContentProps) {
return (
<InvoiceMailDialogBoot
invoiceId={invoiceId}
redirectToInvoicesList={redirectToInvoicesList}
>
<InvoiceMailDialogForm />
<InvoiceMailDialogBoot invoiceId={invoiceId}>
<InvoiceMailDialogForm
onFormSubmit={onFormSubmit}
onCancelClick={onCancelClick}
/>
</InvoiceMailDialogBoot>
);
}

View File

@@ -1,12 +1,9 @@
// @ts-nocheck
import { Formik } from 'formik';
import * as R from 'ramda';
import { Intent } from '@blueprintjs/core';
import { useInvoiceMailDialogBoot } from './InvoiceMailDialogBoot';
import { DialogsName } from '@/constants/dialogs';
import { AppToaster } from '@/components';
import { useSendSaleInvoiceMail } from '@/hooks/query';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import { InvoiceMailDialogFormContent } from './InvoiceMailDialogFormContent';
import { InvoiceMailFormSchema } from './InvoiceMailDialogForm.schema';
import {
@@ -15,7 +12,6 @@ import {
transformMailFormToRequest,
transformMailFormToInitialValues,
} from '@/containers/SendMailNotification/utils';
import { useHistory } from 'react-router-dom';
const initialFormValues = {
...initialMailNotificationValues,
@@ -26,13 +22,8 @@ interface InvoiceMailFormValues extends MailNotificationFormValues {
attachInvoice: boolean;
}
function InvoiceMailDialogFormRoot({
// #withDialogActions
closeDialog,
}) {
const history = useHistory();
const { mailOptions, saleInvoiceId, redirectToInvoicesList } =
useInvoiceMailDialogBoot();
export function InvoiceMailDialogForm({ onFormSubmit, onCancelClick }) {
const { mailOptions, saleInvoiceId } = useInvoiceMailDialogBoot();
const { mutateAsync: sendInvoiceMail } = useSendSaleInvoiceMail();
const initialValues = transformMailFormToInitialValues(
@@ -50,13 +41,8 @@ function InvoiceMailDialogFormRoot({
message: 'The mail notification has been sent successfully.',
intent: Intent.SUCCESS,
});
closeDialog(DialogsName.InvoiceMail);
setSubmitting(false);
// Redirect to the dashboard if the option was enabled.
if (redirectToInvoicesList) {
history.push('/invoices');
}
onFormSubmit && onFormSubmit(values);
})
.catch(() => {
AppToaster.show({
@@ -68,7 +54,7 @@ function InvoiceMailDialogFormRoot({
};
// Handle the close button click.
const handleClose = () => {
closeDialog(DialogsName.InvoiceMail);
onCancelClick && onCancelClick();
};
return (
@@ -81,7 +67,3 @@ function InvoiceMailDialogFormRoot({
</Formik>
);
}
export const InvoiceMailDialogForm = R.compose(withDialogActions)(
InvoiceMailDialogFormRoot,
);

View File

@@ -1 +1,2 @@
export * from './InvoiceMailDialog';
export * from './InvoiceMailDialog';
export * from './InvoiceMailDialogContent';