Skip to content

Commit

Permalink
Merge pull request #701 from bigcapitalhq/fix-disable-tabs-customize
Browse files Browse the repository at this point in the history
fix: Disable tabs of the pdf customization if the first field not filed up
  • Loading branch information
abouolia authored Oct 12, 2024
2 parents cf78255 + 863c769 commit 817ef90
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ export function BrandingTemplateForm<
const { mutateAsync: editPdfTemplate } = useEditPdfTemplate();

const initialValues = useBrandingTemplateFormInitialValues<T>(defaultValues);
const brandingState = useBrandingState();

const [, setIsLoading] = useState<boolean>(false);

// Uploads the attachments.
Expand Down Expand Up @@ -138,7 +136,6 @@ export function BrandingTemplateForm<
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleFormSubmit}
brandingState={brandingState || {}}
{...props}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,22 @@ import { ElementCustomizeFields } from './ElementCustomizeFields';
import { ElementCustomizePreview } from './ElementCustomizePreview';
import { extractChildren } from '@/utils/extract-children';
import { ElementPreviewState } from '../BrandingTemplates/types';
import { TabProps } from '@blueprintjs/core';
import { useBrandingState } from '../BrandingTemplates/_utils';

export interface ElementCustomizeProps<T, Y>
extends ElementCustomizeFormProps<T, Y> {
brandingState?: Y;
children?: React.ReactNode;
}

