mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14: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 React from 'react';
|
||||||
import { omit } from 'lodash';
|
import { MenuItem } from '@blueprintjs/core';
|
||||||
import { MenuItem, Button } from '@blueprintjs/core';
|
import { MultiSelect } from './MultiSelectTaggable';
|
||||||
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],
|
|
||||||
);
|
|
||||||
|
|
||||||
|
export default function AccountsMultiSelect({ ...multiSelectProps }) {
|
||||||
return (
|
return (
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
items={accounts}
|
itemRenderer={(
|
||||||
noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
|
item,
|
||||||
itemRenderer={accountItem}
|
{ 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 }}
|
popoverProps={{ minimal: true }}
|
||||||
filterable={true}
|
fill={true}
|
||||||
onItemSelect={onAccountSelect}
|
tagRenderer={(item) => item.name}
|
||||||
>
|
resetOnSelect={true}
|
||||||
<Button
|
{...multiSelectProps}
|
||||||
text={
|
/>
|
||||||
countSelectedAccounts === 0 ? (
|
|
||||||
<T id={'all_accounts'} />
|
|
||||||
) : (
|
|
||||||
`(${countSelectedAccounts}) Selected accounts`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</MultiSelect>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,59 +1,11 @@
|
|||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
import { MenuItem, Button } from '@blueprintjs/core';
|
import { MenuItem } from '@blueprintjs/core';
|
||||||
import intl from 'react-intl-universal';
|
import { MultiSelect } from '../components/MultiSelectTaggable';
|
||||||
import MultiSelect from 'components/MultiSelect';
|
|
||||||
import { FormattedMessage as T } from 'components';
|
|
||||||
import { safeInvoke } from 'utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contacts multi-select component.
|
* Contacts multi-select component.
|
||||||
*/
|
*/
|
||||||
export default function ContactsMultiSelect({
|
export default function ContactsMultiSelect({ ...multiSelectProps }) {
|
||||||
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],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Filters accounts items.
|
// Filters accounts items.
|
||||||
const filterContactsPredicater = useCallback(
|
const filterContactsPredicater = useCallback(
|
||||||
(query, contact, _index, exactMatch) => {
|
(query, contact, _index, exactMatch) => {
|
||||||
@@ -71,23 +23,20 @@ export default function ContactsMultiSelect({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
items={contacts}
|
itemRenderer={(contact, { selected, active, handleClick }) => (
|
||||||
noResults={<MenuItem disabled={true} text={<T id={'no_results'} />} />}
|
<MenuItem
|
||||||
itemRenderer={contactRenderer}
|
active={active}
|
||||||
|
icon={selected ? 'tick' : 'blank'}
|
||||||
|
text={contact.display_name}
|
||||||
|
key={contact.id}
|
||||||
|
onClick={handleClick}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
popoverProps={{ minimal: true }}
|
popoverProps={{ minimal: true }}
|
||||||
filterable={true}
|
fill={true}
|
||||||
onItemSelect={handleItemSelect}
|
|
||||||
itemPredicate={filterContactsPredicater}
|
itemPredicate={filterContactsPredicater}
|
||||||
|
tagRenderer={(item) => item.display_name}
|
||||||
{...multiSelectProps}
|
{...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 React, { useCallback } from 'react';
|
||||||
import { MenuItem, Button, Intent } from '@blueprintjs/core';
|
import { MenuItem } from '@blueprintjs/core';
|
||||||
import { MultiSelect } from '@blueprintjs/select';
|
import { MultiSelect } from '../../components';
|
||||||
import { FormattedMessage as T } from 'components';
|
|
||||||
import { safeInvoke } from 'utils';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Items multi-select.
|
* Items multi-select.
|
||||||
*/
|
*/
|
||||||
export function ItemsMultiSelect({
|
export function ItemsMultiSelect({ ...multiSelectProps }) {
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Filters accounts items.
|
// Filters accounts items.
|
||||||
const filterItemsPredicater = useCallback(
|
const filterItemsPredicater = useCallback(
|
||||||
(query, item, _index, exactMatch) => {
|
(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 (
|
return (
|
||||||
<MultiSelect
|
<MultiSelect
|
||||||
items={items}
|
itemRenderer={(item, { selected, handleClick, active }) => (
|
||||||
noResults={<MenuItem disabled={true} text={<T id={'No items'} />} />}
|
<MenuItem
|
||||||
itemRenderer={itemRenderer}
|
active={active}
|
||||||
popoverProps={{
|
icon={selected ? 'tick' : 'blank'}
|
||||||
minimal: true,
|
text={item.name}
|
||||||
usePortal: false,
|
label={item.code}
|
||||||
targetTagName: 'div ',
|
key={item.id}
|
||||||
}}
|
onClick={handleClick}
|
||||||
selectedItems={itemsSelected()}
|
/>
|
||||||
|
)}
|
||||||
|
popoverProps={{ minimal: true, usePortal: false, targetTagName: 'div ' }}
|
||||||
fill={true}
|
fill={true}
|
||||||
onItemSelect={handleItemSelect}
|
|
||||||
itemPredicate={filterItemsPredicater}
|
itemPredicate={filterItemsPredicater}
|
||||||
tagRenderer={onTagRenderer}
|
tagRenderer={(item) => item.name}
|
||||||
tagInputProps={{
|
|
||||||
tagProps: { intent: Intent.NONE, minimal: false },
|
|
||||||
onRemove: handleTagRemove,
|
|
||||||
// rightElement: clearButton,
|
|
||||||
}}
|
|
||||||
resetOnSelect={true}
|
resetOnSelect={true}
|
||||||
// openOnKeyDown={true}
|
|
||||||
{...multiSelectProps}
|
{...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 './Dashboard';
|
||||||
export * from './Drawer';
|
export * from './Drawer';
|
||||||
export * from './Forms';
|
export * from './Forms';
|
||||||
|
export * from './MultiSelectTaggable'
|
||||||
const Hint = FieldHint;
|
const Hint = FieldHint;
|
||||||
|
|
||||||
const T = FormattedMessage;
|
const T = FormattedMessage;
|
||||||
|
|||||||
@@ -99,11 +99,10 @@ export default function APAgingSummaryHeaderGeneralContent() {
|
|||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<ContactsMultiSelect
|
<ContactsMultiSelect
|
||||||
defaultText={<T id={'all_vendors'} />}
|
items={vendors}
|
||||||
contacts={vendors}
|
onItemSelect={(vendors) => {
|
||||||
contactsSelected={value}
|
const vendorsIds = vendors.map((customer) => customer.id);
|
||||||
onContactSelect={(contactsIds) => {
|
setFieldValue('vendorsIds', vendorsIds);
|
||||||
setFieldValue('vendorsIds', contactsIds);
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|||||||
@@ -105,10 +105,12 @@ export default function ARAgingSummaryHeaderGeneralContent() {
|
|||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<ContactsMultiSelect
|
<ContactsMultiSelect
|
||||||
contacts={customers}
|
items={customers}
|
||||||
contactsSelected={value}
|
onItemSelect={(customers) => {
|
||||||
onContactSelect={(contactsIds) => {
|
const customersIds = customers.map(
|
||||||
setFieldValue('customersIds', contactsIds);
|
(customer) => customer.id,
|
||||||
|
);
|
||||||
|
setFieldValue('customersIds', customersIds);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|||||||
@@ -74,15 +74,15 @@ export default function CustomersBalanceSummaryGeneralPanelContent() {
|
|||||||
meta: { error, touched },
|
meta: { error, touched },
|
||||||
}) => (
|
}) => (
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'Specific customers'} />}
|
label={<T id={'specific_customers'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<ContactsMultiSelect
|
<ContactsMultiSelect
|
||||||
onContactSelect={(contactsIds) => {
|
items={customers}
|
||||||
setFieldValue('customersIds', contactsIds);
|
onItemSelect={(contacts) => {
|
||||||
|
const customersIds = contacts.map(contact => contact.id);
|
||||||
|
setFieldValue('customersIds', customersIds);
|
||||||
}}
|
}}
|
||||||
contacts={customers}
|
|
||||||
contactsSelected={value}
|
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -3,8 +3,12 @@ import classNames from 'classnames';
|
|||||||
import { Field } from 'formik';
|
import { Field } from 'formik';
|
||||||
import { Classes, FormGroup } from '@blueprintjs/core';
|
import { Classes, FormGroup } from '@blueprintjs/core';
|
||||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||||
import { Row, Col } from 'components';
|
import {
|
||||||
import { ContactsMultiSelect, FormattedMessage as T } from 'components';
|
Row,
|
||||||
|
Col,
|
||||||
|
ContactsMultiSelect,
|
||||||
|
FormattedMessage as T,
|
||||||
|
} from '../../../components';
|
||||||
import {
|
import {
|
||||||
CustomersTransactionsGeneralPanelProvider,
|
CustomersTransactionsGeneralPanelProvider,
|
||||||
useCustomersTransactionsGeneralPanelContext,
|
useCustomersTransactionsGeneralPanelContext,
|
||||||
@@ -40,11 +44,13 @@ function CustomersTransactionsHeaderGeneralPanelContent() {
|
|||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<ContactsMultiSelect
|
<ContactsMultiSelect
|
||||||
onContactSelect={(contactsIds) => {
|
items={customers}
|
||||||
setFieldValue('customersIds', contactsIds);
|
onItemSelect={(customers) => {
|
||||||
|
const customersIds = customers.map(
|
||||||
|
(customer) => customer.id,
|
||||||
|
);
|
||||||
|
setFieldValue('customersIds', customersIds);
|
||||||
}}
|
}}
|
||||||
contacts={customers}
|
|
||||||
contactsSelected={value}
|
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function GLHeaderGeneralPaneContent() {
|
|||||||
label={<T id={'specific_accounts'} />}
|
label={<T id={'specific_accounts'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<AccountsMultiSelect accounts={accounts} />
|
<AccountsMultiSelect items={accounts} />
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|||||||
@@ -2,10 +2,18 @@ import React from 'react';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||||
import { Field } from 'formik';
|
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 FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||||
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
|
|
||||||
import { InventoryItemDetailsHeaderGeneralProvider } from './InventoryItemDetailsHeaderGeneralProvider';
|
import {
|
||||||
|
InventoryItemDetailsHeaderGeneralProvider,
|
||||||
|
useInventoryItemDetailsHeaderGeneralContext,
|
||||||
|
} from './InventoryItemDetailsHeaderGeneralProvider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inventory item details header - General panel.
|
* Inventory item details header - General panel.
|
||||||
@@ -22,7 +30,7 @@ export default function InventoryItemDetailsHeaderGeneralPanel() {
|
|||||||
* Inventory item details header - General panel - Content.
|
* Inventory item details header - General panel - Content.
|
||||||
*/
|
*/
|
||||||
function InventoryItemDetailsHeaderGeneralPanelContent() {
|
function InventoryItemDetailsHeaderGeneralPanelContent() {
|
||||||
const { items } = useInventoryItemDetailsContext();
|
const { items } = useInventoryItemDetailsHeaderGeneralContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -39,7 +47,15 @@ function InventoryItemDetailsHeaderGeneralPanelContent() {
|
|||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'Specific items'} />}
|
label={<T id={'Specific items'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
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>
|
</Field>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -3,8 +3,14 @@ import { FastField, Field } from 'formik';
|
|||||||
import { DateInput } from '@blueprintjs/datetime';
|
import { DateInput } from '@blueprintjs/datetime';
|
||||||
import { FormGroup, Position, Classes } from '@blueprintjs/core';
|
import { FormGroup, Position, Classes } from '@blueprintjs/core';
|
||||||
import classNames from 'classnames';
|
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 {
|
import {
|
||||||
momentFormatter,
|
momentFormatter,
|
||||||
tansformDateValue,
|
tansformDateValue,
|
||||||
@@ -64,16 +70,18 @@ function InventoryValuationHeaderGeneralPanelContent() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col xs={5}>
|
<Col xs={5}>
|
||||||
<Field name={'itemsIds'}>
|
<Field name={'itemsIds'}>
|
||||||
{({
|
{({ form: { setFieldValue } }) => (
|
||||||
form: { setFieldValue },
|
|
||||||
field: { value },
|
|
||||||
meta: { error, touched },
|
|
||||||
}) => (
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'Specific items'} />}
|
label={<T id={'Specific items'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
|
<ItemsMultiSelect
|
||||||
|
items={items}
|
||||||
|
onItemSelect={(items) => {
|
||||||
|
const itemsIds = items.map((item) => item.id);
|
||||||
|
setFieldValue('itemsIds', itemsIds);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||||
import { Field } from 'formik';
|
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 classNames from 'classnames';
|
||||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||||
|
|
||||||
import { ItemsMultiSelect } from 'components';
|
|
||||||
import {
|
import {
|
||||||
PurchasesByItemsGeneralPanelProvider,
|
PurchasesByItemsGeneralPanelProvider,
|
||||||
usePurchaseByItemsGeneralPanelContext,
|
usePurchaseByItemsGeneralPanelContext,
|
||||||
@@ -35,16 +39,18 @@ function PurchasesByItemsGeneralPanelContent() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<Field name={'itemsIds'}>
|
<Field name={'itemsIds'}>
|
||||||
{({
|
{({ form: { setFieldValue } }) => (
|
||||||
form: { setFieldValue },
|
|
||||||
field: { value },
|
|
||||||
meta: { error, touched },
|
|
||||||
}) => (
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'Specific items'} />}
|
label={<T id={'Specific items'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
|
<ItemsMultiSelect
|
||||||
|
items={items}
|
||||||
|
onItemSelect={(items) => {
|
||||||
|
const itemsIds = items.map((item) => item.id);
|
||||||
|
setFieldValue('itemsIds', itemsIds);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
|
|||||||
@@ -28,13 +28,9 @@ function SalesByItemsHeader({
|
|||||||
// #withSalesByItemsActions
|
// #withSalesByItemsActions
|
||||||
toggleSalesByItemsFilterDrawer,
|
toggleSalesByItemsFilterDrawer,
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
|
|
||||||
// Form validation schema.
|
// Form validation schema.
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
fromDate: Yup.date()
|
fromDate: Yup.date().required().label(intl.get('from_date')),
|
||||||
.required()
|
|
||||||
.label(intl.get('from_date')),
|
|
||||||
toDate: Yup.date()
|
toDate: Yup.date()
|
||||||
.min(Yup.ref('fromDate'))
|
.min(Yup.ref('fromDate'))
|
||||||
.required()
|
.required()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { FormGroup, Classes } from '@blueprintjs/core';
|
import { FormGroup, Classes } from '@blueprintjs/core';
|
||||||
import { Field } from 'formik';
|
import { Field } from 'formik';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { get } from 'lodash';
|
||||||
|
|
||||||
import { Row, Col, ItemsMultiSelect, FormattedMessage as T } from 'components';
|
import { Row, Col, ItemsMultiSelect, FormattedMessage as T } from 'components';
|
||||||
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
import FinancialStatementDateRange from 'containers/FinancialStatements/FinancialStatementDateRange';
|
||||||
@@ -34,22 +35,17 @@ function SalesByItemsHeaderGeneralPanelContent() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<Field name={'itemsIds'}>
|
<Field name={'itemsIds'}>
|
||||||
{({
|
{({ form: { setFieldValue }, field: { value } }) => (
|
||||||
form: { setFieldValue },
|
|
||||||
field: { value },
|
|
||||||
meta: { error, touched },
|
|
||||||
}) => (
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'Specific items'} />}
|
label={<T id={'Specific items'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<ItemsMultiSelect
|
<ItemsMultiSelect
|
||||||
items={items}
|
items={items}
|
||||||
selectedItems={value}
|
onItemSelect={(items) => {
|
||||||
onItemSelect={(itemsIds) => {
|
const itemsIds = items.map((item) => item.id);
|
||||||
setFieldValue('itemsIds', itemsIds);
|
setFieldValue('itemsIds', itemsIds);
|
||||||
}}
|
}}
|
||||||
onTagRenderer={(value) => value}
|
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,7 +4,13 @@ import { DateInput } from '@blueprintjs/datetime';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { FormGroup, Position, Classes, Checkbox } from '@blueprintjs/core';
|
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 {
|
import {
|
||||||
momentFormatter,
|
momentFormatter,
|
||||||
tansformDateValue,
|
tansformDateValue,
|
||||||
@@ -68,15 +74,19 @@ export default function VendorsBalanceSummaryHeaderGeneralContent() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col xs={4}>
|
<Col xs={4}>
|
||||||
<Field name={'vendorsIds'}>
|
<Field name={'vendorsIds'}>
|
||||||
{({
|
{({ form: { setFieldValue } }) => (
|
||||||
form: { setFieldValue },
|
|
||||||
field: { value },
|
|
||||||
meta: { error, touched },
|
|
||||||
}) => (
|
|
||||||
<FormGroup
|
<FormGroup
|
||||||
label={<T id={'specific_vendors'} />}
|
label={<T id={'specific_vendors'} />}
|
||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
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>
|
</Field>
|
||||||
</Col>
|
</Col>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
Col,
|
Col,
|
||||||
ContactsMultiSelect,
|
ContactsMultiSelect,
|
||||||
FormattedMessage as T,
|
FormattedMessage as T,
|
||||||
} from 'components';
|
} from '../../../components';
|
||||||
import {
|
import {
|
||||||
VendorsTransactionsGeneralPanelProvider,
|
VendorsTransactionsGeneralPanelProvider,
|
||||||
useVendorsTransactionsGeneralPanelContext,
|
useVendorsTransactionsGeneralPanelContext,
|
||||||
@@ -45,11 +45,11 @@ function VendorsTransactionsHeaderGeneralPanelContent() {
|
|||||||
className={classNames('form-group--select-list', Classes.FILL)}
|
className={classNames('form-group--select-list', Classes.FILL)}
|
||||||
>
|
>
|
||||||
<ContactsMultiSelect
|
<ContactsMultiSelect
|
||||||
onContactSelect={(contactsIds) => {
|
items={vendors}
|
||||||
setFieldValue('vendorsIds', contactsIds);
|
onItemSelect={(vendors) => {
|
||||||
|
const vendorsIds = vendors.map((customer) => customer.id);
|
||||||
|
setFieldValue('vendorsIds', vendorsIds);
|
||||||
}}
|
}}
|
||||||
contacts={vendors}
|
|
||||||
contactsSelected={value}
|
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user