Merge pull request #879 from bigcapitalhq/refactor-bound-formik-fields

refactor(webapp): bound Formik fields
This commit is contained in:
Ahmed Bouhuolia
2025-12-22 23:28:17 +02:00
committed by GitHub
12 changed files with 492 additions and 696 deletions

View File

@@ -1,7 +1,7 @@
// @ts-nocheck
import React from 'react';
import { Intent } from '@blueprintjs/core';
import { Field, getIn } from 'formik';
import { Field, FastField, getIn } from 'formik';
import { CurrencyInput } from './MoneyInputGroup';
const fieldToMoneyInputGroup = ({
@@ -32,6 +32,7 @@ function FieldToMoneyInputGroup({ ...props }) {
return <CurrencyInput {...fieldToMoneyInputGroup(props)} />;
}
export function FMoneyInputGroup({ ...props }) {
return <Field {...props} component={FieldToMoneyInputGroup} />;
export function FMoneyInputGroup({ fastField, ...props }) {
const FieldComponent = fastField ? FastField : Field;
return <FieldComponent {...props} component={FieldToMoneyInputGroup} />;
}

View File

@@ -1,35 +1,38 @@
// @ts-nocheck
import React from 'react';
import { Field, FastField, ErrorMessage } from 'formik';
import { FormGroup, InputGroup } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { useAutofocus } from '@/hooks';
import { Row, Col, MoneyInputGroup, FormattedMessage as T } from '@/components';
import { inputIntent, toSafeNumber } from '@/utils';
import {
Row,
Col,
FMoneyInputGroup,
FormattedMessage as T,
FFormGroup,
FInputGroup,
} from '@/components';
import { toSafeNumber } from '@/utils';
import { decrementQuantity, incrementQuantity } from './utils';
export default function IncrementAdjustmentFields() {
const incrementFieldRef = useAutofocus();
const { values, setFieldValue } = useFormikContext();
return (
<Row>
{/*------------ Quantity on hand -----------*/}
<Col className={'col--quantity-on-hand'}>
<FastField name={'quantity_on_hand'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'qty_on_hand'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="quantity_on_hand" />}
>
<InputGroup
disabled={true}
medium={'true'}
intent={inputIntent({ error, touched })}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'quantity_on_hand'}
label={<T id={'qty_on_hand'} />}
fastField
>
<FInputGroup
name={'quantity_on_hand'}
disabled={true}
medium={'true'}
fastField
/>
</FFormGroup>
</Col>
{/*------------ Sign -----------*/}
@@ -39,65 +42,36 @@ export default function IncrementAdjustmentFields() {
{/*------------ Increment -----------*/}
<Col className={'col--quantity'}>
<Field name={'quantity'}>
{({
form: { values, setFieldValue },
field,
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'increment'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="quantity" />}
fill={true}
>
<MoneyInputGroup
value={field.value}
allowDecimals={false}
allowNegativeValue={true}
inputRef={(ref) => (incrementFieldRef.current = ref)}
onChange={(value) => {
setFieldValue('quantity', value);
}}
onBlurValue={(value) => {
setFieldValue(
'new_quantity',
incrementQuantity(
toSafeNumber(value),
toSafeNumber(values.quantity_on_hand),
),
);
}}
intent={inputIntent({ error, touched })}
/>
</FormGroup>
)}
</Field>
<FFormGroup
name={'quantity'}
label={<T id={'increment'} />}
fill
fastField
>
<FMoneyInputGroup
name={'quantity'}
allowDecimals={false}
allowNegativeValue={true}
inputRef={(ref) => (incrementFieldRef.current = ref)}
onBlurValue={(value) => {
setFieldValue(
'new_quantity',
incrementQuantity(
toSafeNumber(value),
toSafeNumber(values.quantity_on_hand),
),
);
}}
fastField
/>
</FFormGroup>
</Col>
{/*------------ Cost -----------*/}
<Col className={'col--cost'}>
<FastField name={'cost'}>
{({
form: { setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'cost'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="cost" />}
>
<MoneyInputGroup
value={value}
onChange={(value) => {
setFieldValue('cost', value);
}}
intent={inputIntent({ error, touched })}
/>
</FormGroup>
)}
</FastField>
<FFormGroup name={'cost'} label={<T id={'cost'} />} fastField>
<FMoneyInputGroup name={'cost'} fastField />
</FFormGroup>
</Col>
{/*------------ Sign -----------*/}
@@ -107,38 +81,27 @@ export default function IncrementAdjustmentFields() {
{/*------------ New quantity -----------*/}
<Col className={'col--quantity-on-hand'}>
<Field name={'new_quantity'}>
{({
form: { values, setFieldValue },
field,
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'new_quantity'} />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="new_quantity" />}
>
<MoneyInputGroup
value={field.value}
allowDecimals={false}
allowNegativeValue={true}
onChange={(value) => {
setFieldValue('new_quantity', value);
}}
onBlurValue={(value) => {
setFieldValue(
'quantity',
decrementQuantity(
toSafeNumber(value),
toSafeNumber(values.quantity_on_hand),
),
);
}}
intent={inputIntent({ error, touched })}
/>
</FormGroup>
)}
</Field>
<FFormGroup
name={'new_quantity'}
label={<T id={'new_quantity'} />}
fastField
>
<FMoneyInputGroup
name={'new_quantity'}
allowDecimals={false}
allowNegativeValue={true}
onBlurValue={(value) => {
setFieldValue(
'quantity',
decrementQuantity(
toSafeNumber(value),
toSafeNumber(values.quantity_on_hand),
),
);
}}
fastField
/>
</FFormGroup>
</Col>
</Row>
);

View File

@@ -1,11 +1,15 @@
// @ts-nocheck
import React from 'react';
import { Classes, FormGroup, InputGroup, TextArea } from '@blueprintjs/core';
import { FormattedMessage as T, FieldRequiredHint } from '@/components';
import { ErrorMessage, FastField } from 'formik';
import { Classes } from '@blueprintjs/core';
import {
FormattedMessage as T,
FieldRequiredHint,
FFormGroup,
FInputGroup,
FTextArea,
} from '@/components';
import { useAutofocus } from '@/hooks';
import { inputIntent } from '@/utils';
/**
* Item category form fields.
@@ -16,45 +20,35 @@ export default function ItemCategoryFormFields() {
return (
<div className={Classes.DIALOG_BODY}>
{/* ----------- Category name ----------- */}
<FastField name={'name'}>
{({ field, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'category_name'} />}
labelInfo={<FieldRequiredHint />}
className={'form-group--category-name'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="name" />}
inline={true}
>
<InputGroup
medium={true}
inputRef={(ref) => (categoryNameFieldRef.current = ref)}
intent={inputIntent({ error, touched })}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'name'}
label={<T id={'category_name'} />}
labelInfo={<FieldRequiredHint />}
inline
fastField
>
<FInputGroup
name={'name'}
medium={true}
inputRef={(ref) => (categoryNameFieldRef.current = ref)}
fastField
/>
</FFormGroup>
{/* ----------- Description ----------- */}
<FastField name={'description'}>
{({ field, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'description'} />}
className={'form-group--description'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="description" />}
inline={true}
>
<TextArea
growVertically={true}
large={true}
intent={inputIntent({ error, touched })}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'description'}
label={<T id={'description'} />}
inline
fastField
>
<FTextArea
name={'description'}
growVertically={true}
large={true}
fastField
/>
</FFormGroup>
</div>
);
}

View File

@@ -1,8 +1,6 @@
// @ts-nocheck
import React from 'react';
import { FastField, ErrorMessage } from 'formik';
import { Classes, FormGroup, Position } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
import { Classes, Position } from '@blueprintjs/core';
import classNames from 'classnames';
import { CLASSES } from '@/constants/classes';
import {
@@ -10,14 +8,10 @@ import {
FormattedMessage as T,
FFormGroup,
FTextArea,
FDateInput,
} from '@/components';
import { useAutofocus } from '@/hooks';
import {
inputIntent,
momentFormatter,
tansformDateValue,
handleDateChange,
} from '@/utils';
import { momentFormatter } from '@/utils';
/**
* locking Transactions form fields.
@@ -28,31 +22,24 @@ export default function LockingTransactionsFormFields() {
return (
<div className={Classes.DIALOG_BODY}>
{/*------------ Locking Date -----------*/}
<FastField name={'lock_to_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'locking_transactions.dialog.locking_date'} />}
labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="lock_to_date" />}
minimal={true}
className={classNames(CLASSES.FILL, 'form-group--date')}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('lock_to_date', formattedDate);
})}
value={tansformDateValue(value)}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
intent={inputIntent({ error, touched })}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'lock_to_date'}
label={<T id={'locking_transactions.dialog.locking_date'} />}
labelInfo={<FieldRequiredHint />}
minimal={true}
className={classNames(CLASSES.FILL, 'form-group--date')}
fastField
>
<FDateInput
name={'lock_to_date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
fastField
/>
</FFormGroup>
{/*------------ Locking Reason -----------*/}
<FFormGroup
@@ -66,6 +53,7 @@ export default function LockingTransactionsFormFields() {
growVertically={true}
large={true}
inputRef={(ref) => (reasonFieldRef.current = ref)}
fill
fastField
/>
</FFormGroup>

View File

@@ -2,18 +2,10 @@
import React from 'react';
import intl from 'react-intl-universal';
import styled from 'styled-components';
import { FastField, ErrorMessage, useFormikContext } from 'formik';
import {
Classes,
FormGroup,
InputGroup,
TextArea,
Position,
ControlGroup,
} from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { Classes, Position, ControlGroup } from '@blueprintjs/core';
import classNames from 'classnames';
import { CLASSES } from '@/constants/classes';
import { DateInput } from '@blueprintjs/datetime';
import { isEqual } from 'lodash';
import {
Icon,
@@ -23,20 +15,18 @@ import {
FieldRequiredHint,
FAccountsSuggestField,
InputPrependText,
MoneyInputGroup,
FMoneyInputGroup,
FormattedMessage as T,
ExchangeRateMutedField,
BranchSelect,
BranchSelectButton,
FeatureCan,
FFormGroup,
FDateInput,
FInputGroup,
FTextArea,
} from '@/components';
import {
inputIntent,
momentFormatter,
tansformDateValue,
handleDateChange,
compose,
} from '@/utils';
import { momentFormatter, compose } from '@/utils';
import { useAutofocus } from '@/hooks';
import { Features, ACCOUNT_TYPE } from '@/constants';
import { useSetPrimaryBranchToForm } from './utils';
@@ -63,46 +53,39 @@ function RefundVendorCreditFormFields({
<FeatureCan feature={Features.Branches}>
<Row>
<Col xs={5}>
<FormGroup
label={<T id={'branch'} />}
className={classNames('form-group--select-list', Classes.FILL)}
>
<FFormGroup name={'branch_id'} label={<T id={'branch'} />} fill>
<BranchSelect
name={'branch_id'}
branches={branches}
input={BranchSelectButton}
popoverProps={{ minimal: true }}
/>
</FormGroup>
</FFormGroup>
</Col>
</Row>
<BranchRowDivider />
</FeatureCan>
<Row>
<Col xs={5}>
{/* ------------- Refund date ------------- */}
<FastField name={'refund_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FFormGroup
name={'refund_date'}
label={<T id={'refund_vendor_credit.dialog.refund_date'} />}
labelInfo={<FieldRequiredHint />}
fill
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('refund_date', formattedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
/>
</FFormGroup>
)}
</FastField>
<FFormGroup
name={'refund_date'}
label={<T id={'refund_vendor_credit.dialog.refund_date'} />}
labelInfo={<FieldRequiredHint />}
fill
fastField
>
<FDateInput
name={'refund_date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
fastField
/>
</FFormGroup>
</Col>
<Col xs={5}>
@@ -130,34 +113,23 @@ function RefundVendorCreditFormFields({
</Row>
{/* ------------- Amount ------------- */}
<FastField name={'amount'}>
{({
form: { values, setFieldValue },
field: { value },
meta: { error, touched },
}) => (
<FormGroup
label={<T id={'refund_vendor_credit.dialog.amount'} />}
labelInfo={<FieldRequiredHint />}
className={classNames('form-group--amount', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="amount" />}
>
<ControlGroup>
<InputPrependText text={values.currency_code} />
<MoneyInputGroup
value={value}
minimal={true}
onChange={(amount) => {
setFieldValue('amount', amount);
}}
intent={inputIntent({ error, touched })}
inputRef={(ref) => (amountFieldRef.current = ref)}
/>
</ControlGroup>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'amount'}
label={<T id={'refund_vendor_credit.dialog.amount'} />}
labelInfo={<FieldRequiredHint />}
fill
fastField
>
<ControlGroup>
<InputPrependText text={values.currency_code} />
<FMoneyInputGroup
name={'amount'}
minimal={true}
inputRef={(ref) => (amountFieldRef.current = ref)}
fastField
/>
</ControlGroup>
</FFormGroup>
<If condition={!isEqual(base_currency, values.currency_code)}>
{/*------------ exchange rate -----------*/}
@@ -172,34 +144,19 @@ function RefundVendorCreditFormFields({
</If>
{/* ------------ Reference No. ------------ */}
<FastField name={'reference_no'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'reference_no'} />}
className={classNames('form-group--reference', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="reference" />}
>
<InputGroup
intent={inputIntent({ error, touched })}
minimal={true}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'reference_no'}
label={<T id={'reference_no'} />}
fill
fastField
>
<FInputGroup name={'reference_no'} minimal={true} fastField />
</FFormGroup>
{/* --------- Statement --------- */}
<FastField name={'description'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'refund_vendor_credit.dialog.description'} />}
className={'form-group--description'}
>
<TextArea growVertically={true} {...field} />
</FormGroup>
)}
</FastField>
<FFormGroup name={'description'} fill fastField>
<FTextArea name={'description'} growVertically={true} fastField />
</FFormGroup>
</div>
);
}

View File

@@ -1,8 +1,6 @@
// @ts-nocheck
import React from 'react';
import { FastField, ErrorMessage } from 'formik';
import { Classes, FormGroup, TextArea, Position } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
import { Classes, Position } from '@blueprintjs/core';
import classNames from 'classnames';
import { CLASSES } from '@/constants/classes';
import {
@@ -10,13 +8,11 @@ import {
Col,
Row,
FormattedMessage as T,
FFormGroup,
FDateInput,
FTextArea,
} from '@/components';
import {
inputIntent,
momentFormatter,
tansformDateValue,
handleDateChange,
} from '@/utils';
import { momentFormatter } from '@/utils';
import { useAutofocus } from '@/hooks';
/**
@@ -30,87 +26,65 @@ export default function UnlockingPartialTransactionsFormFields() {
<Row>
<Col xs={6}>
{/*------------ Unlocking from date -----------*/}
<FastField name={'unlock_from_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={
<T id={'unlocking_partial_transactions.dialog.from_date'} />
}
labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="unlock_from_date" />}
minimal={true}
className={classNames(CLASSES.FILL, 'form-group--date')}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('unlock_from_date', formattedDate);
})}
value={tansformDateValue(value)}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
intent={inputIntent({ error, touched })}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'unlock_from_date'}
label={<T id={'unlocking_partial_transactions.dialog.from_date'} />}
labelInfo={<FieldRequiredHint />}
fill
minimal
fastField
>
<FDateInput
name={'unlock_from_date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
fastField
/>
</FFormGroup>
</Col>
<Col xs={6}>
{/*------------ Unlocking from date -----------*/}
<FastField name={'unlock_to_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={
<T id={'unlocking_partial_transactions.dialog.to_date'} />
}
labelInfo={<FieldRequiredHint />}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="unlock_to_date" />}
minimal={true}
className={classNames(CLASSES.FILL, 'form-group--date')}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('unlock_to_date', formattedDate);
})}
value={tansformDateValue(value)}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
intent={inputIntent({ error, touched })}
/>
</FormGroup>
)}
</FastField>
{/*------------ Unlocking to date -----------*/}
<FFormGroup
name={'unlock_to_date'}
label={<T id={'unlocking_partial_transactions.dialog.to_date'} />}
labelInfo={<FieldRequiredHint />}
minimal={true}
fill
fastField
>
<FDateInput
name={'unlock_to_date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{
position: Position.BOTTOM,
minimal: true,
}}
fastField
/>
</FFormGroup>
</Col>
</Row>
{/*------------ unLocking reason -----------*/}
<FastField name={'reason'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'unlocking_partial_transactions.dialog.reason'} />}
labelInfo={<FieldRequiredHint />}
className={'form-group--reason'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'reason'} />}
>
<TextArea
growVertically={true}
large={true}
intent={inputIntent({ error, touched })}
inputRef={(ref) => (reasonFieldRef.current = ref)}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'reason'}
label={<T id={'unlocking_partial_transactions.dialog.reason'} />}
labelInfo={<FieldRequiredHint />}
fastField
>
<FTextArea
name={'reason'}
growVertically={true}
large={true}
inputRef={(ref) => (reasonFieldRef.current = ref)}
fill
fastField
/>
</FFormGroup>
</div>
);
}

