feat: wip send estimate mail preview

This commit is contained in:
Ahmed Bouhuolia
2024-11-18 15:15:03 +02:00
parent 53ab40a075
commit 7df316aa56
34 changed files with 405 additions and 459 deletions

View File

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

View File

@@ -1,40 +0,0 @@
// @ts-nocheck
import * as R from 'ramda';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import { useHistory } from 'react-router-dom';
import EstimateMailDialogContent from '../../EstimateMailDialog/EstimateMailDialogContent';
import { DialogsName } from '@/constants/dialogs';
interface EstimateFormDeliverDialogContent {
estimateId: number;
}
function EstimateFormDeliverDialogContentRoot({
estimateId,
// #withDialogActions
closeDialog,
}: EstimateFormDeliverDialogContent) {
const history = useHistory();
const handleSubmit = () => {
closeDialog(DialogsName.EstimateFormMailDeliver);
history.push('/estimates');
};
const handleCancel = () => {
closeDialog(DialogsName.EstimateFormMailDeliver);
history.push('/estimates');
};
return (
<EstimateMailDialogContent
estimateId={estimateId}
onFormSubmit={handleSubmit}
onCancelClick={handleCancel}
/>
);
}
export default R.compose(withDialogActions)(
EstimateFormDeliverDialogContentRoot,
);

View File

@@ -1,9 +1,6 @@
// @ts-nocheck
import React from 'react';
import { useFormikContext } from 'formik';
import EstimateNumberDialog from '@/containers/Dialogs/EstimateNumberDialog';
import EstimateFormMailDeliverDialog from './Dialogs/EstimateFormMailDeliverDialog';
import { DialogsName } from '@/constants/dialogs';
/**
* Estimate form dialogs.
@@ -27,9 +24,6 @@ export default function EstimateFormDialogs() {
dialogName={'estimate-number-form'}
onConfirm={handleEstimateNumberFormConfirm}
/>
<EstimateFormMailDeliverDialog
dialogName={DialogsName.EstimateFormMailDeliver}
/>
</>
);
}

View File

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

View File

@@ -1,33 +0,0 @@
// @ts-nocheck
import * as R from 'ramda';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import EstimateMailDialogContent from './EstimateMailDialogContent';
import { DialogsName } from '@/constants/dialogs';
interface EstimateMailDialogBodyProps {
estimateId: number;
}
function EstimateMailDialogBodyRoot({
estimateId,
// #withDialogActions
closeDialog,
}: EstimateMailDialogBodyProps) {
const handleSubmit = () => {
closeDialog(DialogsName.EstimateMail);
};
const handleCancelClick = () => {
closeDialog(DialogsName.EstimateMail);
};
return (
<EstimateMailDialogContent
estimateId={estimateId}
onFormSubmit={handleSubmit}
onCancelClick={handleCancelClick}
/>
);
}
export default R.compose(withDialogActions)(EstimateMailDialogBodyRoot);

View File

@@ -1,48 +0,0 @@
// @ts-nocheck
import React, { createContext } from 'react';
import { useSaleEstimateDefaultOptions } from '@/hooks/query';
import { DialogContent } from '@/components';
interface EstimateMailDialogBootValues {
estimateId: number;
mailOptions: any;
redirectToEstimatesList: boolean;
}
const EstimateMailDialagBoot = createContext<EstimateMailDialogBootValues>();
interface EstimateMailDialogBootProps {
estimateId: number;
redirectToEstimatesList?: boolean;
children: React.ReactNode;
}
/**
* Estimate mail dialog boot provider.
*/
function EstimateMailDialogBoot({
estimateId,
redirectToEstimatesList,
...props
}: EstimateMailDialogBootProps) {
const { data: mailOptions, isLoading: isMailOptionsLoading } =
useSaleEstimateDefaultOptions(estimateId);
const provider = {
saleEstimateId: estimateId,
mailOptions,
isMailOptionsLoading,
redirectToEstimatesList,
};
return (
<DialogContent isLoading={isMailOptionsLoading}>
<EstimateMailDialagBoot.Provider value={provider} {...props} />
</DialogContent>
);
}
const useEstimateMailDialogBoot = () =>
React.useContext<EstimateMailDialogBootValues>(EstimateMailDialagBoot);
export { EstimateMailDialogBoot, useEstimateMailDialogBoot };

