mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 06:10:31 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
63
client/src/components/ContactSelecetList.js
Normal file
63
client/src/components/ContactSelecetList.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import React, { useCallback, useState, useEffect, useMemo } from 'react';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { ListSelect } from 'components';
|
||||
import { MenuItem } from '@blueprintjs/core';
|
||||
|
||||
export default function ContactSelecetList({
|
||||
contactsList,
|
||||
selectedContactId,
|
||||
defaultSelectText = <T id={'select_contact'} />,
|
||||
onContactSelected,
|
||||
// disabled = false,
|
||||
...restProps
|
||||
}) {
|
||||
const [selecetedContact, setSelectedContact] = useState(null);
|
||||
|
||||
// Filter Contact List
|
||||
const FilterContacts = (query, contact, index, exactMatch) => {
|
||||
const normalizedTitle = contact.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${contact.display_name} ${normalizedTitle}`.indexOf(normalizedQuery) >=
|
||||
0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onContactSelect = useCallback(
|
||||
(contact) => {
|
||||
setSelectedContact({ ...contact });
|
||||
onContactSelected && onContactSelected(contact);
|
||||
},
|
||||
[setSelectedContact, onContactSelected],
|
||||
);
|
||||
|
||||
const handleContactRenderer = useCallback(
|
||||
(contact, { handleClick }) => (
|
||||
<MenuItem
|
||||
key={contact.id}
|
||||
text={contact.display_name}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
return (
|
||||
<ListSelect
|
||||
items={contactsList}
|
||||
selectedItemProp={'id'}
|
||||
selectedItem={selectedContactId}
|
||||
labelProp={'display_name'}
|
||||
defaultText={defaultSelectText}
|
||||
onItemSelect={onContactSelect}
|
||||
itemPredicate={FilterContacts}
|
||||
itemRenderer={handleContactRenderer}
|
||||
popoverProps={{ minimal: true }}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import Row from './Grid/Row';
|
||||
import Col from './Grid/Col';
|
||||
import CloudLoadingIndicator from './CloudLoadingIndicator';
|
||||
import MoneyExchangeRate from './MoneyExchangeRate';
|
||||
import ContactSelecetList from './ContactSelecetList';
|
||||
|
||||
const Hint = FieldHint;
|
||||
|
||||
@@ -67,4 +68,5 @@ export {
|
||||
Row,
|
||||
CloudLoadingIndicator,
|
||||
MoneyExchangeRate,
|
||||
ContactSelecetList ,
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
AccountsSelectList,
|
||||
FieldRequiredHint,
|
||||
@@ -29,7 +30,7 @@ function ExpenseFormHeader({
|
||||
currenciesList,
|
||||
accountsList,
|
||||
accountsTypes,
|
||||
customersItems,
|
||||
customers,
|
||||
}) {
|
||||
const [selectedItems, setSelectedItems] = useState({});
|
||||
|
||||
@@ -101,21 +102,6 @@ function ExpenseFormHeader({
|
||||
[],
|
||||
);
|
||||
|
||||
// Filter Customer
|
||||
const filterCustomer = (query, customer, _index, exactMatch) => {
|
||||
const normalizedTitle = customer.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${customer.display_name} ${normalizedTitle}`.indexOf(
|
||||
normalizedQuery,
|
||||
) >= 0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// handle change customer
|
||||
const onChangeCustomer = useCallback(
|
||||
(filedName) => {
|
||||
@@ -142,17 +128,11 @@ function ExpenseFormHeader({
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={customersItems}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={CustomerRenderer}
|
||||
itemPredicate={filterCustomer}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeCustomer('customer_id')}
|
||||
selectedItem={values.customer_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_customer_account'} />}
|
||||
labelProp={'display_name'}
|
||||
<ContactSelecetList
|
||||
contactsList={customers}
|
||||
selectedContactId={values.customer_id}
|
||||
defaultSelectText={<T id={'select_customer_account'} />}
|
||||
onContactSelected={onChangeCustomer('customer_id')}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
@@ -273,7 +253,7 @@ export default compose(
|
||||
withCurrencies(({ currenciesList }) => ({
|
||||
currenciesList,
|
||||
})),
|
||||
withCustomers(({ customersItems }) => ({
|
||||
customersItems,
|
||||
withCustomers(({ customers }) => ({
|
||||
customers,
|
||||
})),
|
||||
)(ExpenseFormHeader);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import {
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
Row,
|
||||
@@ -49,31 +49,6 @@ function BillFormHeader({
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
const vendorNameRenderer = useCallback(
|
||||
(accept, { handleClick }) => (
|
||||
<MenuItem
|
||||
key={accept.id}
|
||||
text={accept.display_name}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
// Filter vendor name
|
||||
const filterVendorAccount = (query, vendor, _index, exactMatch) => {
|
||||
const normalizedTitle = vendor.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${vendor.display_name} ${normalizedTitle}`.indexOf(normalizedQuery) >=
|
||||
0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBillNumberBlur = (event) => {
|
||||
onBillNumberChanged && onBillNumberChanged(event.currentTarget.value);
|
||||
};
|
||||
@@ -96,17 +71,11 @@ function BillFormHeader({
|
||||
<ErrorMessage name={'vendor_id'} {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={vendorItems}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={vendorNameRenderer}
|
||||
itemPredicate={filterVendorAccount}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeSelected('vendor_id')}
|
||||
selectedItem={values.vendor_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_vendor_account'} />}
|
||||
labelProp={'display_name'}
|
||||
<ContactSelecetList
|
||||
contactsList={vendorItems}
|
||||
selectedContactId={values.vendor_id}
|
||||
defaultSelectText={ <T id={'select_vender_account'} /> }
|
||||
onContactSelected={onChangeSelected('vendor_id')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -140,7 +109,7 @@ function BillFormHeader({
|
||||
className={classNames(
|
||||
'form-group--due-date',
|
||||
'form-group--select-list',
|
||||
CLASSES.FILL
|
||||
CLASSES.FILL,
|
||||
)}
|
||||
intent={errors.due_date && touched.due_date && Intent.DANGER}
|
||||
helperText={
|
||||
|
||||
@@ -16,7 +16,7 @@ import { CLASSES } from 'common/classes';
|
||||
import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||
import {
|
||||
AccountsSelectList,
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
Money,
|
||||
@@ -60,39 +60,14 @@ function PaymentMadeFormHeader({
|
||||
},
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
const handleVenderRenderer = useCallback(
|
||||
(vender, { handleClick }) => (
|
||||
<MenuItem
|
||||
key={vender.id}
|
||||
text={vender.display_name}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const triggerFullAmountChanged = (value) => {
|
||||
onFullAmountChanged && onFullAmountChanged(value);
|
||||
}
|
||||
};
|
||||
|
||||
const handleFullAmountBlur = (event) => {
|
||||
triggerFullAmountChanged(event.currentTarget.value);
|
||||
};
|
||||
|
||||
const handleFilterVender = (query, vender, index, exactMatch) => {
|
||||
const normalizedTitle = vender.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${vender.display_name} ${normalizedTitle}`.indexOf(normalizedQuery) >=
|
||||
0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeSelect = useCallback(
|
||||
(filedName) => {
|
||||
return (item) => {
|
||||
@@ -131,18 +106,11 @@ function PaymentMadeFormHeader({
|
||||
<ErrorMessage name={'vendor_id'} {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={vendorItems}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={handleVenderRenderer}
|
||||
itemPredicate={handleFilterVender}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeSelect('vendor_id')}
|
||||
selectedItem={values.vendor_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_vender_account'} />}
|
||||
labelProp={'display_name'}
|
||||
buttonProps={{ disabled: !isNewMode }}
|
||||
<ContactSelecetList
|
||||
contactsList={vendorItems}
|
||||
selectedContactId={values.vendor_id}
|
||||
defaultSelectText={ <T id={'select_vender_account'} /> }
|
||||
onContactSelected={onChangeSelect('vendor_id')}
|
||||
disabled={!isNewMode}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -14,7 +14,7 @@ import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import {
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
@@ -53,21 +53,6 @@ function EstimateFormHeader({
|
||||
[],
|
||||
);
|
||||
|
||||
// Filter Customer
|
||||
const filterCustomer = (query, customer, _index, exactMatch) => {
|
||||
const normalizedTitle = customer.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${customer.display_name} ${normalizedTitle}`.indexOf(
|
||||
normalizedQuery,
|
||||
) >= 0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// handle change customer
|
||||
const onChangeCustomer = useCallback(
|
||||
(filedName) => {
|
||||
@@ -99,17 +84,11 @@ function EstimateFormHeader({
|
||||
<ErrorMessage name={'customer_id'} {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={customers}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={CustomerRenderer}
|
||||
itemPredicate={filterCustomer}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeCustomer('customer_id')}
|
||||
selectedItem={values.customer_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_customer_account'} />}
|
||||
labelProp={'display_name'}
|
||||
<ContactSelecetList
|
||||
contactsList={customers}
|
||||
selectedContactId={values.customer_id}
|
||||
defaultSelectText={<T id={'select_customer_account'} />}
|
||||
onContactSelected={onChangeCustomer('customer_id')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import {
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
@@ -52,21 +52,6 @@ function InvoiceFormHeader({
|
||||
[],
|
||||
);
|
||||
|
||||
// Filter Customer
|
||||
const filterCustomer = (query, customer, _index, exactMatch) => {
|
||||
const normalizedTitle = customer.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${customer.display_name} ${normalizedTitle}`.indexOf(
|
||||
normalizedQuery,
|
||||
) >= 0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// handle change customer
|
||||
const onChangeCustomer = useCallback(
|
||||
(filedName) => {
|
||||
@@ -99,17 +84,11 @@ function InvoiceFormHeader({
|
||||
<ErrorMessage name={'customer_id'} {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={customers}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={CustomerRenderer}
|
||||
itemPredicate={filterCustomer}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeCustomer('customer_id')}
|
||||
selectedItem={values.customer_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_customer_account'} />}
|
||||
labelProp={'display_name'}
|
||||
<ContactSelecetList
|
||||
contactsList={customers}
|
||||
selectedContactId={values.customer_id}
|
||||
defaultSelectText={<T id={'select_customer_account'} />}
|
||||
onContactSelected={onChangeCustomer('customer_id')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { CLASSES } from 'common/classes';
|
||||
import { momentFormatter, compose, tansformDateValue } from 'utils';
|
||||
import {
|
||||
AccountsSelectList,
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
Hint,
|
||||
@@ -55,31 +55,6 @@ function PaymentReceiveFormHeader({
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
const handleCusomterRenderer = useCallback(
|
||||
(custom, { handleClick }) => (
|
||||
<MenuItem
|
||||
key={custom.id}
|
||||
text={custom.display_name}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
const handleFilterCustomer = (query, customer, index, exactMatch) => {
|
||||
const normalizedTitle = customer.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${customer.display_name} ${normalizedTitle}`.indexOf(
|
||||
normalizedQuery,
|
||||
) >= 0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onChangeSelect = useCallback(
|
||||
(filedName) => {
|
||||
return (item) => {
|
||||
@@ -124,17 +99,11 @@ function PaymentReceiveFormHeader({
|
||||
<ErrorMessage name={'customer_id'} {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={customers}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={handleCusomterRenderer}
|
||||
itemPredicate={handleFilterCustomer}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeSelect('customer_id')}
|
||||
selectedItem={values.customer_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_customer_account'} />}
|
||||
labelProp={'display_name'}
|
||||
<ContactSelecetList
|
||||
contactsList={customers}
|
||||
selectedContactId={values.customer_id}
|
||||
defaultSelectText={<T id={'select_customer_account'} />}
|
||||
onContactSelected={onChangeSelect('customer_id')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
import {
|
||||
AccountsSelectList,
|
||||
ListSelect,
|
||||
ContactSelecetList,
|
||||
ErrorMessage,
|
||||
FieldRequiredHint,
|
||||
Icon,
|
||||
@@ -44,32 +44,6 @@ function ReceiptFormHeader({
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
const CustomerRenderer = useCallback(
|
||||
(cutomer, { handleClick }) => (
|
||||
<MenuItem
|
||||
key={cutomer.id}
|
||||
text={cutomer.display_name}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[],
|
||||
);
|
||||
|
||||
// Filter Customer
|
||||
const filterCustomer = (query, customer, _index, exactMatch) => {
|
||||
const normalizedTitle = customer.display_name.toLowerCase();
|
||||
const normalizedQuery = query.toLowerCase();
|
||||
if (exactMatch) {
|
||||
return normalizedTitle === normalizedQuery;
|
||||
} else {
|
||||
return (
|
||||
`${customer.display_name} ${normalizedTitle}`.indexOf(
|
||||
normalizedQuery,
|
||||
) >= 0
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// handle change
|
||||
const onChangeSelect = useCallback(
|
||||
(filedName) => {
|
||||
@@ -108,17 +82,11 @@ function ReceiptFormHeader({
|
||||
<ErrorMessage name={'customer_id'} {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<ListSelect
|
||||
items={customers}
|
||||
noResults={<MenuItem disabled={true} text="No results." />}
|
||||
itemRenderer={CustomerRenderer}
|
||||
itemPredicate={filterCustomer}
|
||||
popoverProps={{ minimal: true }}
|
||||
onItemSelect={onChangeSelect('customer_id')}
|
||||
selectedItem={values.customer_id}
|
||||
selectedItemProp={'id'}
|
||||
defaultText={<T id={'select_customer_account'} />}
|
||||
labelProp={'display_name'}
|
||||
<ContactSelecetList
|
||||
contactsList={customers}
|
||||
selectedContactId={values.customer_id}
|
||||
defaultSelectText={<T id={'select_customer_account'} />}
|
||||
onContactSelected={onChangeSelect('customer_id')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user