View File

@@ -1,7 +1,5 @@
// @ts-nocheck
import { FastField } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import { FormGroup, Position, Checkbox } from '@blueprintjs/core';
import { Position } from '@blueprintjs/core';
import {
FormattedMessage as T,
Row,
@@ -9,13 +7,10 @@ import {
FieldHint,
CustomersMultiSelect,
FFormGroup,
FDateInput,
FCheckbox,
} from '@/components';
import {
momentFormatter,
tansformDateValue,
inputIntent,
handleDateChange,
} from '@/utils';
import { momentFormatter } from '@/utils';
import { filterCustomersOptions } from '../constants';
import { useCustomersBalanceSummaryGeneralContext } from './CustomersBalanceSummaryGeneralProvider';
import FinancialStatementsFilter from '../FinancialStatementsFilter';
@@ -30,45 +25,40 @@ export default function CustomersBalanceSummaryGeneralPanelContent() {
<div>
<Row>
<Col xs={5}>
<FastField name={'asDate'}>
{({ form, field: { value }, meta: { error } }) => (
<FormGroup
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill={true}
intent={inputIntent({ error })}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((selectedDate) => {
form.setFieldValue('asDate', selectedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'asDate'}
label={<T id={'as_date'} />}
labelInfo={<FieldHint />}
fill
fastField
>
<FDateInput
name={'asDate'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
minimal={true}
fill={true}
fastField
/>
</FFormGroup>
</Col>
</Row>
<Row>
<Col xs={5}>
<FastField name={'percentage_column'} type={'checkbox'}>
{({ field }) => (
<FormGroup labelInfo={<FieldHint />}>
<Checkbox
inline={true}
name={'percentage'}
small={true}
label={<T id={'percentage_of_column'} />}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'percentage_column'}
labelInfo={<FieldHint />}
fastField
>
<FCheckbox
name={'percentage_column'}
inline={true}
small={true}
label={<T id={'percentage_of_column'} />}
fastField
/>
</FFormGroup>
</Col>
</Row>

View File

@@ -5,6 +5,7 @@ import { FormGroup, Classes, Checkbox, ControlGroup } from '@blueprintjs/core';
import {
AccountsSelect,
MoneyInputGroup,
FMoneyInputGroup,
Col,
Row,
Hint,
@@ -59,33 +60,24 @@ function ItemFormBody({ organization: { base_currency } }) {
</FastField>
{/*------------- Selling price ------------- */}
<FastField
<FFormGroup
name={'sell_price'}
sellable={values.sellable}
shouldUpdate={sellPriceFieldShouldUpdate}
label={<T id={'selling_price'} />}
inline
fastField
>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'selling_price'} />}
className={'form-group--sell_price'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'sell_price'} />}
inline={true}
>
<ControlGroup>
<InputPrependText text={base_currency} />
<MoneyInputGroup
value={value}
inputGroupProps={{ fill: true }}
disabled={!form.values.sellable}
onChange={(unformattedValue) => {
form.setFieldValue('sell_price', unformattedValue);
}}
/>
</ControlGroup>
</FormGroup>
)}
</FastField>
<ControlGroup>
<InputPrependText text={base_currency} />
<FMoneyInputGroup
name={'sell_price'}
shouldUpdate={sellPriceFieldShouldUpdate}
sellable={values.sellable}
inputGroupProps={{ fill: true }}
disabled={!values.sellable}
fastField
/>
</ControlGroup>
</FFormGroup>
{/*------------- Selling account ------------- */}
<FFormGroup
@@ -138,6 +130,7 @@ function ItemFormBody({ organization: { base_currency } }) {
growVertically={true}
height={280}
disabled={!values.sellable}
fill
fastField
/>
</FFormGroup>
@@ -162,33 +155,25 @@ function ItemFormBody({ organization: { base_currency } }) {
</FastField>
{/*------------- Cost price ------------- */}
<FastField
<FFormGroup
name={'cost_price'}
purchasable={values.purchasable}
shouldUpdate={costPriceFieldShouldUpdate}
label={<T id={'cost_price'} />}
inline
fastField
>
{({ field, form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'cost_price'} />}
className={'form-group--item-cost-price'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="cost_price" />}
inline={true}
>
<ControlGroup>
<InputPrependText text={base_currency} />
<MoneyInputGroup
value={value}
inputGroupProps={{ medium: true }}
disabled={!form.values.purchasable}
onChange={(unformattedValue) => {
form.setFieldValue('cost_price', unformattedValue);
}}
/>
</ControlGroup>
</FormGroup>
)}
</FastField>
<ControlGroup>
<InputPrependText text={base_currency} />
<FMoneyInputGroup
name={'cost_price'}
shouldUpdate={costPriceFieldShouldUpdate}
purchasable={values.purchasable}
inputGroupProps={{ medium: true }}
disabled={!values.purchasable}
fastField
/>
</ControlGroup>
</FFormGroup>
{/*------------- Cost account ------------- */}
<FFormGroup
@@ -249,6 +234,7 @@ function ItemFormBody({ organization: { base_currency } }) {
growVertically={true}
height={280}
disabled={!values.purchasable}
fill
/>
</FFormGroup>
</Col>

View File

@@ -1,10 +1,16 @@
// @ts-nocheck
import React from 'react';
import { FastField, useFormikContext } from 'formik';
import { FormGroup, InputGroup, Radio } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import { Radio } from '@blueprintjs/core';
import { FormattedMessage as T, Row, Col, ErrorMessage } from '@/components';
import { inputIntent } from '@/utils';
import {
FormattedMessage as T,
Row,
Col,
FFormGroup,
FInputGroup,
FRadioGroup,
} from '@/components';
/**
* Reference number form content.
@@ -13,33 +19,21 @@ export default function ReferenceNumberFormContent() {
return (
<>
{/* ------------- Auto increment mode ------------- */}
<FastField name={'incrementMode'}>
{({ form, field, meta: { error, touched } }) => (
<Radio
label={<T id={'auto_increment.field.auto'} />}
value="auto-increment"
onChange={() => {
form.setFieldValue('incrementMode', 'auto');
}}
checked={field.value === 'auto'}
/>
)}
</FastField>
<FRadioGroup name={'incrementMode'} fastField>
<Radio
label={<T id={'auto_increment.field.auto'} />}
value="auto"
/>
</FRadioGroup>
<ReferenceNumberAutoIncrement />
{/* ------------- Manual increment mode ------------- */}
<FastField name={'incrementMode'}>
{({ form, field, meta: { error, touched } }) => (
<Radio
label={<T id={'auto_increment.field.manually'} />}
value="manual"
onChange={() => {
form.setFieldValue('incrementMode', 'manual');
}}
checked={field.value === 'manual'}
/>
)}
</FastField>
<FRadioGroup name={'incrementMode'} fastField>
<Radio
label={<T id={'auto_increment.field.manually'} />}
value="manual"
/>
</FRadioGroup>
{/* ------------- Transaction manual increment mode ------------- */}
<ReferenceNumberManualOnce />
@@ -49,40 +43,32 @@ export default function ReferenceNumberFormContent() {
function ReferenceNumberAutoIncrement() {
const { values } = useFormikContext();
if (!values.incrementMode === 'auto') return null;
if (values.incrementMode !== 'auto') return null;
return (
<Row>
{/* ------------- Prefix ------------- */}
<Col xs={4}>
<FastField name={'numberPrefix'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'prefix'} />}
className={'form-group--'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'numberPrefix'} />}
>
<InputGroup intent={inputIntent({ error, touched })} {...field} />
</FormGroup>
)}
</FastField>
<FFormGroup
name={'numberPrefix'}
label={<T id={'prefix'} />}
className={'form-group--'}
fastField
>
<FInputGroup name={'numberPrefix'} fastField />
</FFormGroup>
</Col>
{/* ------------- Next number ------------- */}
<Col xs={6}>
<FastField name={'nextNumber'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'next_number'} />}
className={'form-group--next-number'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'nextNumber'} />}
>
<InputGroup intent={inputIntent({ error, touched })} {...field} />
</FormGroup>
)}
</FastField>
<FFormGroup
name={'nextNumber'}
label={<T id={'next_number'} />}
className={'form-group--next-number'}
fastField
>
<FInputGroup name={'nextNumber'} fastField />
</FFormGroup>
</Col>
</Row>
);
@@ -95,17 +81,13 @@ function ReferenceNumberManualOnce() {
if (!values.onceManualNumber) return null;
return (
<FastField name={'incrementMode'}>
{({ form, field, meta: { error, touched } }) => (
<FFormGroup name={'incrementMode'} fastField>
<FRadioGroup name={'incrementMode'} fastField>
<Radio
label={<T id={'auto_increment.field.manual_this_transaction'} />}
value="manual"
onChange={() => {
form.setFieldValue('incrementMode', 'manual-transaction');
}}
checked={field.value === 'manual-transaction'}
value="manual-transaction"
/>
)}
</FastField>
</FRadioGroup>
</FFormGroup>
);
}