View File

@@ -1,22 +0,0 @@
import { EstimateMailDialogBoot } from './EstimateMailDialogBoot';
import { EstimateMailDialogForm } from './EstimateMailDialogForm';
interface EstimateMailDialogContentProps {
estimateId: number;
onFormSubmit?: () => void;
onCancelClick?: () => void;
}
export default function EstimateMailDialogContent({
estimateId,
onFormSubmit,
onCancelClick,
}: EstimateMailDialogContentProps) {
return (
<EstimateMailDialogBoot estimateId={estimateId}>
<EstimateMailDialogForm
onFormSubmit={onFormSubmit}
onCancelClick={onCancelClick}
/>
</EstimateMailDialogBoot>
);
}

View File

@@ -1,81 +0,0 @@
// @ts-nocheck
import { Formik } from 'formik';
import * as R from 'ramda';
import { Intent } from '@blueprintjs/core';
import { useEstimateMailDialogBoot } from './EstimateMailDialogBoot';
import { DialogsName } from '@/constants/dialogs';
import withDialogActions from '@/containers/Dialog/withDialogActions';
import { useSendSaleEstimateMail } from '@/hooks/query';
import { EstimateMailDialogFormContent } from './EstimateMailDialogFormContent';
import {
initialMailNotificationValues,
MailNotificationFormValues,
transformMailFormToInitialValues,
transformMailFormToRequest,
} from '@/containers/SendMailNotification/utils';
import { AppToaster } from '@/components';
const initialFormValues = {
...initialMailNotificationValues,
attachEstimate: true,
};
interface EstimateMailFormValues extends MailNotificationFormValues {
attachEstimate: boolean;
}
function EstimateMailDialogFormRoot({
onFormSubmit,
onCancelClick,
// #withDialogClose
closeDialog,
}) {
const { mutateAsync: sendEstimateMail } = useSendSaleEstimateMail();
const { mailOptions, saleEstimateId, } =
useEstimateMailDialogBoot();
const initialValues = transformMailFormToInitialValues(
mailOptions,
initialFormValues,
);
// Handle the form submitting.
const handleSubmit = (values: EstimateMailFormValues, { setSubmitting }) => {
const reqValues = transformMailFormToRequest(values);
setSubmitting(true);
sendEstimateMail([saleEstimateId, reqValues])
.then(() => {
AppToaster.show({
message: 'The mail notification has been sent successfully.',
intent: Intent.SUCCESS,
});
closeDialog(DialogsName.EstimateMail);
setSubmitting(false);
onFormSubmit && onFormSubmit();
})
.catch(() => {
setSubmitting(false);
closeDialog(DialogsName.EstimateMail);
AppToaster.show({
message: 'Something went wrong.',
intent: Intent.DANGER,
});
onCancelClick && onCancelClick();
});
};
const handleClose = () => {
closeDialog(DialogsName.EstimateMail);
};
return (
<Formik initialValues={initialValues} onSubmit={handleSubmit}>
<EstimateMailDialogFormContent onClose={handleClose} />
</Formik>
);
}
export const EstimateMailDialogForm = R.compose(withDialogActions)(
EstimateMailDialogFormRoot,
);

View File

