mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 12:20:31 +00:00
BIG-59: Refactoring mutli-select component.
This commit is contained in:
@@ -1,76 +1,30 @@
|
||||
import React, { useMemo, useCallback, useState } from 'react';
|
||||
import { omit } from 'lodash';
|
||||
import { MenuItem, Button } from '@blueprintjs/core';
|
||||
import MultiSelect from 'components/MultiSelect';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
|
||||
export default function AccountsMultiSelect({ accounts, onAccountSelected }) {
|
||||
const [selectedAccounts, setSelectedAccounts] = useState({});
|
||||
|
||||
const isAccountSelect = useCallback(
|
||||
(accountId) => {
|
||||
return 'undefined' !== typeof selectedAccounts[accountId];
|
||||
},
|
||||
[selectedAccounts],
|
||||
);
|
||||
|
||||
// Account item of select accounts field.
|
||||
const accountItem = useCallback(
|
||||
(item, { handleClick, modifiers, query }) => {
|
||||
return (
|
||||
<MenuItem
|
||||
icon={isAccountSelect(item.id) ? 'tick' : 'blank'}
|
||||
text={item.name}
|
||||
label={item.code}
|
||||
key={item.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
);
|
||||
},
|
||||
[isAccountSelect],
|
||||
);
|
||||
|
||||
const countSelectedAccounts = useMemo(
|
||||
() => Object.values(selectedAccounts).length,
|
||||
[selectedAccounts],
|
||||
);
|
||||
|
||||
const onAccountSelect = useCallback(
|
||||
(account) => {
|
||||
const selected = {
|
||||
...(!isAccountSelect(account.id)
|
||||
? {
|
||||
...selectedAccounts,
|
||||
[account.id]: true,
|
||||
}
|
||||
: {
|
||||
...omit(selectedAccounts, [account.id]),
|
||||
}),
|
||||
};
|
||||
setSelectedAccounts({ ...selected });
|
||||
onAccountSelected && onAccountSelected(selected);
|
||||
},
|
||||
[setSelectedAccounts, selectedAccounts, isAccountSelect, onAccountSelected],
|
||||
);
|
||||
import React from 'react';
|
||||
import { MenuItem } from '@blueprintjs/core';
|
||||
import { MultiSelect } from './MultiSelectTaggable';
|
||||
|
||||
export default function AccountsMultiSelect({ ...multiSelectProps }) {
|
||||
return (
|
||||
<MultiSelect
|
||||
items={accounts}
|
||||
noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
|
||||
itemRenderer={accountItem}
|
||||
itemRenderer={(
|
||||
item,
|
||||
{ active, selected, handleClick, modifiers, query },
|
||||
) => {
|
||||
return (
|
||||
<MenuItem
|
||||
active={active}
|
||||
icon={selected ? 'tick' : 'blank'}
|
||||
text={item.name}
|
||||
label={item.code}
|
||||
key={item.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
popoverProps={{ minimal: true }}
|
||||
filterable={true}
|
||||
onItemSelect={onAccountSelect}
|
||||
>
|
||||
<Button
|
||||
text={
|
||||
countSelectedAccounts === 0 ? (
|
||||
<T id={'all_accounts'} />
|
||||
) : (
|
||||
`(${countSelectedAccounts}) Selected accounts`
|
||||
)
|
||||
}
|
||||
/>
|
||||
</MultiSelect>
|
||||
fill={true}
|
||||
tagRenderer={(item) => item.name}
|
||||
resetOnSelect={true}
|
||||
{...multiSelectProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,59 +1,11 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { MenuItem, Button } from '@blueprintjs/core';
|
||||
import intl from 'react-intl-universal';
|
||||
import MultiSelect from 'components/MultiSelect';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
import { safeInvoke } from 'utils';
|
||||
import React, { useCallback } from 'react';
|
||||
import { MenuItem } from '@blueprintjs/core';
|
||||
import { MultiSelect } from '../components/MultiSelectTaggable';
|
||||
|
||||
/**
|
||||
* Contacts multi-select component.
|
||||
*/
|
||||
export default function ContactsMultiSelect({
|
||||
contacts,
|
||||
defaultText = <T id={'all_customers'} />,
|
||||
buttonProps,
|
||||
|
||||
onContactSelect,
|
||||
contactsSelected = [],
|
||||
...multiSelectProps
|
||||
}) {
|
||||
const [localSelected, setLocalSelected] = useState([...contactsSelected]);
|
||||
|
||||
// Detarmines the given id is selected.
|
||||
const isItemSelected = useCallback(
|
||||
(id) => localSelected.some((s) => s === id),
|
||||
[localSelected],
|
||||
);
|
||||
|
||||
// Contact item renderer.
|
||||
const contactRenderer = useCallback(
|
||||
(contact, { handleClick }) => (
|
||||
<MenuItem
|
||||
icon={isItemSelected(contact.id) ? 'tick' : 'blank'}
|
||||
text={contact.display_name}
|
||||
key={contact.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[isItemSelected],
|
||||
);
|
||||
|
||||
// Count selected items.
|
||||
const countSelected = localSelected.length;
|
||||
|
||||
// Handle item selected.
|
||||
const handleItemSelect = useCallback(
|
||||
({ id }) => {
|
||||
const selected = isItemSelected(id)
|
||||
? localSelected.filter((s) => s !== id)
|
||||
: [...localSelected, id];
|
||||
|
||||
setLocalSelected([...selected]);
|
||||
safeInvoke(onContactSelect, selected);
|
||||
},
|
||||
[setLocalSelected, localSelected, isItemSelected, onContactSelect],
|
||||
);
|
||||
|
||||
export default function ContactsMultiSelect({ ...multiSelectProps }) {
|
||||
// Filters accounts items.
|
||||
const filterContactsPredicater = useCallback(
|
||||
(query, contact, _index, exactMatch) => {
|
||||
@@ -71,23 +23,20 @@ export default function ContactsMultiSelect({
|
||||
|
||||
return (
|
||||
<MultiSelect
|
||||
items={contacts}
|
||||
noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
|
||||
itemRenderer={contactRenderer}
|
||||
itemRenderer={(contact, { selected, active, handleClick }) => (
|
||||
<MenuItem
|
||||
active={active}
|
||||
icon={selected ? 'tick' : 'blank'}
|
||||
text={contact.display_name}
|
||||
key={contact.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
)}
|
||||
popoverProps={{ minimal: true }}
|
||||
filterable={true}
|
||||
onItemSelect={handleItemSelect}
|
||||
fill={true}
|
||||
itemPredicate={filterContactsPredicater}
|
||||
tagRenderer={(item) => item.display_name}
|
||||
{...multiSelectProps}
|
||||
>
|
||||
<Button
|
||||
text={
|
||||
countSelected === 0
|
||||
? defaultText
|
||||
: intl.get('selected_customers', { count: countSelected })
|
||||
}
|
||||
{...buttonProps}
|
||||
/>
|
||||
</MultiSelect>
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,64 +1,11 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { MenuItem, Button, Intent } from '@blueprintjs/core';
|
||||
import { MultiSelect } from '@blueprintjs/select';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
import { safeInvoke } from 'utils';
|
||||
import React, { useCallback } from 'react';
|
||||
import { MenuItem } from '@blueprintjs/core';
|
||||
import { MultiSelect } from '../../components';
|
||||
|
||||
/**
|
||||
* Items multi-select.
|
||||
*/
|
||||
export function ItemsMultiSelect({
|
||||
items,
|
||||
defaultText = <T id={'All items'} />,
|
||||
buttonProps,
|
||||
onTagRenderer,
|
||||
selectedItems = [],
|
||||
onItemSelect,
|
||||
...multiSelectProps
|
||||
}) {
|
||||
const [localSelected, setLocalSelected] = useState([...selectedItems]);
|
||||
|
||||
// Detarmines the given id is selected.
|
||||
const isItemSelected = useCallback(
|
||||
(id) => localSelected.some((s) => s === id),
|
||||
[localSelected],
|
||||
);
|
||||
|
||||
// Contact item renderer.
|
||||
const itemRenderer = useCallback(
|
||||
(item, { handleClick }) => (
|
||||
<MenuItem
|
||||
icon={isItemSelected(item.id) ? 'tick' : 'blank'}
|
||||
text={item.name}
|
||||
label={item.code}
|
||||
key={item.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
),
|
||||
[isItemSelected],
|
||||
);
|
||||
|
||||
// Handle item selected.
|
||||
const handleItemSelect = useCallback(
|
||||
({ id }) => {
|
||||
const selected = isItemSelected(id)
|
||||
? localSelected.filter((s) => s !== id)
|
||||
: [...localSelected, id];
|
||||
|
||||
setLocalSelected([...selected]);
|
||||
safeInvoke(onItemSelect, selected);
|
||||
},
|
||||
[setLocalSelected, localSelected, isItemSelected, onItemSelect],
|
||||
);
|
||||
|
||||
const itemsSelected = () => {
|
||||
const results = [];
|
||||
items.map(({ id, name }) => {
|
||||
return isItemSelected(id) ? results.push(name) : [];
|
||||
});
|
||||
return results;
|
||||
};
|
||||
|
||||
export function ItemsMultiSelect({ ...multiSelectProps }) {
|
||||
// Filters accounts items.
|
||||
const filterItemsPredicater = useCallback(
|
||||
(query, item, _index, exactMatch) => {
|
||||
@@ -74,48 +21,28 @@ export function ItemsMultiSelect({
|
||||
[],
|
||||
);
|
||||
|
||||
// Count selected items.
|
||||
const countSelected = itemsSelected().length;
|
||||
|
||||
// Clear Button
|
||||
const clearButton =
|
||||
countSelected > 0 ? (
|
||||
<Button
|
||||
icon="cross"
|
||||
minimal={true}
|
||||
// onClick={() => setLocalSelected([])}
|
||||
/>
|
||||
) : undefined;
|
||||
|
||||
// handle remove tag
|
||||
const handleTagRemove = (tag) => {
|
||||
let tagList = localSelected.filter((s) => s !== tag);
|
||||
setLocalSelected(tagList);
|
||||
};
|
||||
|
||||
return (
|
||||
<MultiSelect
|
||||
items={items}
|
||||
noResults={<MenuItem disabled={true} text={<T id={'No items'} />} />}
|
||||
itemRenderer={itemRenderer}
|
||||
popoverProps={{
|
||||
minimal: true,
|
||||
usePortal: false,
|
||||
targetTagName: 'div ',
|
||||
}}
|
||||
selectedItems={itemsSelected()}
|
||||
itemRenderer={(item, { selected, handleClick, active }) => (
|
||||
<MenuItem
|
||||
active={active}
|
||||
icon={selected ? 'tick' : 'blank'}
|
||||
text={item.name}
|
||||
label={item.code}
|
||||
key={item.id}
|
||||
onClick={handleClick}
|
||||
/>
|
||||
)}
|
||||
popoverProps={{ minimal: true, usePortal: false, targetTagName: 'div ' }}
|
||||
fill={true}
|
||||
onItemSelect={handleItemSelect}
|
||||
itemPredicate={filterItemsPredicater}
|
||||
tagRenderer={onTagRenderer}
|
||||
tagInputProps={{
|
||||
tagProps: { intent: Intent.NONE, minimal: false },
|
||||
onRemove: handleTagRemove,
|
||||
// rightElement: clearButton,
|
||||
}}
|
||||
tagRenderer={(item) => item.name}
|
||||
resetOnSelect={true}
|
||||
// openOnKeyDown={true}
|
||||
{...multiSelectProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
ItemsMultiSelect.defaultProps = {
|
||||
initialSelectedItems: [],
|
||||
};
|
||||
|
||||
81
client/src/components/MultiSelectTaggable/index.js
Normal file
81
client/src/components/MultiSelectTaggable/index.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { includes } from 'lodash';
|
||||
import { MenuItem } from '@blueprintjs/core';
|
||||
import { MultiSelect as MultiSelectBP } from '@blueprintjs/select';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
import { safeInvoke } from 'utils';
|
||||
|
||||
/**
|
||||
* Items multi-select.
|
||||
*/
|
||||
export function MultiSelect({
|
||||
items,
|
||||
initialSelectedItems,
|
||||
onItemSelect,
|
||||
...multiSelectProps
|
||||
}) {
|
||||
const [localSelected, setLocalSelected] = useState(initialSelectedItems);
|
||||
|
||||
// Detarmines whether the given id is selected.
|
||||
const isItemSelected = useCallback(
|
||||
(item) => includes(localSelected, item),
|
||||
[localSelected],
|
||||
);
|
||||
|
||||
// Removes the given item from selected items.
|
||||
const removeSelectedItem = React.useCallback(
|
||||
(item) => localSelected.filter((localItem) => localItem !== item),
|
||||
[localSelected],
|
||||
);
|
||||
|
||||
// Adds the given item to selected items.
|
||||
const addSelectedItem = React.useCallback(
|
||||
(item) => [...localSelected, item],
|
||||
[localSelected],
|
||||
);
|
||||
|
||||
// Handle item selected.
|
||||
const handleItemSelect = useCallback(
|
||||
(item) => {
|
||||
const selected = isItemSelected(item)
|
||||
? removeSelectedItem(item)
|
||||
: addSelectedItem(item);
|
||||
|
||||
setLocalSelected(selected);
|
||||
safeInvoke(onItemSelect, selected);
|
||||
},
|
||||
[addSelectedItem, removeSelectedItem, isItemSelected, onItemSelect],
|
||||
);
|
||||
|
||||
// handle remove tag
|
||||
const handleTagRemove = (item) => {
|
||||
const selected = removeSelectedItem(item);
|
||||
|
||||
setLocalSelected(selected);
|
||||
safeInvoke(onItemSelect, selected);
|
||||
};
|
||||
const itemRenderer = (item, props) => {
|
||||
return multiSelectProps.itemRenderer(item, {
|
||||
selected: isItemSelected(item),
|
||||
...props,
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<MultiSelectBP
|
||||
items={items}
|
||||
noResults={<MenuItem disabled={true} text={<T id={'No items'} />} />}
|
||||
tagInputProps={{
|
||||
onRemove: handleTagRemove,
|
||||
}}
|
||||
{...multiSelectProps}
|
||||
itemRenderer={itemRenderer}
|
||||
selectedItems={localSelected}
|
||||
onItemSelect={handleItemSelect}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
MultiSelect.defaultProps = {
|
||||
initialSelectedItems: [],
|
||||
};
|
||||
@@ -77,7 +77,7 @@ export * from './Subscriptions';
|
||||
export * from './Dashboard';
|
||||
export * from './Drawer';
|
||||
export * from './Forms';
|
||||
|
||||
export * from './MultiSelectTaggable'
|
||||
const Hint = FieldHint;
|
||||
|
||||
const T = FormattedMessage;
|
||||
|
||||
@@ -99,11 +99,10 @@ export default function APAgingSummaryHeaderGeneralContent() {
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
defaultText={<T id={'all_vendors'} />}
|
||||
contacts={vendors}
|
||||
contactsSelected={value}
|
||||
onContactSelect={(contactsIds) => {
|
||||
setFieldValue('vendorsIds', contactsIds);
|
||||
items={vendors}
|
||||
onItemSelect={(vendors) => {
|
||||
const vendorsIds = vendors.map((customer) => customer.id);
|
||||
setFieldValue('vendorsIds', vendorsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -105,10 +105,12 @@ export default function ARAgingSummaryHeaderGeneralContent() {
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
contacts={customers}
|
||||
contactsSelected={value}
|
||||
onContactSelect={(contactsIds) => {
|
||||
setFieldValue('customersIds', contactsIds);
|
||||
items={customers}
|
||||
onItemSelect={(customers) => {
|
||||
const customersIds = customers.map(
|
||||
(customer) => customer.id,
|
||||
);
|
||||
setFieldValue('customersIds', customersIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -74,15 +74,15 @@ export default function CustomersBalanceSummaryGeneralPanelContent() {
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific customers'} />}
|
||||
label={<T id={'specific_customers'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
onContactSelect={(contactsIds) => {
|
||||
setFieldValue('customersIds', contactsIds);
|
||||
items={customers}
|
||||
onItemSelect={(contacts) => {
|
||||
const customersIds = contacts.map(contact => contact.id);
|
||||
setFieldValue('customersIds', customersIds);
|
||||
}}
|
||||
contacts={customers}
|
||||
contactsSelected={value}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
||||
@@ -3,8 +3,12 @@ import classNames from 'classnames';
|
||||
import { Field } from 'formik';
|
||||
import { Classes, FormGroup } from '@blueprintjs/core';
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
import { Row, Col } from 'components';
|
||||
import { ContactsMultiSelect, FormattedMessage as T } from 'components';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
ContactsMultiSelect,
|
||||
FormattedMessage as T,
|
||||
} from '../../../components';
|
||||
import {
|
||||
CustomersTransactionsGeneralPanelProvider,
|
||||
useCustomersTransactionsGeneralPanelContext,
|
||||
@@ -40,11 +44,13 @@ function CustomersTransactionsHeaderGeneralPanelContent() {
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
onContactSelect={(contactsIds) => {
|
||||
setFieldValue('customersIds', contactsIds);
|
||||
items={customers}
|
||||
onItemSelect={(customers) => {
|
||||
const customersIds = customers.map(
|
||||
(customer) => customer.id,
|
||||
);
|
||||
setFieldValue('customersIds', customersIds);
|
||||
}}
|
||||
contacts={customers}
|
||||
contactsSelected={value}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
||||
@@ -43,7 +43,7 @@ function GLHeaderGeneralPaneContent() {
|
||||
label={<T id={'specific_accounts'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<AccountsMultiSelect accounts={accounts} />
|
||||
<AccountsMultiSelect items={accounts} />
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -2,10 +2,18 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Field } from 'formik';
|
||||
import { Row, Col, FormattedMessage as T } from 'components';
|
||||
import {
|
||||
ItemsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FormattedMessage as T,
|
||||
} from '../../../components';
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
|
||||
import { InventoryItemDetailsHeaderGeneralProvider } from './InventoryItemDetailsHeaderGeneralProvider';
|
||||
|
||||
import {
|
||||
InventoryItemDetailsHeaderGeneralProvider,
|
||||
useInventoryItemDetailsHeaderGeneralContext,
|
||||
} from './InventoryItemDetailsHeaderGeneralProvider';
|
||||
|
||||
/**
|
||||
* Inventory item details header - General panel.
|
||||
@@ -22,7 +30,7 @@ export default function InventoryItemDetailsHeaderGeneralPanel() {
|
||||
* Inventory item details header - General panel - Content.
|
||||
*/
|
||||
function InventoryItemDetailsHeaderGeneralPanelContent() {
|
||||
const { items } = useInventoryItemDetailsContext();
|
||||
const { items } = useInventoryItemDetailsHeaderGeneralContext();
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -39,7 +47,15 @@ function InventoryItemDetailsHeaderGeneralPanelContent() {
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
></FormGroup>
|
||||
>
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</Col>
|
||||
|
||||
@@ -3,8 +3,14 @@ import { FastField, Field } from 'formik';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FormGroup, Position, Classes } from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
import { ItemsMultiSelect, Row, Col, FieldHint } from 'components';
|
||||
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
ItemsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
} from '../../../components';
|
||||
import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
@@ -64,16 +70,18 @@ function InventoryValuationHeaderGeneralPanelContent() {
|
||||
<Row>
|
||||
<Col xs={5}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({
|
||||
form: { setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
{({ form: { setFieldValue } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import React from 'react';
|
||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Field } from 'formik';
|
||||
import { Row, Col, FormattedMessage as T } from 'components';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
FormattedMessage as T,
|
||||
ItemsMultiSelect,
|
||||
} from '../../../components';
|
||||
import classNames from 'classnames';
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
|
||||
import { ItemsMultiSelect } from 'components';
|
||||
import {
|
||||
PurchasesByItemsGeneralPanelProvider,
|
||||
usePurchaseByItemsGeneralPanelContext,
|
||||
} from './PurchasesByItemsGeneralPanelProvider';
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
export default function PurchasesByItemsGeneralPanel() {
|
||||
return (
|
||||
@@ -35,16 +39,18 @@ function PurchasesByItemsGeneralPanelContent() {
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({
|
||||
form: { setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
{({ form: { setFieldValue } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
|
||||
@@ -28,13 +28,9 @@ function SalesByItemsHeader({
|
||||
// #withSalesByItemsActions
|
||||
toggleSalesByItemsFilterDrawer,
|
||||
}) {
|
||||
|
||||
|
||||
// Form validation schema.
|
||||
const validationSchema = Yup.object().shape({
|
||||
fromDate: Yup.date()
|
||||
.required()
|
||||
.label(intl.get('from_date')),
|
||||
fromDate: Yup.date().required().label(intl.get('from_date')),
|
||||
toDate: Yup.date()
|
||||
.min(Yup.ref('fromDate'))
|
||||
.required()
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||
import { Field } from 'formik';
|
||||
import classNames from 'classnames';
|
||||
import { get } from 'lodash';
|
||||
|
||||
import { Row, Col, ItemsMultiSelect, FormattedMessage as T } from 'components';
|
||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||
@@ -34,22 +35,17 @@ function SalesByItemsHeaderGeneralPanelContent() {
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'itemsIds'}>
|
||||
{({
|
||||
form: { setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
{({ form: { setFieldValue }, field: { value } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'Specific items'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ItemsMultiSelect
|
||||
items={items}
|
||||
selectedItems={value}
|
||||
onItemSelect={(itemsIds) => {
|
||||
onItemSelect={(items) => {
|
||||
const itemsIds = items.map((item) => item.id);
|
||||
setFieldValue('itemsIds', itemsIds);
|
||||
}}
|
||||
onTagRenderer={(value) => value}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
||||
@@ -4,7 +4,13 @@ import { DateInput } from '@blueprintjs/datetime';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup, Position, Classes, Checkbox } from '@blueprintjs/core';
|
||||
|
||||
import { Row, Col, FieldHint, FormattedMessage as T } from 'components';
|
||||
import {
|
||||
ContactsMultiSelect,
|
||||
Row,
|
||||
Col,
|
||||
FieldHint,
|
||||
FormattedMessage as T,
|
||||
} from '../../../components';
|
||||
import {
|
||||
momentFormatter,
|
||||
tansformDateValue,
|
||||
@@ -68,15 +74,19 @@ export default function VendorsBalanceSummaryHeaderGeneralContent() {
|
||||
<Row>
|
||||
<Col xs={4}>
|
||||
<Field name={'vendorsIds'}>
|
||||
{({
|
||||
form: { setFieldValue },
|
||||
field: { value },
|
||||
meta: { error, touched },
|
||||
}) => (
|
||||
{({ form: { setFieldValue } }) => (
|
||||
<FormGroup
|
||||
label={<T id={'specific_vendors'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
></FormGroup>
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
items={vendors}
|
||||
onItemSelect={(contacts) => {
|
||||
const vendorsIds = contacts.map((contact) => contact.id);
|
||||
setFieldValue('vendorsIds', vendorsIds);
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
</Field>
|
||||
</Col>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
Col,
|
||||
ContactsMultiSelect,
|
||||
FormattedMessage as T,
|
||||
} from 'components';
|
||||
} from '../../../components';
|
||||
import {
|
||||
VendorsTransactionsGeneralPanelProvider,
|
||||
useVendorsTransactionsGeneralPanelContext,
|
||||
@@ -45,11 +45,11 @@ function VendorsTransactionsHeaderGeneralPanelContent() {
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
>
|
||||
<ContactsMultiSelect
|
||||
onContactSelect={(contactsIds) => {
|
||||
setFieldValue('vendorsIds', contactsIds);
|
||||
items={vendors}
|
||||
onItemSelect={(vendors) => {
|
||||
const vendorsIds = vendors.map((customer) => customer.id);
|
||||
setFieldValue('vendorsIds', vendorsIds);
|
||||
}}
|
||||
contacts={vendors}
|
||||
contactsSelected={value}
|
||||
/>
|
||||
</FormGroup>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user