View File

@@ -1,10 +1,6 @@
// @ts-nocheck
import React from 'react';
import { ErrorMessage, FastField } from 'formik';
import { FormGroup, InputGroup, TextArea } from '@blueprintjs/core';
import { inputIntent } from '@/utils';
import { FormattedMessage as T, FieldRequiredHint, Card } from '@/components';
import { FormattedMessage as T, FieldRequiredHint, Card, FFormGroup, FInputGroup, FTextArea } from '@/components';
import { useAutofocus } from '@/hooks';
/**
@@ -17,48 +13,42 @@ export function RoleFormHeader() {
return (
<Card>
{/* ---------- Name ---------- */}
<FastField name={'role_name'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={
<strong>
<T id={'roles.label.role_name'} />
</strong>
}
labelInfo={<FieldRequiredHint />}
className={'form-group--name'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="role_name" />}
inline={true}
>
<InputGroup
medium={true}
inputRef={(ref) => (roleNameFieldRef.current = ref)}
{...field}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'role_name'}
label={
<strong>
<T id={'roles.label.role_name'} />
</strong>
}
labelInfo={<FieldRequiredHint />}
inline
fastField
>
<FInputGroup
name={'role_name'}
medium={true}
inputRef={(ref) => (roleNameFieldRef.current = ref)}
fill
fastField
/>
</FFormGroup>
{/* ---------- Description ---------- */}
<FastField name={'role_description'}>
{({ field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'description'} />}
className={'form-group--description'}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name={'role_description'} />}
inline={true}
>
<TextArea
growVertically={true}
height={280}
{...field}
placeholder="Max. 500 characters"
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'role_description'}
label={<T id={'description'} />}
inline
fastField
>
<FTextArea
name={'role_description'}
growVertically={true}
height={280}
placeholder="Max. 500 characters"
fill
fastField
/>
</FFormGroup>
</Card>
);
}

