mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-20 23:00:34 +00:00
feat(webapp): allow to create a new account item in accounts list component.
This commit is contained in:
@@ -3,8 +3,8 @@ import React, { useMemo } from 'react';
|
|||||||
import { MenuItem } from '@blueprintjs/core';
|
import { MenuItem } from '@blueprintjs/core';
|
||||||
import { FMultiSelect } from '../Forms';
|
import { FMultiSelect } from '../Forms';
|
||||||
import { accountPredicate } from './_components';
|
import { accountPredicate } from './_components';
|
||||||
import { filterAccountsByQuery, nestedArrayToflatten } from '@/utils';
|
|
||||||
import { MenuItemNestedText } from '../Menu';
|
import { MenuItemNestedText } from '../Menu';
|
||||||
|
import { usePreprocessingAccounts } from './_hooks';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default account item renderer of the list.
|
* Default account item renderer of the list.
|
||||||
@@ -45,23 +45,13 @@ export function AccountsMultiSelect({
|
|||||||
|
|
||||||
...rest
|
...rest
|
||||||
}) {
|
}) {
|
||||||
// Filters accounts based on the given filter props.
|
// Filters accounts based on filter props.
|
||||||
const filteredAccounts = useMemo(() => {
|
const filteredAccounts = usePreprocessingAccounts(accounts, {
|
||||||
const flattenAccounts = nestedArrayToflatten(items);
|
|
||||||
|
|
||||||
return filterAccountsByQuery(flattenAccounts, {
|
|
||||||
filterByRootTypes,
|
|
||||||
filterByParentTypes,
|
|
||||||
filterByTypes,
|
|
||||||
filterByNormal,
|
|
||||||
});
|
|
||||||
}, [
|
|
||||||
items,
|
|
||||||
filterByRootTypes,
|
|
||||||
filterByParentTypes,
|
filterByParentTypes,
|
||||||
filterByTypes,
|
filterByTypes,
|
||||||
filterByNormal,
|
filterByNormal,
|
||||||
]);
|
filterByRootTypes,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FMultiSelect
|
<FMultiSelect
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React, { useMemo } from 'react';
|
import React from 'react';
|
||||||
import * as R from 'ramda';
|
import * as R from 'ramda';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { MenuItem } from '@blueprintjs/core';
|
import { MenuItem } from '@blueprintjs/core';
|
||||||
import {
|
import { MenuItemNestedText, FSelect } from '@/components';
|
||||||
MenuItemNestedText,
|
|
||||||
FormattedMessage as T,
|
|
||||||
FSelect,
|
|
||||||
} from '@/components';
|
|
||||||
import { filterAccountsByQuery, nestedArrayToflatten } from '@/utils';
|
|
||||||
import { accountPredicate } from './_components';
|
import { accountPredicate } from './_components';
|
||||||
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
import withDialogActions from '@/containers/Dialog/withDialogActions';
|
||||||
|
import { usePreprocessingAccounts } from './_hooks';
|
||||||
|
|
||||||
// Create new account renderer.
|
// Create new account renderer.
|
||||||
const createNewItemRenderer = (query, active, handleClick) => {
|
const createNewItemRenderer = (query, active, handleClick) => {
|
||||||
@@ -25,11 +21,7 @@ const createNewItemRenderer = (query, active, handleClick) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create new item from the given query string.
|
// Create new item from the given query string.
|
||||||
const createNewItemFromQuery = (name) => {
|
const createNewItemFromQuery = (name) => ({ name });
|
||||||
return {
|
|
||||||
name,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default account item renderer.
|
* Default account item renderer.
|
||||||
@@ -61,6 +53,7 @@ function AccountsSelectRoot({
|
|||||||
|
|
||||||
// #ownProps
|
// #ownProps
|
||||||
items,
|
items,
|
||||||
|
allowCreate,
|
||||||
|
|
||||||
filterByParentTypes,
|
filterByParentTypes,
|
||||||
filterByTypes,
|
filterByTypes,
|
||||||
@@ -70,23 +63,17 @@ function AccountsSelectRoot({
|
|||||||
...restProps
|
...restProps
|
||||||
}) {
|
}) {
|
||||||
// Filters accounts based on filter props.
|
// Filters accounts based on filter props.
|
||||||
const filteredAccounts = useMemo(() => {
|
const filteredAccounts = usePreprocessingAccounts(items, {
|
||||||
const flattenAccounts = nestedArrayToflatten(items);
|
|
||||||
|
|
||||||
const filteredAccounts = filterAccountsByQuery(flattenAccounts, {
|
|
||||||
filterByRootTypes,
|
|
||||||
filterByParentTypes,
|
|
||||||
filterByTypes,
|
|
||||||
filterByNormal,
|
|
||||||
});
|
|
||||||
return filteredAccounts;
|
|
||||||
}, [
|
|
||||||
items,
|
|
||||||
filterByRootTypes,
|
|
||||||
filterByParentTypes,
|
filterByParentTypes,
|
||||||
filterByTypes,
|
filterByTypes,
|
||||||
filterByNormal,
|
filterByNormal,
|
||||||
]);
|
filterByRootTypes,
|
||||||
|
});
|
||||||
|
// Maybe inject new item props to select component.
|
||||||
|
const maybeCreateNewItemRenderer = allowCreate ? createNewItemRenderer : null;
|
||||||
|
const maybeCreateNewItemFromQuery = allowCreate
|
||||||
|
? createNewItemFromQuery
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FSelect
|
<FSelect
|
||||||
@@ -97,6 +84,8 @@ function AccountsSelectRoot({
|
|||||||
popoverProps={{ minimal: true, usePortal: true, inline: false }}
|
popoverProps={{ minimal: true, usePortal: true, inline: false }}
|
||||||
itemPredicate={accountPredicate}
|
itemPredicate={accountPredicate}
|
||||||
itemRenderer={accountRenderer}
|
itemRenderer={accountRenderer}
|
||||||
|
createNewItemRenderer={maybeCreateNewItemRenderer}
|
||||||
|
createNewItemFromQuery={maybeCreateNewItemFromQuery}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { MenuItem } from '@blueprintjs/core';
|
|
||||||
import { MenuItemNestedText } from '../Menu';
|
|
||||||
|
|
||||||
|
|
||||||
// Filters accounts items.
|
// Filters accounts items.
|
||||||
export const accountPredicate = (query, account, _index, exactMatch) => {
|
export const accountPredicate = (query, account, _index, exactMatch) => {
|
||||||
|
|||||||
36
packages/webapp/src/components/Accounts/_hooks.ts
Normal file
36
packages/webapp/src/components/Accounts/_hooks.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { useMemo } from 'react';
|
||||||
|
import { filterAccountsByQuery, nestedArrayToflatten } from '@/utils';
|
||||||
|
|
||||||
|
interface PreprocessingAccountsOptions {
|
||||||
|
filterByRootTypes: string[];
|
||||||
|
filterByParentTypes: string[];
|
||||||
|
filterByTypes: string[];
|
||||||
|
filterByNormal: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const usePreprocessingAccounts = (
|
||||||
|
items: any,
|
||||||
|
{
|
||||||
|
filterByRootTypes,
|
||||||
|
filterByParentTypes,
|
||||||
|
filterByTypes,
|
||||||
|
filterByNormal,
|
||||||
|
}: PreprocessingAccountsOptions,
|
||||||
|
) => {
|
||||||
|
return useMemo(() => {
|
||||||
|
const flattenAccounts = nestedArrayToflatten(items);
|
||||||
|
const filteredAccounts = filterAccountsByQuery(flattenAccounts, {
|
||||||
|
filterByRootTypes,
|
||||||
|
filterByParentTypes,
|
||||||
|
filterByTypes,
|
||||||
|
filterByNormal,
|
||||||
|
});
|
||||||
|
return filteredAccounts;
|
||||||
|
}, [
|
||||||
|
items,
|
||||||
|
filterByRootTypes,
|
||||||
|
filterByParentTypes,
|
||||||
|
filterByTypes,
|
||||||
|
filterByNormal,
|
||||||
|
]);
|
||||||
|
};
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
|
||||||
import clsx from 'classnames';
|
|
||||||
import { Button } from '@blueprintjs/core';
|
import { Button } from '@blueprintjs/core';
|
||||||
import { Select } from '@blueprintjs-formik/select';
|
import { Select } from '@blueprintjs-formik/select';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import clsx from 'classnames';
|
||||||
|
|
||||||
export function FSelect({ ...props }) {
|
export function FSelect({ ...props }) {
|
||||||
const input = ({ activeItem, text, label, value }) => {
|
const input = ({ activeItem, text, label, value }) => {
|
||||||
return (
|
return (
|
||||||
<SelectButton
|
<SelectButton
|
||||||
text={text || props.placeholder || 'Select an item ...'}
|
text={text || props.placeholder || 'Select an item ...'}
|
||||||
|
disabled={props.disabled || false}
|
||||||
{...props.buttonProps}
|
{...props.buttonProps}
|
||||||
className={clsx({ 'is-selected': !!text }, props.className)}
|
className={clsx({ 'is-selected': !!text }, props.className)}
|
||||||
/>
|
/>
|
||||||
@@ -45,7 +46,6 @@ const SelectButton = styled(Button)`
|
|||||||
margin-right: 12px;
|
margin-right: 12px;
|
||||||
border-radius: 1px;
|
border-radius: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not([class*='bp3-intent-']) {
|
&:not([class*='bp3-intent-']) {
|
||||||
&,
|
&,
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ function AccountFormDialogFields({
|
|||||||
buttonProps={{ disabled: !values.subaccount }}
|
buttonProps={{ disabled: !values.subaccount }}
|
||||||
fastField={true}
|
fastField={true}
|
||||||
fill={true}
|
fill={true}
|
||||||
|
allowCreate={true}
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ function ItemFormBody({ organization: { base_currency } }) {
|
|||||||
items={accounts}
|
items={accounts}
|
||||||
sellable={values.sellable}
|
sellable={values.sellable}
|
||||||
shouldUpdate={sellAccountFieldShouldUpdate}
|
shouldUpdate={sellAccountFieldShouldUpdate}
|
||||||
|
fastField={true}
|
||||||
>
|
>
|
||||||
<AccountsSelect
|
<AccountsSelect
|
||||||
name={'sell_account_id'}
|
name={'sell_account_id'}
|
||||||
@@ -110,6 +111,7 @@ function ItemFormBody({ organization: { base_currency } }) {
|
|||||||
filterByParentTypes={[ACCOUNT_PARENT_TYPE.INCOME]}
|
filterByParentTypes={[ACCOUNT_PARENT_TYPE.INCOME]}
|
||||||
fill={true}
|
fill={true}
|
||||||
allowCreate={true}
|
allowCreate={true}
|
||||||
|
fastField={true}
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import intl from 'react-intl-universal';
|
import intl from 'react-intl-universal';
|
||||||
import { Form, FastField, useFormikContext } from 'formik';
|
import { Form, FastField, useFormikContext } from 'formik';
|
||||||
|
import styled from 'styled-components';
|
||||||
import {
|
import {
|
||||||
FormGroup,
|
FormGroup,
|
||||||
RadioGroup,
|
RadioGroup,
|
||||||
@@ -21,7 +22,6 @@ import {
|
|||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { handleStringChange, inputIntent } from '@/utils';
|
import { handleStringChange, inputIntent } from '@/utils';
|
||||||
import { ACCOUNT_PARENT_TYPE, ACCOUNT_TYPE } from '@/constants/accountTypes';
|
import { ACCOUNT_PARENT_TYPE, ACCOUNT_TYPE } from '@/constants/accountTypes';
|
||||||
|
|
||||||
import { useAccountantFormContext } from './AccountantFormProvider';
|
import { useAccountantFormContext } from './AccountantFormProvider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,7 +118,7 @@ export default function AccountantForm() {
|
|||||||
</FastField>
|
</FastField>
|
||||||
|
|
||||||
{/* ----------- Deposit customer account ----------- */}
|
{/* ----------- Deposit customer account ----------- */}
|
||||||
<FFormGroup
|
<AccountantFormGroup
|
||||||
name={'preferred_deposit_account'}
|
name={'preferred_deposit_account'}
|
||||||
label={
|
label={
|
||||||
<strong>
|
<strong>
|
||||||
@@ -133,6 +133,7 @@ export default function AccountantForm() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
fastField={true}
|
||||||
>
|
>
|
||||||
<AccountsSelect
|
<AccountsSelect
|
||||||
name={'preferred_deposit_account'}
|
name={'preferred_deposit_account'}
|
||||||
@@ -143,11 +144,12 @@ export default function AccountantForm() {
|
|||||||
ACCOUNT_TYPE.BANK,
|
ACCOUNT_TYPE.BANK,
|
||||||
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
||||||
]}
|
]}
|
||||||
|
fastField={true}
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</AccountantFormGroup>
|
||||||
|
|
||||||
{/* ----------- Withdrawal vendor account ----------- */}
|
{/* ----------- Withdrawal vendor account ----------- */}
|
||||||
<FFormGroup
|
<AccountantFormGroup
|
||||||
name={'withdrawal_account'}
|
name={'withdrawal_account'}
|
||||||
label={
|
label={
|
||||||
<strong>
|
<strong>
|
||||||
@@ -162,6 +164,7 @@ export default function AccountantForm() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
fastField={true}
|
||||||
>
|
>
|
||||||
<AccountsSelect
|
<AccountsSelect
|
||||||
name={'withdrawal_account'}
|
name={'withdrawal_account'}
|
||||||
@@ -172,11 +175,12 @@ export default function AccountantForm() {
|
|||||||
ACCOUNT_TYPE.BANK,
|
ACCOUNT_TYPE.BANK,
|
||||||
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
ACCOUNT_TYPE.OTHER_CURRENT_ASSET,
|
||||||
]}
|
]}
|
||||||
|
fastField={true}
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</AccountantFormGroup>
|
||||||
|
|
||||||
{/* ----------- Withdrawal customer account ----------- */}
|
{/* ----------- Withdrawal customer account ----------- */}
|
||||||
<FFormGroup
|
<AccountantFormGroup
|
||||||
name={'preferred_advance_deposit'}
|
name={'preferred_advance_deposit'}
|
||||||
label={
|
label={
|
||||||
<strong>
|
<strong>
|
||||||
@@ -191,14 +195,16 @@ export default function AccountantForm() {
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
|
fastField={true}
|
||||||
>
|
>
|
||||||
<AccountsSelect
|
<AccountsSelect
|
||||||
name={'preferred_advance_deposit'}
|
name={'preferred_advance_deposit'}
|
||||||
items={accounts}
|
items={accounts}
|
||||||
placeholder={<T id={'select_payment_account'} />}
|
placeholder={<T id={'select_payment_account'} />}
|
||||||
filterByParentTypes={[ACCOUNT_PARENT_TYPE.CURRENT_ASSET]}
|
filterByParentTypes={[ACCOUNT_PARENT_TYPE.CURRENT_ASSET]}
|
||||||
|
fastField={true}
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</AccountantFormGroup>
|
||||||
|
|
||||||
<CardFooterActions>
|
<CardFooterActions>
|
||||||
<Button intent={Intent.PRIMARY} loading={isSubmitting} type="submit">
|
<Button intent={Intent.PRIMARY} loading={isSubmitting} type="submit">
|
||||||
@@ -211,3 +217,7 @@ export default function AccountantForm() {
|
|||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AccountantFormGroup = styled(FFormGroup)`
|
||||||
|
width: 450px;
|
||||||
|
`;
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ function ReceiptFormHeader({
|
|||||||
labelInfo={<FieldRequiredHint />}
|
labelInfo={<FieldRequiredHint />}
|
||||||
name={'deposit_account_id'}
|
name={'deposit_account_id'}
|
||||||
items={accounts}
|
items={accounts}
|
||||||
|
fastField={true}
|
||||||
shouldUpdate={accountsFieldShouldUpdate}
|
shouldUpdate={accountsFieldShouldUpdate}
|
||||||
>
|
>
|
||||||
<AccountsSelect
|
<AccountsSelect
|
||||||
@@ -144,6 +145,8 @@ function ReceiptFormHeader({
|
|||||||
]}
|
]}
|
||||||
allowCreate={true}
|
allowCreate={true}
|
||||||
fill={true}
|
fill={true}
|
||||||
|
fastField={true}
|
||||||
|
shouldUpdate={accountsFieldShouldUpdate}
|
||||||
/>
|
/>
|
||||||
</FFormGroup>
|
</FFormGroup>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user