refactor(webapp): bound Formik fields

This commit is contained in:
Ahmed Bouhuolia
2025-12-22 23:25:43 +02:00
parent 37f0f4e227
commit 6fea7779da
12 changed files with 492 additions and 696 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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