diff --git a/packages/webapp/package.json b/packages/webapp/package.json index ffccc6209..4b6ed1037 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -5,7 +5,7 @@ "dependencies": { "@blueprintjs-formik/core": "^0.2.1", "@blueprintjs-formik/datetime": "^0.3.4", - "@blueprintjs-formik/select": "^0.1.4", + "@blueprintjs-formik/select": "^0.2.2", "@blueprintjs/core": "^3.50.2", "@blueprintjs/datetime": "^3.23.12", "@blueprintjs/popover2": "^0.11.1", diff --git a/packages/webapp/src/components/Accounts/AccountMultiSelect.tsx b/packages/webapp/src/components/Accounts/AccountMultiSelect.tsx deleted file mode 100644 index 710859e5b..000000000 --- a/packages/webapp/src/components/Accounts/AccountMultiSelect.tsx +++ /dev/null @@ -1,74 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import styled from 'styled-components'; -import { MenuItem } from '@blueprintjs/core'; -import { FMultiSelect } from '../Forms'; -import classNames from 'classnames'; -import { Classes } from '@blueprintjs/popover2'; - -/** - * - * @param {*} query - * @param {*} account - * @param {*} _index - * @param {*} exactMatch - * @returns - */ -const accountItemPredicate = (query, account, _index, exactMatch) => { - const normalizedTitle = account.name.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return `${account.code}. ${normalizedTitle}`.indexOf(normalizedQuery) >= 0; - } -}; - -/** - * - * @param {*} account - * @param {*} param1 - * @returns - */ -const accountItemRenderer = ( - account, - { handleClick, modifiers, query }, - { isSelected }, -) => { - return ( - - ); -}; - -const accountSelectProps = { - itemPredicate: accountItemPredicate, - itemRenderer: accountItemRenderer, - valueAccessor: (item) => item.id, - labelAccessor: (item) => item.code, - tagRenderer: (item) => item.name, -}; - -/** - * branches mulit select. - * @param {*} param0 - * @returns {JSX.Element} - */ -export function AccountMultiSelect({ accounts, ...rest }) { - return ( - - ); -} diff --git a/packages/webapp/src/components/Accounts/AccountsMultiSelect.tsx b/packages/webapp/src/components/Accounts/AccountsMultiSelect.tsx index c648c2119..687b8f5bf 100644 --- a/packages/webapp/src/components/Accounts/AccountsMultiSelect.tsx +++ b/packages/webapp/src/components/Accounts/AccountsMultiSelect.tsx @@ -1,31 +1,79 @@ // @ts-nocheck -import React from 'react'; +import React, { useMemo } from 'react'; import { MenuItem } from '@blueprintjs/core'; -import { MultiSelect } from '../MultiSelectTaggable'; +import { FMultiSelect } from '../Forms'; +import { accountPredicate } from './_components'; +import { filterAccountsByQuery, nestedArrayToflatten } from '@/utils'; +import { MenuItemNestedText } from '../Menu'; -export function AccountsMultiSelect({ ...multiSelectProps }) { +/** + * Default account item renderer of the list. + * @returns {JSX.Element} + */ +const accountRenderer = ( + item, + { handleClick, modifiers, query }, + { isSelected }, +) => { + if (!modifiers.matchesPredicate) { + return null; + } return ( - { - return ( - - ); - }} + } + key={item.id} + onClick={handleClick} + icon={isSelected ? 'tick' : 'blank'} + /> + ); +}; + +/** + * Accounts multi-select field binded with Formik form. + * @param {*} param0 + * @returns {JSX.Element} + */ +export function AccountsMultiSelect({ + items, + + filterByRootTypes, + filterByParentTypes, + filterByTypes, + filterByNormal, + + ...rest +}) { + // Filters accounts based on the given filter props. + const filteredAccounts = useMemo(() => { + const flattenAccounts = nestedArrayToflatten(items); + + return filterAccountsByQuery(flattenAccounts, { + filterByRootTypes, + filterByParentTypes, + filterByTypes, + filterByNormal, + }); + }, [ + items, + filterByRootTypes, + filterByParentTypes, + filterByTypes, + filterByNormal, + ]); + + return ( + item.name} - resetOnSelect={true} - {...multiSelectProps} + itemPredicate={accountPredicate} + itemRenderer={accountRenderer} + {...rest} /> ); } diff --git a/packages/webapp/src/components/Accounts/AccountsSelect.tsx b/packages/webapp/src/components/Accounts/AccountsSelect.tsx new file mode 100644 index 000000000..9c67c3f85 --- /dev/null +++ b/packages/webapp/src/components/Accounts/AccountsSelect.tsx @@ -0,0 +1,105 @@ +// @ts-nocheck +import React, { useMemo } from 'react'; +import * as R from 'ramda'; +import intl from 'react-intl-universal'; +import { MenuItem } from '@blueprintjs/core'; +import { + MenuItemNestedText, + FormattedMessage as T, + FSelect, +} from '@/components'; +import { filterAccountsByQuery, nestedArrayToflatten } from '@/utils'; +import { accountPredicate } from './_components'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; + +// Create new account renderer. +const createNewItemRenderer = (query, active, handleClick) => { + return ( + + ); +}; + +// Create new item from the given query string. +const createNewItemFromQuery = (name) => { + return { + name, + }; +}; + +/** + * Default account item renderer. + * @returns {JSX.Element} + */ +const accountRenderer = (item, { handleClick, modifiers, query }) => { + if (!modifiers.matchesPredicate) { + return null; + } + return ( + } + onClick={handleClick} + /> + ); +}; + +/** + * Accounts select field binded with Formik form. + * @returns {JSX.Element} + */ +function AccountsSelectRoot({ + // #withDialogActions + openDialog, + + // #ownProps + items, + + filterByParentTypes, + filterByTypes, + filterByNormal, + filterByRootTypes, + + ...restProps +}) { + // Filters accounts based on filter props. + const filteredAccounts = useMemo(() => { + const flattenAccounts = nestedArrayToflatten(items); + + const filteredAccounts = filterAccountsByQuery(flattenAccounts, { + filterByRootTypes, + filterByParentTypes, + filterByTypes, + filterByNormal, + }); + return filteredAccounts; + }, [ + items, + filterByRootTypes, + filterByParentTypes, + filterByTypes, + filterByNormal, + ]); + + return ( + + ); +} + +export const AccountsSelect = R.compose(withDialogActions)(AccountsSelectRoot); diff --git a/packages/webapp/src/components/Accounts/AccountsSelectList.tsx b/packages/webapp/src/components/Accounts/AccountsSelectList.tsx deleted file mode 100644 index 8ec02d8e4..000000000 --- a/packages/webapp/src/components/Accounts/AccountsSelectList.tsx +++ /dev/null @@ -1,177 +0,0 @@ -// @ts-nocheck -import React, { useCallback, useState, useEffect, useMemo } from 'react'; -import intl from 'react-intl-universal'; -import classNames from 'classnames'; -import { MenuItem, Button } from '@blueprintjs/core'; -import { Select } from '@blueprintjs/select'; -import * as R from 'ramda'; - -import { MenuItemNestedText, FormattedMessage as T } from '@/components'; -import { nestedArrayToflatten, filterAccountsByQuery } from '@/utils'; - -import { CLASSES } from '@/constants/classes'; -import { DialogsName } from '@/constants/dialogs'; - -import withDialogActions from '@/containers/Dialog/withDialogActions'; - -// Create new account renderer. -const createNewItemRenderer = (query, active, handleClick) => { - return ( - - ); -}; - -// Create new item from the given query string. -const createNewItemFromQuery = (name) => { - return { - name, - }; -}; - -// Filters accounts items. -const filterAccountsPredicater = (query, account, _index, exactMatch) => { - const normalizedTitle = account.name.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return `${account.code} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0; - } -}; - -/** - * Accounts select list. - */ -function AccountsSelectListRoot({ - // #withDialogActions - openDialog, - - // #ownProps - accounts, - initialAccountId, - selectedAccountId, - defaultSelectText = 'Select account', - onAccountSelected, - disabled = false, - popoverFill = false, - - filterByParentTypes, - filterByTypes, - filterByNormal, - filterByRootTypes, - - allowCreate, - - buttonProps = {}, -}) { - const flattenAccounts = useMemo( - () => nestedArrayToflatten(accounts), - [accounts], - ); - - // Filters accounts based on filter props. - const filteredAccounts = useMemo(() => { - let filteredAccounts = filterAccountsByQuery(flattenAccounts, { - filterByRootTypes, - filterByParentTypes, - filterByTypes, - filterByNormal, - }); - return filteredAccounts; - }, [ - flattenAccounts, - filterByRootTypes, - filterByParentTypes, - filterByTypes, - filterByNormal, - ]); - - // Find initial account object to set it as default account in initial render. - const initialAccount = useMemo( - () => filteredAccounts.find((a) => a.id === initialAccountId), - [initialAccountId, filteredAccounts], - ); - - // Select account item. - const [selectedAccount, setSelectedAccount] = useState( - initialAccount || null, - ); - - useEffect(() => { - if (typeof selectedAccountId !== 'undefined') { - const account = selectedAccountId - ? filteredAccounts.find((a) => a.id === selectedAccountId) - : null; - setSelectedAccount(account); - } - }, [selectedAccountId, filteredAccounts, setSelectedAccount]); - - // Account item of select accounts field. - const accountItem = useCallback((item, { handleClick, modifiers, query }) => { - return ( - } - label={item.code} - key={item.id} - onClick={handleClick} - /> - ); - }, []); - - // Handle the account item select. - const handleAccountSelect = useCallback( - (account) => { - if (account.id) { - setSelectedAccount({ ...account }); - onAccountSelected && onAccountSelected(account); - } else { - openDialog(DialogsName.AccountForm); - } - }, - [setSelectedAccount, onAccountSelected, openDialog], - ); - - // Maybe inject new item props to select component. - const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null; - const maybeCreateNewItemFromQuery = allowCreate - ? createNewItemFromQuery - : null; - - return ( - - ); -} - -export const AccountsSelectList = R.compose(withDialogActions)( - AccountsSelectListRoot, -); diff --git a/packages/webapp/src/components/Accounts/AccountsTypesSelect.tsx b/packages/webapp/src/components/Accounts/AccountsTypesSelect.tsx index b00ab710a..5357ae95b 100644 --- a/packages/webapp/src/components/Accounts/AccountsTypesSelect.tsx +++ b/packages/webapp/src/components/Accounts/AccountsTypesSelect.tsx @@ -1,49 +1,15 @@ // @ts-nocheck -import React, { useCallback } from 'react'; -import classNames from 'classnames'; -import { ListSelect } from '@/components'; -import { CLASSES } from '@/constants/classes'; - -export function AccountsTypesSelect({ - accountsTypes, - selectedTypeId, - defaultSelectText = 'Select account type', - onTypeSelected, - disabled = false, - popoverFill = false, - ...restProps -}) { - // Filters accounts types items. - const filterAccountTypeItems = (query, accountType, _index, exactMatch) => { - const normalizedTitle = accountType.label.toLowerCase(); - const normalizedQuery = query.toLowerCase(); - - if (exactMatch) { - return normalizedTitle === normalizedQuery; - } else { - return normalizedTitle.indexOf(normalizedQuery) >= 0; - } - }; - - // Handle item selected. - const handleItemSelected = (accountType) => { - onTypeSelected && onTypeSelected(accountType); - }; +import React from 'react'; +import { FSelect } from '@/components/Forms'; +export function AccountsTypesSelect({ ...props }) { return ( - ); } diff --git a/packages/webapp/src/components/Accounts/_components.tsx b/packages/webapp/src/components/Accounts/_components.tsx new file mode 100644 index 000000000..95db8e018 --- /dev/null +++ b/packages/webapp/src/components/Accounts/_components.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { MenuItem } from '@blueprintjs/core'; +import { MenuItemNestedText } from '../Menu'; + + +// Filters accounts items. +export const accountPredicate = (query, account, _index, exactMatch) => { + const normalizedTitle = account.name.toLowerCase(); + const normalizedQuery = query.toLowerCase(); + + if (exactMatch) { + return normalizedTitle === normalizedQuery; + } else { + return `${account.code} ${normalizedTitle}`.indexOf(normalizedQuery) >= 0; + } +}; diff --git a/packages/webapp/src/components/Accounts/index.tsx b/packages/webapp/src/components/Accounts/index.tsx index a6832e01d..0cc82f2be 100644 --- a/packages/webapp/src/components/Accounts/index.tsx +++ b/packages/webapp/src/components/Accounts/index.tsx @@ -1,5 +1,4 @@ -export * from './AccountMultiSelect'; +export * from './AccountsSelect'; export * from './AccountsMultiSelect'; -export * from './AccountsSelectList'; export * from './AccountsSuggestField'; export * from './AccountsTypesSelect'; diff --git a/packages/webapp/src/components/Currencies/CurrencySelect.tsx b/packages/webapp/src/components/Currencies/CurrencySelect.tsx index 5d5654667..1e47c9b9d 100644 --- a/packages/webapp/src/components/Currencies/CurrencySelect.tsx +++ b/packages/webapp/src/components/Currencies/CurrencySelect.tsx @@ -45,13 +45,6 @@ const currencyItemRenderer = (currency, { handleClick, modifiers, query }) => { ); }; -const currencySelectProps = { - itemPredicate: currencyItemPredicate, - itemRenderer: currencyItemRenderer, - valueAccessor: 'currency_code', - labelAccessor: 'currency_code', -}; - /** * * @param {*} currencies @@ -60,7 +53,10 @@ const currencySelectProps = { export function CurrencySelect({ currencies, ...rest }) { return ( { + return ( +