diff --git a/client/src/components/DialogsContainer.js b/client/src/components/DialogsContainer.js
index 23ce3cde6..897653a12 100644
--- a/client/src/components/DialogsContainer.js
+++ b/client/src/components/DialogsContainer.js
@@ -2,9 +2,9 @@ import React, { lazy } from 'react';
import AccountFormDialog from 'containers/Dialogs/AccountFormDialog';
-// import UserFormDialog from 'containers/Dialogs/UserFormDialog';
+import UserFormDialog from 'containers/Dialogs/UserFormDialog';
// import ItemCategoryDialog from 'containers/Dialogs/ItemCategoryDialog';
-// import CurrencyDialog from 'containers/Dialogs/CurrencyDialog';
+import CurrencyFormDialog from 'containers/Dialogs/CurrencyFormDialog';
// import InviteUserDialog from 'containers/Dialogs/InviteUserDialog';
// import ExchangeRateDialog from 'containers/Dialogs/ExchangeRateDialog';
import JournalNumberDialog from 'containers/Dialogs/JournalNumberDialog';
@@ -23,6 +23,8 @@ export default function DialogsContainer() {
+
+
);
}
diff --git a/client/src/containers/Currencies/withCurrency.js b/client/src/containers/Currencies/withCurrency.js
deleted file mode 100644
index cb38db924..000000000
--- a/client/src/containers/Currencies/withCurrency.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { connect } from 'react-redux';
-import {
- getCurrencyById,
- getCurrencyByCode,
-} from 'store/currencies/currencies.selector';
-
-
-const mapStateToProps = (state, props) => ({
- ...(props.currencyId) ? {
- currency: getCurrencyById(state.currencies.data, props.currencyId),
- } : (props.currencyCode) ? {
- currency: getCurrencyByCode(state.currencies.data, props.currencyCode),
- } : {},
-});
-
-export default connect(mapStateToProps);
\ No newline at end of file
diff --git a/client/src/containers/Currencies/withCurrencyDetail.js b/client/src/containers/Currencies/withCurrencyDetail.js
new file mode 100644
index 000000000..efd0b19a7
--- /dev/null
+++ b/client/src/containers/Currencies/withCurrencyDetail.js
@@ -0,0 +1,12 @@
+import { connect } from 'react-redux';
+import {
+ getCurrencyById,
+ getCurrencyByCode,
+} from 'store/currencies/currencies.selector';
+
+const mapStateToProps = (state, props) => ({
+ currency: getCurrencyByCode(state, props),
+});
+
+export default connect(mapStateToProps);
+
diff --git a/client/src/containers/Dialogs/CurrencyDialog.js b/client/src/containers/Dialogs/CurencyFormDialogContent.js
similarity index 75%
rename from client/src/containers/Dialogs/CurrencyDialog.js
rename to client/src/containers/Dialogs/CurencyFormDialogContent.js
index 4aac6789c..9ac0bf890 100644
--- a/client/src/containers/Dialogs/CurrencyDialog.js
+++ b/client/src/containers/Dialogs/CurencyFormDialogContent.js
@@ -7,40 +7,41 @@ import {
Intent,
} from '@blueprintjs/core';
import * as Yup from 'yup';
-import { FormattedMessage as T, useIntl } from 'react-intl';
import { useFormik } from 'formik';
import { useQuery, queryCache } from 'react-query';
-import { connect } from 'react-redux';
+import { FormattedMessage as T, useIntl } from 'react-intl';
import { pick } from 'lodash';
-
-import AppToaster from 'components/AppToaster';
-import Dialog from 'components/Dialog';
-import withDialogRedux from 'components/DialogReduxConnect';
-import ErrorMessage from 'components/ErrorMessage';
import classNames from 'classnames';
-import withDialogActions from 'containers/Dialog/withDialogActions';
+import {
+ If,
+ ErrorMessage,
+ AppToaster,
+ FieldRequiredHint,
+ DialogContent,
+} from 'components';
-import withCurrency from 'containers/Currencies/withCurrency';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+import withCurrencyDetail from 'containers/Currencies/withCurrencyDetail';
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
import { compose } from 'utils';
-function CurrencyDialog({
- dialogName,
- payload,
- isOpen,
-
- // #withDialogActions
- closeDialog,
-
- // #withCurrency
- currencyCode,
+function CurencyFormDialogContent({
+ // #withCurrencyDetail
currency,
// #wihtCurrenciesActions
requestFetchCurrencies,
requestSubmitCurrencies,
requestEditCurrency,
+
+ // #withDialogActions
+ closeDialog,
+
+ // #ownProp
+ action,
+ currencyId,
+ dialogName,
}) {
const { formatMessage } = useIntl();
const fetchCurrencies = useQuery('currencies', () =>
@@ -63,7 +64,6 @@ function CurrencyDialog({
}),
[],
);
-
const {
values,
errors,
@@ -75,12 +75,11 @@ function CurrencyDialog({
} = useFormik({
enableReinitialize: true,
initialValues: {
- ...(payload.action === 'edit' &&
- pick(currency, Object.keys(initialValues))),
+ ...(action === 'edit' && pick(currency, Object.keys(initialValues))),
},
validationSchema: validationSchema,
onSubmit: (values, { setSubmitting }) => {
- if (payload.action === 'edit') {
+ if (action === 'edit') {
requestEditCurrency(currency.id, values)
.then((response) => {
closeDialog(dialogName);
@@ -115,7 +114,6 @@ function CurrencyDialog({
}
},
});
-
const handleClose = useCallback(() => {
closeDialog(dialogName);
}, [dialogName, closeDialog]);
@@ -129,35 +127,13 @@ function CurrencyDialog({
closeDialog(dialogName);
}, [closeDialog, dialogName, resetForm]);
- const requiredSpan = useMemo(() => *, []);
-
return (
-
- ) : (
-
- )
- }
- className={classNames(
- {
- 'dialog--loading': fetchCurrencies.isFetching,
- },
- 'dialog--currency-form',
- )}
- isOpen={isOpen}
- onClosed={onDialogClosed}
- onOpening={onDialogOpening}
- isLoading={fetchCurrencies.isFetching}
- onClose={handleClose}
- >
+
-
+
);
}
-const mapStateToProps = (state, props) => ({
- currency: 'currency-form',
-});
-
-const withCurrencyFormDialog = connect(mapStateToProps);
-
export default compose(
- withCurrencyFormDialog,
- withDialogRedux(null, 'currency-form'),
- withCurrency,
+ withCurrencyDetail,
withDialogActions,
withCurrenciesActions,
-)(CurrencyDialog);
+)(CurencyFormDialogContent);
diff --git a/client/src/containers/Dialogs/CurrencyFormDialog.js b/client/src/containers/Dialogs/CurrencyFormDialog.js
new file mode 100644
index 000000000..48c6757cb
--- /dev/null
+++ b/client/src/containers/Dialogs/CurrencyFormDialog.js
@@ -0,0 +1,41 @@
+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 CurrencyFormDialogContent = lazy(() =>
+ import('./CurencyFormDialogContent'),
+);
+function CurrencyFormDialog({
+ dialogName,
+ payload = { action: '', id: null },
+ isOpen,
+}) {
+ return (
+
+ ) : (
+
+ )
+ }
+ className={'dialog--currency-form'}
+ isOpen={isOpen}
+ autoFocus={true}
+ canEscapeKeyClose={true}
+ >
+
+
+
+
+ );
+}
+
+export default compose(withDialogRedux())(CurrencyFormDialog);
diff --git a/client/src/containers/Dialogs/UserFormDialog.connector.js b/client/src/containers/Dialogs/UserFormDialog.connector.js
index 856c81668..6aeb7d2ad 100644
--- a/client/src/containers/Dialogs/UserFormDialog.connector.js
+++ b/client/src/containers/Dialogs/UserFormDialog.connector.js
@@ -7,7 +7,7 @@ export const mapStateToProps = (state, props) => {
const dialogPayload = getDialogPayload(state, 'user-form');
return {
- name: 'user-form',
+ dialogName: 'user-form',
payload: { action: 'new', id: null },
userDetails:
dialogPayload.action === 'edit'
diff --git a/client/src/containers/Dialogs/UserFormDialog.js b/client/src/containers/Dialogs/UserFormDialog.js
index accdef28a..09fa56aaf 100644
--- a/client/src/containers/Dialogs/UserFormDialog.js
+++ b/client/src/containers/Dialogs/UserFormDialog.js
@@ -1,110 +1,19 @@
-import React, { useCallback } from 'react';
+import React, { lazy } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl';
-import { useFormik } from 'formik';
-import * as Yup from 'yup';
-import {
- Dialog,
- Button,
- FormGroup,
- InputGroup,
- Intent,
- Classes,
-} from '@blueprintjs/core';
-import { objectKeysTransform } from 'utils';
-import { pick, snakeCase } from 'lodash';
-import classNames from 'classnames';
-import { queryCache, useQuery } from 'react-query';
-
-import AppToaster from 'components/AppToaster';
-import DialogReduxConnect from 'components/DialogReduxConnect';
-import ErrorMessage from 'components/ErrorMessage';
-
-import UserFormDialogConnect from 'containers/Dialogs/UserFormDialog.connector';
-import withUsersActions from 'containers/Users/withUsersActions';
-import withDialogActions from 'containers/Dialog/withDialogActions';
-
+import { Dialog, DialogSuspense } from 'components';
+import withDialogRedux from 'components/DialogReduxConnect';
import { compose } from 'utils';
+const UserFormDialogContent = lazy(() => import('./UserFormDialogContent'));
+
function UserFormDialog({
- requestFetchUser,
- requestSubmitInvite,
- name,
- payload,
+ dialogName,
+ payload = { action: '', id: null },
isOpen,
- closeDialog,
}) {
- const { formatMessage } = useIntl();
-
- const fetchHook = useQuery(
- payload.action === 'edit' && ['user', payload.user.id],
- (key, id) => requestFetchUser(id),
- { manual: true },
- );
- const validationSchema = Yup.object().shape({
- email: Yup.string()
- .email()
- .required()
- .label(formatMessage({ id: 'email' })),
- });
-
- const initialValues = {
- status: 1,
- ...(payload.action === 'edit' &&
- pick(
- objectKeysTransform(payload.user, snakeCase),
- Object.keys(validationSchema.fields),
- )),
- };
-
- const {
- errors,
- touched,
- resetForm,
- getFieldProps,
- handleSubmit,
- isSubmitting,
- } = useFormik({
- enableReinitialize: true,
- initialValues,
- validationSchema,
- onSubmit: (values, { setSubmitting }) => {
- const form = { ...values };
-
- requestSubmitInvite(form)
- .then((response) => {
- closeDialog(name);
- AppToaster.show({
- message: formatMessage({
- id: 'teammate_invited_to_organization_account',
- }),
- intent: Intent.SUCCESS,
- });
- setSubmitting(false);
- queryCache.invalidateQueries('users-table');
- })
- .catch((errors) => {
- setSubmitting(false);
- });
- },
- });
-
- // Handle the dialog opening.
- const onDialogOpening = useCallback(() => {
- fetchHook.refetch();
- }, [fetchHook]);
-
- const onDialogClosed = useCallback(() => {
- resetForm();
- }, [resetForm]);
-
- // Handles dialog close.
- const handleClose = useCallback(() => {
- closeDialog(name);
- }, [closeDialog, name]);
-
return (
@@ -112,66 +21,23 @@ function UserFormDialog({
)
}
- className={classNames({
- 'dialog--loading': fetchHook.pending,
- 'dialog--invite-form': true,
- })}
- //
+ className={'dialog--invite-form'}
autoFocus={true}
canEscapeKeyClose={true}
isOpen={isOpen}
- isLoading={fetchHook.pending}
- onClosed={onDialogClosed}
- onOpening={onDialogOpening}
- onClose={handleClose}
>
-
+
+
+
);
}
export default compose(
- UserFormDialogConnect,
- withUsersActions,
- withDialogActions,
- DialogReduxConnect,
+ // UserFormDialogConnect,
+ withDialogRedux(),
)(UserFormDialog);
diff --git a/client/src/containers/Dialogs/UserFormDialogContent.js b/client/src/containers/Dialogs/UserFormDialogContent.js
new file mode 100644
index 000000000..44bf2ae77
--- /dev/null
+++ b/client/src/containers/Dialogs/UserFormDialogContent.js
@@ -0,0 +1,162 @@
+import React, { useCallback } from 'react';
+import { useFormik } from 'formik';
+import * as Yup from 'yup';
+import {
+ Button,
+ FormGroup,
+ InputGroup,
+ Intent,
+ Classes,
+} from '@blueprintjs/core';
+import { pick, snakeCase } from 'lodash';
+import classNames from 'classnames';
+import { queryCache, useQuery } from 'react-query';
+import { FormattedMessage as T, useIntl } from 'react-intl';
+import {
+ If,
+ ErrorMessage,
+ AppToaster,
+ FieldRequiredHint,
+ DialogContent,
+} from 'components';
+
+import UserFormDialogConnect from 'containers/Dialogs/UserFormDialog.connector';
+import withUsersActions from 'containers/Users/withUsersActions';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+
+import { compose, objectKeysTransform } from 'utils';
+
+function UserFormDialogContent({
+ // #wihtCurrenciesActions
+ requestFetchUser,
+ requestSubmitInvite,
+
+ // #withDialogActions
+ closeDialog,
+
+ // #ownProp
+ action,
+ userId,
+ dialogName,
+}) {
+ const { formatMessage } = useIntl();
+
+ const fetchHook = useQuery(
+ // action === 'edit' && ['user', action.user.id],
+ action === 'edit' && ['user', userId],
+ (key, id) => requestFetchUser(id),
+ { enabled: userId },
+ );
+
+ const validationSchema = Yup.object().shape({
+ email: Yup.string()
+ .email()
+ .required()
+ .label(formatMessage({ id: 'email' })),
+ });
+
+ const initialValues = {
+ status: 1,
+ ...(action === 'edit' &&
+ pick(
+ objectKeysTransform(userId, snakeCase),
+ Object.keys(validationSchema.fields),
+ )),
+ };
+
+ const {
+ errors,
+ touched,
+ resetForm,
+ getFieldProps,
+ handleSubmit,
+ isSubmitting,
+ } = useFormik({
+ enableReinitialize: true,
+ initialValues,
+ validationSchema,
+ onSubmit: (values, { setSubmitting }) => {
+ const form = { ...values };
+
+ requestSubmitInvite(form)
+ .then((response) => {
+ closeDialog(dialogName);
+ AppToaster.show({
+ message: formatMessage({
+ id: 'teammate_invited_to_organization_account',
+ }),
+ intent: Intent.SUCCESS,
+ });
+ setSubmitting(false);
+ queryCache.invalidateQueries('users-table');
+ })
+ .catch((errors) => {
+ setSubmitting(false);
+ });
+ },
+ });
+
+ // Handles dialog close.
+ const handleClose = useCallback(() => {
+ closeDialog(dialogName);
+ }, [closeDialog, dialogName]);
+
+ // Handle the dialog opening.
+ const onDialogOpening = useCallback(() => {
+ fetchHook.refetch();
+ }, [fetchHook]);
+
+ const onDialogClosed = useCallback(() => {
+ resetForm();
+ closeDialog(dialogName);
+ }, [resetForm]);
+
+ console.log(action, 'action');
+
+ return (
+
+
+
+ );
+}
+
+export default compose(
+ // UserFormDialogConnect,
+ withDialogActions,
+ withUsersActions,
+)(UserFormDialogContent);
diff --git a/client/src/containers/Preferences/Currencies/CurrenciesDataTable.js b/client/src/containers/Preferences/Currencies/CurrenciesDataTable.js
new file mode 100644
index 000000000..232e6113f
--- /dev/null
+++ b/client/src/containers/Preferences/Currencies/CurrenciesDataTable.js
@@ -0,0 +1,154 @@
+import React, { useCallback, useState, useMemo } from 'react';
+import {
+ Intent,
+ Button,
+ Popover,
+ Menu,
+ MenuItem,
+ Position,
+} from '@blueprintjs/core';
+import { withRouter } from 'react-router';
+import { FormattedMessage as T, useIntl } from 'react-intl';
+import { compose } from 'utils';
+import { useUpdateEffect } from 'hooks';
+import LoadingIndicator from 'components/LoadingIndicator';
+import { DataTable, Icon } from 'components';
+
+import withDashboardActions from 'containers/Dashboard/withDashboardActions';
+import withCurrencies from 'containers/Currencies/withCurrencies';
+import withDialogActions from 'containers/Dialog/withDialogActions';
+
+function CurrenciesDataTable({
+ // #withCurrencies
+ currenciesList,
+ currenciesLoading,
+
+ loading,
+ onFetchData,
+ onSelectedRowsChange,
+ onDeleteCurrency,
+
+ // #withDialog.
+ openDialog,
+}) {
+ const [initialMount, setInitialMount] = useState(false);
+
+ const { formatMessage } = useIntl();
+
+ useUpdateEffect(() => {
+ if (!currenciesLoading) {
+ setInitialMount(true);
+ }
+ }, [currenciesLoading, setInitialMount]);
+
+ const handleEditCurrency = useCallback(
+ (currency) => {
+ openDialog('currency-form', {
+ action: 'edit',
+ currencyCode: currency.currency_code,
+ });
+ },
+ [openDialog],
+ );
+
+ const actionMenuList = useCallback(
+ (currency) => (
+
+ ),
+ [handleEditCurrency, onDeleteCurrency, formatMessage],
+ );
+
+ const onRowContextMenu = useCallback(
+ (cell) => {
+ return actionMenuList(cell.row.original);
+ },
+ [actionMenuList],
+ );
+
+ const columns = useMemo(
+ () => [
+ {
+ Header: formatMessage({ id: 'currency_name' }),
+ accessor: 'currency_name',
+ width: 150,
+ },
+ {
+ Header: formatMessage({ id: 'currency_code' }),
+ accessor: 'currency_code',
+ className: 'currency_code',
+ width: 120,
+ },
+ {
+ Header: 'Currency sign',
+ width: 120,
+ },
+ {
+ id: 'actions',
+ Header: '',
+ Cell: ({ cell }) => (
+
+ } />
+
+ ),
+ className: 'actions',
+ width: 50,
+ disableResizing: true,
+ },
+ ],
+ [actionMenuList, formatMessage],
+ );
+
+ const handleDataTableFetchData = useCallback(
+ (...args) => {
+ onFetchData && onFetchData(...args);
+ },
+ [onFetchData],
+ );
+
+ const handleSelectedRowsChange = useCallback(
+ (selectedRows) => {
+ onSelectedRowsChange &&
+ onSelectedRowsChange(selectedRows.map((s) => s.original));
+ },
+ [onSelectedRowsChange],
+ );
+
+ return (
+
+
+
+ );
+}
+
+export default compose(
+ withRouter,
+ withDashboardActions,
+ withDialogActions,
+ withCurrencies(({ currenciesList }) => ({
+ currenciesList,
+ })),
+)(CurrenciesDataTable);
diff --git a/client/src/containers/Preferences/Currencies/CurrenciesList.js b/client/src/containers/Preferences/Currencies/CurrenciesList.js
index 0c8fb7eb1..e3c3d2764 100644
--- a/client/src/containers/Preferences/Currencies/CurrenciesList.js
+++ b/client/src/containers/Preferences/Currencies/CurrenciesList.js
@@ -1,13 +1,5 @@
import React, { useCallback, useState, useMemo, useEffect } from 'react';
-import {
- Button,
- Popover,
- Menu,
- MenuItem,
- Position,
- Alert,
- Intent,
-} from '@blueprintjs/core';
+import { Alert, Intent } from '@blueprintjs/core';
import { useQuery, queryCache } from 'react-query';
import {
FormattedMessage as T,
@@ -15,13 +7,12 @@ import {
useIntl,
} from 'react-intl';
-import Icon from 'components/Icon';
-import LoadingIndicator from 'components/LoadingIndicator';
-import DataTable from 'components/DataTable';
+import CurrenciesDataTable from './CurrenciesDataTable';
+import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
+import DashboardInsider from 'components/Dashboard/DashboardInsider';
import AppToaster from 'components/AppToaster';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
-import withCurrencies from 'containers/Currencies/withCurrencies';
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
import withDialogActions from 'containers/Dialog/withDialogActions';
@@ -41,41 +32,34 @@ function CurrenciesList({
// #withDashboardActions
changePreferencesPageTitle,
-
- // #ownProps
- onFetchData,
}) {
const [deleteCurrencyState, setDeleteCurrencyState] = useState(false);
+ const [selectedRows, setSelectedRows] = useState([]);
const { formatMessage } = useIntl();
- const fetchCurrencies = useQuery('currencies-table',
+ const fetchCurrencies = useQuery(
+ 'currencies-table',
() => requestFetchCurrencies(),
{ enabled: true },
);
-
-
useEffect(() => {
changePreferencesPageTitle(formatMessage({ id: 'currencies' }));
}, [changePreferencesPageTitle, formatMessage]);
- const handleEditCurrency = useCallback(
- (currency) => {
- openDialog('currency-form', {
- action: 'edit',
- currencyCode: currency.currency_code,
- });
- },
- [openDialog],
- );
+ const handleEditCurrency = useCallback(() => {}, []);
- const onDeleteCurrency = useCallback((currency) => {
+ // Handle click and cancel/confirm currency delete
+ const handleDeleteCurrency = useCallback((currency) => {
setDeleteCurrencyState(currency);
}, []);
+
+ // handle cancel delete currency alert.
const handleCancelCurrencyDelete = () => {
setDeleteCurrencyState(false);
};
+ // Handle confirm Currency delete
const handleConfirmCurrencyDelete = useCallback(
(refetch) => {
requestDeleteCurrency(deleteCurrencyState.currency_code)
@@ -95,95 +79,44 @@ function CurrenciesList({
[deleteCurrencyState, requestDeleteCurrency, formatMessage],
);
- const actionMenuList = useCallback(
- (currency) => (
-
- ),
- [handleEditCurrency, onDeleteCurrency],
+ // Handle selected rows change.
+ const handleSelectedRowsChange = useCallback(
+ (accounts) => {
+ setSelectedRows(accounts);
+ },
+ [setSelectedRows],
);
- const columns = useMemo(
- () => [
- {
- Header: formatMessage({ id: 'currency_name' }),
- accessor: 'currency_name',
- width: 150,
- },
- {
- Header: formatMessage({ id: 'currency_code' }),
- accessor: 'currency_code',
- className: 'currency_code',
- width: 120,
- },
- {
- Header: 'Currency sign',
- width: 120,
- },
- {
- id: 'actions',
- Header: '',
- Cell: ({ cell }) => (
-
- } />
-
- ),
- className: 'actions',
- width: 50,
- },
- ],
- [actionMenuList, formatMessage],
- );
-
- const handleDataTableFetchData = useCallback(() => {
- // fetchCurrencies.refetch();
- }, [fetchCurrencies]);
-
return (
-
-
- }
- confirmButtonText={}
- icon="trash"
- intent={Intent.DANGER}
- isOpen={deleteCurrencyState}
- onCancel={handleCancelCurrencyDelete}
- onConfirm={handleConfirmCurrencyDelete}
- >
-
-
-
-
-
+
+
+
+ }
+ confirmButtonText={}
+ icon="trash"
+ intent={Intent.DANGER}
+ isOpen={deleteCurrencyState}
+ onCancel={handleCancelCurrencyDelete}
+ onConfirm={handleConfirmCurrencyDelete}
+ >
+
+
+
+
+
+
);
}
export default compose(
withDashboardActions,
- withCurrencies(({ currenciesList }) => ({
- currenciesList,
- })),
withCurrenciesActions,
withDialogActions,
)(CurrenciesList);
diff --git a/client/src/containers/Preferences/General/General.js b/client/src/containers/Preferences/General/General.js
index 228fd90fe..c8eed2ceb 100644
--- a/client/src/containers/Preferences/General/General.js
+++ b/client/src/containers/Preferences/General/General.js
@@ -1,5 +1,6 @@
import React, { useState, useCallback, useEffect } from 'react';
import { useFormik } from 'formik';
+import { mapKeys, snakeCase } from 'lodash';
import * as Yup from 'yup';
import {
Button,
@@ -9,19 +10,30 @@ import {
MenuItem,
Classes,
Spinner,
+ Position,
} from '@blueprintjs/core';
import classNames from 'classnames';
import { TimezonePicker } from '@blueprintjs/timezone';
import { useQuery, queryCache } from 'react-query';
import { FormattedMessage as T, useIntl } from 'react-intl';
+import { DateInput } from '@blueprintjs/datetime';
import moment from 'moment';
+import { useHistory } from 'react-router-dom';
-import { compose, optionsMapToArray } from 'utils';
+import {
+ compose,
+ optionsMapToArray,
+ tansformDateValue,
+ momentFormatter,
+} from 'utils';
-import ErrorMessage from 'components/ErrorMessage';
-import AppToaster from 'components/AppToaster';
-import { ListSelect } from 'components';
-import { If } from 'components';
+import {
+ If,
+ FieldRequiredHint,
+ ListSelect,
+ ErrorMessage,
+ AppToaster,
+} from 'components';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withSettings from 'containers/Settings/withSettings';
@@ -40,14 +52,11 @@ function GeneralPreferences({
}) {
const { formatMessage } = useIntl();
const [selectedItems, setSelectedItems] = useState({});
+ const history = useHistory();
- const fetchHook = useQuery(
- ['settings'],
- () => {
- requestFetchOptions();
- },
- { manual: true },
- );
+ const fetchHook = useQuery(['settings'], () => {
+ requestFetchOptions();
+ });
useEffect(() => {
changePreferencesPageTitle(formatMessage({ id: 'general' }));
@@ -193,16 +202,21 @@ function GeneralPreferences({
name: Yup.string()
.required()
.label(formatMessage({ id: 'organization_name_' })),
+ financial_date_start: Yup.date()
+ .required()
+ .label(formatMessage({ id: 'date_start_' })),
industry: Yup.string()
.required()
.label(formatMessage({ id: 'organization_industry_' })),
location: Yup.string()
.required()
.label(formatMessage({ id: 'location' })),
- base_currency: Yup.string().required(formatMessage({ id: 'required' })),
- fiscal_year: Yup.string()
+ base_currency: Yup.string()
.required()
.label(formatMessage({ id: 'base_currency_' })),
+ fiscal_year: Yup.string()
+ .required()
+ .label(formatMessage({ id: 'fiscal_year_' })),
language: Yup.string()
.required()
.label(formatMessage({ id: 'language' })),
@@ -214,6 +228,12 @@ function GeneralPreferences({
.label(formatMessage({ id: 'date_format_' })),
});
+ function snakeCaseChange(data) {
+ return mapKeys(data, (value, key) => snakeCase(key));
+ }
+
+ const initialValues = snakeCaseChange(organizationSettings);
+
const {
values,
errors,
@@ -226,7 +246,7 @@ function GeneralPreferences({
} = useFormik({
enableReinitialize: true,
initialValues: {
- ...organizationSettings,
+ ...initialValues,
},
validationSchema,
onSubmit: (values, { setSubmitting }) => {
@@ -264,6 +284,13 @@ function GeneralPreferences({
/>
);
+ const handleDateChange = useCallback(
+ (date) => {
+ const formatted = moment(date).format('YYYY-MM-DD');
+ setFieldValue('financial_date_start', formatted);
+ },
+ [setFieldValue],
+ );
const date_format = (item, { handleClick }) => (