mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
Fix : Customers
This commit is contained in:
@@ -2,22 +2,25 @@ import React, { useCallback } from 'react';
|
||||
import { useParams, useHistory } from 'react-router-dom';
|
||||
import { useQuery } from 'react-query';
|
||||
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
import CustomerForm from 'containers/Customers/CustomerForm';
|
||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
import withCustomersActions from './withCustomersActions';
|
||||
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
function Customer({
|
||||
// #withDashboardActions
|
||||
changePageTitle,
|
||||
// // #withDashboardActions
|
||||
// changePageTitle,
|
||||
|
||||
formik,
|
||||
// formik,
|
||||
//#withCustomersActions
|
||||
requestFetchCustomers,
|
||||
requestFetchCustomer,
|
||||
|
||||
// #wihtCurrenciesActions
|
||||
requestFetchCurrencies,
|
||||
}) {
|
||||
const { id } = useParams();
|
||||
const history = useHistory();
|
||||
@@ -32,7 +35,11 @@ function Customer({
|
||||
(key, customerId) => requestFetchCustomer(customerId),
|
||||
{ enabled: id && id },
|
||||
);
|
||||
|
||||
// Handle fetch Currencies data table
|
||||
const fetchCurrencies = useQuery('currencies', () =>
|
||||
requestFetchCurrencies(),
|
||||
);
|
||||
|
||||
const handleFormSubmit = useCallback(
|
||||
(payload) => {
|
||||
payload.redirect && history.push('/customers');
|
||||
@@ -46,7 +53,11 @@ function Customer({
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={fetchCustomer.isFetching || fetchCustomers.isFetching}
|
||||
loading={
|
||||
fetchCustomer.isFetching ||
|
||||
fetchCustomers.isFetching ||
|
||||
fetchCurrencies.isFetching
|
||||
}
|
||||
name={'customer-form'}
|
||||
>
|
||||
<CustomerForm
|
||||
@@ -58,4 +69,4 @@ function Customer({
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDashboardActions, withCustomersActions)(Customer);
|
||||
export default compose(withCustomersActions, withCurrenciesActions)(Customer);
|
||||
|
||||
@@ -18,7 +18,7 @@ const CustomerBillingAddress = ({
|
||||
<h4>
|
||||
<T id={'billing_address'} />
|
||||
</h4>
|
||||
|
||||
{/*------------ Billing Address country -----------*/}
|
||||
<FormGroup
|
||||
className={'form-group--journal-number'}
|
||||
intent={
|
||||
@@ -44,7 +44,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_country')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Billing Address 1 -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'address_line_1'} />}
|
||||
className={'form-group--address_line_1'}
|
||||
@@ -67,7 +67,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_1')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Billing Address 2 -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'address_line_2'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -90,7 +90,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_2')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Billing Address city -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'city_town'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -116,7 +116,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_city')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Billing Address state -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'state'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -142,47 +142,47 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_state')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Billing Address postcode -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'zip_code'} />}
|
||||
intent={
|
||||
errors.billing_address_zipcode &&
|
||||
touched.billing_address_zipcode &&
|
||||
errors.billing_address_postcode &&
|
||||
touched.billing_address_postcode &&
|
||||
Intent.DANGER
|
||||
}
|
||||
inline={true}
|
||||
helperText={
|
||||
<ErrorMessage
|
||||
name="billing_address_zipcode"
|
||||
name="billing_address_postcode"
|
||||
{...{ errors, touched }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.billing_address_zipcode &&
|
||||
touched.billing_address_zipcode &&
|
||||
errors.billing_address_postcode &&
|
||||
touched.billing_address_postcode &&
|
||||
Intent.DANGER
|
||||
}
|
||||
{...getFieldProps('billing_address_zipcode')}
|
||||
{...getFieldProps('billing_address_postcode')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Billing Address phone -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'phone'} />}
|
||||
intent={
|
||||
errors.shipping_phone && touched.shipping_phone && Intent.DANGER
|
||||
errors.billing_address_phone && touched.billing_address_phone && Intent.DANGER
|
||||
}
|
||||
inline={true}
|
||||
helperText={
|
||||
<ErrorMessage name="shipping_phone" {...{ errors, touched }} />
|
||||
<ErrorMessage name="billing_address_phone" {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.shipping_phone && touched.shipping_phone && Intent.DANGER
|
||||
errors.billing_address_phone && touched.billing_address_phone && Intent.DANGER
|
||||
}
|
||||
{...getFieldProps('shipping_phone')}
|
||||
{...getFieldProps('billing_address_phone')}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
@@ -191,7 +191,7 @@ const CustomerBillingAddress = ({
|
||||
<h4>
|
||||
<T id={'shipping_address'} />
|
||||
</h4>
|
||||
|
||||
{/*------------ Shipping Address country -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'country'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -217,7 +217,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('shipping_address_country')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Shipping Address 1 -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'address_line_1'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -240,7 +240,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_1')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Shipping Address 2 -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'address_line_2'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -263,7 +263,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('billing_address_2')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Shipping Address city -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'city_town'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -289,7 +289,7 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('shipping_address_city')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Shipping Address state -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'state'} />}
|
||||
className={'form-group--journal-number'}
|
||||
@@ -315,47 +315,47 @@ const CustomerBillingAddress = ({
|
||||
{...getFieldProps('shipping_address_state')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Shipping Address postcode -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'zip_code'} />}
|
||||
intent={
|
||||
errors.shipping_address_zipcode &&
|
||||
touched.shipping_address_zipcode &&
|
||||
errors.shipping_address_postcode &&
|
||||
touched.shipping_address_postcode &&
|
||||
Intent.DANGER
|
||||
}
|
||||
inline={true}
|
||||
helperText={
|
||||
<ErrorMessage
|
||||
name="shipping_address_zipcode"
|
||||
name="shipping_address_postcode"
|
||||
{...{ errors, touched }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.shipping_address_zipcode &&
|
||||
touched.shipping_address_zipcode &&
|
||||
errors.shipping_address_postcode &&
|
||||
touched.shipping_address_postcode &&
|
||||
Intent.DANGER
|
||||
}
|
||||
{...getFieldProps('shipping_address_zipcode')}
|
||||
{...getFieldProps('shipping_address_postcode')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Shipping Address phone -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'phone'} />}
|
||||
intent={
|
||||
errors.shipping_phone && touched.shipping_phone && Intent.DANGER
|
||||
errors.shipping_address_phone && touched.shipping_address_phone && Intent.DANGER
|
||||
}
|
||||
inline={true}
|
||||
helperText={
|
||||
<ErrorMessage name="shipping_phone" {...{ errors, touched }} />
|
||||
<ErrorMessage name="shipping_address_phone" {...{ errors, touched }} />
|
||||
}
|
||||
>
|
||||
<InputGroup
|
||||
intent={
|
||||
errors.shipping_phone && touched.shipping_phone && Intent.DANGER
|
||||
errors.shipping_address_phone && touched.shipping_address_phone && Intent.DANGER
|
||||
}
|
||||
{...getFieldProps('shipping_phone')}
|
||||
{...getFieldProps('shipping_address_phone')}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import moment from 'moment';
|
||||
import classNames from 'classnames';
|
||||
import { FormGroup, Intent, Position, Classes } from '@blueprintjs/core';
|
||||
@@ -6,52 +6,86 @@ import { DateInput } from '@blueprintjs/datetime';
|
||||
import {
|
||||
ErrorMessage,
|
||||
MoneyInputGroup,
|
||||
CurrenciesSelectList,
|
||||
CurrencySelectList,
|
||||
Row,
|
||||
Col,
|
||||
} from 'components';
|
||||
import { FormattedMessage as T } from 'react-intl';
|
||||
import { momentFormatter, tansformDateValue } from 'utils';
|
||||
|
||||
export default function CustomerFinancialPanel({
|
||||
import withCurrencies from 'containers/Currencies/withCurrencies';
|
||||
|
||||
import { compose, momentFormatter, tansformDateValue } from 'utils';
|
||||
|
||||
function CustomerFinancialPanel({
|
||||
setFieldValue,
|
||||
errors,
|
||||
touched,
|
||||
values,
|
||||
|
||||
// #withCurrencies
|
||||
currenciesList,
|
||||
|
||||
customerId,
|
||||
}) {
|
||||
const [selectedItems, setSelectedItems] = useState();
|
||||
|
||||
const handleDateChange = useCallback(
|
||||
(date) => {
|
||||
const formatted = moment(date).format('YYYY-MM-DD');
|
||||
setFieldValue('payment_date', formatted);
|
||||
setFieldValue('opening_balance_at', formatted);
|
||||
},
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
const handleMoneyInputChange = useCallback(
|
||||
(e, value) => {
|
||||
setFieldValue('opening_balance', value);
|
||||
},
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
const onItemsSelect = useCallback(
|
||||
(filedName) => {
|
||||
return (filed) => {
|
||||
setSelectedItems({
|
||||
...selectedItems,
|
||||
[filedName]: filed,
|
||||
});
|
||||
setFieldValue(filedName, filed.currency_code);
|
||||
};
|
||||
},
|
||||
[setFieldValue, selectedItems],
|
||||
);
|
||||
return (
|
||||
<div className={'tab-panel--financial'}>
|
||||
<Row>
|
||||
<Col xs={6}>
|
||||
{/*------------ Opening balance at -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'opening_balance_at'} />}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
intent={
|
||||
errors.opening_balance_date &&
|
||||
touched.opening_balance_date &&
|
||||
errors.opening_balance_at &&
|
||||
touched.opening_balance_at &&
|
||||
Intent.DANGER
|
||||
}
|
||||
inline={true}
|
||||
helperText={
|
||||
<ErrorMessage name="payment_date" {...{ errors, touched }} />
|
||||
<ErrorMessage
|
||||
name="opening_balance_at"
|
||||
{...{ errors, touched }}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<DateInput
|
||||
{...momentFormatter('YYYY/MM/DD')}
|
||||
value={tansformDateValue(values.payment_date)}
|
||||
value={tansformDateValue(values.opening_balance_at)}
|
||||
onChange={handleDateChange}
|
||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||
disabled={customerId}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Opening balance -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'opening_balance'} />}
|
||||
className={classNames('form-group--opening-balance', Classes.FILL)}
|
||||
@@ -63,12 +97,14 @@ export default function CustomerFinancialPanel({
|
||||
<MoneyInputGroup
|
||||
value={values.opening_balance}
|
||||
prefix={'$'}
|
||||
onChange={handleMoneyInputChange}
|
||||
inputGroupProps={{
|
||||
fill: true,
|
||||
}}
|
||||
disabled={customerId}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Currency -----------*/}
|
||||
<FormGroup
|
||||
label={<T id={'currency'} />}
|
||||
className={classNames(
|
||||
@@ -78,10 +114,20 @@ export default function CustomerFinancialPanel({
|
||||
)}
|
||||
inline={true}
|
||||
>
|
||||
<CurrenciesSelectList />
|
||||
{/* <CurrenciesSelectList /> */}
|
||||
<CurrencySelectList
|
||||
currenciesList={currenciesList}
|
||||
selectedCurrencyCode={values.currency_code}
|
||||
onCurrencySelected={onItemsSelect('currency_code')}
|
||||
disabled={customerId}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(
|
||||
withCurrencies(({ currenciesList }) => ({ currenciesList })),
|
||||
)(CustomerFinancialPanel);
|
||||
|
||||
@@ -15,8 +15,8 @@ export default function CustomerFloatingActions({
|
||||
return (
|
||||
<div className={classNames(CLASSES.PAGE_FORM_FLOATING_ACTIONS)}>
|
||||
<Button
|
||||
intent={Intent.PRIMARY}
|
||||
disabled={isSubmitting}
|
||||
intent={Intent.PRIMARY}
|
||||
type="submit"
|
||||
onClick={() => {
|
||||
onSubmitClick({ publish: true, redirect: true });
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useMemo, useCallback, useEffect } from 'react';
|
||||
import * as Yup from 'yup';
|
||||
import { useFormik } from 'formik';
|
||||
import moment from 'moment';
|
||||
import { Intent } from '@blueprintjs/core';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
@@ -24,6 +25,9 @@ import useMedia from 'hooks/useMedia';
|
||||
|
||||
import { compose } from 'utils';
|
||||
|
||||
/**
|
||||
* Customer form.
|
||||
*/
|
||||
function CustomerForm({
|
||||
// #withDashboardActions
|
||||
changePageTitle,
|
||||
@@ -36,7 +40,6 @@ function CustomerForm({
|
||||
|
||||
// #withCustomersActions
|
||||
requestSubmitCustomer,
|
||||
requestFetchCustomers,
|
||||
requestEditCustomer,
|
||||
|
||||
// #withMediaActions
|
||||
@@ -67,6 +70,7 @@ function CustomerForm({
|
||||
.required()
|
||||
.trim()
|
||||
.label(formatMessage({ id: 'customer_type_' })),
|
||||
salutation: Yup.string().trim(),
|
||||
first_name: Yup.string().trim(),
|
||||
last_name: Yup.string().trim(),
|
||||
company_name: Yup.string().trim(),
|
||||
@@ -74,48 +78,71 @@ function CustomerForm({
|
||||
.trim()
|
||||
.required()
|
||||
.label(formatMessage({ id: 'display_name_' })),
|
||||
|
||||
email: Yup.string().email(),
|
||||
|
||||
work_phone: Yup.number(),
|
||||
personal_phone: Yup.number(),
|
||||
website: Yup.string().url(),
|
||||
|
||||
active: Yup.boolean(),
|
||||
note: Yup.string().trim(),
|
||||
|
||||
billing_address_city: Yup.string().trim(),
|
||||
billing_address_country: Yup.string().trim(),
|
||||
billing_address_email: Yup.string().email(),
|
||||
billing_address_zipcode: Yup.number().nullable(),
|
||||
billing_address_phone: Yup.number(),
|
||||
billing_address_1: Yup.string().trim(),
|
||||
billing_address_2: Yup.string().trim(),
|
||||
billing_address_city: Yup.string().trim(),
|
||||
billing_address_state: Yup.string().trim(),
|
||||
billing_address_postcode: Yup.number().nullable(),
|
||||
billing_address_phone: Yup.number(),
|
||||
|
||||
shipping_address_city: Yup.string().trim(),
|
||||
shipping_address_country: Yup.string().trim(),
|
||||
shipping_address_email: Yup.string().email(),
|
||||
shipping_address_zipcode: Yup.number().nullable(),
|
||||
shipping_address_phone: Yup.number(),
|
||||
shipping_address_1: Yup.string().trim(),
|
||||
shipping_address_2: Yup.string().trim(),
|
||||
shipping_address_city: Yup.string().trim(),
|
||||
shipping_address_state: Yup.string().trim(),
|
||||
shipping_address_postcode: Yup.number().nullable(),
|
||||
shipping_address_phone: Yup.number(),
|
||||
|
||||
opening_balance: Yup.number(),
|
||||
currency_code: Yup.string(),
|
||||
opening_balance_at: Yup.date(),
|
||||
});
|
||||
|
||||
const defaultInitialValues = useMemo(
|
||||
() => ({
|
||||
customer_type: 'business',
|
||||
salutation: '',
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
company_name: '',
|
||||
display_name: '',
|
||||
|
||||
email: '',
|
||||
work_phone: '',
|
||||
personal_phone: '',
|
||||
website: '',
|
||||
note: '',
|
||||
active: true,
|
||||
|
||||
billing_address_city: '',
|
||||
billing_address_country: '',
|
||||
billing_address_zipcode: null,
|
||||
billing_address_phone: '',
|
||||
billing_address_1: '',
|
||||
billing_address_2: '',
|
||||
billing_address_city: '',
|
||||
billing_address_state: '',
|
||||
billing_address_postcode: null,
|
||||
billing_address_phone: '',
|
||||
|
||||
shipping_address_city: '',
|
||||
shipping_address_country: '',
|
||||
shipping_address_zipcode: null,
|
||||
shipping_address_phone: '',
|
||||
shipping_address_1: '',
|
||||
shipping_address_2: '',
|
||||
shipping_address_city: '',
|
||||
shipping_address_state: '',
|
||||
shipping_address_postcode: null,
|
||||
shipping_address_phone: '',
|
||||
|
||||
opening_balance: '',
|
||||
currency_code: '',
|
||||
opening_balance_at: moment(new Date()).format('YYYY-MM-DD'),
|
||||
}),
|
||||
[],
|
||||
);
|
||||
@@ -147,7 +174,10 @@ function CustomerForm({
|
||||
: changePageTitle(formatMessage({ id: 'new_customer' }));
|
||||
}, [changePageTitle, customer, formatMessage]);
|
||||
|
||||
const handleFormSubmit = (values, { setSubmitting, resetForm, setErrors }) => {
|
||||
const handleFormSubmit = (
|
||||
values,
|
||||
{ setSubmitting, resetForm, setErrors },
|
||||
) => {
|
||||
const formValues = { ...values, status: payload.publish };
|
||||
if (customer && customer.id) {
|
||||
requestEditCustomer(customer.id, formValues)
|
||||
@@ -189,7 +219,8 @@ function CustomerForm({
|
||||
errors,
|
||||
values,
|
||||
touched,
|
||||
handleSubmit
|
||||
isSubmitting,
|
||||
handleSubmit,
|
||||
} = useFormik({
|
||||
enableReinitialize: true,
|
||||
validationSchema: validationSchema,
|
||||
@@ -199,7 +230,6 @@ function CustomerForm({
|
||||
onSubmit: handleFormSubmit,
|
||||
});
|
||||
|
||||
|
||||
const initialAttachmentFiles = useMemo(() => {
|
||||
return customer && customer.media
|
||||
? customer.media.map((attach) => ({
|
||||
@@ -209,6 +239,7 @@ function CustomerForm({
|
||||
}))
|
||||
: [];
|
||||
}, []);
|
||||
|
||||
const handleDropFiles = useCallback((_files) => {
|
||||
setFiles(_files.filter((file) => file.uploaded === false));
|
||||
}, []);
|
||||
@@ -269,16 +300,19 @@ function CustomerForm({
|
||||
getFieldProps={getFieldProps}
|
||||
errors={errors}
|
||||
values={values}
|
||||
touched={touched} />
|
||||
touched={touched}
|
||||
customerId={customer}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<CustomerFloatingActions
|
||||
onSubmitClick={handleSubmitClick}
|
||||
customer={customer}
|
||||
onCancelClick={handleCancelClick}
|
||||
customerId={null}
|
||||
/>
|
||||
</form>
|
||||
|
||||
<CustomerFloatingActions
|
||||
isSubmitting={isSubmitting}
|
||||
onSubmitClick={handleSubmitClick}
|
||||
// customer={customer}
|
||||
onCancelClick={handleCancelClick}
|
||||
customerId={customer}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -31,12 +31,8 @@ export default function CustomerFormAfterPrimarySection({
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
{/*------------ Customer email -----------*/}
|
||||
{/*------------ Phone number -----------*/}
|
||||
<FormGroup
|
||||
intent={errors.work_phone && touched.work_phone && Intent.DANGER}
|
||||
helperText={
|
||||
<ErrorMessage name={'work_phone'} {...{ errors, touched }} />
|
||||
}
|
||||
className={'form-group--phone-number'}
|
||||
label={<T id={'phone_number'} />}
|
||||
inline={true}
|
||||
@@ -49,8 +45,8 @@ export default function CustomerFormAfterPrimarySection({
|
||||
/>
|
||||
|
||||
<InputGroup
|
||||
intent={errors.work_phone && touched.work_phone && Intent.DANGER}
|
||||
{...getFieldProps('work_phone')}
|
||||
intent={errors.personal_phone && touched.personal_phone && Intent.DANGER}
|
||||
{...getFieldProps('personal_phone')}
|
||||
placeholder={'Mobile'}
|
||||
/>
|
||||
</ControlGroup>
|
||||
|
||||
@@ -32,15 +32,20 @@ export default function CustomerFormPrimarySection({
|
||||
);
|
||||
|
||||
// Handle salutation field select.
|
||||
const handleSalutationSelect = useCallback((salutation) => {
|
||||
setFieldValue('salutation', salutation.label);
|
||||
}, [setFieldValue]);
|
||||
const handleSalutationSelect = useCallback(
|
||||
(salutation) => {
|
||||
setFieldValue('salutation', salutation.label);
|
||||
},
|
||||
[setFieldValue],
|
||||
);
|
||||
|
||||
// Handle display name field select.
|
||||
const handleDisplayNameSelect = useCallback((displayName) => {
|
||||
setFieldValue('display_name', displayName.label);
|
||||
}, [setFieldValue]);
|
||||
|
||||
const handleDisplayNameSelect = useCallback(
|
||||
(displayName) => {
|
||||
setFieldValue('display_name', displayName.label);
|
||||
},
|
||||
[setFieldValue],
|
||||
);
|
||||
return (
|
||||
<div className={'customer-form__primary-section-content'}>
|
||||
{/**-----------Customer type. -----------*/}
|
||||
@@ -58,6 +63,7 @@ export default function CustomerFormPrimarySection({
|
||||
<ControlGroup>
|
||||
<SalutationList
|
||||
onItemSelect={handleSalutationSelect}
|
||||
selectedItem={values.salutation}
|
||||
popoverProps={{ minimal: true }}
|
||||
className={classNames(
|
||||
CLASSES.FORM_GROUP_LIST_SELECT,
|
||||
@@ -119,6 +125,7 @@ export default function CustomerFormPrimarySection({
|
||||
company={values.company_name}
|
||||
salutation={values.salutation}
|
||||
onItemSelect={handleDisplayNameSelect}
|
||||
// selectedItem={values.display_name}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -10,14 +10,12 @@ import {
|
||||
} from '@blueprintjs/core';
|
||||
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import DataTable from 'components/DataTable';
|
||||
import Icon from 'components/Icon';
|
||||
import { Money } from 'components';
|
||||
import { useUpdateEffect } from 'hooks';
|
||||
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
import withCustomers from './withCustomers';
|
||||
import { DataTable, Icon, Money } from 'components';
|
||||
|
||||
import withCustomers from './withCustomers';
|
||||
import { compose, firstLettersArgs, saveInvoke } from 'utils';
|
||||
|
||||
const AvatarCell = (row) => {
|
||||
@@ -25,13 +23,13 @@ const AvatarCell = (row) => {
|
||||
};
|
||||
|
||||
const CustomerTable = ({
|
||||
loading,
|
||||
|
||||
//#withCustomers
|
||||
customers,
|
||||
customersLoading,
|
||||
customerPagination,
|
||||
|
||||
//#props
|
||||
//#OwnProps
|
||||
loading,
|
||||
onEditCustomer,
|
||||
onDeleteCustomer,
|
||||
onFetchData,
|
||||
@@ -80,18 +78,21 @@ const CustomerTable = ({
|
||||
);
|
||||
|
||||
// Renders actions table cell.
|
||||
const renderActionsCell = useMemo(() => ({ cell }) => (
|
||||
<Popover
|
||||
content={renderContextMenu({
|
||||
customer: cell.row.original,
|
||||
onEditCustomer,
|
||||
onDeleteCustomer,
|
||||
})}
|
||||
position={Position.RIGHT_BOTTOM}
|
||||
>
|
||||
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
|
||||
</Popover>
|
||||
), [onDeleteCustomer, onEditCustomer, renderContextMenu]);
|
||||
const renderActionsCell = useMemo(
|
||||
() => ({ cell }) => (
|
||||
<Popover
|
||||
content={renderContextMenu({
|
||||
customer: cell.row.original,
|
||||
onEditCustomer,
|
||||
onDeleteCustomer,
|
||||
})}
|
||||
position={Position.RIGHT_BOTTOM}
|
||||
>
|
||||
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
|
||||
</Popover>
|
||||
),
|
||||
[onDeleteCustomer, onEditCustomer, renderContextMenu],
|
||||
);
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
@@ -186,14 +187,19 @@ const CustomerTable = ({
|
||||
loading={customersLoading && !initialMount}
|
||||
spinnerProps={{ size: 30 }}
|
||||
rowContextMenu={rowContextMenu}
|
||||
pagination={true}
|
||||
pagesCount={customerPagination.pagesCount}
|
||||
initialPageSize={customerPagination.pageSize}
|
||||
initialPageIndex={customerPagination.page - 1}
|
||||
/>
|
||||
</LoadingIndicator>
|
||||
);
|
||||
};
|
||||
|
||||
export default compose(
|
||||
withCustomers(({ customers, customersLoading }) => ({
|
||||
withCustomers(({ customers, customersLoading, customerPagination }) => ({
|
||||
customers,
|
||||
customersLoading,
|
||||
customerPagination,
|
||||
})),
|
||||
)(CustomerTable);
|
||||
|
||||
@@ -16,8 +16,10 @@ import CustomersTable from 'containers/Customers/CustomerTable';
|
||||
import CustomerActionsBar from 'containers/Customers/CustomerActionsBar';
|
||||
import CustomersViewsTabs from 'containers/Customers/CustomersViewsTabs';
|
||||
|
||||
import withCustomers from 'containers/Customers/withCustomers';
|
||||
import withCustomersActions from 'containers/Customers/withCustomersActions';
|
||||
import withResourceActions from 'containers/Resources/withResourcesActions';
|
||||
import withViewsActions from 'containers/Views/withViewsActions';
|
||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||
|
||||
import { compose } from 'utils';
|
||||
@@ -30,7 +32,10 @@ function CustomersList({
|
||||
requestFetchResourceViews,
|
||||
requestFetchResourceFields,
|
||||
|
||||
//#withCustomersActions
|
||||
// #withCustomers
|
||||
customersTableQuery,
|
||||
|
||||
// #withCustomersActions
|
||||
requestFetchCustomers,
|
||||
requestDeleteCustomer,
|
||||
requestDeleteBulkCustomers,
|
||||
@@ -57,9 +62,10 @@ function CustomersList({
|
||||
// ]);
|
||||
// });
|
||||
|
||||
const fetchCustomers = useQuery('customers-table', () => {
|
||||
requestFetchCustomers({});
|
||||
});
|
||||
const fetchCustomers = useQuery(
|
||||
['customers-table', customersTableQuery],
|
||||
() => requestFetchCustomers(),
|
||||
);
|
||||
|
||||
const handleEditCustomer = useCallback(
|
||||
(cusomter) => {
|
||||
@@ -67,6 +73,7 @@ function CustomersList({
|
||||
},
|
||||
[history],
|
||||
);
|
||||
|
||||
// Handle click delete customer.
|
||||
const handleDeleteCustomer = useCallback(
|
||||
(customer) => {
|
||||
@@ -169,26 +176,29 @@ function CustomersList({
|
||||
}, [requestDeleteBulkCustomers, bulkDelete, formatMessage]);
|
||||
|
||||
return (
|
||||
<DashboardInsider
|
||||
loading={fetchCustomers.isFetching}
|
||||
name={'customers-list'}
|
||||
>
|
||||
<DashboardInsider name={'customers-list'}>
|
||||
<CustomerActionsBar
|
||||
selectedRows={selectedRows}
|
||||
onFilterChanged={handleFilterChanged}
|
||||
onBulkDelete={handleBulkDelete}
|
||||
/>
|
||||
|
||||
<CustomersViewsTabs />
|
||||
|
||||
<DashboardPageContent>
|
||||
<CustomersTable
|
||||
loading={tableLoading}
|
||||
onDeleteCustomer={handleDeleteCustomer}
|
||||
onEditCustomer={handleEditCustomer}
|
||||
onfetchData={handleFetchData}
|
||||
onSelectedRowsChange={handleSelectedRowsChange}
|
||||
/>
|
||||
<Switch>
|
||||
<Route
|
||||
exact={true}
|
||||
path={['/customers/:custom_view_id/custom_view', '/customers']}
|
||||
>
|
||||
<CustomersViewsTabs />
|
||||
<CustomersTable
|
||||
loading={fetchCustomers.isFetching}
|
||||
onDeleteCustomer={handleDeleteCustomer}
|
||||
onEditCustomer={handleEditCustomer}
|
||||
onfetchData={handleFetchData}
|
||||
onSelectedRowsChange={handleSelectedRowsChange}
|
||||
/>
|
||||
</Route>
|
||||
</Switch>
|
||||
|
||||
<Alert
|
||||
cancelButtonText={<T id={'cancel'} />}
|
||||
@@ -230,6 +240,7 @@ function CustomersList({
|
||||
|
||||
export default compose(
|
||||
withResourceActions,
|
||||
withDashboardActions,
|
||||
withCustomersActions,
|
||||
withDashboardActions,
|
||||
withCustomers(({ customersTableQuery }) => ({ customersTableQuery })),
|
||||
)(CustomersList);
|
||||
|
||||
@@ -12,9 +12,11 @@ export default function CustomersTabs({
|
||||
errors,
|
||||
values,
|
||||
touched,
|
||||
customerId,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const [customer] = useState(customerId);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tabs
|
||||
@@ -32,6 +34,7 @@ export default function CustomersTabs({
|
||||
errors={errors}
|
||||
setFieldValue={setFieldValue}
|
||||
touched={touched}
|
||||
customerId={customer}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { getCustomersItems, getCustomersListFactory } from 'store/customers/customers.selectors';
|
||||
import { getResourceViews } from 'store/customViews/customViews.selectors';
|
||||
import {
|
||||
getCustomerCurrentPageFactory,
|
||||
getCustomerPaginationMetaFactory,
|
||||
getCustomerTableQueryFactory,
|
||||
} from 'store/customers/customers.selectors';
|
||||
|
||||
export default (mapState) => {
|
||||
const getCustomersList = getCustomersListFactory();
|
||||
const getCustomersList = getCustomerCurrentPageFactory();
|
||||
const getCustomerPaginationMeta = getCustomerPaginationMetaFactory();
|
||||
const getCustomerTableQuery = getCustomerTableQueryFactory();
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const query = getCustomerTableQuery(state, props);
|
||||
|
||||
const mapped = {
|
||||
customers: getCustomersList(state, props, query),
|
||||
customersViews: getResourceViews(state, props, 'customers'),
|
||||
customersItems: getCustomersList(state, props),
|
||||
customers: getCustomersItems(state, state.customers.currentViewId),
|
||||
customersTableQuery: query,
|
||||
customerPagination: getCustomerPaginationMeta(state, props, query),
|
||||
customersLoading: state.customers.loading,
|
||||
customerErrors: state.customers.errors,
|
||||
customersItems: state.customers.items,
|
||||
// customerErrors: state.customers.errors,
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user