mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
feat: wip estimate send mail
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import { Spinner } from '@blueprintjs/core';
|
||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { useSaleEstimateMailState } from '@/hooks/query';
|
||||
import { SaleEstimateMailStateResponse, useSaleEstimateMailState } from '@/hooks/query';
|
||||
|
||||
interface EstimateSendMailBootValues {
|
||||
estimateId: number;
|
||||
|
||||
estimateMailState: any;
|
||||
estimateMailState: SaleEstimateMailStateResponse | undefined;
|
||||
isEstimateMailState: boolean;
|
||||
}
|
||||
interface EstimateSendMailBootProps {
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
import { useFormikContext } from 'formik';
|
||||
import { SendViewPreviewHeader } from '../SendMailViewDrawer/SendMailViewPreviewHeader';
|
||||
import { useEstimateSendMailBoot } from './EstimateSendMailBoot';
|
||||
import { useSendEstimateMailSubject } from './hooks';
|
||||
import { EstimateSendMailFormValues } from './_interfaces';
|
||||
|
||||
export function EstimateSendMailPreviewHeader() {
|
||||
const subject = useSendEstimateMailSubject();
|
||||
const { estimateMailState } = useEstimateSendMailBoot();
|
||||
const {
|
||||
values: { to, from },
|
||||
} = useFormikContext<EstimateSendMailFormValues>();
|
||||
|
||||
return (
|
||||
<SendViewPreviewHeader
|
||||
companyName="A"
|
||||
customerName="A"
|
||||
subject={'adsfsdf'}
|
||||
from={['a.bouhuolia@gmail.com']}
|
||||
to={['a.bouhuolia@gmail.com']}
|
||||
companyName={estimateMailState?.companyName}
|
||||
customerName={estimateMailState?.customerName}
|
||||
subject={subject}
|
||||
from={from}
|
||||
to={to}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { useFormikContext } from 'formik';
|
||||
import { Button, Intent } from '@blueprintjs/core';
|
||||
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 { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||
import { useDrawerActions } from '@/hooks/state';
|
||||
import { useSendEstimateFormatArgsOptions } from './hooks';
|
||||
import { useSendMailItems } from '../SendMailViewDrawer/hooks';
|
||||
|
||||
const items: Array<any> = [];
|
||||
const argsOptions: Array<any> = [];
|
||||
|
||||
export function EstimateSendMailFields() {
|
||||
const argOptions = useSendEstimateFormatArgsOptions();
|
||||
const items = useSendMailItems();
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Stack flex={1}>
|
||||
<Stack spacing={0} overflow="auto" flex="1" p={'30px'}>
|
||||
<SendMailViewToAddressField
|
||||
toMultiSelectProps={{ items }}
|
||||
@@ -22,7 +25,7 @@ export function EstimateSendMailFields() {
|
||||
<FInputGroup name={'subject'} large fastField />
|
||||
</FFormGroup>
|
||||
|
||||
<SendMailViewMessageField argsOptions={argsOptions} />
|
||||
<SendMailViewMessageField argsOptions={argOptions} />
|
||||
|
||||
<Group>
|
||||
<FCheckbox name={'attachPdf'} label={'Attach PDF'} />
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
export interface EstimateSendMailFormValues {}
|
||||
import { SendMailViewFormValues } from '../SendMailViewDrawer/_types';
|
||||
|
||||
export interface EstimateSendMailFormValues extends SendMailViewFormValues {
|
||||
attachPdf?: boolean;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { useMemo } from 'react';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { SelectOptionProps } from '@blueprintjs-formik/select';
|
||||
import { useEstimateSendMailBoot } from './EstimateSendMailBoot';
|
||||
import {
|
||||
formatMailMessage,
|
||||
transformEmailArgs,
|
||||
transformFormatArgsToOptions,
|
||||
} from '../SendMailViewDrawer/hooks';
|
||||
import { EstimateSendMailFormValues } from './_interfaces';
|
||||
|
||||
/**
|
||||
* Retrieves the mail format arguments of estimate mail.
|
||||
* @returns {Record<string, string>}
|
||||
*/
|
||||
export const useSendEstimateMailFormatArgs = (): Record<string, string> => {
|
||||
const { estimateMailState } = useEstimateSendMailBoot();
|
||||
|
||||
return useMemo(() => {
|
||||
return transformEmailArgs(estimateMailState?.formatArgs || {});
|
||||
}, [estimateMailState]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the formatted estimate subject.
|
||||
* @returns {string}
|
||||
*/
|
||||
export const useSendEstimateMailSubject = (): string => {
|
||||
const { values } = useFormikContext<EstimateSendMailFormValues>();
|
||||
const formatArgs = useSendEstimateMailFormatArgs();
|
||||
|
||||
return formatMailMessage(values?.subject, formatArgs);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the estimate format options.
|
||||
* @returns {Array<SelectOptionProps>}
|
||||
*/
|
||||
export const useSendEstimateFormatArgsOptions =
|
||||
(): Array<SelectOptionProps> => {
|
||||
const formatArgs = useSendEstimateMailFormatArgs();
|
||||
|
||||
return transformFormatArgsToOptions(formatArgs);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the formatted estimate message.
|
||||
* @returns {string}
|
||||
*/
|
||||
export const useSendEstimateMailMessage = (): string => {
|
||||
const { values } = useFormikContext<EstimateSendMailFormValues>();
|
||||
const formatArgs = useSendEstimateMailFormatArgs();
|
||||
|
||||
return formatMailMessage(values?.message, formatArgs);
|
||||
};
|
||||
@@ -1 +1,8 @@
|
||||
export interface SendMailViewFormValues {}
|
||||
export interface SendMailViewFormValues {
|
||||
from: Array<string>;
|
||||
to: Array<string>;
|
||||
cc: Array<string>;
|
||||
bcc: Array<string>;
|
||||
subject: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { useFormikContext } from 'formik';
|
||||
import { chain, defaultTo, mapKeys, snakeCase, startCase } from 'lodash';
|
||||
import { SendMailViewFormValues } from './_types';
|
||||
|
||||
export const useSendInvoiceMailForm = () => {
|
||||
return useFormikContext<SendMailViewFormValues>();
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the suggest items of to, cc and bcc fields.
|
||||
* @returns {Array<{ value: string, text: string }>}
|
||||
*/
|
||||
export const useSendMailItems = (): Array<{ value: string; text: string }> => {
|
||||
const { values } = useSendInvoiceMailForm();
|
||||
const cc = values?.cc || [];
|
||||
const bcc = values?.bcc || [];
|
||||
|
||||
return chain([...values?.to, ...cc, ...bcc])
|
||||
.filter((email) => !!email?.trim())
|
||||
.uniq()
|
||||
.map((email) => ({
|
||||
value: email,
|
||||
text: email,
|
||||
}))
|
||||
.value();
|
||||
};
|
||||
|
||||
export const transformEmailArgs = (formatArgs: Record<string, string>) => {
|
||||
return mapKeys(formatArgs, (_, key) =>
|
||||
startCase(snakeCase(key).replace('_', ' ')),
|
||||
);
|
||||
};
|
||||
|
||||
export const transformFormatArgsToOptions = (
|
||||
formatArgs: Record<string, string>,
|
||||
) => {
|
||||
return Object.keys(formatArgs).map((key) => ({
|
||||
value: key,
|
||||
text: key,
|
||||
}));
|
||||
};
|
||||
|
||||
export const formatMailMessage = (
|
||||
message: string,
|
||||
args: Record<string, any>,
|
||||
) => {
|
||||
let formattedMessage = message;
|
||||
|
||||
Object.keys(args).forEach((key) => {
|
||||
const variable = `{${key}}`;
|
||||
const value = defaultTo(args[key], '');
|
||||
|
||||
formattedMessage = formattedMessage.replace(variable, value);
|
||||
});
|
||||
return formattedMessage;
|
||||
};
|
||||
@@ -1,5 +1,11 @@
|
||||
// @ts-nocheck
|
||||
import { useQueryClient, useMutation, useQuery } from 'react-query';
|
||||
import {
|
||||
useQueryClient,
|
||||
useMutation,
|
||||
useQuery,
|
||||
UseQueryOptions,
|
||||
UseQueryResult,
|
||||
} from 'react-query';
|
||||
import { useRequestQuery } from '../useQueryRequest';
|
||||
import useApiRequest from '../useRequest';
|
||||
import { transformPagination, transformToCamelCase } from '@/utils';
|
||||
@@ -257,13 +263,36 @@ export function useSendSaleEstimateMail(props = {}) {
|
||||
);
|
||||
}
|
||||
|
||||
export interface SaleEstimateMailStateResponse {
|
||||
attachEstimate: boolean;
|
||||
companyLogoUri: string;
|
||||
companyName: string;
|
||||
customerName: string;
|
||||
entries: Array<any>;
|
||||
estimateDate: string;
|
||||
formatArgs: {
|
||||
customerName: string;
|
||||
estimateAmount: string;
|
||||
};
|
||||
formattedEstimateDate: string;
|
||||
from: Array<string>;
|
||||
fromOptions: Array<any>;
|
||||
message: string;
|
||||
subject: string;
|
||||
to: Array<string>;
|
||||
toOptions: Array<any>;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Retrieves the sale estimate mail state.
|
||||
* @param {number} estimateId
|
||||
* @param props
|
||||
* @returns
|
||||
* @param {UseQueryOptions<SaleEstimateMailStateResponse, Error>} props
|
||||
* @returns {UseQueryResult<SaleEstimateMailStateResponse, Error>}
|
||||
*/
|
||||
export function useSaleEstimateMailState(estimateId: number, props?= {}) {
|
||||
export function useSaleEstimateMailState(
|
||||
estimateId: number,
|
||||
props?: UseQueryOptions<SaleEstimateMailStateResponse, Error>,
|
||||
): UseQueryResult<SaleEstimateMailStateResponse, Error> {
|
||||
const apiRequest = useApiRequest();
|
||||
return useQuery([t.SALE_ESTIMATE_MAIL_OPTIONS, estimateId], () =>
|
||||
apiRequest
|
||||
|
||||
Reference in New Issue
Block a user