View File

@@ -2,9 +2,8 @@
import React from 'react';
import styled from 'styled-components';
import classNames from 'classnames';
import { FastField, ErrorMessage, useFormikContext } from 'formik';
import { FormGroup, InputGroup, Classes, Position } from '@blueprintjs/core';
import { DateInput } from '@blueprintjs/datetime';
import { useFormikContext } from 'formik';
import { Classes, Position } from '@blueprintjs/core';
import { css } from '@emotion/css';
import { FeatureCan, Stack, FormattedMessage as T } from '@/components';
@@ -15,6 +14,8 @@ import {
Icon,
VendorDrawerLink,
VendorsSelect,
FDateInput,
FInputGroup,
} from '@/components';
import { useBillFormContext } from './BillFormProvider';
@@ -28,9 +29,6 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
import {
momentFormatter,
compose,
tansformDateValue,
handleDateChange,
inputIntent,
} from '@/utils';
import { Features } from '@/constants';
import { useTheme } from '@emotion/react';
@@ -74,57 +72,43 @@ function BillFormHeader() {
/>
{/* ------- Bill date ------- */}
<FastField name={'bill_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'bill_date'} />}
inline={true}
labelInfo={<FieldRequiredHint />}
className={classNames(CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="bill_date" />}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('bill_date', formattedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
inputProps={{ leftIcon: <Icon icon={'date-range'} /> }}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'bill_date'}
label={<T id={'bill_date'} />}
inline
labelInfo={<FieldRequiredHint />}
className={classNames(CLASSES.FILL)}
fastField
>
<FDateInput
name={'bill_date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
inputProps={{ leftIcon: <Icon icon={'date-range'} /> }}
fill
fastField
/>
</FFormGroup>
{/* ------- Due date ------- */}
<FastField name={'due_date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'due_date'} />}
inline={true}
className={classNames(
'form-group--due-date',
'form-group--select-list',
CLASSES.FILL,
)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="due_date" />}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('due_date', formattedDate);
})}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'due_date'}
label={<T id={'due_date'} />}
inline
fill
fastField
>
<FDateInput
name={'due_date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{ position: Position.BOTTOM, minimal: true }}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
fill
fastField
/>
</FFormGroup>
{/* ------- Bill number ------- */}
<FFormGroup

View File

@@ -1,24 +1,19 @@
// @ts-nocheck
import React from 'react';
import {
FormGroup,
InputGroup,
Position,
ControlGroup,
} from '@blueprintjs/core';
import { FastField, Field, ErrorMessage } from 'formik';
import { DateInput } from '@blueprintjs/datetime';
import { Position, ControlGroup } from '@blueprintjs/core';
import { useFormikContext } from 'formik';
import {
FFormGroup,
FormattedMessage as T,
WarehouseSelect,
FDateInput,
FInputGroup,
} from '@/components';
import { momentFormatter, compose, tansformDateValue } from '@/utils';
import { momentFormatter, compose } from '@/utils';
import classNames from 'classnames';
import { CLASSES } from '@/constants/classes';
import { FieldRequiredHint, Icon, InputPrependButton } from '@/components';
import { inputIntent, handleDateChange } from '@/utils';
import { useWarehouseTransferFormContext } from './WarehouseTransferFormProvider';
import { useObserveTransferNoSettings } from './utils';
import withSettings from '@/containers/Settings/withSettings';
@@ -37,6 +32,7 @@ function WarehouseTransferFormHeaderFields({
warehouseTransferNumberPrefix,
}) {
const { warehouses } = useWarehouseTransferFormContext();
const { values } = useFormikContext();
// Handle warehouse transfer number changing.
const handleTransferNumberChange = () => {
@@ -44,10 +40,13 @@ function WarehouseTransferFormHeaderFields({
};
// Handle transfer no. field blur.
const handleTransferNoBlur = (form, field) => (event) => {
const handleTransferNoBlur = (event) => {
const newValue = event.target.value;
if (field.value !== newValue && warehouseTransferAutoIncrement) {
if (
values.transaction_number !== newValue &&
warehouseTransferAutoIncrement
) {
openDialog('warehouse-transfer-no-form', {
initialFormValues: {
manualTransactionNo: newValue,
@@ -66,70 +65,58 @@ function WarehouseTransferFormHeaderFields({
return (
<div className={classNames(CLASSES.PAGE_FORM_HEADER_FIELDS)}>
{/* ----------- Date ----------- */}
<FastField name={'date'}>
{({ form, field: { value }, meta: { error, touched } }) => (
<FormGroup
label={<T id={'date'} />}
inline={true}
labelInfo={<FieldRequiredHint />}
className={classNames('form-group--date', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="date" />}
>
<DateInput
{...momentFormatter('YYYY/MM/DD')}
value={tansformDateValue(value)}
onChange={handleDateChange((formattedDate) => {
form.setFieldValue('date', formattedDate);
})}
popoverProps={{ position: Position.BOTTOM_LEFT, minimal: true }}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
/>
</FormGroup>
)}
</FastField>
<FFormGroup
name={'date'}
label={<T id={'date'} />}
inline
labelInfo={<FieldRequiredHint />}
fill
fastField
>
<FDateInput
name={'date'}
{...momentFormatter('YYYY/MM/DD')}
popoverProps={{ position: Position.BOTTOM_LEFT, minimal: true }}
inputProps={{
leftIcon: <Icon icon={'date-range'} />,
}}
fastField
/>
</FFormGroup>
{/* ----------- Transfer number ----------- */}
<Field name={'transaction_number'}>
{({ form, field, meta: { error, touched } }) => (
<FormGroup
label={<T id={'warehouse_transfer.label.transfer_no'} />}
// labelInfo={<FieldRequiredHint />}
inline={true}
className={classNames('form-group--transfer-no', CLASSES.FILL)}
intent={inputIntent({ error, touched })}
helperText={<ErrorMessage name="transfer_number" />}
>
<ControlGroup fill={true}>
<InputGroup
minimal={true}
value={field.value}
asyncControl={true}
onBlur={handleTransferNoBlur(form, field)}
/>
<InputPrependButton
buttonProps={{
onClick: handleTransferNumberChange,
icon: <Icon icon={'settings-18'} />,
}}
tooltip={true}
tooltipProps={{
content: (
<T
id={
'warehouse_transfer.setting_your_auto_generated_transfer_no'
}
/>
),
position: Position.BOTTOM_LEFT,
}}
/>
</ControlGroup>
</FormGroup>
)}
</Field>
<FFormGroup
name={'transaction_number'}
label={<T id={'warehouse_transfer.label.transfer_no'} />}
inline
fill
>
<ControlGroup fill={true}>
<FInputGroup
name={'transaction_number'}
minimal={true}
asyncControl={true}
onBlur={handleTransferNoBlur}
/>
<InputPrependButton
buttonProps={{
onClick: handleTransferNumberChange,
icon: <Icon icon={'settings-18'} />,
}}
tooltip={true}
tooltipProps={{
content: (
<T
id={
'warehouse_transfer.setting_your_auto_generated_transfer_no'
}
/>
),
position: Position.BOTTOM_LEFT,
}}
/>
</ControlGroup>
</FFormGroup>
{/* ----------- Form Warehouse ----------- */}
<FFormGroup