@@ -1,66 +0,0 @@
// @ts-nocheck
import { Form, useFormikContext } from 'formik';
import { Button, Classes, Intent } from '@blueprintjs/core';
import styled from 'styled-components';
import { FFormGroup, FSwitch } from '@/components';
import { MailNotificationForm } from '@/containers/SendMailNotification';
import { saveInvoke } from '@/utils';
import { useEstimateMailDialogBoot } from './EstimateMailDialogBoot';
interface EstimateMailDialogFormContentProps {
onClose?: () => void;
}
export function EstimateMailDialogFormContent({
onClose,
}: EstimateMailDialogFormContentProps) {
const { isSubmitting } = useFormikContext();
const { mailOptions } = useEstimateMailDialogBoot();
const handleClose = () => {
saveInvoke(onClose);
};
return (
<Form>
<div className={Classes.DIALOG_BODY}>
<MailNotificationForm
fromAddresses={mailOptions.from_options}
toAddresses={mailOptions.to_options}
/>
<AttachFormGroup name={'attachEstimate'} inline>
<FSwitch name={'attachEstimate'} label={'Attach Estimate'} />
</AttachFormGroup>
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button
disabled={isSubmitting}
onClick={handleClose}
style={{ minWidth: '65px' }}
>
Close
</Button>
<Button
intent={Intent.PRIMARY}
loading={isSubmitting}
style={{ minWidth: '75px' }}
type="submit"
>
Send
</Button>
</div>
</div>
</Form>
);
}
const AttachFormGroup = styled(FFormGroup)`
background: #f8f9fb;
margin-top: 0.6rem;
padding: 4px 14px;
border-radius: 5px;
border: 1px solid #dcdcdd;
`;

View File

@@ -1 +0,0 @@
export * from './EstimateMailDialog';

View File

