mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: hook up branding templates to invoices
This commit is contained in:
@@ -6,16 +6,14 @@ import styled from 'styled-components';
|
||||
import clsx from 'classnames';
|
||||
|
||||
export function FSelect({ ...props }) {
|
||||
const input = ({ activeItem, text, label, value }) => {
|
||||
return (
|
||||
<SelectButton
|
||||
text={text || props.placeholder || 'Select an item ...'}
|
||||
disabled={props.disabled || false}
|
||||
{...props.buttonProps}
|
||||
className={clsx({ 'is-selected': !!text }, props.className)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const input = ({ activeItem, text, label, value }) => (
|
||||
<SelectButton
|
||||
text={text || props.placeholder || 'Select an item ...'}
|
||||
disabled={props.disabled || false}
|
||||
{...props.buttonProps}
|
||||
className={clsx({ 'is-selected': !!text }, props.className)}
|
||||
/>
|
||||
);
|
||||
return <Select input={input} fill={true} {...props} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import styled from 'styled-components';
|
||||
import { FFormGroup } from '@/components';
|
||||
|
||||
export const BrandingThemeFormGroup = styled(FFormGroup)`
|
||||
margin-bottom: 0;
|
||||
|
||||
.bp4-label {
|
||||
color: #7a8492;
|
||||
}
|
||||
|
||||
&.bp4-inline label.bp4-label {
|
||||
margin-right: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
export const BrandingThemeSelectButton = styled(Button)`
|
||||
position: relative;
|
||||
padding-right: 26px;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
|
||||
border-left: 4px solid transparent;
|
||||
border-right: 4px solid transparent;
|
||||
border-top: 5px solid #98a1ae;
|
||||
|
||||
position: absolute;
|
||||
right: -2px;
|
||||
top: 50%;
|
||||
margin-top: -2px;
|
||||
margin-right: 12px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
export const convertBrandingTemplatesToOptions = (brandingTemplates: Array<any>) => {
|
||||
return brandingTemplates?.map(
|
||||
(template) =>
|
||||
({ text: template.template_name, value: template.id } || []),
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import {
|
||||
Intent,
|
||||
Button,
|
||||
@@ -10,12 +10,17 @@ import {
|
||||
Menu,
|
||||
MenuItem,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { If, Icon, FormattedMessage as T, Group } from '@/components';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import classNames from 'classnames';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { CLASSES } from '@/constants/classes';
|
||||
import { If, Icon, FormattedMessage as T, Group, FSelect } from '@/components';
|
||||
import { useInvoiceFormContext } from './InvoiceFormProvider';
|
||||
import { useInvoiceFormBrandingTemplatesOptions } from './utils';
|
||||
import {
|
||||
BrandingThemeFormGroup,
|
||||
BrandingThemeSelectButton,
|
||||
} from '@/containers/BrandingTemplates/BrandingTemplatesSelectFields';
|
||||
|
||||
/**
|
||||
* Invoice floating actions bar.
|
||||
@@ -75,6 +80,8 @@ export default function InvoiceFloatingActions() {
|
||||
resetForm();
|
||||
};
|
||||
|
||||
const brandingTemplatesOptions = useInvoiceFormBrandingTemplatesOptions();
|
||||
|
||||
return (
|
||||
<Group
|
||||
spacing={10}
|
||||
@@ -192,6 +199,26 @@ export default function InvoiceFloatingActions() {
|
||||
onClick={handleCancelBtnClick}
|
||||
text={<T id={'cancel'} />}
|
||||
/>
|
||||
|
||||
{/* ----------- Branding Template Select ----------- */}
|
||||
<BrandingThemeFormGroup
|
||||
name={'pdf_template_id'}
|
||||
label={'Branding'}
|
||||
inline
|
||||
fastField
|
||||
style={{ marginLeft: 20 }}
|
||||
>
|
||||
<FSelect
|
||||
name={'pdf_template_id'}
|
||||
items={brandingTemplatesOptions}
|
||||
input={({ activeItem, text, label, value }) => (
|
||||
<BrandingThemeSelectButton text={text || 'Brand Theme'} minimal />
|
||||
)}
|
||||
filterable={false}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</BrandingThemeFormGroup>
|
||||
</Group>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
} from '@/hooks/query';
|
||||
import { useProjects } from '@/containers/Projects/hooks';
|
||||
import { useTaxRates } from '@/hooks/query/taxRates';
|
||||
import { useGetPdfTemplates } from '@/hooks/query/pdf-templates';
|
||||
|
||||
const InvoiceFormContext = createContext();
|
||||
|
||||
@@ -55,6 +56,10 @@ function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
|
||||
{ enabled: !!estimateId },
|
||||
);
|
||||
|
||||
// Fetches branding templates of invoice.
|
||||
const { data: brandingTemplates, isLoading: isBrandingTemplatesLoading } =
|
||||
useGetPdfTemplates({ resource: 'SaleInvoice' });
|
||||
|
||||
const newInvoice = !isEmpty(estimate)
|
||||
? transformToEditForm({
|
||||
...pick(estimate, ['customer_id', 'currency_code', 'entries']),
|
||||
@@ -105,7 +110,7 @@ function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
|
||||
|
||||
// Determines whether the warehouse and branches are loading.
|
||||
const isFeatureLoading =
|
||||
isWarehouesLoading || isBranchesLoading || isProjectsLoading;
|
||||
isWarehouesLoading || isBranchesLoading || isProjectsLoading || isBrandingTemplatesLoading;
|
||||
|
||||
const provider = {
|
||||
invoice,
|
||||
@@ -119,6 +124,7 @@ function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
|
||||
warehouses,
|
||||
projects,
|
||||
taxRates,
|
||||
brandingTemplates,
|
||||
|
||||
isInvoiceLoading,
|
||||
isItemsLoading,
|
||||
@@ -130,6 +136,7 @@ function InvoiceFormProvider({ invoiceId, baseCurrency, ...props }) {
|
||||
isBranchesSuccess,
|
||||
isWarehousesSuccess,
|
||||
isTaxRatesLoading,
|
||||
isBrandingTemplatesLoading,
|
||||
|
||||
createInvoiceMutate,
|
||||
editInvoiceMutate,
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
transformAttachmentsToForm,
|
||||
transformAttachmentsToRequest,
|
||||
} from '@/containers/Attachments/utils';
|
||||
import { convertBrandingTemplatesToOptions } from '@/containers/BrandingTemplates/BrandingTemplatesSelectFields';
|
||||
|
||||
export const MIN_LINES_NUMBER = 1;
|
||||
|
||||
@@ -66,6 +67,7 @@ export const defaultInvoice = {
|
||||
branch_id: '',
|
||||
warehouse_id: '',
|
||||
project_id: '',
|
||||
pdf_template_id: '',
|
||||
entries: [...repeatValue(defaultInvoiceEntry, MIN_LINES_NUMBER)],
|
||||
attachments: [],
|
||||
};
|
||||
@@ -406,3 +408,12 @@ export const useInvoiceCurrencyCode = () => {
|
||||
|
||||
return values.currency_code;
|
||||
};
|
||||
|
||||
export const useInvoiceFormBrandingTemplatesOptions = () => {
|
||||
const { brandingTemplates } = useInvoiceFormContext();
|
||||
|
||||
return React.useMemo(
|
||||
() => convertBrandingTemplatesToOptions(brandingTemplates),
|
||||
[brandingTemplates],
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user