mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
BIG-26: fix items preferences form.
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import React from 'react';
|
||||
import { Formik, Form } from 'formik';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import intl from 'react-intl-universal';
|
||||
import classNames from 'classnames';
|
||||
import { defaultTo } from 'lodash';
|
||||
|
||||
import 'style/pages/Items/PageForm.scss';
|
||||
|
||||
@@ -15,43 +14,15 @@ import ItemFormBody from './ItemFormBody';
|
||||
import ItemFormFloatingActions from './ItemFormFloatingActions';
|
||||
import ItemFormInventorySection from './ItemFormInventorySection';
|
||||
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
|
||||
import { compose, transformToForm } from 'utils';
|
||||
import {
|
||||
EditItemFormSchema,
|
||||
CreateItemFormSchema,
|
||||
transformItemFormData,
|
||||
} from './ItemForm.schema';
|
||||
import { useItemFormInitialValues } from './utils';
|
||||
import { EditItemFormSchema, CreateItemFormSchema } from './ItemForm.schema';
|
||||
|
||||
import { useItemFormContext } from './ItemFormProvider';
|
||||
|
||||
const defaultInitialValues = {
|
||||
active: 1,
|
||||
name: '',
|
||||
type: 'service',
|
||||
code: '',
|
||||
cost_price: '',
|
||||
sell_price: '',
|
||||
cost_account_id: '',
|
||||
sell_account_id: '',
|
||||
inventory_account_id: '',
|
||||
category_id: '',
|
||||
sellable: 1,
|
||||
purchasable: true,
|
||||
sell_description: '',
|
||||
purchase_description: '',
|
||||
};
|
||||
|
||||
/**
|
||||
* Item form.
|
||||
*/
|
||||
function ItemForm({
|
||||
// #withSettings
|
||||
preferredCostAccount,
|
||||
preferredSellAccount,
|
||||
preferredInventoryAccount,
|
||||
}) {
|
||||
export default function ItemForm() {
|
||||
// Item form context.
|
||||
const {
|
||||
itemId,
|
||||
@@ -66,32 +37,8 @@ function ItemForm({
|
||||
// History context.
|
||||
const history = useHistory();
|
||||
|
||||
/**
|
||||
* Initial values in create and edit mode.
|
||||
*/
|
||||
const initialValues = useMemo(
|
||||
() => ({
|
||||
...defaultInitialValues,
|
||||
cost_account_id: defaultTo(preferredCostAccount, ''),
|
||||
sell_account_id: defaultTo(preferredSellAccount, ''),
|
||||
inventory_account_id: defaultTo(preferredInventoryAccount, ''),
|
||||
/**
|
||||
* We only care about the fields in the form. Previously unfilled optional
|
||||
* values such as `notes` come back from the API as null, so remove those
|
||||
* as well.
|
||||
*/
|
||||
...transformToForm(
|
||||
transformItemFormData(item, defaultInitialValues),
|
||||
defaultInitialValues,
|
||||
),
|
||||
}),
|
||||
[
|
||||
item,
|
||||
preferredCostAccount,
|
||||
preferredSellAccount,
|
||||
preferredInventoryAccount,
|
||||
],
|
||||
);
|
||||
// Initial values in create and edit mode.
|
||||
const initialValues = useItemFormInitialValues(item);
|
||||
|
||||
// Transform API errors.
|
||||
const transformApiErrors = (error) => {
|
||||
@@ -179,11 +126,3 @@ function ItemForm({
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withSettings(({ itemsSettings }) => ({
|
||||
preferredCostAccount: parseInt(itemsSettings?.costAccount),
|
||||
preferredSellAccount: parseInt(itemsSettings?.sellAccount),
|
||||
preferredInventoryAccount: parseInt(itemsSettings?.inventoryAccount),
|
||||
})),
|
||||
)(ItemForm);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useEffect, createContext, useState } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
import {
|
||||
useItem,
|
||||
useSettingsItems,
|
||||
useItemsCategories,
|
||||
useCreateItem,
|
||||
useEditItem,
|
||||
@@ -37,6 +38,13 @@ function ItemFormProvider({ itemId, ...props }) {
|
||||
enabled: !!itemId || !!duplicateId,
|
||||
},
|
||||
);
|
||||
|
||||
// Fetches item settings.
|
||||
const {
|
||||
isLoading: isItemsSettingsLoading,
|
||||
isFetching: isItemsSettingsFetching,
|
||||
} = useSettingsItems();
|
||||
|
||||
// Create and edit item mutations.
|
||||
const { mutateAsync: editItemMutate } = useEditItem();
|
||||
const { mutateAsync: createItemMutate } = useCreateItem();
|
||||
@@ -65,9 +73,6 @@ function ItemFormProvider({ itemId, ...props }) {
|
||||
setSubmitPayload,
|
||||
};
|
||||
|
||||
// Format message intl.
|
||||
|
||||
|
||||
// Change page title dispatcher.
|
||||
const changePageTitle = useDashboardPageTitle();
|
||||
|
||||
@@ -78,11 +83,14 @@ function ItemFormProvider({ itemId, ...props }) {
|
||||
: changePageTitle(intl.get('edit_item_details'));
|
||||
}, [changePageTitle, isNewMode]);
|
||||
|
||||
const loading =
|
||||
isItemsSettingsLoading ||
|
||||
isAccountsLoading ||
|
||||
isItemsCategoriesLoading ||
|
||||
isItemLoading;
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={isAccountsLoading || isItemsCategoriesLoading || isItemLoading}
|
||||
name={'item-form'}
|
||||
>
|
||||
<DashboardInsider loading={loading} name={'item-form'}>
|
||||
<ItemFormContext.Provider value={provider} {...props} />
|
||||
</DashboardInsider>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,61 @@
|
||||
import { useMemo } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { defaultTo } from 'lodash';
|
||||
import { AppToaster } from 'components';
|
||||
import {
|
||||
transformTableStateToQuery,
|
||||
defaultFastFieldShouldUpdate,
|
||||
} from 'utils';
|
||||
import { transformToForm } from 'utils';
|
||||
import { useSettingsSelector } from '../../hooks/state';
|
||||
import { transformItemFormData } from './ItemForm.schema';
|
||||
|
||||
const defaultInitialValues = {
|
||||
active: 1,
|
||||
name: '',
|
||||
type: 'service',
|
||||
code: '',
|
||||
cost_price: '',
|
||||
sell_price: '',
|
||||
cost_account_id: '',
|
||||
sell_account_id: '',
|
||||
inventory_account_id: '',
|
||||
category_id: '',
|
||||
sellable: 1,
|
||||
purchasable: true,
|
||||
sell_description: '',
|
||||
purchase_description: '',
|
||||
};
|
||||
|
||||
/**
|
||||
* Initial values in create and edit mode.
|
||||
*/
|
||||
export const useItemFormInitialValues = (item) => {
|
||||
const { items: itemsSettings } = useSettingsSelector();
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
...defaultInitialValues,
|
||||
cost_account_id: defaultTo(itemsSettings.preferredCostAccount, ''),
|
||||
sell_account_id: defaultTo(itemsSettings.preferredSellAccount, ''),
|
||||
inventory_account_id: defaultTo(
|
||||
itemsSettings.preferredInventoryAccount,
|
||||
'',
|
||||
),
|
||||
/**
|
||||
* We only care about the fields in the form. Previously unfilled optional
|
||||
* values such as `notes` come back from the API as null, so remove those
|
||||
* as well.
|
||||
*/
|
||||
...transformToForm(
|
||||
transformItemFormData(item, defaultInitialValues),
|
||||
defaultInitialValues,
|
||||
),
|
||||
}),
|
||||
[item, itemsSettings],
|
||||
);
|
||||
};
|
||||
|
||||
export const transitionItemTypeKeyToLabel = (itemTypeKey) => {
|
||||
const table = {
|
||||
@@ -130,4 +181,4 @@ export function transformItemsTableState(tableState) {
|
||||
...transformTableStateToQuery(tableState),
|
||||
inactive_mode: tableState.inactiveMode,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import React from 'react';
|
||||
import ItemFormPage from './ItemFormPage';
|
||||
import { ItemFormProvider } from './ItemFormProvider';
|
||||
|
||||
/**
|
||||
* items preferences.
|
||||
*/
|
||||
export default function ItemsPreferences() {
|
||||
return (
|
||||
<ItemFormProvider>
|
||||
<ItemFormPage />
|
||||
</ItemFormProvider>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const Schema = Yup.object().shape({
|
||||
sell_account: Yup.number().nullable(),
|
||||
cost_account: Yup.number().nullable(),
|
||||
inventory_account: Yup.number().nullable(),
|
||||
});
|
||||
|
||||
export const ItemPreferencesSchema = Schema;
|
||||
@@ -0,0 +1,9 @@
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const Schema = Yup.object().shape({
|
||||
preferred_sell_account: Yup.number().nullable(),
|
||||
preferred_cost_account: Yup.number().nullable(),
|
||||
preferred_inventory_account: Yup.number().nullable(),
|
||||
});
|
||||
|
||||
export const ItemPreferencesSchema = Schema;
|
||||
@@ -1,21 +1,23 @@
|
||||
import React from 'react';
|
||||
import { Form, FastField, useFormikContext } from 'formik';
|
||||
import { FormGroup, Button, Intent } from '@blueprintjs/core';
|
||||
import { AccountsSelectList, FieldRequiredHint } from 'components';
|
||||
import { FormattedMessage as T } from 'components';
|
||||
import intl from 'react-intl-universal';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import {
|
||||
AccountsSelectList,
|
||||
FieldRequiredHint,
|
||||
FormattedMessage as T,
|
||||
} from 'components';
|
||||
import { inputIntent } from 'utils';
|
||||
import { ACCOUNT_PARENT_TYPE, ACCOUNT_TYPE } from 'common/accountTypes';
|
||||
|
||||
import { useItemFormContext } from './ItemFormProvider';
|
||||
import { useItemPreferencesFormContext } from './ItemPreferencesFormProvider';
|
||||
|
||||
/**
|
||||
* item form preferences.
|
||||
* Item preferences form.
|
||||
*/
|
||||
export default function ItemForm() {
|
||||
const history = useHistory();
|
||||
const { accounts } = useItemFormContext();
|
||||
const { accounts } = useItemPreferencesFormContext();
|
||||
|
||||
const { isSubmitting } = useFormikContext();
|
||||
|
||||
@@ -26,7 +28,7 @@ export default function ItemForm() {
|
||||
return (
|
||||
<Form>
|
||||
{/* ----------- preferred sell account ----------- */}
|
||||
<FastField name={'sell_account'}>
|
||||
<FastField name={'preferred_sell_account'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
@@ -51,7 +53,7 @@ export default function ItemForm() {
|
||||
<AccountsSelectList
|
||||
accounts={accounts}
|
||||
onAccountSelected={({ id }) => {
|
||||
setFieldValue('sell_account', id);
|
||||
setFieldValue('preferred_sell_account', id);
|
||||
}}
|
||||
selectedAccountId={value}
|
||||
defaultSelectText={<T id={'select_payment_account'} />}
|
||||
@@ -62,7 +64,7 @@ export default function ItemForm() {
|
||||
</FastField>
|
||||
|
||||
{/* ----------- preferred cost account ----------- */}
|
||||
<FastField name={'cost_account'}>
|
||||
<FastField name={'preferred_cost_account'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
@@ -87,7 +89,7 @@ export default function ItemForm() {
|
||||
<AccountsSelectList
|
||||
accounts={accounts}
|
||||
onAccountSelected={({ id }) => {
|
||||
setFieldValue('cost_account', id);
|
||||
setFieldValue('preferred_cost_account', id);
|
||||
}}
|
||||
selectedAccountId={value}
|
||||
defaultSelectText={<T id={'select_payment_account'} />}
|
||||
@@ -98,7 +100,7 @@ export default function ItemForm() {
|
||||
</FastField>
|
||||
|
||||
{/* ----------- preferred inventory account ----------- */}
|
||||
<FastField name={'inventory_account'}>
|
||||
<FastField name={'preferred_inventory_account'}>
|
||||
{({
|
||||
form: { values, setFieldValue },
|
||||
field: { value },
|
||||
@@ -123,7 +125,7 @@ export default function ItemForm() {
|
||||
<AccountsSelectList
|
||||
accounts={accounts}
|
||||
onAccountSelected={({ id }) => {
|
||||
setFieldValue('inventory_account', id);
|
||||
setFieldValue('preferred_inventory_account', id);
|
||||
}}
|
||||
selectedAccountId={value}
|
||||
defaultSelectText={<T id={'select_payment_account'} />}
|
||||
@@ -3,10 +3,10 @@ import { Formik } from 'formik';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { AppToaster } from 'components';
|
||||
import intl from 'react-intl-universal';
|
||||
import { ItemPreferencesSchema } from './Item.schema';
|
||||
import ItemForm from './ItemForm';
|
||||
import { ItemPreferencesSchema } from './ItemPreferences.schema';
|
||||
import ItemPreferencesForm from './ItemPreferencesForm';
|
||||
|
||||
import { useItemFormContext } from './ItemFormProvider';
|
||||
import { useItemPreferencesFormContext } from './ItemPreferencesFormProvider';
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withSettings from 'containers/Settings/withSettings';
|
||||
import { compose, optionsMapToArray, transformGeneralSettings } from 'utils';
|
||||
@@ -14,20 +14,20 @@ import { compose, optionsMapToArray, transformGeneralSettings } from 'utils';
|
||||
import 'style/pages/Preferences/Accounting.scss';
|
||||
|
||||
// item form page preferences.
|
||||
function ItemFormPage({
|
||||
function ItemPreferencesFormPage({
|
||||
// #withSettings
|
||||
itemsSettings,
|
||||
|
||||
// #withDashboardActions
|
||||
changePreferencesPageTitle,
|
||||
}) {
|
||||
|
||||
const { saveSettingMutate } = useItemFormContext();
|
||||
const { saveSettingMutate } = useItemPreferencesFormContext();
|
||||
|
||||
// Initial values.
|
||||
const initialValues = {
|
||||
sell_account: '',
|
||||
cost_account: '',
|
||||
inventory_account: '',
|
||||
preferred_sell_account: '',
|
||||
preferred_cost_account: '',
|
||||
preferred_inventory_account: '',
|
||||
...transformGeneralSettings(itemsSettings),
|
||||
};
|
||||
|
||||
@@ -59,7 +59,7 @@ function ItemFormPage({
|
||||
initialValues={initialValues}
|
||||
validationSchema={ItemPreferencesSchema}
|
||||
onSubmit={handleFormSubmit}
|
||||
component={ItemForm}
|
||||
component={ItemPreferencesForm}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -67,4 +67,4 @@ function ItemFormPage({
|
||||
export default compose(
|
||||
withSettings(({ itemsSettings }) => ({ itemsSettings })),
|
||||
withDashboardActions,
|
||||
)(ItemFormPage);
|
||||
)(ItemPreferencesFormPage);
|
||||
@@ -2,7 +2,7 @@ import React, { useContext, createContext } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { CLASSES } from 'common/classes';
|
||||
|
||||
import { useAccounts, useSaveSettings } from 'hooks/query';
|
||||
import { useSettingsItems, useAccounts, useSaveSettings } from 'hooks/query';
|
||||
import PreferencesPageLoader from '../PreferencesPageLoader';
|
||||
|
||||
const ItemFormContext = createContext();
|
||||
@@ -11,10 +11,15 @@ const ItemFormContext = createContext();
|
||||
* Item data provider.
|
||||
*/
|
||||
|
||||
function ItemFormProvider({ ...props }) {
|
||||
function ItemPreferencesFormProvider({ ...props }) {
|
||||
// Fetches the accounts list.
|
||||
const { isLoading: isAccountsLoading, data: accounts } = useAccounts();
|
||||
|
||||
const {
|
||||
isLoading: isItemsSettingsLoading,
|
||||
isFetching: isItemsSettingsFetching,
|
||||
} = useSettingsItems();
|
||||
|
||||
// Save Organization Settings.
|
||||
const { mutateAsync: saveSettingMutate } = useSaveSettings();
|
||||
|
||||
@@ -24,7 +29,7 @@ function ItemFormProvider({ ...props }) {
|
||||
saveSettingMutate,
|
||||
};
|
||||
|
||||
const isLoading = isAccountsLoading;
|
||||
const isLoading = isAccountsLoading || isItemsSettingsLoading;
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -44,6 +49,6 @@ function ItemFormProvider({ ...props }) {
|
||||
);
|
||||
}
|
||||
|
||||
const useItemFormContext = () => useContext(ItemFormContext);
|
||||
const useItemPreferencesFormContext = () => useContext(ItemFormContext);
|
||||
|
||||
export { useItemFormContext, ItemFormProvider };
|
||||
export { useItemPreferencesFormContext, ItemPreferencesFormProvider };
|
||||
14
client/src/containers/Preferences/Item/index.js
Normal file
14
client/src/containers/Preferences/Item/index.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import ItemPreferencesFormPage from './ItemPreferencesFormPage';
|
||||
import { ItemPreferencesFormProvider } from './ItemPreferencesFormProvider';
|
||||
|
||||
/**
|
||||
* items preferences.
|
||||
*/
|
||||
export default function ItemsPreferences() {
|
||||
return (
|
||||
<ItemPreferencesFormProvider>
|
||||
<ItemPreferencesFormPage />
|
||||
</ItemPreferencesFormProvider>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user