diff --git a/packages/webapp/package-lock.json b/packages/webapp/package-lock.json index 0918dffb5..86134863b 100644 --- a/packages/webapp/package-lock.json +++ b/packages/webapp/package-lock.json @@ -17751,4 +17751,4 @@ "integrity": "sha512-7UlRWU4Q3uCMCeDVMOm7eBrIu145OqsIJ3p6zq58l8UsSYwKWxc6zEapC5YA9tIeh0oheb4cT9Kk2Wq353loFg==" } } -} +} \ No newline at end of file diff --git a/packages/webapp/src/components/Customers/CustomerSelectField.tsx b/packages/webapp/src/components/Customers/CustomerSelectField.tsx deleted file mode 100644 index e7d5dce2a..000000000 --- a/packages/webapp/src/components/Customers/CustomerSelectField.tsx +++ /dev/null @@ -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 = , - 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 ( - - ); -} - -export const CustomerSelectField = R.compose(withDrawerActions)( - CustomerSelectFieldRoot, -); diff --git a/packages/webapp/src/components/Customers/CustomersSelect.tsx b/packages/webapp/src/components/Customers/CustomersSelect.tsx new file mode 100644 index 000000000..60e030314 --- /dev/null +++ b/packages/webapp/src/components/Customers/CustomersSelect.tsx @@ -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 ( + + ); +} + +export const CustomersSelect = R.compose(withDrawerActions)(CustomerSelectRoot); diff --git a/packages/webapp/src/components/Customers/index.tsx b/packages/webapp/src/components/Customers/index.tsx index eb057000f..aef111932 100644 --- a/packages/webapp/src/components/Customers/index.tsx +++ b/packages/webapp/src/components/Customers/index.tsx @@ -1,3 +1,3 @@ // @ts-nocheck -export * from './CustomerSelectField'; export * from './CustomerDrawerLink'; +export * from './CustomersSelect'; diff --git a/packages/webapp/src/components/Vendors/VendorSelectField.tsx b/packages/webapp/src/components/Vendors/VendorSelectField.tsx deleted file mode 100644 index 6883baccb..000000000 --- a/packages/webapp/src/components/Vendors/VendorSelectField.tsx +++ /dev/null @@ -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 = , - 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 ( - - ); -} - -export const VendorSelectField = R.compose(withDrawerActions)( - VendorSelectFieldRoot, -); diff --git a/packages/webapp/src/components/Vendors/VendorsSelect.tsx b/packages/webapp/src/components/Vendors/VendorsSelect.tsx new file mode 100644 index 000000000..4b460d1f4 --- /dev/null +++ b/packages/webapp/src/components/Vendors/VendorsSelect.tsx @@ -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 ( + + ); +} + +export const VendorsSelect = R.compose(withDrawerActions)(VendorsSelectRoot); diff --git a/packages/webapp/src/components/Vendors/index.tsx b/packages/webapp/src/components/Vendors/index.tsx index a57d1571c..ae7471ccc 100644 --- a/packages/webapp/src/components/Vendors/index.tsx +++ b/packages/webapp/src/components/Vendors/index.tsx @@ -1,3 +1,3 @@ // @ts-nocheck export * from './VendorDrawerLink' -export * from './VendorSelectField' \ No newline at end of file +export * from './VendorsSelect'; \ No newline at end of file diff --git a/packages/webapp/src/containers/Expenses/ExpenseForm/ExpenseFormHeaderFields.tsx b/packages/webapp/src/containers/Expenses/ExpenseForm/ExpenseFormHeaderFields.tsx index 103a43b13..067bcda94 100644 --- a/packages/webapp/src/containers/Expenses/ExpenseForm/ExpenseFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Expenses/ExpenseForm/ExpenseFormHeaderFields.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { InputGroup, FormGroup, Position, Classes } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; import { FastField, ErrorMessage } from 'formik'; -import { FormattedMessage as T } from '@/components'; +import { CustomersSelect, FormattedMessage as T } from '@/components'; import classNames from 'classnames'; import { CLASSES } from '@/constants/classes'; import { @@ -121,33 +121,39 @@ export default function ExpenseFormHeader() { )} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - className={classNames('form-group--select-list', Classes.FILL)} - labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} - inline={true} - > - } - onContactSelected={(customer) => { - form.setFieldValue('customer_id', customer.id); - }} - allowCreate={true} - popoverFill={true} - /> - - )} - + {/* ----------- Customer ----------- */} + ); } + +/** + * Customer select field of expense form. + * @returns {React.ReactNode} + */ +function ExpenseFormCustomerSelect() { + const { customers } = useExpenseFormContext(); + + return ( + } + labelInfo={} + inline={true} + name={'customer_id'} + fastField={true} + shouldUpdateDeps={{ items: customers }} + shouldUpdate={customersFieldShouldUpdate} + > + } + allowCreate={true} + popoverFill={true} + fastField={true} + shouldUpdateDeps={{ items: customers }} + shouldUpdate={customersFieldShouldUpdate} + /> + + ); +} diff --git a/packages/webapp/src/containers/Expenses/ExpenseForm/utils.tsx b/packages/webapp/src/containers/Expenses/ExpenseForm/utils.tsx index ff27b127b..73c28bdad 100644 --- a/packages/webapp/src/containers/Expenses/ExpenseForm/utils.tsx +++ b/packages/webapp/src/containers/Expenses/ExpenseForm/utils.tsx @@ -104,7 +104,7 @@ export const transformToEditForm = ( */ export const customersFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.customers !== oldProps.customers || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx b/packages/webapp/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx index d4877d4d5..659f5056a 100644 --- a/packages/webapp/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx +++ b/packages/webapp/src/containers/Projects/containers/ProjectFormDialog/ProjectFormFields.tsx @@ -15,11 +15,10 @@ import { FMoneyInputGroup, InputPrependText, FormattedMessage as T, - FieldRequiredHint, - CustomerSelectField, Stack, + CustomersSelect, } from '@/components'; -import { inputIntent, momentFormatter } from '@/utils'; +import { momentFormatter } from '@/utils'; import { useProjectFormContext } from './ProjectFormProvider'; /** @@ -27,9 +26,6 @@ import { useProjectFormContext } from './ProjectFormProvider'; * @returns */ function ProjectFormFields() { - // project form dialog context. - const { customers } = useProjectFormContext(); - // Formik context. const { values } = useFormikContext(); @@ -37,26 +33,7 @@ function ProjectFormFields() {
{/*------------ Contact -----------*/} - - {({ form, field: { value }, meta: { error, touched } }) => ( - - { - form.setFieldValue('contact_id', customer.id); - }} - allowCreate={true} - popoverFill={true} - /> - - )} - + {/*------------ Project Name -----------*/} + + + ); +} + export default ProjectFormFields; diff --git a/packages/webapp/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx b/packages/webapp/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx index 7e051cb8b..0b797c2e5 100644 --- a/packages/webapp/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Purchases/Bills/BillForm/BillFormHeaderFields.tsx @@ -2,18 +2,18 @@ import React from 'react'; import styled from 'styled-components'; import classNames from 'classnames'; +import { FastField, ErrorMessage, useFormikContext } from 'formik'; import { FormGroup, InputGroup, Classes, Position } from '@blueprintjs/core'; -import { FastField, ErrorMessage } from 'formik'; import { DateInput } from '@blueprintjs/datetime'; + import { FeatureCan, FormattedMessage as T } from '@/components'; import { CLASSES } from '@/constants/classes'; - import { FFormGroup, - VendorSelectField, FieldRequiredHint, Icon, VendorDrawerLink, + VendorsSelect, } from '@/components'; import { useBillFormContext } from './BillFormProvider'; @@ -43,43 +43,7 @@ function BillFormHeader() { return (
{/* ------- Vendor name ------ */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames( - 'form-group--vendor-name', - 'form-group--select-list', - CLASSES.FILL, - )} - labelInfo={} - > - } - onContactSelected={(contact) => { - form.setFieldValue('vendor_id', contact.id); - form.setFieldValue('currency_code', contact?.currency_code); - }} - popoverFill={true} - allowCreate={true} - /> - - {value && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + inline={true} + labelInfo={} + fastField={true} + shouldUpdate={vendorsFieldShouldUpdate} + shouldUpdateDeps={{ items: vendors }} + > + } + onItemChange={(contact) => { + setFieldValue('vendor_id', contact.id); + setFieldValue('currency_code', contact?.currency_code); + }} + allowCreate={true} + fastField={true} + shouldUpdate={vendorsFieldShouldUpdate} + shouldUpdateDeps={{ items: vendors }} + /> + {values.vendor_id && ( + + + + )} + + ); +} + export default compose(withDialogActions)(BillFormHeader); const VendorButtonLink = styled(VendorDrawerLink)` diff --git a/packages/webapp/src/containers/Purchases/Bills/BillForm/utils.tsx b/packages/webapp/src/containers/Purchases/Bills/BillForm/utils.tsx index 272ea3a21..7e7cce017 100644 --- a/packages/webapp/src/containers/Purchases/Bills/BillForm/utils.tsx +++ b/packages/webapp/src/containers/Purchases/Bills/BillForm/utils.tsx @@ -19,7 +19,10 @@ import { ensureEntriesHaveEmptyLine, } from '@/containers/Entries/utils'; import { useCurrentOrganization } from '@/hooks/state'; -import { isLandedCostDisabled, getEntriesTotal } from '@/containers/Entries/utils'; +import { + isLandedCostDisabled, + getEntriesTotal, +} from '@/containers/Entries/utils'; import { useBillFormContext } from './BillFormProvider'; export const MIN_LINES_NUMBER = 1; @@ -153,7 +156,7 @@ export const handleDeleteErrors = (errors) => { */ export const vendorsFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.vendors !== oldProps.vendors || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx index e6db12915..89d76922f 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/VendorCreditNoteFormHeaderFields.tsx @@ -9,17 +9,17 @@ import { ControlGroup, } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FastField, ErrorMessage } from 'formik'; +import { FastField, ErrorMessage, useFormikContext } from 'formik'; import { CLASSES } from '@/constants/classes'; import { FFormGroup, - VendorSelectField, FieldRequiredHint, InputPrependButton, Icon, FormattedMessage as T, VendorDrawerLink, + VendorsSelect, } from '@/components'; import { vendorsFieldShouldUpdate, @@ -51,9 +51,6 @@ function VendorCreditNoteFormHeaderFields({ vendorcreditNumberPrefix, vendorcreditNextNumber, }) { - // Vendor Credit form context. - const { vendors } = useVendorCreditNoteFormContext(); - // Handle vendor credit number changing. const handleVendorCreditNumberChange = () => { openDialog('vendor-credit-form'); @@ -81,39 +78,7 @@ function VendorCreditNoteFormHeaderFields({ return (
{/* ----------- Vendor name ----------- */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames(CLASSES.FILL, 'form-group--vendor')} - labelInfo={} - > - } - onContactSelected={(contact) => { - form.setFieldValue('vendor_id', contact.id); - form.setFieldValue('currency_code', contact?.currency_code); - }} - popoverFill={true} - allowCreate={true} - /> - - {value && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + inline={true} + labelInfo={} + fastField={true} + shouldUpdate={vendorsFieldShouldUpdate} + shouldUpdateDeps={{ items: vendors }} + > + } + onItemChange={(contact) => { + setFieldValue('vendor_id', contact.id); + setFieldValue('currency_code', contact?.currency_code); + }} + popoverFill={true} + allowCreate={true} + fastField={true} + shouldUpdate={vendorsFieldShouldUpdate} + shouldUpdateDeps={{ items: vendors }} + /> + {values.vendor_id && ( + + + + )} + + ); +} + export default compose( withDialogActions, withSettings(({ vendorsCreditNoteSetting }) => ({ diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.tsx index 094f7bb55..db276ea11 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNoteForm/utils.tsx @@ -113,7 +113,7 @@ export const transformFormValuesToRequest = (values) => { */ export const vendorsFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.vendors !== oldProps.vendors || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.tsx b/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.tsx index 2023fcb41..6a72e9968 100644 --- a/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/PaymentMadeFormHeaderFields.tsx @@ -12,14 +12,13 @@ import { } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; 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 { CLASSES } from '@/constants/classes'; import { FFormGroup, AccountsSelect, - VendorSelectField, FieldRequiredHint, InputPrependText, Money, @@ -55,8 +54,7 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) { } = useFormikContext(); // Payment made form context. - const { vendors, accounts, isNewMode, setPaymentVendorId } = - usePaymentMadeFormContext(); + const { accounts } = usePaymentMadeFormContext(); // Sumation of payable full-amount. const payableFullAmount = useMemo( @@ -82,41 +80,7 @@ function PaymentMadeFormHeaderFields({ organization: { base_currency } }) { return (
{/* ------------ Vendor name ------------ */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames('form-group--select-list', Classes.FILL)} - labelInfo={} - > - } - 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 && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + labelInfo={} + inline={true} + fastField={true} + shouldUpdate={vendorsFieldShouldUpdate} + shouldUpdateDeps={{ items: vendors }} + > + } + onItemChange={(contact) => { + setFieldValue('vendor_id', contact.id); + setFieldValue('currency_code', contact?.currency_code); + setPaymentVendorId(contact.id); + }} + disabled={!isNewMode} + allowCreate={true} + fastField={true} + shouldUpdate={vendorsFieldShouldUpdate} + shouldUpdateDeps={{ items: vendors }} + /> + {values.vendor_id && ( + + + + )} + + ); +} + export default compose(withCurrentOrganization())(PaymentMadeFormHeaderFields); const VendorButtonLink = styled(VendorDrawerLink)` diff --git a/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/utils.tsx b/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/utils.tsx index 2858e21ae..0714d1042 100644 --- a/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/utils.tsx +++ b/packages/webapp/src/containers/Purchases/PaymentMades/PaymentForm/utils.tsx @@ -74,7 +74,7 @@ export const transformToNewPageEntries = (entries) => { */ export const vendorsFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.vendors !== oldProps.vendors || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.tsx b/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.tsx index 1c767d790..cd2fc1d1a 100644 --- a/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/CreditNoteFormHeaderFields.tsx @@ -4,15 +4,16 @@ import classNames from 'classnames'; import styled from 'styled-components'; import { FormGroup, InputGroup, Position } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FastField, ErrorMessage } from 'formik'; +import { FastField, ErrorMessage, useFormikContext } from 'formik'; import { CLASSES } from '@/constants/classes'; import { - CustomerSelectField, FieldRequiredHint, Icon, FormattedMessage as T, CustomerDrawerLink, + FFormGroup, + CustomersSelect, } from '@/components'; import { customerNameFieldShouldUpdate } from './utils'; @@ -30,49 +31,10 @@ import { * Credit note form header fields. */ export default function CreditNoteFormHeaderFields({}) { - // Credit note form context. - const { customers } = useCreditNoteFormContext(); - return (
{/* ----------- Customer name ----------- */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames( - 'form-group--customer-name', - 'form-group--select-list', - CLASSES.FILL, - )} - labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} - > - } - onContactSelected={(customer) => { - form.setFieldValue('customer_id', customer.id); - form.setFieldValue('currency_code', customer?.currency_code); - }} - popoverFill={true} - allowCreate={true} - /> - {value && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + labelInfo={} + inline={true} + fastField={true} + shouldUpdate={customerNameFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + > + } + onItemChange={(customer) => { + setFieldValue('customer_id', customer.id); + setFieldValue('currency_code', customer?.currency_code); + }} + popoverFill={true} + allowCreate={true} + fastField={true} + shouldUpdate={customerNameFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + /> + {values.customer_id && ( + + + + )} + + ); +} + const CustomerButtonLink = styled(CustomerDrawerLink)` font-size: 11px; margin-top: 6px; diff --git a/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/utils.tsx b/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/utils.tsx index 11ffb118d..2200146de 100644 --- a/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/utils.tsx +++ b/packages/webapp/src/containers/Sales/CreditNotes/CreditNoteForm/utils.tsx @@ -116,7 +116,7 @@ export const transformFormValuesToRequest = (values) => { */ export const customerNameFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.customers !== oldProps.customers || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx index 513025139..e3bfabb9a 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateForm/EstimateFormHeaderFields.tsx @@ -4,16 +4,16 @@ import styled from 'styled-components'; import classNames from 'classnames'; import { FormGroup, InputGroup, Position, Classes } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FastField, ErrorMessage } from 'formik'; +import { FastField, ErrorMessage, useFormikContext } from 'formik'; import { FeatureCan, FFormGroup, FormattedMessage as T, - CustomerSelectField, FieldRequiredHint, Icon, CustomerDrawerLink, + CustomersSelect, } from '@/components'; import { momentFormatter, @@ -42,41 +42,7 @@ export default function EstimateFormHeader() { return (
{/* ----------- Customer name ----------- */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames(CLASSES.FILL, 'form-group--customer')} - labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} - > - } - onContactSelected={(customer) => { - form.setFieldValue('customer_id', customer.id); - form.setFieldValue('currency_code', customer?.currency_code); - }} - popoverFill={true} - intent={inputIntent({ error, touched })} - allowCreate={true} - /> - - {value && ( - - - - )} - - )} - + {/* ----------- Exchange Rate ----------- */} } + inline={true} + labelInfo={} + name={'customer_id'} + fastField={true} + shouldUpdate={customersFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + > + } + onItemChange={(customer) => { + setFieldValue('customer_id', customer.id); + setFieldValue('currency_code', customer?.currency_code); + }} + popoverFill={true} + allowCreate={true} + fastField={true} + shouldUpdate={customersFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + /> + {values.customer_id && ( + + + + )} + + ); +} + const CustomerButtonLink = styled(CustomerDrawerLink)` font-size: 11px; margin-top: 6px; diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimateForm/utils.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimateForm/utils.tsx index cf2fb74b6..029a3a70d 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimateForm/utils.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimateForm/utils.tsx @@ -80,7 +80,7 @@ export const transformToEditForm = (estimate) => { */ export const customersFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.customers !== oldProps.customers || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx index b3302cbbd..8697e52bc 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/InvoiceFormHeaderFields.tsx @@ -12,9 +12,9 @@ import { Col, Row, CustomerDrawerLink, - CustomerSelectField, FieldRequiredHint, FeatureCan, + CustomersSelect, } from '@/components'; import { momentFormatter, @@ -42,49 +42,13 @@ import { Features } from '@/constants'; */ export default function InvoiceFormHeaderFields() { // Invoice form context. - const { customers, projects } = useInvoiceFormContext(); + const { projects } = useInvoiceFormContext(); const { values } = useFormikContext(); return (
{/* ----------- Customer name ----------- */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames( - 'form-group--customer-name', - 'form-group--select-list', - CLASSES.FILL, - )} - labelInfo={} - > - } - onContactSelected={(customer) => { - form.setFieldValue('customer_id', customer.id); - form.setFieldValue('currency_code', customer?.currency_code); - }} - popoverFill={true} - allowCreate={true} - /> - - {value && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + inline={true} + labelInfo={} + fastField={true} + shouldUpdate={customerNameFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + > + } + onItemChange={(customer) => { + setFieldValue('customer_id', customer.id); + setFieldValue('currency_code', customer?.currency_code); + }} + allowCreate={true} + fastField={true} + shouldUpdate={customerNameFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + /> + {values.customer_id && ( + + + + )} + + ); +} + const CustomerButtonLink = styled(CustomerDrawerLink)` font-size: 11px; margin-top: 6px; diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/utils.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/utils.tsx index 536f0081c..4af9dabb9 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/utils.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoiceForm/utils.tsx @@ -114,7 +114,7 @@ export const transformErrors = (errors, { setErrors }) => { */ export const customerNameFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.customers !== oldProps.customers || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items|| defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx b/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx index db47b1132..9ed1e5503 100644 --- a/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx +++ b/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/PaymentReceiveHeaderFields.tsx @@ -14,8 +14,11 @@ import { DateInput } from '@blueprintjs/datetime'; import { toSafeInteger } from 'lodash'; import { FastField, Field, useFormikContext, ErrorMessage } from 'formik'; -import { FeatureCan, FormattedMessage as T } from '@/components'; -import { useAutofocus } from '@/hooks'; +import { + FeatureCan, + CustomersSelect, + FormattedMessage as T, +} from '@/components'; import { CLASSES } from '@/constants/classes'; import { safeSumBy, @@ -27,7 +30,6 @@ import { import { FFormGroup, AccountsSelect, - CustomerSelectField, FieldRequiredHint, Icon, MoneyInputGroup, @@ -58,8 +60,7 @@ import { PaymentReceivePaymentNoField } from './PaymentReceivePaymentNoField'; */ export default function PaymentReceiveHeaderFields() { // Payment receive form context. - const { customers, accounts, projects, isNewMode } = - usePaymentReceiveFormContext(); + const { accounts, projects } = usePaymentReceiveFormContext(); // Formik form context. const { @@ -67,8 +68,6 @@ export default function PaymentReceiveHeaderFields() { setFieldValue, } = useFormikContext(); - const customerFieldRef = useAutofocus(); - // Calculates the full-amount received. const totalDueAmount = useMemo( () => safeSumBy(entries, 'due_amount'), @@ -91,45 +90,7 @@ export default function PaymentReceiveHeaderFields() { return (
{/* ------------- Customer name ------------- */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames('form-group--select-list', CLASSES.FILL)} - labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} - > - } - 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 && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + inline={true} + labelInfo={} + name={'customer_id'} + fastField={true} + shouldUpdate={customersFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + > + } + onItemChange={(customer) => { + setFieldValue('customer_id', customer.id); + setFieldValue('full_amount', ''); + setFieldValue('currency_code', customer?.currency_code); + }} + popoverFill={true} + disabled={!isNewMode} + allowCreate={true} + fastField={true} + shouldUpdate={customersFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + /> + {values.customer_id && ( + + + + )} + + ); +} diff --git a/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/utils.tsx b/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/utils.tsx index ec33a1b64..900eb9f9a 100644 --- a/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/utils.tsx +++ b/packages/webapp/src/containers/Sales/PaymentReceives/PaymentReceiveForm/utils.tsx @@ -129,7 +129,7 @@ export const fullAmountPaymentEntries = (entries) => { */ export const customersFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.customers !== oldProps.customers || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx index b269d724c..92ef297cb 100644 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/ReceiptFormHeaderFields.tsx @@ -4,7 +4,7 @@ import styled from 'styled-components'; import classNames from 'classnames'; import { FormGroup, InputGroup, Position, Classes } from '@blueprintjs/core'; import { DateInput } from '@blueprintjs/datetime'; -import { FastField, ErrorMessage } from 'formik'; +import { FastField, ErrorMessage, useFormikContext } from 'formik'; import { CLASSES } from '@/constants/classes'; import { ACCOUNT_TYPE } from '@/constants/accountTypes'; @@ -12,7 +12,7 @@ import { Features } from '@/constants'; import { FFormGroup, AccountsSelect, - CustomerSelectField, + CustomersSelect, FieldRequiredHint, Icon, CustomerDrawerLink, @@ -38,44 +38,12 @@ import { ReceiptFormReceiptNumberField } from './ReceiptFormReceiptNumberField'; * Receipt form header fields. */ export default function ReceiptFormHeader() { - const { accounts, customers, projects } = useReceiptFormContext(); + const { accounts, projects } = useReceiptFormContext(); return (
{/* ----------- Customer name ----------- */} - - {({ form, field: { value }, meta: { error, touched } }) => ( - } - inline={true} - className={classNames(CLASSES.FILL, 'form-group--customer')} - labelInfo={} - intent={inputIntent({ error, touched })} - helperText={} - > - } - onContactSelected={(customer) => { - form.setFieldValue('customer_id', customer.id); - form.setFieldValue('currency_code', customer?.currency_code); - }} - popoverFill={true} - allowCreate={true} - /> - {value && ( - - - - )} - - )} - + {/* ----------- Exchange rate ----------- */} } + labelInfo={} + inline={true} + fastField={true} + shouldUpdate={customersFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + > + } + onItemChange={(customer) => { + setFieldValue('customer_id', customer.id); + setFieldValue('currency_code', customer?.currency_code); + }} + popoverFill={true} + allowCreate={true} + fastField={true} + shouldUpdate={customersFieldShouldUpdate} + shouldUpdateDeps={{ items: customers }} + /> + {values.customer_id && ( + + + + )} + + ); +} + const CustomerButtonLink = styled(CustomerDrawerLink)` font-size: 11px; margin-top: 6px; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/utils.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/utils.tsx index 4dcaec4b2..b1f766d3b 100644 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/utils.tsx +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptForm/utils.tsx @@ -104,7 +104,7 @@ export const accountsFieldShouldUpdate = (newProps, oldProps) => { */ export const customersFieldShouldUpdate = (newProps, oldProps) => { return ( - newProps.customers !== oldProps.customers || + newProps.shouldUpdateDeps.items !== oldProps.shouldUpdateDeps.items || defaultFastFieldShouldUpdate(newProps, oldProps) ); }; diff --git a/packages/webapp/src/lang/en/index.json b/packages/webapp/src/lang/en/index.json index 60cacb3a0..a329faa9b 100644 --- a/packages/webapp/src/lang/en/index.json +++ b/packages/webapp/src/lang/en/index.json @@ -379,7 +379,7 @@ "the_expenses_have_been_deleted_successfully": "The expenses have been deleted successfully", "once_delete_these_expenses_you_will_not_able_restore_them": "Once you delete these expenses, you won't be able to retrieve them later. Are you sure you want to delete them?", "the_expense_has_been_published": "The expense has been published", - "select_customer": "Select customer", + "select_customer": "Select Customer...", "total_amount_equals_zero": "Total amount equals zero", "value": "Value", "you_reached_conditions_limit": "You have reached to conditions limit.", @@ -480,7 +480,7 @@ "estimate_date": "Estimate Date", "expiration_date": "Expiration Date", "customer_note": "Customer Note", - "select_customer_account": "Select Customer Account", + "select_customer_account": "Select Customer Account...", "select_product": "Select Product", "reference": "Reference #", "clear": "Clear",