export function ElementCustomize<T, Y extends ElementPreviewState>({
initialValues,
validationSchema,
brandingState,
onSubmit,
export interface ElementCustomizeContentProps {
children?: React.ReactNode;
}

export function ElementCustomizeContent({
children,
}: ElementCustomizeProps<T, Y>) {
}: ElementCustomizeContentProps) {
const PaperTemplate = React.useMemo(
() => extractChildren(children, ElementCustomize.PaperTemplate),
[children],
Expand All @@ -32,23 +34,34 @@ export function ElementCustomize<T, Y extends ElementPreviewState>({
() => extractChildren(children, ElementCustomize.FieldsTab),
[children],
);

const brandingState = useBrandingState();
const value = { PaperTemplate, CustomizeTabs, brandingState };

return (
<ElementCustomizeTabsControllerProvider>
<ElementCustomizeProvider value={value}>
<Group spacing={0} align="stretch">
<ElementCustomizeFields />
<ElementCustomizePreview />
</Group>
</ElementCustomizeProvider>
</ElementCustomizeTabsControllerProvider>
);
}

export function ElementCustomize<T, Y extends ElementPreviewState>({
initialValues,
validationSchema,
onSubmit,
children,
}: ElementCustomizeProps<T, Y>) {
return (
<ElementCustomizeForm
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
>
<ElementCustomizeTabsControllerProvider>
<ElementCustomizeProvider value={value}>
<Group spacing={0} align="stretch">
<ElementCustomizeFields />
<ElementCustomizePreview />
</Group>
</ElementCustomizeProvider>
</ElementCustomizeTabsControllerProvider>
{children}
</ElementCustomizeForm>
);
}
Expand All @@ -63,16 +76,17 @@ ElementCustomize.PaperTemplate = ({
return <>{children}</>;
};

export interface ElementCustomizeContentProps {
export interface ElementCustomizeFieldsTabProps {
id: string;
label: string;
children?: React.ReactNode;
tabProps?: Partial<TabProps>;
}

ElementCustomize.FieldsTab = ({
id,
label,
children,
}: ElementCustomizeContentProps) => {
}: ElementCustomizeFieldsTabProps) => {
return <>{children}</>;
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { Box, Stack } from '@/components';
import { Tab, Tabs } from '@blueprintjs/core';
import { Tab, TabProps, Tabs } from '@blueprintjs/core';
import { ElementCustomizeHeader } from './ElementCustomizeHeader';
import {
ElementCustomizeTabsEnum,
Expand All @@ -11,7 +11,6 @@ import styles from './ElementCustomizeTabs.module.scss';

export function ElementCustomizeTabs() {
const { setCurrentTabId } = useElementCustomizeTabsController();

const { CustomizeTabs } = useElementCustomizeContext();

const tabItems = React.Children.map(CustomizeTabs, (node) => ({
Expand All @@ -32,9 +31,19 @@ export function ElementCustomizeTabs() {
onChange={handleChange}
className={styles.tabsList}
>
{tabItems?.map(({ id, label }: { id: string; label: string }) => (
<Tab id={id} key={id} title={label} />
))}
{tabItems?.map(
({
id,
label,
tabProps,
}: {
id: string;
label: string;
tabProps?: TabProps;
}) => (
<Tab id={id} key={id} title={label} {...tabProps} />
),
)}
</Tabs>
</Box>
</Stack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { useFormikContext } from 'formik';
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
import {
ElementCustomize,
ElementCustomizeContent,
} from '../../../ElementCustomize/ElementCustomize';
import { CreditNoteCustomizeGeneralField } from './CreditNoteCustomizeGeneralFields';
import { CreditNoteCustomizeContentFields } from './CreditNoteCutomizeContentFields';
import { CreditNotePaperTemplate, CreditNotePaperTemplateProps } from './CreditNotePaperTemplate';
import {
CreditNotePaperTemplate,
CreditNotePaperTemplateProps,
} from './CreditNotePaperTemplate';
import { CreditNoteBrandingState, CreditNoteCustomizeValues } from './types';
import { initialValues } from './constants';
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
import { useDrawerActions } from '@/hooks/state';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';

export function CreditNoteCustomizeContent() {
const { payload, name } = useDrawerContext();
Expand All @@ -27,6 +34,16 @@ export function CreditNoteCustomizeContent() {
defaultValues={initialValues}
onSuccess={handleSuccess}
>
<CreditNoteCustomizeFormContent />
</BrandingTemplateForm>
);
}

function CreditNoteCustomizeFormContent() {
const isTemplateNameFilled = useIsTemplateNamedFilled();

return (
<ElementCustomizeContent>
<ElementCustomize.PaperTemplate>
<CreditNotePaperTemplateFormConnected />
</ElementCustomize.PaperTemplate>
Expand All @@ -35,18 +52,25 @@ export function CreditNoteCustomizeContent() {
<CreditNoteCustomizeGeneralField />
</ElementCustomize.FieldsTab>

<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
<ElementCustomize.FieldsTab
id={'content'}
label={'Content'}
tabProps={{ disabled: !isTemplateNameFilled }}
>
<CreditNoteCustomizeContentFields />
</ElementCustomize.FieldsTab>
</BrandingTemplateForm>
</ElementCustomizeContent>
);
}

function CreditNotePaperTemplateFormConnected() {
const { values } = useFormikContext<CreditNoteCustomizeValues>();
const { brandingState } = useElementCustomizeContext();

const mergedProps: CreditNotePaperTemplateProps = { ...brandingState, ...values };
const mergedProps: CreditNotePaperTemplateProps = {
...brandingState,
...values,
};

return <CreditNotePaperTemplate {...mergedProps} />;
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { useFormikContext } from 'formik';
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
import {
ElementCustomize,
ElementCustomizeContent,
} from '../../../ElementCustomize/ElementCustomize';
import { EstimateCustomizeGeneralField } from './EstimateCustomizeFieldsGeneral';
import { EstimateCustomizeContentFields } from './EstimateCustomizeFieldsContent';
import { EstimatePaperTemplate, EstimatePaperTemplateProps } from './EstimatePaperTemplate';
import {
EstimatePaperTemplate,
EstimatePaperTemplateProps,
} from './EstimatePaperTemplate';
import { EstimateBrandingState, EstimateCustomizeValues } from './types';
import { initialValues } from './constants';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useDrawerActions } from '@/hooks/state';
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';

export function EstimateCustomizeContent() {
const { payload, name } = useDrawerContext();
Expand All @@ -26,6 +33,16 @@ export function EstimateCustomizeContent() {
onSuccess={handleSuccess}
resource={'SaleEstimate'}
>
<EstimateCustomizeFormContent />
</BrandingTemplateForm>
);
}

function EstimateCustomizeFormContent() {
const isTemplateNameFilled = useIsTemplateNamedFilled();

return (
<ElementCustomizeContent>
<ElementCustomize.PaperTemplate>
<EstimatePaperTemplateFormConnected />
</ElementCustomize.PaperTemplate>
Expand All @@ -34,10 +51,14 @@ export function EstimateCustomizeContent() {
<EstimateCustomizeGeneralField />
</ElementCustomize.FieldsTab>

<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
<ElementCustomize.FieldsTab
id={'content'}
label={'Content'}
tabProps={{ disabled: !isTemplateNameFilled }}
>
<EstimateCustomizeContentFields />
</ElementCustomize.FieldsTab>
</BrandingTemplateForm>
</ElementCustomizeContent>
);
}

Expand All @@ -47,9 +68,12 @@ export function EstimateCustomizeContent() {
*/
function EstimatePaperTemplateFormConnected() {
const { values } = useFormikContext<EstimateCustomizeValues>();
const { brandingState } = useElementCustomizeContext()
const { brandingState } = useElementCustomizeContext();

const mergedProps: EstimatePaperTemplateProps = { ...brandingState, ...values, }
const mergedProps: EstimatePaperTemplateProps = {
...brandingState,
...values,
};

return <EstimatePaperTemplate {...mergedProps} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@ import {
InvoicePaperTemplate,
InvoicePaperTemplateProps,
} from './InvoicePaperTemplate';
import { ElementCustomize } from '../../../ElementCustomize/ElementCustomize';
import {
ElementCustomize,
ElementCustomizeContent,
} from '../../../ElementCustomize/ElementCustomize';
import { InvoiceCustomizeGeneralField } from './InvoiceCustomizeGeneralFields';
import { InvoiceCustomizeContentFields } from './InvoiceCutomizeContentFields';
import { InvoiceCustomizeFormValues, InvoiceCustomizeState } from './types';
import { InvoiceCustomizeSchema } from './InvoiceCustomizeForm.schema';
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
import { useDrawerActions } from '@/hooks/state';
import { BrandingTemplateForm } from '@/containers/BrandingTemplates/BrandingTemplateForm';
import { initialValues } from './constants';
import { useElementCustomizeContext } from '@/containers/ElementCustomize/ElementCustomizeProvider';
import { initialValues } from './constants';
import { useIsTemplateNamedFilled } from '@/containers/BrandingTemplates/utils';

/**
* Invoice branding template customize.
* @return {JSX.Element}
*/
export function InvoiceCustomizeContent() {
const { payload, name } = useDrawerContext();
Expand All @@ -36,6 +41,20 @@ export function InvoiceCustomizeContent() {
onSuccess={handleSuccess}
resource={'SaleInvoice'}
>
<InvoiceCustomizeFormContent />
</BrandingTemplateForm>
);
}

/**
* Invoice branding template customize preview and fields.
* @returns {JSX.Element}
*/
function InvoiceCustomizeFormContent() {
const isTemplateNameFilled = useIsTemplateNamedFilled();

return (
<ElementCustomizeContent>
<ElementCustomize.PaperTemplate>
<InvoicePaperTemplateFormConnected />
</ElementCustomize.PaperTemplate>
Expand All @@ -44,30 +63,38 @@ export function InvoiceCustomizeContent() {
<InvoiceCustomizeGeneralField />
</ElementCustomize.FieldsTab>

<ElementCustomize.FieldsTab id={'content'} label={'Content'}>
<ElementCustomize.FieldsTab
id={'content'}
label={'Content'}
tabProps={{ disabled: !isTemplateNameFilled }}
>
<InvoiceCustomizeContentFields />
</ElementCustomize.FieldsTab>
</BrandingTemplateForm>
</ElementCustomizeContent>
);
}

/**
* Injects the `InvoicePaperTemplate` component props from the form and branding states.
* @param Component
* @param Component
* @returns {JSX.Element}
*/
const withInvoicePreviewTemplateProps = <P extends object>(
Component: React.ComponentType<P>,
) => {
return (props: Omit<P, keyof InvoicePaperTemplateProps>) => {
const { values } = useFormikContext<InvoiceCustomizeFormValues>();
const { brandingState, } = useElementCustomizeContext();
const { brandingState } = useElementCustomizeContext();

const mergedProps: InvoicePaperTemplateProps = { ...brandingState, ...values };
const mergedProps: InvoicePaperTemplateProps = {
...brandingState,
...values,
};

return <Component {...(props as P)} {...mergedProps} />;
};
};

export const InvoicePaperTemplateFormConnected =
R.compose(withInvoicePreviewTemplateProps)(InvoicePaperTemplate);
export const InvoicePaperTemplateFormConnected = R.compose(
withInvoicePreviewTemplateProps,
)(InvoicePaperTemplate);
Loading

0 comments on commit 817ef90

Please sign in to comment.