mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 14:50:32 +00:00
feat(webapp): refactor customer and vendor select component
This commit is contained in:
@@ -1,119 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React, { useCallback, useState, useEffect, useMemo } from 'react';
|
|
||||||
import { FormattedMessage as T } from '@/components';
|
|
||||||
import intl from 'react-intl-universal';
|
|
||||||
import * as R from 'ramda';
|
|
||||||
|
|
||||||
import { MenuItem, Button } from '@blueprintjs/core';
|
|
||||||
import { Select } from '@blueprintjs/select';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { CLASSES } from '@/constants/classes';
|
|
||||||
|
|
||||||
import {
|
|
||||||
itemPredicate,
|
|
||||||
handleContactRenderer,
|
|
||||||
createNewItemRenderer,
|
|
||||||
createNewItemFromQuery,
|
|
||||||
} from './utils';
|
|
||||||
|
|
||||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
|
||||||
|
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
|
||||||
|
|
||||||
function CustomerSelectFieldRoot({
|
|
||||||
// #withDrawerActions
|
|
||||||
openDrawer,
|
|
||||||
|
|
||||||
// #ownProps
|
|
||||||
contacts,
|
|
||||||
initialContactId,
|
|
||||||
selectedContactId,
|
|
||||||
defaultSelectText = <T id={'select_contact'} />,
|
|
||||||
onContactSelected,
|
|
||||||
popoverFill = false,
|
|
||||||
disabled = false,
|
|
||||||
allowCreate,
|
|
||||||
buttonProps,
|
|
||||||
|
|
||||||
...restProps
|
|
||||||
}) {
|
|
||||||
const localContacts = useMemo(
|
|
||||||
() =>
|
|
||||||
contacts.map((contact) => ({
|
|
||||||
...contact,
|
|
||||||
_id: `${contact.id}_${contact.contact_type}`,
|
|
||||||
})),
|
|
||||||
[contacts],
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialContact = useMemo(
|
|
||||||
() => contacts.find((a) => a.id === initialContactId),
|
|
||||||
[initialContactId, contacts],
|
|
||||||
);
|
|
||||||
|
|
||||||
const [selecetedContact, setSelectedContact] = useState(
|
|
||||||
initialContact || null,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof selectedContactId !== 'undefined') {
|
|
||||||
const account = selectedContactId
|
|
||||||
? contacts.find((a) => a.id === selectedContactId)
|
|
||||||
: null;
|
|
||||||
setSelectedContact(account);
|
|
||||||
}
|
|
||||||
}, [selectedContactId, contacts, setSelectedContact]);
|
|
||||||
|
|
||||||
const handleContactSelect = useCallback(
|
|
||||||
(contact) => {
|
|
||||||
if (contact.id) {
|
|
||||||
setSelectedContact({ ...contact });
|
|
||||||
onContactSelected && onContactSelected(contact);
|
|
||||||
} else {
|
|
||||||
openDrawer(DRAWERS.QUICK_CREATE_CUSTOMER);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[setSelectedContact, onContactSelected, openDrawer],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Maybe inject create new item props to suggest component.
|
|
||||||
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
|
||||||
const maybeCreateNewItemFromQuery = allowCreate
|
|
||||||
? createNewItemFromQuery
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
items={localContacts}
|
|
||||||
noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
|
|
||||||
itemRenderer={handleContactRenderer}
|
|
||||||
itemPredicate={itemPredicate}
|
|
||||||
filterable={true}
|
|
||||||
disabled={disabled}
|
|
||||||
onItemSelect={handleContactSelect}
|
|
||||||
popoverProps={{ minimal: true, usePortal: !popoverFill }}
|
|
||||||
className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, {
|
|
||||||
[CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
|
|
||||||
})}
|
|
||||||
inputProps={{
|
|
||||||
placeholder: intl.get('filter_'),
|
|
||||||
}}
|
|
||||||
createNewItemRenderer={maybeCreateNewItemRenderer}
|
|
||||||
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
|
||||||
createNewItemPosition={'top'}
|
|
||||||
{...restProps}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
disabled={disabled}
|
|
||||||
text={
|
|
||||||
selecetedContact ? selecetedContact.display_name : defaultSelectText
|
|
||||||
}
|
|
||||||
{...buttonProps}
|
|
||||||
/>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CustomerSelectField = R.compose(withDrawerActions)(
|
|
||||||
CustomerSelectFieldRoot,
|
|
||||||
);
|
|
||||||
48
packages/webapp/src/components/Customers/CustomersSelect.tsx
Normal file
48
packages/webapp/src/components/Customers/CustomersSelect.tsx
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import { createNewItemFromQuery, createNewItemRenderer } from './utils';
|
||||||
|
import { FSelect } from '../Forms';
|
||||||
|
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||||
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function CustomerSelectRoot({
|
||||||
|
// #withDrawerActions
|
||||||
|
openDrawer,
|
||||||
|
|
||||||
|
// #ownProps
|
||||||
|
items,
|
||||||
|
allowCreate,
|
||||||
|
...props
|
||||||
|
}) {
|
||||||
|
// Maybe inject create new item props to suggest component.
|
||||||
|
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
||||||
|
const maybeCreateNewItemFromQuery = allowCreate
|
||||||
|
? createNewItemFromQuery
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// Handles the create item click.
|
||||||
|
const handleCreateItemClick = () => {
|
||||||
|
openDrawer(DRAWERS.QUICK_CREATE_CUSTOMER);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FSelect
|
||||||
|
items={items}
|
||||||
|
textAccessor={'display_name'}
|
||||||
|
labelAccessor={'code'}
|
||||||
|
valueAccessor={'id'}
|
||||||
|
popoverProps={{ minimal: true, usePortal: true, inline: false }}
|
||||||
|
createNewItemRenderer={maybeCreateNewItemRenderer}
|
||||||
|
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
||||||
|
onCreateItemSelect={handleCreateItemClick}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CustomersSelect = R.compose(withDrawerActions)(CustomerSelectRoot);
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
export * from './CustomerSelectField';
|
|
||||||
export * from './CustomerDrawerLink';
|
export * from './CustomerDrawerLink';
|
||||||
|
export * from './CustomersSelect';
|
||||||
|
|||||||
@@ -1,118 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
import React, { useCallback, useState, useEffect, useMemo } from 'react';
|
|
||||||
import { FormattedMessage as T } from '@/components';
|
|
||||||
import intl from 'react-intl-universal';
|
|
||||||
import * as R from 'ramda';
|
|
||||||
|
|
||||||
import { MenuItem, Button } from '@blueprintjs/core';
|
|
||||||
import { Select } from '@blueprintjs/select';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
import { CLASSES } from '@/constants/classes';
|
|
||||||
|
|
||||||
import {
|
|
||||||
itemPredicate,
|
|
||||||
handleContactRenderer,
|
|
||||||
createNewItemFromQuery,
|
|
||||||
createNewItemRenderer,
|
|
||||||
} from './utils';
|
|
||||||
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
|
||||||
|
|
||||||
import { DRAWERS } from '@/constants/drawers';
|
|
||||||
|
|
||||||
function VendorSelectFieldRoot({
|
|
||||||
// #withDrawerActions
|
|
||||||
openDrawer,
|
|
||||||
|
|
||||||
// #ownProps
|
|
||||||
contacts,
|
|
||||||
initialContactId,
|
|
||||||
selectedContactId,
|
|
||||||
defaultSelectText = <T id={'select_contact'} />,
|
|
||||||
onContactSelected,
|
|
||||||
popoverFill = false,
|
|
||||||
disabled = false,
|
|
||||||
allowCreate,
|
|
||||||
buttonProps,
|
|
||||||
|
|
||||||
...restProps
|
|
||||||
}) {
|
|
||||||
const localContacts = useMemo(
|
|
||||||
() =>
|
|
||||||
contacts.map((contact) => ({
|
|
||||||
...contact,
|
|
||||||
_id: `${contact.id}_${contact.contact_type}`,
|
|
||||||
})),
|
|
||||||
[contacts],
|
|
||||||
);
|
|
||||||
|
|
||||||
const initialContact = useMemo(
|
|
||||||
() => contacts.find((a) => a.id === initialContactId),
|
|
||||||
[initialContactId, contacts],
|
|
||||||
);
|
|
||||||
|
|
||||||
const [selecetedContact, setSelectedContact] = useState(
|
|
||||||
initialContact || null,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (typeof selectedContactId !== 'undefined') {
|
|
||||||
const account = selectedContactId
|
|
||||||
? contacts.find((a) => a.id === selectedContactId)
|
|
||||||
: null;
|
|
||||||
setSelectedContact(account);
|
|
||||||
}
|
|
||||||
}, [selectedContactId, contacts, setSelectedContact]);
|
|
||||||
|
|
||||||
const handleContactSelect = useCallback(
|
|
||||||
(contact) => {
|
|
||||||
if (contact.id) {
|
|
||||||
setSelectedContact({ ...contact });
|
|
||||||
onContactSelected && onContactSelected(contact);
|
|
||||||
} else {
|
|
||||||
openDrawer(DRAWERS.QUICK_WRITE_VENDOR);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[setSelectedContact, onContactSelected, openDrawer],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Maybe inject create new item props to suggest component.
|
|
||||||
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
|
||||||
const maybeCreateNewItemFromQuery = allowCreate
|
|
||||||
? createNewItemFromQuery
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Select
|
|
||||||
items={localContacts}
|
|
||||||
noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
|
|
||||||
itemRenderer={handleContactRenderer}
|
|
||||||
itemPredicate={itemPredicate}
|
|
||||||
filterable={true}
|
|
||||||
disabled={disabled}
|
|
||||||
onItemSelect={handleContactSelect}
|
|
||||||
popoverProps={{ minimal: true, usePortal: !popoverFill }}
|
|
||||||
className={classNames(CLASSES.FORM_GROUP_LIST_SELECT, {
|
|
||||||
[CLASSES.SELECT_LIST_FILL_POPOVER]: popoverFill,
|
|
||||||
})}
|
|
||||||
inputProps={{
|
|
||||||
placeholder: intl.get('filter_'),
|
|
||||||
}}
|
|
||||||
createNewItemRenderer={maybeCreateNewItemRenderer}
|
|
||||||
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
|
||||||
createNewItemPosition={'top'}
|
|
||||||
{...restProps}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
disabled={disabled}
|
|
||||||
text={
|
|
||||||
selecetedContact ? selecetedContact.display_name : defaultSelectText
|
|
||||||
}
|
|
||||||
{...buttonProps}
|
|
||||||
/>
|
|
||||||
</Select>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const VendorSelectField = R.compose(withDrawerActions)(
|
|
||||||
VendorSelectFieldRoot,
|
|
||||||
);
|
|
||||||
49
packages/webapp/src/components/Vendors/VendorsSelect.tsx
Normal file
49
packages/webapp/src/components/Vendors/VendorsSelect.tsx
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
import React from 'react';
|
||||||
|
import * as R from 'ramda';
|
||||||
|
import withDrawerActions from '@/containers/Drawer/withDrawerActions';
|
||||||
|
import { createNewItemFromQuery, createNewItemRenderer } from './utils';
|
||||||
|
import { FSelect } from '../Forms';
|
||||||
|
import { DRAWERS } from '@/constants/drawers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor select.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function VendorsSelectRoot({
|
||||||
|
// #withDrawerActions
|
||||||
|
openDrawer,
|
||||||
|
|
||||||
|
// #ownProps
|
||||||
|
items,
|
||||||
|
allowCreate,
|
||||||
|
|
||||||
|
...restProps
|
||||||
|
}) {
|
||||||
|
// Maybe inject create new item props to suggest component.
|
||||||
|
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
||||||
|
const maybeCreateNewItemFromQuery = allowCreate
|
||||||
|
? createNewItemFromQuery
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// Handles the create item click.
|
||||||
|
const handleCreateItemClick = () => {
|
||||||
|
openDrawer(DRAWERS.QUICK_WRITE_VENDOR);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FSelect
|
||||||
|
items={items}
|
||||||
|
textAccessor={'display_name'}
|
||||||
|
labelAccessor={'code'}
|
||||||
|
valueAccessor={'id'}
|
||||||
|
popoverProps={{ minimal: true, usePortal: true, inline: false }}
|
||||||
|
createNewItemRenderer={maybeCreateNewItemRenderer}
|
||||||
|
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
||||||
|
onCreateItemSelect={handleCreateItemClick}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VendorsSelect = R.compose(withDrawerActions)(VendorsSelectRoot);
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
export * from './VendorDrawerLink'
|
export * from './VendorDrawerLink'
|
||||||
export * from './VendorSelectField'
|
export * from './VendorsSelect';
|
||||||
@@ -3,7 +3,7 @@ import React from 'react';
|
|||||||
import { InputGroup, FormGroup, Position, Classes } from '@blueprintjs/core';
|
import { InputGroup, FormGroup, Position, Classes } from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, ErrorMessage } from 'formik';
|
import { FastField, ErrorMessage } from 'formik';
|
||||||
import { FormattedMessage as T } from '@/components';
|
import { CustomersSelect, FormattedMessage as T } from '@/components';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
import {
|
import {
|
||||||
@@ -121,33 +121,35 @@ export default function ExpenseFormHeader() {
|
|||||||
)}
|
)}
|
||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
<FastField
|
{/* ----------- Customer ----------- */}
|
||||||
name={'customer_id'}
|
<ExpenseFormCustomerSelect />
|
||||||
customers={customers}
|
|
||||||
shouldUpdate={customersFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={<T id={'customer'} />}
|
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
|
||||||
labelInfo={<Hint />}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
helperText={<ErrorMessage name={'assign_to_customer'} />}
|
|
||||||
inline={true}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('customer_id', customer.id);
|
|
||||||
}}
|
|
||||||
allowCreate={true}
|
|
||||||
popoverFill={true}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field of expense form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function ExpenseFormCustomerSelect() {
|
||||||
|
const { customers } = useExpenseFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormGroup
|
||||||
|
label={<T id={'customer'} />}
|
||||||
|
labelInfo={<Hint />}
|
||||||
|
inline={true}
|
||||||
|
name={'customer_id'}
|
||||||
|
customers={customers}
|
||||||
|
shouldUpdate={customersFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'customer_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={<T id={'select_customer_account'} />}
|
||||||
|
allowCreate={true}
|
||||||
|
popoverFill={true}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,11 +15,10 @@ import {
|
|||||||
FMoneyInputGroup,
|
FMoneyInputGroup,
|
||||||
InputPrependText,
|
InputPrependText,
|
||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
FieldRequiredHint,
|
|
||||||
CustomerSelectField,
|
|
||||||
Stack,
|
Stack,
|
||||||
|
CustomersSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { inputIntent, momentFormatter } from '@/utils';
|
import { momentFormatter } from '@/utils';
|
||||||
import { useProjectFormContext } from './ProjectFormProvider';
|
import { useProjectFormContext } from './ProjectFormProvider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,9 +26,6 @@ import { useProjectFormContext } from './ProjectFormProvider';
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
function ProjectFormFields() {
|
function ProjectFormFields() {
|
||||||
// project form dialog context.
|
|
||||||
const { customers } = useProjectFormContext();
|
|
||||||
|
|
||||||
// Formik context.
|
// Formik context.
|
||||||
const { values } = useFormikContext();
|
const { values } = useFormikContext();
|
||||||
|
|
||||||
@@ -37,26 +33,7 @@ function ProjectFormFields() {
|
|||||||
<div className={Classes.DIALOG_BODY}>
|
<div className={Classes.DIALOG_BODY}>
|
||||||
<Stack spacing={25}>
|
<Stack spacing={25}>
|
||||||
{/*------------ Contact -----------*/}
|
{/*------------ Contact -----------*/}
|
||||||
<FastField name={'contact_id'}>
|
<ProjectFormCustomerSelect />
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={intl.get('projects.dialog.contact')}
|
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={'Find or create a customer'}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('contact_id', customer.id);
|
|
||||||
}}
|
|
||||||
allowCreate={true}
|
|
||||||
popoverFill={true}
|
|
||||||
/>
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/*------------ Project Name -----------*/}
|
{/*------------ Project Name -----------*/}
|
||||||
<FFormGroup
|
<FFormGroup
|
||||||
@@ -113,4 +90,21 @@ function ProjectFormFields() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ProjectFormCustomerSelect() {
|
||||||
|
// project form dialog context.
|
||||||
|
const { customers } = useProjectFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FormGroup name={'contact_id'} label={intl.get('projects.dialog.contact')}>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'contact_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={'Find or create a customer'}
|
||||||
|
allowCreate={true}
|
||||||
|
popoverFill={true}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default ProjectFormFields;
|
export default ProjectFormFields;
|
||||||
|
|||||||
@@ -3,17 +3,17 @@ import React from 'react';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FormGroup, InputGroup, Classes, Position } from '@blueprintjs/core';
|
import { FormGroup, InputGroup, Classes, Position } from '@blueprintjs/core';
|
||||||
import { FastField, ErrorMessage } from 'formik';
|
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FeatureCan, FormattedMessage as T } from '@/components';
|
import { FeatureCan, FormattedMessage as T } from '@/components';
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
VendorSelectField,
|
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Icon,
|
Icon,
|
||||||
VendorDrawerLink,
|
VendorDrawerLink,
|
||||||
|
VendorsSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
|
|
||||||
import { useBillFormContext } from './BillFormProvider';
|
import { useBillFormContext } from './BillFormProvider';
|
||||||
@@ -43,43 +43,7 @@ function BillFormHeader() {
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ------- Vendor name ------ */}
|
{/* ------- Vendor name ------ */}
|
||||||
<FastField
|
<BillFormVendorField />
|
||||||
name={'vendor_id'}
|
|
||||||
vendors={vendors}
|
|
||||||
shouldUpdate={vendorsFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FFormGroup
|
|
||||||
name={'vendor_id'}
|
|
||||||
label={<T id={'vendor_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames(
|
|
||||||
'form-group--vendor-name',
|
|
||||||
'form-group--select-list',
|
|
||||||
CLASSES.FILL,
|
|
||||||
)}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
>
|
|
||||||
<VendorSelectField
|
|
||||||
contacts={vendors}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_vender_account'} />}
|
|
||||||
onContactSelected={(contact) => {
|
|
||||||
form.setFieldValue('vendor_id', contact.id);
|
|
||||||
form.setFieldValue('currency_code', contact?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{value && (
|
|
||||||
<VendorButtonLink vendorId={value}>
|
|
||||||
<T id={'view_vendor_details'} />
|
|
||||||
</VendorButtonLink>
|
|
||||||
)}
|
|
||||||
</FFormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<BillExchangeRateInputField
|
<BillExchangeRateInputField
|
||||||
@@ -190,6 +154,43 @@ function BillFormHeader() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor select field of bill form.
|
||||||
|
* @returns {JSX.Element}
|
||||||
|
*/
|
||||||
|
function BillFormVendorField() {
|
||||||
|
const { values, setFieldValue } = useFormikContext();
|
||||||
|
const { vendors } = useBillFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'vendor_id'}
|
||||||
|
label={<T id={'vendor_name'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
vendors={vendors}
|
||||||
|
fastField={true}
|
||||||
|
shouldUpdate={vendorsFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
<VendorsSelect
|
||||||
|
name={'vendor_id'}
|
||||||
|
items={vendors}
|
||||||
|
placeholder={<T id={'select_vender_account'} />}
|
||||||
|
onItemChange={(contact) => {
|
||||||
|
setFieldValue('vendor_id', contact.id);
|
||||||
|
setFieldValue('currency_code', contact?.currency_code);
|
||||||
|
}}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
{values.vendor_id && (
|
||||||
|
<VendorButtonLink vendorId={values.vendor_id}>
|
||||||
|
<T id={'view_vendor_details'} />
|
||||||
|
</VendorButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default compose(withDialogActions)(BillFormHeader);
|
export default compose(withDialogActions)(BillFormHeader);
|
||||||
|
|
||||||
const VendorButtonLink = styled(VendorDrawerLink)`
|
const VendorButtonLink = styled(VendorDrawerLink)`
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ import {
|
|||||||
ControlGroup,
|
ControlGroup,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, ErrorMessage } from 'formik';
|
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
VendorSelectField,
|
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
InputPrependButton,
|
InputPrependButton,
|
||||||
Icon,
|
Icon,
|
||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
VendorDrawerLink,
|
VendorDrawerLink,
|
||||||
|
VendorsSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import {
|
import {
|
||||||
vendorsFieldShouldUpdate,
|
vendorsFieldShouldUpdate,
|
||||||
@@ -51,9 +51,6 @@ function VendorCreditNoteFormHeaderFields({
|
|||||||
vendorcreditNumberPrefix,
|
vendorcreditNumberPrefix,
|
||||||
vendorcreditNextNumber,
|
vendorcreditNextNumber,
|
||||||
}) {
|
}) {
|
||||||
// Vendor Credit form context.
|
|
||||||
const { vendors } = useVendorCreditNoteFormContext();
|
|
||||||
|
|
||||||
// Handle vendor credit number changing.
|
// Handle vendor credit number changing.
|
||||||
const handleVendorCreditNumberChange = () => {
|
const handleVendorCreditNumberChange = () => {
|
||||||
openDialog('vendor-credit-form');
|
openDialog('vendor-credit-form');
|
||||||
@@ -81,39 +78,7 @@ function VendorCreditNoteFormHeaderFields({
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ----------- Vendor name ----------- */}
|
{/* ----------- Vendor name ----------- */}
|
||||||
<FastField
|
<VendorCreditFormVendorSelect />
|
||||||
name={'vendor_id'}
|
|
||||||
vendors={vendors}
|
|
||||||
shouldUpdate={vendorsFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FFormGroup
|
|
||||||
name={'vendor_id'}
|
|
||||||
label={<T id={'vendor_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames(CLASSES.FILL, 'form-group--vendor')}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
>
|
|
||||||
<VendorSelectField
|
|
||||||
contacts={vendors}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_vender_account'} />}
|
|
||||||
onContactSelected={(contact) => {
|
|
||||||
form.setFieldValue('vendor_id', contact.id);
|
|
||||||
form.setFieldValue('currency_code', contact?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{value && (
|
|
||||||
<VendorButtonLink vendorId={value}>
|
|
||||||
<T id={'view_vendor_details'} />
|
|
||||||
</VendorButtonLink>
|
|
||||||
)}
|
|
||||||
</FFormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<VendorCreditNoteExchangeRateInputField
|
<VendorCreditNoteExchangeRateInputField
|
||||||
@@ -205,6 +170,45 @@ function VendorCreditNoteFormHeaderFields({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor select field of vendor credit form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function VendorCreditFormVendorSelect() {
|
||||||
|
const { values, setFieldValue } = useFormikContext();
|
||||||
|
|
||||||
|
// Vendor Credit form context.
|
||||||
|
const { vendors } = useVendorCreditNoteFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'vendor_id'}
|
||||||
|
label={<T id={'vendor_name'} />}
|
||||||
|
inline={true}
|
||||||
|
vendors={vendors}
|
||||||
|
shouldUpdate={vendorsFieldShouldUpdate}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
>
|
||||||
|
<VendorsSelect
|
||||||
|
name={'vendor_id'}
|
||||||
|
items={vendors}
|
||||||
|
placeholder={<T id={'select_vender_account'} />}
|
||||||
|
onItemChange={(contact) => {
|
||||||
|
setFieldValue('vendor_id', contact.id);
|
||||||
|
setFieldValue('currency_code', contact?.currency_code);
|
||||||
|
}}
|
||||||
|
popoverFill={true}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
{values.vendor_id && (
|
||||||
|
<VendorButtonLink vendorId={values.vendor_id}>
|
||||||
|
<T id={'view_vendor_details'} />
|
||||||
|
</VendorButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default compose(
|
export default compose(
|
||||||
withDialogActions,
|
withDialogActions,
|
||||||
withSettings(({ vendorsCreditNoteSetting }) => ({
|
withSettings(({ vendorsCreditNoteSetting }) => ({
|
||||||
|
|||||||
@@ -12,14 +12,13 @@ import {
|
|||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
|
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
|
||||||
import { FormattedMessage as T } from '@/components';
|
import { FormattedMessage as T, VendorsSelect } from '@/components';
|
||||||
import { toSafeInteger } from 'lodash';
|
import { toSafeInteger } from 'lodash';
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
AccountsSelect,
|
AccountsSelect,
|
||||||
VendorSelectField,
|
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
InputPrependText,
|
InputPrependText,
|
||||||
Money,
|
Money,
|
||||||
@@ -55,8 +54,7 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) {
|
|||||||
} = useFormikContext();
|
} = useFormikContext();
|
||||||
|
|
||||||
// Payment made form context.
|
// Payment made form context.
|
||||||
const { vendors, accounts, isNewMode, setPaymentVendorId } =
|
const { accounts } = usePaymentMadeFormContext();
|
||||||
usePaymentMadeFormContext();
|
|
||||||
|
|
||||||
// Sumation of payable full-amount.
|
// Sumation of payable full-amount.
|
||||||
const payableFullAmount = useMemo(
|
const payableFullAmount = useMemo(
|
||||||
@@ -82,41 +80,7 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) {
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ------------ Vendor name ------------ */}
|
{/* ------------ Vendor name ------------ */}
|
||||||
<FastField
|
<PaymentFormVendorSelect />
|
||||||
name={'vendor_id'}
|
|
||||||
vendors={vendors}
|
|
||||||
shouldUpdate={vendorsFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FFormGroup
|
|
||||||
name={'vendor_id'}
|
|
||||||
label={<T id={'vendor_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
>
|
|
||||||
<VendorSelectField
|
|
||||||
contacts={vendors}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_vender_account'} />}
|
|
||||||
onContactSelected={(contact) => {
|
|
||||||
form.setFieldValue('vendor_id', contact.id);
|
|
||||||
form.setFieldValue('currency_code', contact?.currency_code);
|
|
||||||
setPaymentVendorId(contact.id);
|
|
||||||
}}
|
|
||||||
disabled={!isNewMode}
|
|
||||||
popoverFill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{value && (
|
|
||||||
<VendorButtonLink vendorId={value}>
|
|
||||||
<T id={'view_vendor_details'} />
|
|
||||||
</VendorButtonLink>
|
|
||||||
)}
|
|
||||||
</FFormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<PaymentMadeExchangeRateInputField
|
<PaymentMadeExchangeRateInputField
|
||||||
@@ -258,6 +222,48 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor select field of payment receive form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function PaymentFormVendorSelect() {
|
||||||
|
// Formik form context.
|
||||||
|
const { values, setFieldValue } = useFormikContext();
|
||||||
|
|
||||||
|
// Payment made form context.
|
||||||
|
const { vendors, isNewMode, setPaymentVendorId } =
|
||||||
|
usePaymentMadeFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'vendor_id'}
|
||||||
|
label={<T id={'vendor_name'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
vendors={vendors}
|
||||||
|
shouldUpdate={vendorsFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
<VendorsSelect
|
||||||
|
name={'vendor_id'}
|
||||||
|
items={vendors}
|
||||||
|
placeholder={<T id={'select_vender_account'} />}
|
||||||
|
onItemChange={(contact) => {
|
||||||
|
setFieldValue('vendor_id', contact.id);
|
||||||
|
setFieldValue('currency_code', contact?.currency_code);
|
||||||
|
setPaymentVendorId(contact.id);
|
||||||
|
}}
|
||||||
|
disabled={!isNewMode}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
{values.vendor_id && (
|
||||||
|
<VendorButtonLink vendorId={values.vendor_id}>
|
||||||
|
<T id={'view_vendor_details'} />
|
||||||
|
</VendorButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default compose(withCurrentOrganization())(PaymentMadeFormHeaderFields);
|
export default compose(withCurrentOrganization())(PaymentMadeFormHeaderFields);
|
||||||
|
|
||||||
const VendorButtonLink = styled(VendorDrawerLink)`
|
const VendorButtonLink = styled(VendorDrawerLink)`
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
CustomerDrawerLink,
|
CustomerDrawerLink,
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
FInputGroup,
|
FInputGroup,
|
||||||
|
CustomersSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { customerNameFieldShouldUpdate } from './utils';
|
import { customerNameFieldShouldUpdate } from './utils';
|
||||||
|
|
||||||
@@ -121,49 +122,10 @@ const CreditNoteTransactionNoField = R.compose(
|
|||||||
* Credit note form header fields.
|
* Credit note form header fields.
|
||||||
*/
|
*/
|
||||||
export default function CreditNoteFormHeaderFields({}) {
|
export default function CreditNoteFormHeaderFields({}) {
|
||||||
// Credit note form context.
|
|
||||||
const { customers } = useCreditNoteFormContext();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ----------- Customer name ----------- */}
|
{/* ----------- Customer name ----------- */}
|
||||||
<FastField
|
<CreditNoteCustomersSelect />
|
||||||
name={'customer_id'}
|
|
||||||
customers={customers}
|
|
||||||
shouldUpdate={customerNameFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={<T id={'customer_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames(
|
|
||||||
'form-group--customer-name',
|
|
||||||
'form-group--select-list',
|
|
||||||
CLASSES.FILL,
|
|
||||||
)}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
helperText={<ErrorMessage name={'customer_id'} />}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('customer_id', customer.id);
|
|
||||||
form.setFieldValue('currency_code', customer?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
{value && (
|
|
||||||
<CustomerButtonLink customerId={value}>
|
|
||||||
<T id={'view_customer_details'} />
|
|
||||||
</CustomerButtonLink>
|
|
||||||
)}
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<CreditNoteExchangeRateInputField
|
<CreditNoteExchangeRateInputField
|
||||||
@@ -216,6 +178,45 @@ export default function CreditNoteFormHeaderFields({}) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field of credit note form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function CreditNoteCustomersSelect() {
|
||||||
|
// Credit note form context.
|
||||||
|
const { customers } = useCreditNoteFormContext();
|
||||||
|
const { setFieldValue, values } = useFormikContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'customer_id'}
|
||||||
|
label={<T id={'customer_name'} />}
|
||||||
|
customers={customers}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
inline={true}
|
||||||
|
fastField={true}
|
||||||
|
shouldUpdate={customerNameFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'customer_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={<T id={'select_customer_account'} />}
|
||||||
|
onItemChange={(customer) => {
|
||||||
|
setFieldValue('customer_id', customer.id);
|
||||||
|
setFieldValue('currency_code', customer?.currency_code);
|
||||||
|
}}
|
||||||
|
popoverFill={true}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
{values.customer_id && (
|
||||||
|
<CustomerButtonLink customerId={values.customer_id}>
|
||||||
|
<T id={'view_customer_details'} />
|
||||||
|
</CustomerButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
|
|||||||
@@ -11,18 +11,18 @@ import {
|
|||||||
ControlGroup,
|
ControlGroup,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
import { FastField, ErrorMessage, useFormikContext, useFormik } from 'formik';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FeatureCan,
|
FeatureCan,
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
FInputGroup,
|
FInputGroup,
|
||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
CustomerSelectField,
|
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Icon,
|
Icon,
|
||||||
InputPrependButton,
|
InputPrependButton,
|
||||||
CustomerDrawerLink,
|
CustomerDrawerLink,
|
||||||
|
CustomersSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import {
|
import {
|
||||||
momentFormatter,
|
momentFormatter,
|
||||||
@@ -129,41 +129,7 @@ export default function EstimateFormHeader() {
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ----------- Customer name ----------- */}
|
{/* ----------- Customer name ----------- */}
|
||||||
<FastField
|
<EstimateFormCustomerSelect />
|
||||||
name={'customer_id'}
|
|
||||||
customers={customers}
|
|
||||||
shouldUpdate={customersFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={<T id={'customer_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames(CLASSES.FILL, 'form-group--customer')}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
helperText={<ErrorMessage name={'customer_id'} />}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('customer_id', customer.id);
|
|
||||||
form.setFieldValue('currency_code', customer?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{value && (
|
|
||||||
<CustomerButtonLink customerId={value}>
|
|
||||||
<T id={'view_customer_details'} />
|
|
||||||
</CustomerButtonLink>
|
|
||||||
)}
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange Rate ----------- */}
|
{/* ----------- Exchange Rate ----------- */}
|
||||||
<EstimateExchangeRateInputField
|
<EstimateExchangeRateInputField
|
||||||
@@ -264,6 +230,45 @@ export default function EstimateFormHeader() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field of estimate form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function EstimateFormCustomerSelect() {
|
||||||
|
const { setFieldValue, values } = useFormikContext();
|
||||||
|
const { customers } = useEstimateFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
label={<T id={'customer_name'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
name={'customer_id'}
|
||||||
|
customers={customers}
|
||||||
|
shouldUpdate={customersFieldShouldUpdate}
|
||||||
|
fastField={true}
|
||||||
|
>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'customer_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={<T id={'select_customer_account'} />}
|
||||||
|
onItemChange={(customer) => {
|
||||||
|
setFieldValue('customer_id', customer.id);
|
||||||
|
setFieldValue('currency_code', customer?.currency_code);
|
||||||
|
}}
|
||||||
|
popoverFill={true}
|
||||||
|
allowCreate={true}
|
||||||
|
fastField={true}
|
||||||
|
/>
|
||||||
|
{values.customer_id && (
|
||||||
|
<CustomerButtonLink customerId={values.customer_id}>
|
||||||
|
<T id={'view_customer_details'} />
|
||||||
|
</CustomerButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
ControlGroup,
|
ControlGroup,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
import { FastField, ErrorMessage, useFormikContext, useFormik } from 'formik';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -19,12 +19,12 @@ import {
|
|||||||
Col,
|
Col,
|
||||||
Row,
|
Row,
|
||||||
CustomerDrawerLink,
|
CustomerDrawerLink,
|
||||||
CustomerSelectField,
|
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Icon,
|
Icon,
|
||||||
InputPrependButton,
|
InputPrependButton,
|
||||||
FeatureCan,
|
FeatureCan,
|
||||||
FInputGroup,
|
FInputGroup,
|
||||||
|
CustomersSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import {
|
import {
|
||||||
momentFormatter,
|
momentFormatter,
|
||||||
@@ -134,49 +134,13 @@ InvoiceFormInvoiceNumberField.displayName = 'InvoiceFormInvoiceNumberField';
|
|||||||
*/
|
*/
|
||||||
export default function InvoiceFormHeaderFields() {
|
export default function InvoiceFormHeaderFields() {
|
||||||
// Invoice form context.
|
// Invoice form context.
|
||||||
const { customers, projects } = useInvoiceFormContext();
|
const { projects } = useInvoiceFormContext();
|
||||||
const { values } = useFormikContext();
|
const { values } = useFormikContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ----------- Customer name ----------- */}
|
{/* ----------- Customer name ----------- */}
|
||||||
<FastField
|
<InvoiceFormCustomerSelect />
|
||||||
name={'customer_id'}
|
|
||||||
customers={customers}
|
|
||||||
shouldUpdate={customerNameFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FFormGroup
|
|
||||||
name={'customer_id'}
|
|
||||||
label={<T id={'customer_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames(
|
|
||||||
'form-group--customer-name',
|
|
||||||
'form-group--select-list',
|
|
||||||
CLASSES.FILL,
|
|
||||||
)}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('customer_id', customer.id);
|
|
||||||
form.setFieldValue('currency_code', customer?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{value && (
|
|
||||||
<CustomerButtonLink customerId={value}>
|
|
||||||
<T id={'view_customer_details'} />
|
|
||||||
</CustomerButtonLink>
|
|
||||||
)}
|
|
||||||
</FFormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<InvoiceExchangeRateInputField
|
<InvoiceExchangeRateInputField
|
||||||
@@ -284,6 +248,44 @@ export default function InvoiceFormHeaderFields() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field of the invoice form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function InvoiceFormCustomerSelect() {
|
||||||
|
const { customers } = useInvoiceFormContext();
|
||||||
|
const { values, setFieldValue } = useFormikContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'customer_id'}
|
||||||
|
customers={customers}
|
||||||
|
shouldUpdate={customerNameFieldShouldUpdate}
|
||||||
|
label={<T id={'customer_name'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
fastField={true}
|
||||||
|
>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'customer_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={<T id={'select_customer_account'} />}
|
||||||
|
onItemChange={(customer) => {
|
||||||
|
setFieldValue('customer_id', customer.id);
|
||||||
|
setFieldValue('currency_code', customer?.currency_code);
|
||||||
|
}}
|
||||||
|
allowCreate={true}
|
||||||
|
fastField={true}
|
||||||
|
/>
|
||||||
|
{values.customer_id && (
|
||||||
|
<CustomerButtonLink customerId={values.customer_id}>
|
||||||
|
<T id={'view_customer_details'} />
|
||||||
|
</CustomerButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
|
|||||||
@@ -15,8 +15,12 @@ import { toSafeInteger } from 'lodash';
|
|||||||
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
|
import { FastField, Field, useFormikContext, ErrorMessage } from 'formik';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
|
||||||
import { FInputGroup, FeatureCan, FormattedMessage as T } from '@/components';
|
import {
|
||||||
import { useAutofocus } from '@/hooks';
|
CustomersSelect,
|
||||||
|
FInputGroup,
|
||||||
|
FeatureCan,
|
||||||
|
FormattedMessage as T,
|
||||||
|
} from '@/components';
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
import {
|
import {
|
||||||
safeSumBy,
|
safeSumBy,
|
||||||
@@ -28,7 +32,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
FFormGroup,
|
FFormGroup,
|
||||||
AccountsSelect,
|
AccountsSelect,
|
||||||
CustomerSelectField,
|
|
||||||
FieldRequiredHint,
|
FieldRequiredHint,
|
||||||
Icon,
|
Icon,
|
||||||
InputPrependButton,
|
InputPrependButton,
|
||||||
@@ -143,8 +146,7 @@ const PaymentReceivePaymentNoField = R.compose(
|
|||||||
*/
|
*/
|
||||||
export default function PaymentReceiveHeaderFields() {
|
export default function PaymentReceiveHeaderFields() {
|
||||||
// Payment receive form context.
|
// Payment receive form context.
|
||||||
const { customers, accounts, projects, isNewMode } =
|
const { accounts, projects } = usePaymentReceiveFormContext();
|
||||||
usePaymentReceiveFormContext();
|
|
||||||
|
|
||||||
// Formik form context.
|
// Formik form context.
|
||||||
const {
|
const {
|
||||||
@@ -152,8 +154,6 @@ export default function PaymentReceiveHeaderFields() {
|
|||||||
setFieldValue,
|
setFieldValue,
|
||||||
} = useFormikContext();
|
} = useFormikContext();
|
||||||
|
|
||||||
const customerFieldRef = useAutofocus();
|
|
||||||
|
|
||||||
// Calculates the full-amount received.
|
// Calculates the full-amount received.
|
||||||
const totalDueAmount = useMemo(
|
const totalDueAmount = useMemo(
|
||||||
() => safeSumBy(entries, 'due_amount'),
|
() => safeSumBy(entries, 'due_amount'),
|
||||||
@@ -176,45 +176,7 @@ export default function PaymentReceiveHeaderFields() {
|
|||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ------------- Customer name ------------- */}
|
{/* ------------- Customer name ------------- */}
|
||||||
<FastField
|
<PaymentReceiveCustomerSelect />
|
||||||
name={'customer_id'}
|
|
||||||
customers={customers}
|
|
||||||
shouldUpdate={customersFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={<T id={'customer_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames('form-group--select-list', CLASSES.FILL)}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
helperText={<ErrorMessage name={'customer_id'} />}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('customer_id', customer.id);
|
|
||||||
form.setFieldValue('full_amount', '');
|
|
||||||
form.setFieldValue('currency_code', customer?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
disabled={!isNewMode}
|
|
||||||
buttonProps={{
|
|
||||||
elementRef: (ref) => (customerFieldRef.current = ref),
|
|
||||||
}}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{value && (
|
|
||||||
<CustomerButtonLink customerId={value}>
|
|
||||||
<T id={'view_customer_details'} />
|
|
||||||
</CustomerButtonLink>
|
|
||||||
)}
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<PaymentReceiveExchangeRateInputField
|
<PaymentReceiveExchangeRateInputField
|
||||||
@@ -361,3 +323,47 @@ const CustomerButtonLink = styled(CustomerDrawerLink)`
|
|||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field of payment receive form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function PaymentReceiveCustomerSelect() {
|
||||||
|
// Payment receive form context.
|
||||||
|
const { customers, isNewMode } = usePaymentReceiveFormContext();
|
||||||
|
|
||||||
|
// Formik form context.
|
||||||
|
const { values, setFieldValue } = useFormikContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
label={<T id={'customer_name'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
name={'customer_id'}
|
||||||
|
customers={customers}
|
||||||
|
fastField={true}
|
||||||
|
shouldUpdate={customersFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'customer_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={<T id={'select_customer_account'} />}
|
||||||
|
onItemChange={(customer) => {
|
||||||
|
setFieldValue('customer_id', customer.id);
|
||||||
|
setFieldValue('full_amount', '');
|
||||||
|
setFieldValue('currency_code', customer?.currency_code);
|
||||||
|
}}
|
||||||
|
popoverFill={true}
|
||||||
|
disabled={!isNewMode}
|
||||||
|
allowCreate={true}
|
||||||
|
fastField={true}
|
||||||
|
/>
|
||||||
|
{values.customer_id && (
|
||||||
|
<CustomerButtonLink customerId={values.customer_id}>
|
||||||
|
<T id={'view_customer_details'} />
|
||||||
|
</CustomerButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
ControlGroup,
|
ControlGroup,
|
||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FastField, ErrorMessage, useFormikContext } from 'formik';
|
import { FastField, ErrorMessage, useFormikContext, useFormik } from 'formik';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
|
|
||||||
import { CLASSES } from '@/constants/classes';
|
import { CLASSES } from '@/constants/classes';
|
||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
FeatureCan,
|
FeatureCan,
|
||||||
FInputGroup,
|
FInputGroup,
|
||||||
|
CustomersSelect,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { ProjectsSelect } from '@/containers/Projects/components';
|
import { ProjectsSelect } from '@/containers/Projects/components';
|
||||||
import {
|
import {
|
||||||
@@ -130,44 +131,12 @@ const ReceiptFormReceiptNumberField = R.compose(
|
|||||||
* Receipt form header fields.
|
* Receipt form header fields.
|
||||||
*/
|
*/
|
||||||
export default function ReceiptFormHeader() {
|
export default function ReceiptFormHeader() {
|
||||||
const { accounts, customers, projects } = useReceiptFormContext();
|
const { accounts, projects } = useReceiptFormContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
|
||||||
{/* ----------- Customer name ----------- */}
|
{/* ----------- Customer name ----------- */}
|
||||||
<FastField
|
<ReceiptFormCustomerSelect />
|
||||||
name={'customer_id'}
|
|
||||||
customers={customers}
|
|
||||||
shouldUpdate={customersFieldShouldUpdate}
|
|
||||||
>
|
|
||||||
{({ form, field: { value }, meta: { error, touched } }) => (
|
|
||||||
<FormGroup
|
|
||||||
label={<T id={'customer_name'} />}
|
|
||||||
inline={true}
|
|
||||||
className={classNames(CLASSES.FILL, 'form-group--customer')}
|
|
||||||
labelInfo={<FieldRequiredHint />}
|
|
||||||
intent={inputIntent({ error, touched })}
|
|
||||||
helperText={<ErrorMessage name={'customer_id'} />}
|
|
||||||
>
|
|
||||||
<CustomerSelectField
|
|
||||||
contacts={customers}
|
|
||||||
selectedContactId={value}
|
|
||||||
defaultSelectText={<T id={'select_customer_account'} />}
|
|
||||||
onContactSelected={(customer) => {
|
|
||||||
form.setFieldValue('customer_id', customer.id);
|
|
||||||
form.setFieldValue('currency_code', customer?.currency_code);
|
|
||||||
}}
|
|
||||||
popoverFill={true}
|
|
||||||
allowCreate={true}
|
|
||||||
/>
|
|
||||||
{value && (
|
|
||||||
<CustomerButtonLink customerId={value}>
|
|
||||||
<T id={'view_customer_details'} />
|
|
||||||
</CustomerButtonLink>
|
|
||||||
)}
|
|
||||||
</FormGroup>
|
|
||||||
)}
|
|
||||||
</FastField>
|
|
||||||
|
|
||||||
{/* ----------- Exchange rate ----------- */}
|
{/* ----------- Exchange rate ----------- */}
|
||||||
<ReceiptExchangeRateInputField
|
<ReceiptExchangeRateInputField
|
||||||
@@ -264,6 +233,44 @@ export default function ReceiptFormHeader() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Customer select field of receipt form.
|
||||||
|
* @returns {React.ReactNode}
|
||||||
|
*/
|
||||||
|
function ReceiptFormCustomerSelect() {
|
||||||
|
const { setFieldValue, values } = useFormikContext();
|
||||||
|
const { customers } = useReceiptFormContext();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<FFormGroup
|
||||||
|
name={'customer_id'}
|
||||||
|
label={<T id={'customer_name'} />}
|
||||||
|
inline={true}
|
||||||
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
customers={customers}
|
||||||
|
fastField={true}
|
||||||
|
shouldUpdate={customersFieldShouldUpdate}
|
||||||
|
>
|
||||||
|
<CustomersSelect
|
||||||
|
name={'customer_id'}
|
||||||
|
items={customers}
|
||||||
|
placeholder={<T id={'select_customer_account'} />}
|
||||||
|
onItemChange={(customer) => {
|
||||||
|
setFieldValue('customer_id', customer.id);
|
||||||
|
setFieldValue('currency_code', customer?.currency_code);
|
||||||
|
}}
|
||||||
|
popoverFill={true}
|
||||||
|
allowCreate={true}
|
||||||
|
/>
|
||||||
|
{values.customer_id && (
|
||||||
|
<CustomerButtonLink customerId={values.customer_id}>
|
||||||
|
<T id={'view_customer_details'} />
|
||||||
|
</CustomerButtonLink>
|
||||||
|
)}
|
||||||
|
</FFormGroup>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
const CustomerButtonLink = styled(CustomerDrawerLink)`
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
|
|||||||
Reference in New Issue
Block a user