mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -282,7 +282,7 @@ function AccountFormDialogContent({
|
||||
selectedTypeId={values.account_type_id}
|
||||
defaultSelectText={<T id={'select_account_type'} />}
|
||||
onTypeSelected={onChangeAccountType}
|
||||
buttonProps={{ disabled: action === 'edit' }}
|
||||
disabled={action === 'edit'}
|
||||
popoverProps={{ minimal: true }}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { compose } from 'utils';
|
||||
// import { connect } from 'react-redux';
|
||||
// import { compose } from 'utils';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import withExchangeRateDetail from 'containers/ExchangeRates/withExchangeRateDetail';
|
||||
import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions';
|
||||
import withExchangeRates from 'containers/ExchangeRates/withExchangeRates';
|
||||
import withCurrencies from 'containers/Currencies/withCurrencies';
|
||||
// import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
// import withDialogRedux from 'components/DialogReduxConnect';
|
||||
// import withExchangeRateDetail from 'containers/ExchangeRates/withExchangeRateDetail';
|
||||
// import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions';
|
||||
// import withExchangeRates from 'containers/ExchangeRates/withExchangeRates';
|
||||
// import withCurrencies from 'containers/Currencies/withCurrencies';
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
dialogName: 'exchangeRate-form',
|
||||
exchangeRateId:
|
||||
props.payload.action === 'edit' && props.payload.id
|
||||
? props.payload.id
|
||||
: null,
|
||||
});
|
||||
// const mapStateToProps = (state, props) => ({
|
||||
// dialogName: 'exchangeRate-form',
|
||||
// exchangeRateId:
|
||||
// props.payload.action === 'edit' && props.payload.id
|
||||
// ? props.payload.id
|
||||
// : null,
|
||||
// });
|
||||
|
||||
const withExchangeRateDialog = connect(mapStateToProps);
|
||||
// const withExchangeRateDialog = connect(mapStateToProps);
|
||||
|
||||
export default compose(
|
||||
withDialogRedux(null, 'exchangeRate-form'),
|
||||
withExchangeRateDialog,
|
||||
withCurrencies(({ currenciesList }) => ({
|
||||
currenciesList,
|
||||
})),
|
||||
withExchangeRatesActions,
|
||||
withExchangeRateDetail,
|
||||
withExchangeRates(({ exchangeRatesList }) => ({
|
||||
exchangeRatesList,
|
||||
})),
|
||||
withDialogActions,
|
||||
);
|
||||
// export default compose(
|
||||
// withDialogRedux(null, 'exchangeRate-form'),
|
||||
// withExchangeRateDialog,
|
||||
// withCurrencies(({ currenciesList }) => ({
|
||||
// currenciesList,
|
||||
// })),
|
||||
// withExchangeRatesActions,
|
||||
// withExchangeRateDetail,
|
||||
// withExchangeRates(({ exchangeRatesList }) => ({
|
||||
// exchangeRatesList,
|
||||
// })),
|
||||
// withDialogActions,
|
||||
// );
|
||||
|
||||
48
client/src/containers/Dialogs/ExchangeRateFormDialog.js
Normal file
48
client/src/containers/Dialogs/ExchangeRateFormDialog.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import React, { lazy } from 'react';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import {
|
||||
Dialog,
|
||||
DialogSuspense,
|
||||
} from 'components';
|
||||
import withDialogRedux from 'components/DialogReduxConnect';
|
||||
import { compose } from 'utils';
|
||||
|
||||
const ExchangeRateFormDialogContent = lazy(() =>
|
||||
import('./ExchangeRateFormDialogContent'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Exchange rate form dialog.
|
||||
*/
|
||||
function ExchangeRateFormDialog({
|
||||
dialogName,
|
||||
payload = { action: '', id: null },
|
||||
isOpen,
|
||||
}) {
|
||||
return (
|
||||
<Dialog
|
||||
name={dialogName}
|
||||
title={
|
||||
payload.action === 'edit' ? (
|
||||
<T id={'edit_exchange_rate'} />
|
||||
) : (
|
||||
<T id={'new_exchange_rate'} />
|
||||
)
|
||||
}
|
||||
className={'dialog--exchangeRate-form'}
|
||||
isOpen={isOpen}
|
||||
autoFocus={true}
|
||||
canEscapeKeyClose={true}
|
||||
>
|
||||
<DialogSuspense>
|
||||
<ExchangeRateFormDialogContent
|
||||
dialogName={dialogName}
|
||||
action={payload.action}
|
||||
exchangeRateId={payload.id}
|
||||
/>
|
||||
</DialogSuspense>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
export default compose(withDialogRedux())(ExchangeRateFormDialog);
|
||||
@@ -10,25 +10,32 @@ import {
|
||||
} from '@blueprintjs/core';
|
||||
import { pick } from 'lodash';
|
||||
import * as Yup from 'yup';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { useFormik } from 'formik';
|
||||
import { useQuery, queryCache } from 'react-query';
|
||||
import moment from 'moment';
|
||||
import { DateInput } from '@blueprintjs/datetime';
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import { momentFormatter, tansformDateValue } from 'utils';
|
||||
import { AppToaster, Dialog, ErrorMessage, ListSelect } from 'components';
|
||||
import {
|
||||
AppToaster,
|
||||
Dialog,
|
||||
ErrorMessage,
|
||||
ListSelect,
|
||||
DialogContent,
|
||||
FieldRequiredHint,
|
||||
} from 'components';
|
||||
import classNames from 'classnames';
|
||||
import withExchangeRatesDialog from './ExchangeRateDialog.container';
|
||||
import withExchangeRateDetail from 'containers/ExchangeRates/withExchangeRateDetail';
|
||||
import withExchangeRatesActions from 'containers/ExchangeRates/withExchangeRatesActions';
|
||||
|
||||
/**
|
||||
* Exchange rate dialog.
|
||||
*/
|
||||
function ExchangeRateDialog({
|
||||
dialogName,
|
||||
payload = {},
|
||||
isOpen,
|
||||
import withCurrencies from 'containers/Currencies/withCurrencies';
|
||||
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
|
||||
// #withDialog
|
||||
import { compose } from 'utils';
|
||||
|
||||
function ExchangeRateFormDialogContent({
|
||||
// #withDialogActions
|
||||
closeDialog,
|
||||
|
||||
// #withCurrencies
|
||||
@@ -39,12 +46,25 @@ function ExchangeRateDialog({
|
||||
|
||||
// #withExchangeRatesActions
|
||||
requestSubmitExchangeRate,
|
||||
requestFetchExchangeRates,
|
||||
requestEditExchangeRate,
|
||||
|
||||
// #wihtCurrenciesActions
|
||||
requestFetchCurrencies,
|
||||
|
||||
// #ownProp
|
||||
action,
|
||||
exchangeRateId,
|
||||
dialogName,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
const [selectedItems, setSelectedItems] = useState({});
|
||||
|
||||
const fetchCurrencies = useQuery(
|
||||
'currencies',
|
||||
() => requestFetchCurrencies(),
|
||||
{ enabled: true },
|
||||
);
|
||||
|
||||
const validationSchema = Yup.object().shape({
|
||||
exchange_rate: Yup.number()
|
||||
.required()
|
||||
@@ -66,12 +86,6 @@ function ExchangeRateDialog({
|
||||
[],
|
||||
);
|
||||
|
||||
const fetchExchangeRatesDialog = useQuery(
|
||||
'exchange-rates-dialog',
|
||||
() => requestFetchExchangeRates(),
|
||||
{ manual: true },
|
||||
);
|
||||
|
||||
const {
|
||||
values,
|
||||
touched,
|
||||
@@ -85,12 +99,12 @@ function ExchangeRateDialog({
|
||||
enableReinitialize: true,
|
||||
validationSchema,
|
||||
initialValues: {
|
||||
...(payload.action === 'edit' &&
|
||||
pick(exchangeRate, Object.keys(initialValues))),
|
||||
...initialValues,
|
||||
...(action === 'edit' && pick(exchangeRate, Object.keys(initialValues))),
|
||||
},
|
||||
onSubmit: (values, { setSubmitting, setErrors }) => {
|
||||
if (payload.action === 'edit') {
|
||||
requestEditExchangeRate(payload.id, values)
|
||||
if (action === 'edit') {
|
||||
requestEditExchangeRate(exchangeRateId, values)
|
||||
.then((response) => {
|
||||
closeDialog(dialogName);
|
||||
AppToaster.show({
|
||||
@@ -100,7 +114,7 @@ function ExchangeRateDialog({
|
||||
intent: Intent.SUCCESS,
|
||||
});
|
||||
setSubmitting(false);
|
||||
queryCache.invalidateQueries('exchange-rates-dialog');
|
||||
queryCache.invalidateQueries('exchange-rates-table');
|
||||
})
|
||||
.catch((error) => {
|
||||
setSubmitting(false);
|
||||
@@ -134,20 +148,10 @@ function ExchangeRateDialog({
|
||||
},
|
||||
});
|
||||
|
||||
const requiredSpan = useMemo(() => <span class="required">*</span>, []);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
closeDialog(dialogName);
|
||||
}, [dialogName, closeDialog]);
|
||||
|
||||
const onDialogClosed = useCallback(() => {
|
||||
resetForm();
|
||||
closeDialog(dialogName);
|
||||
}, [closeDialog, dialogName, resetForm]);
|
||||
|
||||
const onDialogOpening = useCallback(() => {
|
||||
fetchExchangeRatesDialog.refetch();
|
||||
}, [fetchExchangeRatesDialog]);
|
||||
}, [dialogName, closeDialog]);
|
||||
|
||||
const handleDateChange = useCallback(
|
||||
(date_filed) => (date) => {
|
||||
@@ -197,31 +201,13 @@ function ExchangeRateDialog({
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
name={dialogName}
|
||||
title={
|
||||
payload.action === 'edit' ? (
|
||||
<T id={'edit_exchange_rate'} />
|
||||
) : (
|
||||
<T id={'new_exchange_rate'} />
|
||||
)
|
||||
}
|
||||
className={classNames(
|
||||
{ 'dialog--loading': fetchExchangeRatesDialog.isFetching },
|
||||
'dialog--exchangeRate-form',
|
||||
)}
|
||||
isOpen={isOpen}
|
||||
onClosed={onDialogClosed}
|
||||
onOpening={onDialogOpening}
|
||||
isLoading={fetchExchangeRatesDialog.isFetching}
|
||||
onClose={handleClose}
|
||||
>
|
||||
<DialogContent isLoading={fetchCurrencies.isFetching}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<FormGroup
|
||||
label={<T id={'date'} />}
|
||||
inline={true}
|
||||
labelInfo={requiredSpan}
|
||||
labelInfo={FieldRequiredHint}
|
||||
intent={errors.date && touched.date && Intent.DANGER}
|
||||
helperText={<ErrorMessage name="date" {...{ errors, touched }} />}
|
||||
>
|
||||
@@ -231,33 +217,12 @@ function ExchangeRateDialog({
|
||||
value={tansformDateValue(values.date)}
|
||||
onChange={handleDateChange('date')}
|
||||
popoverProps={{ position: Position.BOTTOM, minimal: true }}
|
||||
disabled={payload.action === 'edit'}
|
||||
disabled={action === 'edit'}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={<T id={'exchange_rate'} />}
|
||||
labelInfo={requiredSpan}
|
||||
intent={
|
||||
errors.exchange_rate && touched.exchange_rate && Intent.DANGER
|
||||
}
|
||||
helperText={
|
||||
<ErrorMessage name="exchange_rate" {...{ errors, touched }} />
|
||||
}
|
||||
inline={true}
|
||||
>
|
||||
<InputGroup
|
||||
medium={true}
|
||||
intent={
|
||||
errors.exchange_rate && touched.exchange_rate && Intent.DANGER
|
||||
}
|
||||
{...getFieldProps('exchange_rate')}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup
|
||||
label={<T id={'currency_code'} />}
|
||||
labelInfo={requiredSpan}
|
||||
labelInfo={FieldRequiredHint}
|
||||
className={classNames('form-group--select-list', Classes.FILL)}
|
||||
inline={true}
|
||||
intent={
|
||||
@@ -278,6 +243,26 @@ function ExchangeRateDialog({
|
||||
selectedItemProp={'currency_code'}
|
||||
defaultText={<T id={'select_currency_code'} />}
|
||||
labelProp={'currency_code'}
|
||||
disabled={action === 'edit'}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup
|
||||
label={<T id={'exchange_rate'} />}
|
||||
labelInfo={FieldRequiredHint}
|
||||
intent={
|
||||
errors.exchange_rate && touched.exchange_rate && Intent.DANGER
|
||||
}
|
||||
helperText={
|
||||
<ErrorMessage name="exchange_rate" {...{ errors, touched }} />
|
||||
}
|
||||
inline={true}
|
||||
>
|
||||
<InputGroup
|
||||
medium={true}
|
||||
intent={
|
||||
errors.exchange_rate && touched.exchange_rate && Intent.DANGER
|
||||
}
|
||||
{...getFieldProps('exchange_rate')}
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
@@ -291,17 +276,19 @@ function ExchangeRateDialog({
|
||||
type="submit"
|
||||
disabled={isSubmitting}
|
||||
>
|
||||
{payload.action === 'edit' ? (
|
||||
<T id={'edit'} />
|
||||
) : (
|
||||
<T id={'submit'} />
|
||||
)}
|
||||
{action === 'edit' ? <T id={'edit'} /> : <T id={'submit'} />}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</Dialog>
|
||||
</DialogContent>
|
||||
);
|
||||
}
|
||||
|
||||
export default withExchangeRatesDialog(ExchangeRateDialog);
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withExchangeRatesActions,
|
||||
withExchangeRateDetail,
|
||||
withCurrenciesActions,
|
||||
withCurrencies(({ currenciesList }) => ({ currenciesList })),
|
||||
)(ExchangeRateFormDialogContent);
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useCallback, useMemo, useState, useEffect } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Popover,
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||
import moment from 'moment';
|
||||
|
||||
import { DataTable, Money, Icon } from 'components';
|
||||
import { DataTable, Icon, MoneyExchangeRate } from 'components';
|
||||
import LoadingIndicator from 'components/LoadingIndicator';
|
||||
|
||||
import withDialogActions from 'containers/Dialog/withDialogActions';
|
||||
@@ -23,7 +23,7 @@ function ExchangeRateTable({
|
||||
// #withExchangeRates
|
||||
exchangeRatesList,
|
||||
exchangeRatesLoading,
|
||||
|
||||
exchangeRatesPageination,
|
||||
// #withDialogActions.
|
||||
openDialog,
|
||||
|
||||
@@ -31,7 +31,6 @@ function ExchangeRateTable({
|
||||
loading,
|
||||
onFetchData,
|
||||
onDeleteExchangeRate,
|
||||
onEditExchangeRate,
|
||||
onSelectedRowsChange,
|
||||
}) {
|
||||
const [initialMount, setInitialMount] = useState(false);
|
||||
@@ -52,20 +51,25 @@ function ExchangeRateTable({
|
||||
(ExchangeRate) => (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={<T id={'edit_exchange_rate'} />}
|
||||
icon={<Icon icon="pen-18" />}
|
||||
text={formatMessage({ id: 'edit_exchange_rate' })}
|
||||
onClick={handelEditExchangeRate(ExchangeRate)}
|
||||
/>
|
||||
<MenuItem
|
||||
text={<T id={'delete_exchange_rate'} />}
|
||||
text={formatMessage({ id: 'delete_exchange_rate' })}
|
||||
intent={Intent.DANGER}
|
||||
onClick={handleDeleteExchangeRate(ExchangeRate)}
|
||||
icon={<Icon icon="trash-16" iconSize={16} />}
|
||||
/>
|
||||
</Menu>
|
||||
),
|
||||
[handelEditExchangeRate, handleDeleteExchangeRate],
|
||||
[handelEditExchangeRate, handleDeleteExchangeRate, formatMessage],
|
||||
);
|
||||
|
||||
const rowContextMenu = (cell) => {
|
||||
return actionMenuList(cell.row.original);
|
||||
};
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -84,7 +88,12 @@ function ExchangeRateTable({
|
||||
{
|
||||
id: 'exchange_rate',
|
||||
Header: formatMessage({ id: 'exchange_rate' }),
|
||||
accessor: (r) => <Money amount={r.exchange_rate} currency={'USD'} />,
|
||||
accessor: (r) => (
|
||||
<MoneyExchangeRate
|
||||
amount={r.exchange_rate}
|
||||
currency={r.currency_code}
|
||||
/>
|
||||
),
|
||||
className: 'exchange_rate',
|
||||
width: 150,
|
||||
},
|
||||
@@ -94,14 +103,13 @@ function ExchangeRateTable({
|
||||
Cell: ({ cell }) => (
|
||||
<Popover
|
||||
content={actionMenuList(cell.row.original)}
|
||||
position={Position.RIGHT_BOTTOM}
|
||||
position={Position.RIGHT_TOP}
|
||||
>
|
||||
<Button icon={<Icon icon="more-h-16" iconSize={16} />} />
|
||||
</Popover>
|
||||
),
|
||||
className: 'actions',
|
||||
width: 50,
|
||||
disableResizing: false,
|
||||
},
|
||||
],
|
||||
[actionMenuList, formatMessage],
|
||||
@@ -143,7 +151,11 @@ function ExchangeRateTable({
|
||||
expandable={true}
|
||||
treeGraph={true}
|
||||
onSelectedRowsChange={handelSelectedRowsChange}
|
||||
spinnerProps={{ size: 30 }}
|
||||
rowContextMenu={rowContextMenu}
|
||||
pagination={true}
|
||||
pagesCount={exchangeRatesPageination.pagesCount}
|
||||
initialPageSize={exchangeRatesPageination.pageSize}
|
||||
initialPageIndex={exchangeRatesPageination.page - 1}
|
||||
/>
|
||||
</LoadingIndicator>
|
||||
);
|
||||
@@ -152,8 +164,15 @@ function ExchangeRateTable({
|
||||
export default compose(
|
||||
withDialogActions,
|
||||
withExchangeRatesActions,
|
||||
withExchangeRates(({ exchangeRatesList, exchangeRatesLoading }) => ({
|
||||
exchangeRatesList,
|
||||
exchangeRatesLoading,
|
||||
})),
|
||||
withExchangeRates(
|
||||
({
|
||||
exchangeRatesList,
|
||||
exchangeRatesLoading,
|
||||
exchangeRatesPageination,
|
||||
}) => ({
|
||||
exchangeRatesList,
|
||||
exchangeRatesLoading,
|
||||
exchangeRatesPageination,
|
||||
}),
|
||||
),
|
||||
)(ExchangeRateTable);
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { getExchangeRatesList } from 'store/ExchangeRate/exchange.selector';
|
||||
import {
|
||||
getExchangeRatesList,
|
||||
getExchangeRatePaginationMetaFactory,
|
||||
getExchangeRatesTableQueryFactory,
|
||||
} from 'store/ExchangeRate/exchange.selector';
|
||||
|
||||
export default (mapState) => {
|
||||
const getExchangeRatesPaginationMeta = getExchangeRatePaginationMetaFactory();
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const query = getExchangeRatesTableQueryFactory(state, props);
|
||||
|
||||
const mapped = {
|
||||
exchangeRatesList: getExchangeRatesList(state, props),
|
||||
exchangeRatesLoading: state.exchangeRates.loading,
|
||||
exchangeRatesPageination: getExchangeRatesPaginationMeta(
|
||||
state,
|
||||
props,
|
||||
query,
|
||||
),
|
||||
};
|
||||
return mapState ? mapState(mapped, state, props) : mapped;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user