@@ -1,11 +1,12 @@
import React, { createContext, useContext } from 'react';
import { Spinner } from '@blueprintjs/core';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useSaleEstimateMailState } from '@/hooks/query';
interface EstimateSendMailBootValues {
estimateId: number;
estimateMailState: GetSaleEstimateDefaultOptionsResponse | undefined;
estimateMailState: any;
isEstimateMailState: boolean;
}
interface EstimateSendMailBootProps {
@@ -15,7 +16,9 @@ interface EstimateSendMailBootProps {
const EstimateSendMailContentBootContext =
createContext<EstimateSendMailBootValues>({} as EstimateSendMailBootValues);
export const EstimateSendMailBoot = ({ children }: EstimateSendMailBootProps) => {
export const EstimateSendMailBoot = ({
children,
}: EstimateSendMailBootProps) => {
const {
payload: { estimateId },
} = useDrawerContext();

View File

@@ -1,9 +1,24 @@
import { Classes } from '@blueprintjs/core';
import { EstimateSendMailBoot } from './EstimateSendMailBoot';
import { Stack } from '@/components';
import { EstimateSendMailForm } from './EstimateSendMailForm';
import { SendMailViewHeader } from '../SendMailViewDrawer/SendMailViewHeader';
import { SendMailViewLayout } from '../SendMailViewDrawer/SendMailViewLayout';
import { EstimateSendMailFields } from './EstimateSnedMailFields';
import { EstimateSendMailPreviewTabs } from './EstimateSendMailPreview';
export function EstimateSendMailContent() {
return (
<Stack className={Classes.DRAWER_BODY}>
<EstimateSendMailBoot>
<EstimateSendMailForm>
<SendMailViewLayout
header={<SendMailViewHeader label={'Send Estimate Mail'} />}
fields={<EstimateSendMailFields />}
preview={<EstimateSendMailPreviewTabs />}
/>
</EstimateSendMailForm>
</EstimateSendMailBoot>
</Stack>
);
}
}

View File

@@ -4,9 +4,9 @@ import * as R from 'ramda';
import { Drawer, DrawerSuspense } from '@/components';
import withDrawers from '@/containers/Drawer/withDrawers';
const EstimateSendMailDrawerProps = React.lazy(() =>
const EstimateSendMailContent = React.lazy(() =>
import('./EstimateSendMailContent').then((module) => ({
default: module.InvoiceSendMailContent,
default: module.EstimateSendMailContent,
})),
);
@@ -31,7 +31,7 @@ function EstimateSendMailDrawerRoot({
size={'calc(100% - 10px)'}
>
<DrawerSuspense>
<EstimateSendMailDrawerProps />
<EstimateSendMailContent />
</DrawerSuspense>
</Drawer>
);

View File

@@ -1,17 +1,17 @@
// @ts-nocheck
import { Form, Formik, FormikHelpers } from 'formik';
import { css } from '@emotion/css';
import { Intent } from '@blueprintjs/core';
import { InvoiceSendMailFormValues } from './_types';
import { InvoiceSendMailFormSchema } from './InvoiceSendMailForm.schema';
import { useSendSaleInvoiceMail } from '@/hooks/query';
import { EstimateSendMailFormValues } from './_interfaces';
import { EstimateSendMailSchema } from './EstimateSendMail.schema';
import { useSendSaleEstimateMail } from '@/hooks/query';
import { AppToaster } from '@/components';
import { useInvoiceSendMailBoot } from './InvoiceSendMailContentBoot';
import { useDrawerActions } from '@/hooks/state';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { transformToForm } from '@/utils';
import { useEstimateSendMailBoot } from './EstimateSendMailBoot';
const initialValues: InvoiceSendMailFormValues = {
const initialValues: EstimateSendMailFormValues = {
subject: '',
message: '',
to: [],
@@ -20,27 +20,27 @@ const initialValues: InvoiceSendMailFormValues = {
attachPdf: true,
};
interface InvoiceSendMailFormProps {
interface EstimateSendMailFormProps {
children: React.ReactNode;
}
export function EstimateSendMailForm({ children }: InvoiceSendMailFormProps) {
const { mutateAsync: sendInvoiceMail } = useSendSaleInvoiceMail();
export function EstimateSendMailForm({ children }: EstimateSendMailFormProps) {
const { mutateAsync: sendEstimateMail } = useSendSaleEstimateMail();
const { estimateId, estimateMailState } = useEstimateSendMailBoot();
const { name } = useDrawerContext();
const { closeDrawer } = useDrawerActions();
const _initialValues: InvoiceSendMailFormValues = {
const _initialValues: EstimateSendMailFormValues = {
...initialValues,
...transformToForm(invoiceMailState, initialValues),
...transformToForm(estimateMailState, initialValues),
};
const handleSubmit = (
values: InvoiceSendMailFormValues,
{ setSubmitting }: FormikHelpers<InvoiceSendMailFormValues>,
values: EstimateSendMailFormValues,
{ setSubmitting }: FormikHelpers<EstimateSendMailFormValues>,
) => {
setSubmitting(true);
sendInvoiceMail({ id: invoiceId, values: { ...values } })
sendEstimateMail({ id: estimateId, values: { ...values } })
.then(() => {
AppToaster.show({
message: 'The invoice mail has been sent to the customer.',
@@ -61,7 +61,7 @@ export function EstimateSendMailForm({ children }: InvoiceSendMailFormProps) {
return (
<Formik
initialValues={_initialValues}
validationSchema={InvoiceSendMailFormSchema}
validationSchema={EstimateSendMailSchema}
onSubmit={handleSubmit}
>
<Form

View File

@@ -0,0 +1,7 @@
export function EstimateSendMailPreviewTabs() {
return (
<h1>asdfsdf</h1>
)
}

View File

@@ -0,0 +1,74 @@
import { FCheckbox, FFormGroup, FInputGroup, Group, Stack } from "@/components";
import { SendMailViewToAddressField } from "../SendMailViewDrawer/SendMailViewToAddressField";
import { SendMailViewMessageField } from "../SendMailViewDrawer/SendMailViewMessageField";
import { Button, Intent } from "@blueprintjs/core";
import { useFormikContext } from "formik";
import { useDrawerContext } from "@/components/Drawer/DrawerProvider";
import { useDrawerActions } from "@/hooks/state";
const items: Array<any> = [];
const argsOptions: Array<any> = [];
export function EstimateSendMailFields() {
return (
<Stack>
<Stack spacing={0} overflow="auto" flex="1" p={'30px'}>
<SendMailViewToAddressField
toMultiSelectProps={{ items }}
ccMultiSelectProps={{ items }}
bccMultiSelectProps={{ items }}
/>
<FFormGroup label={'Submit'} name={'subject'}>
<FInputGroup name={'subject'} large fastField />
</FFormGroup>
<SendMailViewMessageField argsOptions={argsOptions} />
<Group>
<FCheckbox name={'attachPdf'} label={'Attach PDF'} />
</Group>
</Stack>
<EstimateSendMailFooter />
</Stack>
);
}
function EstimateSendMailFooter() {
const { isSubmitting } = useFormikContext();
const { name } = useDrawerContext();
const { closeDrawer } = useDrawerActions();
const handleClose = () => {
closeDrawer(name);
};
return (
<Group
py={'12px'}
px={'16px'}
borderTop="1px solid #d8d8d9"
position={'apart'}
>
<Group spacing={10} ml={'auto'}>
<Button
disabled={isSubmitting}
onClick={handleClose}
style={{ minWidth: '65px' }}
>
Close
</Button>
<Button
intent={Intent.PRIMARY}
loading={isSubmitting}
style={{ minWidth: '85px' }}
type="submit"
>
Send Mail
</Button>
</Group>
</Group>
);
}

View File

@@ -0,0 +1 @@
export * from './EstimateSendMailDrawer';

View File

@@ -107,7 +107,7 @@ function EstimatesDataTable({
// Handle mail send estimate.
const handleMailSendEstimate = ({ id }) => {
openDialog(DialogsName.EstimateMail, { estimateId: id });
openDrawer(DRAWERS.ESTIMATE_SEND_MAIL, { estimateId: id });
}
// Local storage memorizing columns widths.

View File

@@ -0,0 +1,37 @@
import { Group, Stack } from '@/components';
import React from 'react';
interface SendMailViewLayoutProps {
header?: React.ReactNode;
fields?: React.ReactNode;
preview?: React.ReactNode;
}
export function SendMailViewLayout({
header,
fields,
preview,
}: SendMailViewLayoutProps) {
return (
<Stack spacing={0} flex={1} overflow="hidden">
{header}
<Group flex={1} overflow="auto" spacing={0} alignItems={'stretch'}>
<Stack
bg="white"
flex={'1'}
maxWidth="720px"
maxHeight="100%"
spacing={0}
borderRight="1px solid #dcdcdd"
>
{fields}
</Stack>
<Stack bg="#F5F5F5" flex={'1'} maxHeight={'100%'} minWidth="850px">
{preview}
</Stack>
</Group>
</Stack>
);
}

View File

@@ -1,14 +1,13 @@
// @ts-nocheck
import { useCallback, useRef } from 'react';
import { useFormikContext } from 'formik';
import { Button, Icon, Position } from '@blueprintjs/core';
import { SelectOptionProps } from '@blueprintjs-formik/select';
import { FormGroupProps, TextAreaProps } from '@blueprintjs-formik/core';
import { css } from '@emotion/css';
import { FFormGroup, FSelect, FTextArea, Group, Stack } from '@/components';
import { useCallback, useRef } from 'react';
import { InvoiceSendMailFormValues } from '../../Invoices/InvoiceSendMailDrawer/_types';
interface SendMailViewMessageFieldProps {
argsOptions?: Array<SelectOptionProps>;
formGroupProps?: Partial<FormGroupProps>;

View File

@@ -0,0 +1,9 @@
export function SendMailViewPreview() {
return (
<h1>asdasd</h1>
)
}

View File

@@ -1,6 +1,5 @@
import { css } from '@emotion/css';
import { Tabs } from '@blueprintjs/core';
import { Stack } from '@/components';
interface SendMailViewPreviewTabsProps {
children: React.ReactNode;
@@ -10,11 +9,10 @@ export function SendMailViewPreviewTabs({
children,
}: SendMailViewPreviewTabsProps) {
return (
<Stack bg="#F5F5F5" flex={'1'} maxHeight={'100%'} minWidth="850px">
<Tabs
id={'preview'}
defaultSelectedTabId={'payment-page'}
className={css`
<Tabs
id={'preview'}
defaultSelectedTabId={'payment-page'}
className={css`
overflow: hidden;
flex: 1 1;
display: flex;
@@ -39,9 +37,8 @@ export function SendMailViewPreviewTabs({
overflow: auto;
}
`}
>
{children}
</Tabs>
</Stack>
>
{children}
</Tabs>
);
}

View File

@@ -1,3 +1,4 @@
// @ts-nocheck
import { useMemo, useState } from 'react';
import { Button, MenuItem } from '@blueprintjs/core';
import { SelectOptionProps } from '@blueprintjs-formik/select';

View File

@@ -5,20 +5,18 @@ import { InvoiceSendMailForm } from './InvoiceSendMailForm';
import { InvoiceSendMailPreview } from './InvoiceSendMailPreview';
import { InvoiceSendMailFields } from './InvoiceSendMailFields';
import { SendMailViewHeader } from '../../Estimates/SendMailViewDrawer/SendMailViewHeader';
import { SendMailViewLayout } from '../../Estimates/SendMailViewDrawer/SendMailViewLayout';
export function InvoiceSendMailContent() {
return (
<Stack className={Classes.DRAWER_BODY}>
<InvoiceSendMailBoot>
<InvoiceSendMailForm>
<Stack spacing={0} flex={1} overflow="hidden">
<SendMailViewHeader label={'Send Invoice Mail'} />
<Group flex={1} overflow="auto" spacing={0} alignItems={'stretch'}>
<InvoiceSendMailFields />
<InvoiceSendMailPreview />
</Group>
</Stack>
<SendMailViewLayout
header={<SendMailViewHeader label={'Send Invoice Mail'} />}
fields={<InvoiceSendMailFields />}
preview={<InvoiceSendMailPreview />}
/>
</InvoiceSendMailForm>
</InvoiceSendMailBoot>
</Stack>

View File

@@ -1,34 +1,19 @@
// @ts-nocheck
import { Button, Intent, MenuItem, Position } from '@blueprintjs/core';
import { useRef, useState, useMemo, useCallback } from 'react';
import { Button, Intent } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { SelectOptionProps } from '@blueprintjs-formik/select';
import { css } from '@emotion/css';
import {
FCheckbox,
FFormGroup,
FInputGroup,
Group,
Stack,
} from '@/components';
import { FCheckbox, FFormGroup, FInputGroup, Group, Stack } from '@/components';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useDrawerActions } from '@/hooks/state';
import { useInvoiceMailItems, } from './_hooks';
import { useInvoiceMailItems, useSendInvoiceFormatArgsOptions } from './_hooks';
import { SendMailViewToAddressField } from '../../Estimates/SendMailViewDrawer/SendMailViewToAddressField';
import { SendMailViewMessageField } from '../../Estimates/SendMailViewDrawer/SendMailViewMessageField';
export function InvoiceSendMailFields() {
const items = useInvoiceMailItems();
const argsOptions = useSendInvoiceFormatArgsOptions();
return (
<Stack
bg="white"
flex={'1'}
maxWidth="720px"
maxHeight="100%"
spacing={0}
borderRight="1px solid #dcdcdd"
>
<Stack>
<Stack spacing={0} overflow="auto" flex="1" p={'30px'}>
<SendMailViewToAddressField
toMultiSelectProps={{ items }}
@@ -39,7 +24,7 @@ export function InvoiceSendMailFields() {
<FInputGroup name={'subject'} large fastField />
</FFormGroup>
<SendMailViewMessageField />
<SendMailViewMessageField argsOptions={argsOptions} />
<Group>
<FCheckbox name={'attachPdf'} label={'Attach PDF'} />