mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
- feat: Filter expense and payment accounts on expense form.
- feat: Make journal errors with receivable and payable accounts. - fix: Handle database big numbers. - fix: Indexing lines when add a new line on make journal form. - fix: Abstruct accounts type component.
This commit is contained in:
@@ -5,11 +5,10 @@ import { FormattedMessage as T } from 'react-intl';
|
||||
|
||||
export default function AccountsSelectList({
|
||||
accounts,
|
||||
onAccountSelected,
|
||||
error = [],
|
||||
initialAccountId,
|
||||
selectedAccountId,
|
||||
defaultSelectText = 'Select account',
|
||||
onAccountSelected,
|
||||
}) {
|
||||
// Find initial account object to set it as default account in initial render.
|
||||
const initialAccount = useMemo(
|
||||
|
||||
46
client/src/components/AccountsTypesSelect.js
Normal file
46
client/src/components/AccountsTypesSelect.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import {
|
||||
ListSelect,
|
||||
} from 'components';
|
||||
|
||||
export default function AccountsTypesSelect({
|
||||
accountsTypes,
|
||||
selectedTypeId,
|
||||
defaultSelectText = 'Select account type',
|
||||
onTypeSelected,
|
||||
...restProps
|
||||
}) {
|
||||
// Filters accounts types items.
|
||||
const filterAccountTypeItems = (query, accountType, _index, exactMatch) => {
|
||||
const normalizedTitle = accountType.name.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);
|
||||
};
|
||||
|
||||
const items = accountsTypes.map((type) => ({
|
||||
id: type.id, name: type.name,
|
||||
}));
|
||||
|
||||
return (
|
||||
<ListSelect
|
||||
items={items}
|
||||
selectedItemProp={'id'}
|
||||
selectedItem={selectedTypeId}
|
||||
labelProp={'name'}
|
||||
defaultText={defaultSelectText}
|
||||
onItemSelect={handleItemSelected}
|
||||
itemPredicate={filterAccountTypeItems}
|
||||
{...restProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -17,17 +17,9 @@ export default function ContactsListField({
|
||||
initialContact || null
|
||||
);
|
||||
|
||||
const contactTypeLabel = (contactType) => {
|
||||
switch(contactType) {
|
||||
case 'customer':
|
||||
return 'Customer';
|
||||
case 'vendor':
|
||||
return 'Vendor';
|
||||
}
|
||||
};
|
||||
// Contact item of select accounts field.
|
||||
const contactItem = useCallback((item, { handleClick, modifiers, query }) => (
|
||||
<MenuItem text={item.display_name} label={contactTypeLabel(item.contact_type)} key={item.id} onClick={handleClick} />
|
||||
<MenuItem text={item.display_name} key={item.id} onClick={handleClick} />
|
||||
), []);
|
||||
|
||||
const onContactSelect = useCallback((contact) => {
|
||||
|
||||
@@ -1,44 +1,43 @@
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import AccountsSelectList from 'components/AccountsSelectList';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
FormGroup,
|
||||
Classes,
|
||||
Intent,
|
||||
} from '@blueprintjs/core';
|
||||
import { FormGroup, Classes, Intent } from '@blueprintjs/core';
|
||||
|
||||
// Account cell renderer.
|
||||
const AccountCellRenderer = ({
|
||||
column: { id },
|
||||
column: { id, accountsDataProp },
|
||||
row: { index, original },
|
||||
cell: { value: initialValue },
|
||||
payload: { accounts, updateData, errors },
|
||||
payload: { accounts: defaultAccounts, updateData, errors, ...restProps },
|
||||
}) => {
|
||||
const handleAccountSelected = useCallback((account) => {
|
||||
updateData(index, id, account.id);
|
||||
}, [updateData, index, id]);
|
||||
|
||||
const { account_id = false } = (errors[index] || {});
|
||||
|
||||
// const initialAccount = useMemo(() =>
|
||||
// accounts.find(a => a.id === initialValue),
|
||||
// [accounts, initialValue]);
|
||||
const handleAccountSelected = useCallback(
|
||||
(account) => {
|
||||
updateData(index, id, account.id);
|
||||
},
|
||||
[updateData, index, id],
|
||||
);
|
||||
const error = errors?.[index]?.[id];
|
||||
|
||||
const accounts = useMemo(
|
||||
() => restProps[accountsDataProp] || defaultAccounts,
|
||||
[restProps, defaultAccounts, accountsDataProp],
|
||||
);
|
||||
return (
|
||||
<FormGroup
|
||||
intent={account_id ? Intent.DANGER : ''}
|
||||
intent={error ? Intent.DANGER : null}
|
||||
className={classNames(
|
||||
'form-group--select-list',
|
||||
'form-group--account',
|
||||
Classes.FILL)}
|
||||
>
|
||||
Classes.FILL,
|
||||
)}
|
||||
>
|
||||
<AccountsSelectList
|
||||
accounts={accounts}
|
||||
onAccountSelected={handleAccountSelected}
|
||||
error={account_id}
|
||||
selectedAccountId={initialValue} />
|
||||
selectedAccountId={initialValue}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default AccountCellRenderer;
|
||||
export default AccountCellRenderer;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { FormGroup, Classes } from "@blueprintjs/core";
|
||||
import { FormGroup, Intent, Classes } from "@blueprintjs/core";
|
||||
import classNames from 'classnames';
|
||||
import ContactsListField from 'components/ContactsListField';
|
||||
|
||||
@@ -20,8 +20,11 @@ export default function ContactsListCellRenderer({
|
||||
return contacts.find(c => c.id === initialValue);
|
||||
}, [contacts, initialValue]);
|
||||
|
||||
const error = errors?.[index]?.[id];
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
intent={error ? Intent.DANGER : null}
|
||||
className={classNames(
|
||||
'form-group--select-list',
|
||||
'form-group--contacts-list',
|
||||
@@ -32,6 +35,7 @@ export default function ContactsListCellRenderer({
|
||||
contacts={contacts}
|
||||
onContactSelected={handleContactSelected}
|
||||
initialContact={initialContact}
|
||||
|
||||
/>
|
||||
</FormGroup>
|
||||
)
|
||||
|
||||
@@ -1,31 +1,35 @@
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {
|
||||
InputGroup
|
||||
} from '@blueprintjs/core';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Classes, InputGroup, FormGroup } from '@blueprintjs/core';
|
||||
|
||||
const InputEditableCell = ({
|
||||
row: { index },
|
||||
column: { id, },
|
||||
column: { id },
|
||||
cell: { value: initialValue },
|
||||
payload,
|
||||
}) => {
|
||||
const [value, setValue] = useState(initialValue)
|
||||
const [value, setValue] = useState(initialValue);
|
||||
|
||||
const onChange = e => {
|
||||
setValue(e.target.value)
|
||||
}
|
||||
const onChange = (e) => {
|
||||
setValue(e.target.value);
|
||||
};
|
||||
const onBlur = () => {
|
||||
payload.updateData(index, id, value)
|
||||
}
|
||||
payload.updateData(index, id, value);
|
||||
};
|
||||
useEffect(() => {
|
||||
setValue(initialValue)
|
||||
}, [initialValue])
|
||||
setValue(initialValue);
|
||||
}, [initialValue]);
|
||||
|
||||
return (<InputGroup
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
fill={true} />);
|
||||
return (
|
||||
<FormGroup>
|
||||
<InputGroup
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onBlur={onBlur}
|
||||
fill={true}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputEditableCell;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useCallback, useState, useEffect } from 'react';
|
||||
import { FormGroup, Intent } from '@blueprintjs/core';
|
||||
import MoneyInputGroup from 'components/MoneyInputGroup';
|
||||
|
||||
// Input form cell renderer.
|
||||
@@ -6,7 +7,7 @@ const MoneyFieldCellRenderer = ({
|
||||
row: { index },
|
||||
column: { id },
|
||||
cell: { value: initialValue },
|
||||
payload
|
||||
payload: { errors, updateData },
|
||||
}) => {
|
||||
const [value, setValue] = useState(initialValue);
|
||||
|
||||
@@ -15,26 +16,36 @@ const MoneyFieldCellRenderer = ({
|
||||
}, []);
|
||||
|
||||
function isNumeric(data) {
|
||||
return !isNaN(parseFloat(data)) && isFinite(data) && data.constructor !== Array;
|
||||
return (
|
||||
!isNaN(parseFloat(data)) && isFinite(data) && data.constructor !== Array
|
||||
);
|
||||
}
|
||||
|
||||
const onBlur = () => {
|
||||
const updateValue = isNumeric(value) ? parseFloat(value) : value;
|
||||
payload.updateData(index, id, updateValue);
|
||||
updateData(index, id, updateValue);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setValue(initialValue);
|
||||
}, [initialValue])
|
||||
}, [initialValue]);
|
||||
|
||||
return (<MoneyInputGroup
|
||||
value={value}
|
||||
prefix={'$'}
|
||||
onChange={handleFieldChange}
|
||||
inputGroupProps={{
|
||||
fill: true,
|
||||
onBlur,
|
||||
}} />)
|
||||
const error = errors?.[index]?.[id];
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
intent={error ? Intent.DANGER : null}>
|
||||
<MoneyInputGroup
|
||||
value={value}
|
||||
prefix={'$'}
|
||||
onChange={handleFieldChange}
|
||||
inputGroupProps={{
|
||||
fill: true,
|
||||
onBlur,
|
||||
}}
|
||||
/>
|
||||
</FormGroup>
|
||||
);
|
||||
};
|
||||
|
||||
export default MoneyFieldCellRenderer;
|
||||
export default MoneyFieldCellRenderer;
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function ListSelect ({
|
||||
('loading') : <MenuItem disabled={true} text={noResultsText} />;
|
||||
|
||||
const itemRenderer = (item, { handleClick, modifiers, query }) => {
|
||||
return (<MenuItem text={item[labelProp]} key={item[selectedItemProp]} />);
|
||||
return (<MenuItem text={item[labelProp]} key={item[selectedItemProp]} onClick={handleClick} />);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -19,6 +19,7 @@ import Dialog from './Dialog';
|
||||
import AppToaster from './AppToaster';
|
||||
import DataTable from './DataTable';
|
||||
import AccountsSelectList from './AccountsSelectList';
|
||||
import AccountsTypesSelect from './AccountsTypesSelect';
|
||||
|
||||
const Hint = FieldHint;
|
||||
|
||||
@@ -45,4 +46,5 @@ export {
|
||||
AppToaster,
|
||||
DataTable,
|
||||
AccountsSelectList,
|
||||
AccountsTypesSelect,
|
||||
};
|
||||
Reference in New Issue
Block a user