feat: hook up the invice customize api

This commit is contained in:
Ahmed Bouhuolia
2024-09-12 14:16:07 +02:00
parent a7df23cebc
commit 632c4629de
21 changed files with 391 additions and 169 deletions

View File

@@ -26,20 +26,21 @@ export class PdfTemplatesController extends BaseController {
'/:template_id', '/:template_id',
[ [
param('template_id').exists().isInt().toInt(), param('template_id').exists().isInt().toInt(),
check('template_name').exists(),
check('attributes').exists(), check('attributes').exists(),
], ],
this.validationResult, this.validationResult,
this.editPdfTemplate.bind(this) this.editPdfTemplate.bind(this)
); );
router.get('/', this.getPdfTemplates.bind(this));
router.get( router.get(
'/:template_id', '/:template_id',
[param('template_id').exists().isInt().toInt()], [param('template_id').exists().isInt().toInt()],
this.validationResult, this.validationResult,
this.getPdfTemplate.bind(this) this.getPdfTemplate.bind(this)
); );
router.get('/', this.getPdfTemplates.bind(this));
router.post( router.post(
'/invoices', '/',
[check('template_name').exists(), check('attributes').exists()], [check('template_name').exists(), check('attributes').exists()],
this.validationResult, this.validationResult,
this.createPdfInvoiceTemplate.bind(this) this.createPdfInvoiceTemplate.bind(this)
@@ -70,13 +71,13 @@ export class PdfTemplatesController extends BaseController {
async editPdfTemplate(req: Request, res: Response, next: NextFunction) { async editPdfTemplate(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req; const { tenantId } = req;
const { template_id: templateId } = req.params; const { template_id: templateId } = req.params;
const { attributes } = this.matchedBodyData(req); const editTemplateDTO = this.matchedBodyData(req);
try { try {
const result = await this.pdfTemplateApplication.editPdfTemplate( const result = await this.pdfTemplateApplication.editPdfTemplate(
tenantId, tenantId,
Number(templateId), Number(templateId),
attributes editTemplateDTO
); );
return res.status(200).send(result); return res.status(200).send(result);
} catch (error) { } catch (error) {

View File

@@ -30,11 +30,14 @@ export class EditPdfTemplate {
const { PdfTemplate } = this.tenancy.models(tenantId); const { PdfTemplate } = this.tenancy.models(tenantId);
return this.uow.withTransaction(tenantId, async (trx) => { return this.uow.withTransaction(tenantId, async (trx) => {
await PdfTemplate.query(trx) await this.eventPublisher.emitAsync(events.pdfTemplate.onEditing, {
.patch({ tenantId,
...editTemplateDTO, templateId,
}) });
.where('id', templateId); await PdfTemplate.query(trx).where('id', templateId).update({
templateName: editTemplateDTO.templateName,
attributes: editTemplateDTO.attributes,
});
await this.eventPublisher.emitAsync(events.pdfTemplate.onEdited, { await this.eventPublisher.emitAsync(events.pdfTemplate.onEdited, {
tenantId, tenantId,

View File

@@ -1,7 +1,14 @@
// @ts-nocheck // @ts-nocheck
import React, { createContext, useContext } from 'react'; import React, { createContext, useContext } from 'react';
const DrawerContext = createContext(); interface DrawerContextValue {
name: string;
payload: Record<string, any>;
}
const DrawerContext = createContext<DrawerContextValue>(
{} as DrawerContextValue,
);
/** /**
* Account form provider. * Account form provider.

View File

@@ -47,7 +47,7 @@ export function ElementCustomizeFieldsMain() {
function ElementCustomizeFooterActionsRoot({ closeDrawer }) { function ElementCustomizeFooterActionsRoot({ closeDrawer }) {
const { name } = useDrawerContext(); const { name } = useDrawerContext();
const { submitForm } = useFormikContext(); const { submitForm, isSubmitting } = useFormikContext();
const handleSubmitBtnClick = () => { const handleSubmitBtnClick = () => {
submitForm(); submitForm();
@@ -62,6 +62,7 @@ function ElementCustomizeFooterActionsRoot({ closeDrawer }) {
onClick={handleSubmitBtnClick} onClick={handleSubmitBtnClick}
intent={Intent.PRIMARY} intent={Intent.PRIMARY}
style={{ minWidth: 75 }} style={{ minWidth: 75 }}
loading={isSubmitting}
> >
Save Save
</Button> </Button>

View File

@@ -0,0 +1,50 @@
import React, { createContext, useContext } from 'react';
import {
GetPdfTemplateResponse,
useGetPdfTemplate,
} from '@/hooks/query/pdf-templates';
import { Spinner } from '@blueprintjs/core';
interface PdfTemplateContextValue {
templateId: number | string;
pdfTemplate: GetPdfTemplateResponse | undefined;
isPdfTemplateLoading: boolean;
}
interface BrandingTemplateProps {
templateId: number;
children: React.ReactNode;
}
const PdfTemplateContext = createContext<PdfTemplateContextValue>(
{} as PdfTemplateContextValue,
);
export const BrandingTemplateBoot = ({
templateId,
children,
}: BrandingTemplateProps) => {
const { data: pdfTemplate, isLoading: isPdfTemplateLoading } =
useGetPdfTemplate(templateId, {
enabled: !!templateId,
});
const value = {
templateId,
pdfTemplate,
isPdfTemplateLoading,
};
if (isPdfTemplateLoading) {
return <Spinner size={20} />
}
return (
<PdfTemplateContext.Provider value={value}>
{children}
</PdfTemplateContext.Provider>
);
};
export const useBrandingTemplateBoot = () => {
return useContext<PdfTemplateContextValue>(PdfTemplateContext);
};

View File

@@ -2,13 +2,7 @@
import * as R from 'ramda'; import * as R from 'ramda';
import { Button, Classes, Intent } from '@blueprintjs/core'; import { Button, Classes, Intent } from '@blueprintjs/core';
import { BrandingTemplatesBoot } from './BrandingTemplatesBoot'; import { BrandingTemplatesBoot } from './BrandingTemplatesBoot';
import { import { Box, Card, DrawerHeaderContent, Group } from '@/components';
Box,
Card,
DrawerBody,
DrawerHeaderContent,
Group,
} from '@/components';
import { DRAWERS } from '@/constants/drawers'; import { DRAWERS } from '@/constants/drawers';
import { BrandingTemplatesTable } from './BrandingTemplatesTable'; import { BrandingTemplatesTable } from './BrandingTemplatesTable';
import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import withDrawerActions from '@/containers/Drawer/withDrawerActions';

View File

@@ -18,7 +18,6 @@ function BrandingTemplateTableRoot({
}: BrandingTemplatesTableProps) { }: BrandingTemplatesTableProps) {
// Table columns. // Table columns.
const columns = useBrandingTemplatesColumns(); const columns = useBrandingTemplatesColumns();
const { isPdfTemplatesLoading, pdfTemplates } = useBrandingTemplatesBoot(); const { isPdfTemplatesLoading, pdfTemplates } = useBrandingTemplatesBoot();
const handleEditTemplate = (template) => { const handleEditTemplate = (template) => {
@@ -70,7 +69,7 @@ const useBrandingTemplatesColumns = () => {
Header: 'Template Name', Header: 'Template Name',
accessor: (row) => ( accessor: (row) => (
<Group spacing={10}> <Group spacing={10}>
{row.template_name} <Tag round>Default</Tag> {row.template_name} {row.default && <Tag round>Default</Tag>}
</Group> </Group>
), ),
width: 65, width: 65,

View File

@@ -1,98 +1,19 @@
import React from 'react'; // @ts-nocheck
import * as R from 'ramda'; import { Classes } from '@blueprintjs/core';
import { AppToaster, Box } from '@/components'; import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { Classes, Intent } from '@blueprintjs/core'; import { BrandingTemplateBoot } from '../BrandingTemplates/BrandingTemplateBoot';
import { useFormikContext } from 'formik'; import { InvoiceCustomizeContent } from './InvoiceCustomizeContent';
import { import { Box } from '@/components';
InvoicePaperTemplate,
InvoicePaperTemplateProps,
} from './InvoicePaperTemplate';
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
import { InvoiceCustomizeValues } from './types';
import { initialValues } from './constants';
import {
useCreatePdfTemplate,
useEditPdfTemplate,
} from '@/hooks/query/pdf-templates';
import { transformToEditRequest, transformToNewRequest } from './utils';
export default function InvoiceCustomizeContent() { export default function InvoiceCustomize() {
const { mutateAsync: createPdfTemplate } = useCreatePdfTemplate(); const { payload } = useDrawerContext();
const { mutateAsync: editPdfTemplate } = useEditPdfTemplate(); const templateId = payload.templateId;
const templateId: number = 1;
const handleFormSubmit = (values: InvoiceCustomizeValues) => {
const handleSuccess = (message: string) => {
AppToaster.show({
intent: Intent.SUCCESS,
message,
});
};
const handleError = (message: string) => {
AppToaster.show({
intent: Intent.DANGER,
message,
});
};
if (templateId) {
const reqValues = transformToEditRequest(values, templateId);
// Edit existing template
// editPdfTemplate({ templateId, values: reqValues })
// .then(() => handleSuccess('PDF template updated successfully!'))
// .catch(() =>
// handleError('An error occurred while updating the PDF template.'),
// );
} else {
const reqValues = transformToNewRequest(values);
// Create new template
createPdfTemplate(reqValues)
.then(() => handleSuccess('PDF template created successfully!'))
.catch(() =>
handleError('An error occurred while creating the PDF template.'),
);
}
};
return ( return (
<Box className={Classes.DRAWER_BODY}> <Box className={Classes.DRAWER_BODY}>
<ElementCustomize<InvoiceCustomizeValues> <BrandingTemplateBoot templateId={templateId}>
initialValues={initialValues} <InvoiceCustomizeContent />
onSubmit={handleFormSubmit} </BrandingTemplateBoot>
>
<ElementCustomize.PaperTemplate>
<InvoicePaperTemplateFormConnected />
</ElementCustomize.PaperTemplate>
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
<InvoiceCustomizeGeneralField />
</ElementCustomize.FieldsTab>
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
<InvoiceCustomizeContentFields />
</ElementCustomize.FieldsTab>
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
asdfasdfdsaf #3
</ElementCustomize.FieldsTab>
</ElementCustomize>
</Box> </Box>
); );
} }
const withFormikProps = <P extends object>(
Component: React.ComponentType<P>,
) => {
return (props: Omit<P, keyof InvoicePaperTemplateProps>) => {
const { values } = useFormikContext<InvoicePaperTemplateProps>();
return <Component {...(props as P)} {...values} />;
};
};
export const InvoicePaperTemplateFormConnected =
R.compose(withFormikProps)(InvoicePaperTemplate);

View File

@@ -0,0 +1,109 @@
import React from 'react';
import * as R from 'ramda';
import { AppToaster } from '@/components';
import { Intent } from '@blueprintjs/core';
import { FormikHelpers, useFormikContext } from 'formik';
import {
InvoicePaperTemplate,
InvoicePaperTemplateProps,
} from './InvoicePaperTemplate';
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
import { InvoiceCustomizeValues } from './types';
import {
useCreatePdfTemplate,
useEditPdfTemplate,
} from '@/hooks/query/pdf-templates';
import {
transformToEditRequest,
transformToNewRequest,
useInvoiceCustomizeInitialValues,
} from './utils';
import { InvoiceCustomizeSchema } from './InvoiceCustomizeForm.schema';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useDrawerActions } from '@/hooks/state';
export function InvoiceCustomizeContent() {
const { mutateAsync: createPdfTemplate } = useCreatePdfTemplate();
const { mutateAsync: editPdfTemplate } = useEditPdfTemplate();
const { payload, name } = useDrawerContext();
const { closeDrawer } = useDrawerActions();
const templateId = payload?.templateId || null;
const handleFormSubmit = (
values: InvoiceCustomizeValues,
{ setSubmitting }: FormikHelpers<InvoiceCustomizeValues>,
) => {
const handleSuccess = (message: string) => {
AppToaster.show({ intent: Intent.SUCCESS, message });
setSubmitting(false);
closeDrawer(name);
};
const handleError = (message: string) => {
AppToaster.show({ intent: Intent.DANGER, message });
setSubmitting(false);
};
if (templateId) {
const reqValues = transformToEditRequest(values);
setSubmitting(true);
// Edit existing template
editPdfTemplate({ templateId, values: reqValues })
.then(() => handleSuccess('PDF template updated successfully!'))
.catch(() =>
handleError('An error occurred while updating the PDF template.'),
);
} else {
const reqValues = transformToNewRequest(values);
setSubmitting(true);
// Create new template
createPdfTemplate(reqValues)
.then(() => handleSuccess('PDF template created successfully!'))
.catch(() =>
handleError('An error occurred while creating the PDF template.'),
);
}
};
const initialValues = useInvoiceCustomizeInitialValues();
return (
<ElementCustomize<InvoiceCustomizeValues>
initialValues={initialValues}
validationSchema={InvoiceCustomizeSchema}
onSubmit={handleFormSubmit}
>
<ElementCustomize.PaperTemplate>
<InvoicePaperTemplateFormConnected />
</ElementCustomize.PaperTemplate>
<ElementCustomize.FieldsTab id={'general'} label={'General'}>
<InvoiceCustomizeGeneralField />
</ElementCustomize.FieldsTab>
<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
<InvoiceCustomizeContentFields />
</ElementCustomize.FieldsTab>
<ElementCustomize.FieldsTab id={'totals'} label={'Totals'}>
asdfasdfdsaf #3
</ElementCustomize.FieldsTab>
</ElementCustomize>
);
}
const withFormikProps = <P extends object>(
Component: React.ComponentType<P>,
) => {
return (props: Omit<P, keyof InvoicePaperTemplateProps>) => {
const { values } = useFormikContext<InvoicePaperTemplateProps>();
return <Component {...(props as P)} {...values} />;
};
};
export const InvoicePaperTemplateFormConnected =
R.compose(withFormikProps)(InvoicePaperTemplate);

View File

@@ -4,9 +4,7 @@ import * as R from 'ramda';
import { Drawer, DrawerSuspense } from '@/components'; import { Drawer, DrawerSuspense } from '@/components';
import withDrawers from '@/containers/Drawer/withDrawers'; import withDrawers from '@/containers/Drawer/withDrawers';
const InvoiceCustomize = React.lazy( const InvoiceCustomize = React.lazy(() => import('./InvoiceCustomize'));
() => import('./InvoiceCustomize'),
);
/** /**
* Invoice customize drawer. * Invoice customize drawer.
@@ -16,10 +14,10 @@ function InvoiceCustomizeDrawerRoot({
name, name,
// #withDrawer // #withDrawer
isOpen, isOpen,
payload: {}, payload,
}) { }) {
return ( return (
<Drawer isOpen={isOpen} name={name} size={'100%'}> <Drawer isOpen={isOpen} name={name} size={'100%'} payload={payload}>
<DrawerSuspense> <DrawerSuspense>
<InvoiceCustomize /> <InvoiceCustomize />
</DrawerSuspense> </DrawerSuspense>

View File

@@ -0,0 +1,5 @@
import * as Yup from 'yup';
export const InvoiceCustomizeSchema = Yup.object().shape({
templateName: Yup.string().required('Template Name is required'),
});

View File

@@ -1,20 +1,42 @@
// @ts-nocheck // @ts-nocheck
import { Classes, Text } from '@blueprintjs/core'; import { Classes, Text } from '@blueprintjs/core';
import { FFormGroup, FSwitch, Group, Stack } from '@/components'; import {
FFormGroup,
FieldRequiredHint,
FInputGroup,
FSwitch,
Group,
Stack,
} from '@/components';
import { FColorInput } from '@/components/Forms/FColorInput'; import { FColorInput } from '@/components/Forms/FColorInput';
import { CreditCardIcon } from '@/icons/CreditCardIcon'; import { CreditCardIcon } from '@/icons/CreditCardIcon';
import { Overlay } from './Overlay';
import { useIsTemplateNamedFilled } from './utils';
export function InvoiceCustomizeGeneralField() { export function InvoiceCustomizeGeneralField() {
const isTemplateNameFilled = useIsTemplateNamedFilled();
return ( return (
<Stack style={{ padding: 20, flex: '1 1 auto' }}> <Stack style={{ padding: 20, flex: '1 1 auto' }}>
<Stack spacing={0}> <Stack spacing={0}>
<h2 style={{ fontSize: 16, marginBottom: 10 }}>General Branding</h2> <h2 style={{ fontSize: 16, marginBottom: 10 }}>General Branding</h2>
<p className={Classes.TEXT_MUTED}> <p className={Classes.TEXT_MUTED}>
Set your invoice details to be automatically applied every timeyou Set your invoice details to be automatically applied every timeyou
create a new invoice. create a new invoice.
</p> </p>
</Stack> </Stack>
<FFormGroup
name={'templateName'}
label={'Template Name'}
labelInfo={<FieldRequiredHint />}
fastField
style={{ marginBottom: 10 }}
>
<FInputGroup name={'templateName'} fastField />
</FFormGroup>
<Overlay visible={!isTemplateNameFilled}>
<Stack spacing={0}> <Stack spacing={0}>
<FFormGroup <FFormGroup
name={'primaryColor'} name={'primaryColor'}
@@ -56,6 +78,7 @@ export function InvoiceCustomizeGeneralField() {
</Stack> </Stack>
<InvoiceCustomizePaymentManage /> <InvoiceCustomizePaymentManage />
</Overlay>
</Stack> </Stack>
); );
} }

View File

@@ -16,7 +16,7 @@ export function InvoiceCustomizeContentFields() {
<Stack spacing={10}> <Stack spacing={10}>
<h3>General Branding</h3> <h3>General Branding</h3>
<p className={Classes.TEXT_MUTED}> <p className={Classes.TEXT_MUTED}>
Set your invoice details to be automatically applied every timeyou Set your invoice details to be automatically applied every timeyou
create a new invoice. create a new invoice.
</p> </p>
</Stack> </Stack>

View File

@@ -0,0 +1,19 @@
.root {
position: relative;
&.visible::before{
background: rgba(255, 255, 255, 0.75);
z-index: 2;
}
&::before{
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1000;
}
}

View File

@@ -0,0 +1,20 @@
import clsx from 'classnames';
import { Box } from '@/components';
import styles from './Overlay.module.scss';
export interface OverlayProps {
visible?: boolean;
children?: React.ReactNode;
}
export function Overlay({ children, visible }: OverlayProps) {
return (
<Box
className={clsx(styles.root, {
[styles.visible]: visible,
})}
>
{children}
</Box>
);
}

View File

@@ -1,4 +1,6 @@
export const initialValues = { export const initialValues = {
templateName: '',
// Colors // Colors
primaryColor: '#2c3dd8', primaryColor: '#2c3dd8',
secondaryColor: '#2c3dd8', secondaryColor: '#2c3dd8',

View File

@@ -1,4 +1,6 @@
export interface InvoiceCustomizeValues { export interface InvoiceCustomizeValues {
templateName: string;
// Colors // Colors
primaryColor?: string; primaryColor?: string;
secondaryColor?: string; secondaryColor?: string;

View File

@@ -1,14 +1,19 @@
import { omit } from 'lodash'; import { omit } from 'lodash';
import { useFormikContext } from 'formik';
import { InvoiceCustomizeValues } from './types'; import { InvoiceCustomizeValues } from './types';
import { CreatePdfTemplateValues, EditPdfTemplateValues } from '@/hooks/query/pdf-templates'; import {
CreatePdfTemplateValues,
EditPdfTemplateValues,
} from '@/hooks/query/pdf-templates';
import { useBrandingTemplateBoot } from '../BrandingTemplates/BrandingTemplateBoot';
import { transformToForm } from '@/utils';
import { initialValues } from './constants';
export const transformToEditRequest = ( export const transformToEditRequest = (
values: InvoiceCustomizeValues, values: InvoiceCustomizeValues,
templateId: number,
): EditPdfTemplateValues => { ): EditPdfTemplateValues => {
return { return {
templateId, templateName: values.templateName,
templateName: 'Template Name',
attributes: omit(values, ['templateName']), attributes: omit(values, ['templateName']),
}; };
}; };
@@ -18,7 +23,29 @@ export const transformToNewRequest = (
): CreatePdfTemplateValues => { ): CreatePdfTemplateValues => {
return { return {
resource: 'SaleInvoice', resource: 'SaleInvoice',
templateName: 'Template Name', templateName: values.templateName,
attributes: omit(values, ['templateName']), attributes: omit(values, ['templateName']),
}; };
}; };
export const useIsTemplateNamedFilled = () => {
const { values } = useFormikContext<InvoiceCustomizeValues>();
return values.templateName && values.templateName?.length >= 4;
};
export const useInvoiceCustomizeInitialValues = (): InvoiceCustomizeValues => {
const { pdfTemplate } = useBrandingTemplateBoot();
const defaultPdfTemplate = {
templateName: pdfTemplate?.templateName,
...pdfTemplate?.attributes,
};
return {
...initialValues,
...(transformToForm(
defaultPdfTemplate,
initialValues,
) as InvoiceCustomizeValues),
};
};

View File

@@ -190,7 +190,7 @@ function InvoiceActionsBar({
<Menu> <Menu>
<MenuItem <MenuItem
onClick={handleCustomizeBtnClick} onClick={handleCustomizeBtnClick}
text={'Customize Invoice'} text={'Invoice Templates'}
/> />
</Menu> </Menu>
} }

View File

@@ -6,8 +6,12 @@ import {
UseQueryOptions, UseQueryOptions,
UseMutationResult, UseMutationResult,
UseQueryResult, UseQueryResult,
useQueryClient,
} from 'react-query'; } from 'react-query';
import useApiRequest from '../useRequest'; import useApiRequest from '../useRequest';
import { transformToCamelCase, transfromToSnakeCase } from '@/utils';
const PdfTemplatesQueryKey = 'PdfTemplate';
export interface CreatePdfTemplateValues { export interface CreatePdfTemplateValues {
templateName: string; templateName: string;
@@ -18,7 +22,6 @@ export interface CreatePdfTemplateValues {
export interface CreatePdfTemplateResponse {} export interface CreatePdfTemplateResponse {}
export interface EditPdfTemplateValues { export interface EditPdfTemplateValues {
templateId: string | number;
templateName: string; templateName: string;
attributes: Record<string, any>; attributes: Record<string, any>;
} }
@@ -33,7 +36,14 @@ export interface DeletePdfTemplateResponse {}
export interface GetPdfTemplateValues {} export interface GetPdfTemplateValues {}
export interface GetPdfTemplateResponse {} export interface GetPdfTemplateResponse {
templateName: string;
attributes: Record<string, any>;
predefined: boolean;
default: boolean;
createdAt: string;
updatedAt: string | null;
}
export interface GetPdfTemplatesValues {} export interface GetPdfTemplatesValues {}
@@ -52,10 +62,18 @@ export const useCreatePdfTemplate = (
CreatePdfTemplateValues CreatePdfTemplateValues
> => { > => {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
const queryClient = useQueryClient();
return useMutation<CreatePdfTemplateResponse, Error, CreatePdfTemplateValues>( return useMutation<CreatePdfTemplateResponse, Error, CreatePdfTemplateValues>(
(values) => (values) =>
apiRequest.post('/pdf-templates', values).then((res) => res.data), apiRequest
options, .post('/pdf-templates', transfromToSnakeCase(values))
.then((res) => res.data),
{
onSuccess: () => {
queryClient.invalidateQueries([PdfTemplatesQueryKey]);
},
...options,
},
); );
}; };
@@ -71,6 +89,7 @@ export const useEditPdfTemplate = (
Error, Error,
{ templateId: number; values: EditPdfTemplateValues } { templateId: number; values: EditPdfTemplateValues }
> => { > => {
const queryClient = useQueryClient();
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
return useMutation< return useMutation<
EditPdfTemplateResponse, EditPdfTemplateResponse,
@@ -79,9 +98,14 @@ export const useEditPdfTemplate = (
>( >(
({ templateId, values }) => ({ templateId, values }) =>
apiRequest apiRequest
.put(`/pdf-templates/${templateId}`, values) .put(`/pdf-templates/${templateId}`, transfromToSnakeCase(values))
.then((res) => res.data), .then((res) => res.data),
options, {
onSuccess: () => {
queryClient.invalidateQueries([PdfTemplatesQueryKey]);
},
...options,
},
); );
}; };
@@ -98,10 +122,16 @@ export const useDeletePdfTemplate = (
{ templateId: number } { templateId: number }
> => { > => {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
const queryClient = useQueryClient();
return useMutation<DeletePdfTemplateResponse, Error, { templateId: number }>( return useMutation<DeletePdfTemplateResponse, Error, { templateId: number }>(
({ templateId }) => ({ templateId }) =>
apiRequest.delete(`/pdf-templates/${templateId}`).then((res) => res.data), apiRequest.delete(`/pdf-templates/${templateId}`).then((res) => res.data),
options, {
onSuccess: () => {
queryClient.invalidateQueries([PdfTemplatesQueryKey]);
},
...options,
},
); );
}; };
@@ -112,9 +142,11 @@ export const useGetPdfTemplate = (
): UseQueryResult<GetPdfTemplateResponse, Error> => { ): UseQueryResult<GetPdfTemplateResponse, Error> => {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
return useQuery<GetPdfTemplateResponse, Error>( return useQuery<GetPdfTemplateResponse, Error>(
['pdfTemplate', templateId], [PdfTemplatesQueryKey, templateId],
() => () =>
apiRequest.get(`/pdf-templates/${templateId}`).then((res) => res.data), apiRequest
.get(`/pdf-templates/${templateId}`)
.then((res) => transformToCamelCase(res.data)),
options, options,
); );
}; };
@@ -125,7 +157,7 @@ export const useGetPdfTemplates = (
): UseQueryResult<GetPdfTemplatesResponse, Error> => { ): UseQueryResult<GetPdfTemplatesResponse, Error> => {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
return useQuery<GetPdfTemplatesResponse, Error>( return useQuery<GetPdfTemplatesResponse, Error>(
'pdfTemplates', PdfTemplatesQueryKey,
() => apiRequest.get('/pdf-templates').then((res) => res.data), () => apiRequest.get('/pdf-templates').then((res) => res.data),
options, options,
); );

View File

@@ -10,6 +10,8 @@ import {
closeSidebarSubmenu, closeSidebarSubmenu,
openDialog, openDialog,
closeDialog, closeDialog,
openDrawer,
closeDrawer,
} from '@/store/dashboard/dashboard.actions'; } from '@/store/dashboard/dashboard.actions';
export const useDispatchAction = (action) => { export const useDispatchAction = (action) => {
@@ -77,3 +79,10 @@ export const useDialogActions = () => {
closeDialog: useDispatchAction(closeDialog), closeDialog: useDispatchAction(closeDialog),
}; };
}; };
export const useDrawerActions = () => {
return {
openDrawer: useDispatchAction(openDrawer),
closeDrawer: useDispatchAction(closeDrawer),
};
};