WIP optimize connect with redux state in preferences pages.

This commit is contained in:
Ahmed Bouhuolia
2020-05-10 23:22:36 +02:00
parent a0653674ff
commit 464c36d532
32 changed files with 403 additions and 327 deletions

View File

@@ -0,0 +1,13 @@
import { connect } from 'react-redux';
export default (mapState) => {
const mapStateToProps = (state, props) => {
const mapped = {
currencies: state.currencies.data,
currenciesList: Object.values(state.currencies.data),
};
return mapState ? mapState(mapped, state, props) : mapped;
};
return connect(mapStateToProps);
}

View File

@@ -0,0 +1,17 @@
import { connect } from 'react-redux';
import {
fetchCurrencies,
submitCurrencies,
deleteCurrency,
editCurrency,
} from 'store/currencies/currencies.actions';
export const mapDispatchToProps = (dispatch) => ({
requestFetchCurrencies: () => dispatch(fetchCurrencies({})),
requestSubmitCurrencies: (form) => dispatch(submitCurrencies({ form })),
requestEditCurrency: (id, form) => dispatch(editCurrency({ id, form })),
requestDeleteCurrency: (currency_code) => dispatch(deleteCurrency({ currency_code })),
});
export default connect(null, mapDispatchToProps);

View File

@@ -0,0 +1,16 @@
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);

View File

@@ -1,4 +1,4 @@
import React, { useState, useMemo, useCallback } from 'react';
import React, { useMemo, useCallback } from 'react';
import {
Button,
Classes,
@@ -9,26 +9,40 @@ import {
import * as Yup from 'yup';
import { useIntl } from 'react-intl';
import { useFormik } from 'formik';
import { useQuery } from 'react-query';
import { connect } from 'react-redux';
import { compose } from 'utils';
import Dialog from 'components/Dialog';
import useAsync from 'hooks/async';
import AppToaster from 'components/AppToaster';
import DialogConnect from 'connectors/Dialog.connector';
import DialogReduxConnect from 'components/DialogReduxConnect';
import CurrencyFromDialogConnect from 'connectors/CurrencyFromDialog.connect';
import withCurrency from 'containers/Currencies/withCurrency';
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
import ErrorMessage from 'components/ErrorMessage';
import classNames from 'classnames';
import { pick } from 'lodash';
import { getDialogPayload } from 'store/dashboard/dashboard.reducer';
function CurrencyDialog({
name,
payload,
isOpen,
// #withDialog
closeDialog,
// #withCurrency
currencyCode,
currency,
// #wihtCurrenciesActions
requestFetchCurrencies,
requestSubmitCurrencies,
requestEditCurrency,
editCurrency,
}) {
const intl = useIntl();
@@ -40,70 +54,72 @@ function CurrencyDialog({
.max(4)
.required(intl.formatMessage({ id: 'required' })),
});
const initialValues = useMemo(
() => ({
currency_name: '',
currency_code: '',
}),
[]
);
const initialValues = useMemo(() => ({
currency_name: '',
currency_code: '',
}), []);
const formik = useFormik({
const {
values,
errors,
touched,
setFieldValue,
getFieldProps,
isSubmitting,
handleSubmit,
resetForm,
} = useFormik({
enableReinitialize: true,
initialValues: {
...(payload.action === 'edit' &&
pick(editCurrency, Object.keys(initialValues))),
pick(currency, Object.keys(initialValues))),
},
validationSchema: ValidationSchema,
onSubmit: (values, { setSubmitting }) => {
if (payload.action === 'edit') {
requestEditCurrency(editCurrency.id, values)
.then((response) => {
closeDialog(name);
AppToaster.show({
message: 'the_currency_has_been_edited',
});
setSubmitting(false);
})
.catch((error) => {
setSubmitting(false);
requestEditCurrency(currency.id, values).then((response) => {
closeDialog(name);
AppToaster.show({
message: 'the_currency_has_been_edited',
intent: Intent.SUCCESS,
});
setSubmitting(false);
})
.catch((error) => {
setSubmitting(false);
});
} else {
requestSubmitCurrencies(values)
.then((response) => {
closeDialog(name);
AppToaster.show({
message: 'the_currency_has_been_submit',
});
setSubmitting(false);
})
.catch((error) => {
setSubmitting(false);
requestSubmitCurrencies(values).then((response) => {
closeDialog(name);
AppToaster.show({
message: 'the_currency_has_been_submit',
intent: Intent.SUCCESS,
});
setSubmitting(false);
})
.catch((error) => {
setSubmitting(false);
});
}
},
});
const { values, errors, touched } = useMemo(() => formik, [formik]);
const handleClose = useCallback(() => {
closeDialog(name);
}, [name, closeDialog]);
const fetchHook = useAsync(async () => {
await Promise.all([requestFetchCurrencies()]);
});
const fetchCurrencies = useQuery('currencies',
() => { requestFetchCurrencies(); },
{ manual: true });
const onDialogOpening = useCallback(() => {
fetchHook.execute();
}, [fetchHook]);
fetchCurrencies.refetch();
}, [fetchCurrencies]);
const onDialogClosed = useCallback(() => {
formik.resetForm();
resetForm();
closeDialog(name);
}, [formik, closeDialog, name]);
}, [closeDialog, name]);
const requiredSpan = useMemo(() => <span className={'required'}>*</span>, []);
@@ -113,59 +129,53 @@ function CurrencyDialog({
title={payload.action === 'edit' ? 'Edit Currency' : ' New Currency'}
className={classNames(
{
'dialog--loading': fetchHook.pending,
'dialog--loading': fetchCurrencies.isFetching,
},
'dialog--currency-form'
)}
isOpen={isOpen}
onClosed={onDialogClosed}
onOpening={onDialogOpening}
isLoading={fetchHook.pending}
isLoading={fetchCurrencies.isFetching}
onClose={handleClose}
>
<form onSubmit={formik.handleSubmit}>
<form onSubmit={handleSubmit}>
<div className={Classes.DIALOG_BODY}>
<FormGroup
label={'Currency Name'}
labelInfo={requiredSpan}
className={'form-group--currency-name'}
intent={
errors.currency_name && touched.currency_name && Intent.DANGER
}
helperText={<ErrorMessage name='currency_name' {...formik} />}
intent={(errors.currency_name && touched.currency_name) && Intent.DANGER}
helperText={<ErrorMessage name='currency_name' {...{errors, touched}} />}
inline={true}
>
<InputGroup
medium={true}
intent={
errors.currency_name && touched.currency_name && Intent.DANGER
}
{...formik.getFieldProps('currency_name')}
intent={(errors.currency_name && touched.currency_name) && Intent.DANGER}
{...getFieldProps('currency_name')}
/>
</FormGroup>
<FormGroup
label={'Currency Code'}
labelInfo={requiredSpan}
className={'form-group--currency-code'}
intent={
errors.currency_code && touched.currency_code && Intent.DANGER
}
helperText={<ErrorMessage name='currency_code' {...formik} />}
intent={(errors.currency_code && touched.currency_code) && Intent.DANGER}
helperText={<ErrorMessage name='currency_code' {...{errors, touched}} />}
inline={true}
>
<InputGroup
medium={true}
intent={
errors.currency_code && touched.currency_code && Intent.DANGER
}
{...formik.getFieldProps('currency_code')}
intent={(errors.currency_code && touched.currency_code) && Intent.DANGER}
{...getFieldProps('currency_code')}
/>
</FormGroup>
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button onClick={handleClose}>Close</Button>
<Button intent={Intent.PRIMARY} type='submit'>
<Button intent={Intent.PRIMARY} type='submit' disabled={isSubmitting}>
{payload.action === 'edit' ? 'Edit' : 'Submit'}
</Button>
</div>
@@ -175,8 +185,22 @@ function CurrencyDialog({
);
}
const mapStateToProps = (state, props) => {
const dialogPayload = getDialogPayload(state, 'currency-form');
return {
name: 'currency-form',
payload: { action: 'new', currencyCode: null, ...dialogPayload },
currencyCode: dialogPayload?.currencyCode || null,
}
}
const withCurrencyFormDialog = connect(mapStateToProps);
export default compose(
CurrencyFromDialogConnect,
withCurrencyFormDialog,
DialogConnect,
DialogReduxConnect
DialogReduxConnect,
withCurrenciesActions,
withCurrency,
)(CurrencyDialog);

View File

@@ -4,41 +4,53 @@ import {
Popover,
Menu,
MenuItem,
MenuDivider,
Position,
Classes,
Tooltip,
Alert,
Intent,
} from '@blueprintjs/core';
import { useQuery } from 'react-query';
import Icon from 'components/Icon';
import { snakeCase } from 'lodash';
import { compose } from 'utils';
import CurrencyFromDialogConnect from 'connectors/CurrencyFromDialog.connect';
import DialogConnect from 'connectors/Dialog.connector';
import DashboardConnect from 'connectors/Dashboard.connector';
import LoadingIndicator from 'components/LoadingIndicator';
import DataTable from 'components/DataTable';
import AppToaster from 'components/AppToaster';
import withDashboard from 'connectors/Dashboard.connector';
import withCurrencies from 'containers/Currencies/withCurrencies';
import withCurrenciesActions from 'containers/Currencies/withCurrenciesActions';
function CurrenciesList({
currencies,
// #withCurrencies
currenciesList,
// #withCurrenciesActions
requestDeleteCurrency,
requestFetchCurrencies,
// #withDialog
openDialog,
onFetchData,
requestDeleteCurrency,
}) {
const [deleteCurrencyState, setDeleteCurrencyState] = useState(false);
const handleEditCurrency = (currency) => () => {
const fetchCurrencies = useQuery(['currencies-table'],
() => requestFetchCurrencies());
const handleEditCurrency = (currency) => {
openDialog('currency-form', {
action: 'edit',
currency_code: currency.currency_code,
currencyCode: currency.currency_code,
});
};
const onDeleteCurrency = (currency) => {
setDeleteCurrencyState(currency);
};
const handleCancelCurrencyDelete = () => {
setDeleteCurrencyState(false);
};
@@ -54,56 +66,51 @@ function CurrenciesList({
);
}, [deleteCurrencyState]);
const actionMenuList = useCallback(
(currency) => (
<Menu>
<MenuItem text='Edit Currency' onClick={handleEditCurrency(currency)} />
const actionMenuList = useCallback((currency) => (
<Menu>
<MenuItem
text='Edit Currency'
onClick={() => handleEditCurrency(currency)} />
<MenuItem
text='Delete Currency'
onClick={() => onDeleteCurrency(currency)}
/>
</Menu>
),
[]
);
<MenuItem
text='Delete Currency'
onClick={() => onDeleteCurrency(currency)}
/>
</Menu>
), []);
const columns = useMemo(() => [
{
Header: 'Currency Name',
accessor: 'currency_name',
width: 100,
},
{
Header: 'Currency Code',
accessor: 'currency_code',
className: 'currency_code',
width: 100,
},
{
Header: 'Currency sign',
width: 50,
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_TOP}
>
<Button icon={<Icon icon='ellipsis-h' />} />
</Popover>
),
className: 'actions',
width: 50,
},
], [actionMenuList]);
const columns = useMemo(
() => [
{
id: 'currency_name',
Header: 'Currency Name',
accessor: 'currency_name',
width: 100,
},
{
id: 'currency_code',
Header: 'Currency Code',
accessor: 'currency_code',
className: 'currency_code',
width: 100,
},
{
Header: 'Currency sign',
width: 50,
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_TOP}
>
<Button icon={<Icon icon='ellipsis-h' />} />
</Popover>
),
className: 'actions',
width: 50,
},
],
[actionMenuList]
);
const handleDatatableFetchData = useCallback(() => {
onFetchData && onFetchData();
}, []);
@@ -112,9 +119,9 @@ function CurrenciesList({
<LoadingIndicator>
<DataTable
columns={columns}
data={Object.values(currencies)}
onFetchData={handleDatatableFetchData()}
selectionColumn={true}
data={currenciesList}
loading={fetchCurrencies.isFetching}
selectionColumn={false}
/>
<Alert
@@ -136,7 +143,10 @@ function CurrenciesList({
}
export default compose(
CurrencyFromDialogConnect,
withCurrencies(({ currenciesList }) => ({
currenciesList,
})),
withCurrenciesActions,
DialogConnect,
DashboardConnect
withDashboard
)(CurrenciesList);

View File

@@ -9,27 +9,36 @@ import {
MenuItem,
Classes,
} from '@blueprintjs/core';
import { optionsMapToArray, momentFormatter, optionsArrayToMap } from 'utils';
import classNames from 'classnames';
import { TimezonePicker } from '@blueprintjs/timezone';
import { Select } from '@blueprintjs/select';
import classNames from 'classnames';
import ErrorMessage from 'components/ErrorMessage';
import Icon from 'components/Icon';
import { compose } from 'utils';
import SettingsConnect from 'connectors/Settings.connect';
import AppToaster from 'components/AppToaster';
import { useIntl } from 'react-intl';
import useAsync from 'hooks/async';
import { useQuery } from 'react-query';
import { compose, optionsMapToArray } from 'utils';
import ErrorMessage from 'components/ErrorMessage';
import AppToaster from 'components/AppToaster';
import withSettings from 'containers/Settings/withSettings';
import withSettingsActions from 'containers/Settings/withSettingsActions';
function GeneralPreferences({
// #withSettings
organizationSettings,
// #withSettingsActions
requestSubmitOptions,
requestFetchOptions,
}) {
const intl = useIntl();
const [selectedItems, setSelectedItems] = useState({});
const [timeZone, setTimeZone] = useState('');
const fetchHook = useQuery(['settings'],
() => { requestFetchOptions(); });
const businessLocation = [
{ id: 218, name: 'LIBYA', code: 'LY' },
{ id: 380, name: 'UKRAINE', code: 'UA' },
@@ -55,8 +64,6 @@ function GeneralPreferences({
{ id: 6, name: 'Saturday, Apr 11, 2020', format: 'EEEE, MMM d, yyyy' },
];
const intl = useIntl();
const validationSchema = Yup.object().shape({
name: Yup.string().required(intl.formatMessage({ id: 'required' })),
industry: Yup.string().required(intl.formatMessage({ id: 'required' })),
@@ -69,15 +76,22 @@ function GeneralPreferences({
// time_zone: Yup.object().required(intl.formatMessage({ id: 'required' })),
date_format: Yup.date().required(intl.formatMessage({ id: 'required' })),
});
console.log(organizationSettings.name);
const formik = useFormik({
const {
errors,
values,
touched,
isSubmitting,
setFieldValue,
getFieldProps,
handleSubmit,
resetForm,
} = useFormik({
enableReinitialize: true,
initialValues: {
...organizationSettings,
},
validationSchema: validationSchema,
validationSchema,
onSubmit: (values, { setSubmitting }) => {
const options = optionsMapToArray(values).map((option) => {
return { key: option.key, ...option, group: 'organization' };
@@ -96,12 +110,6 @@ function GeneralPreferences({
},
});
const { errors, values, touched } = useMemo(() => formik, [formik]);
const fetchHook = useAsync(async () => {
await Promise.all([requestFetchOptions()]);
});
const businessLocationItem = (item, { handleClick }) => (
<MenuItem
className={'preferences-menu'}
@@ -156,7 +164,7 @@ function GeneralPreferences({
...selectedItems,
[filedName]: filed,
});
formik.setFieldValue(filedName, filed.name);
setFieldValue(filedName, filed.name);
};
};
@@ -170,30 +178,30 @@ function GeneralPreferences({
return (
<div className='preferences__inside-content--general'>
<form onSubmit={formik.handleSubmit}>
<form onSubmit={handleSubmit}>
<FormGroup
label={'Organization Name'}
inline={true}
intent={errors.name && touched.name && Intent.DANGER}
helperText={<ErrorMessage name='name' {...formik} />}
intent={(errors.name && touched.name) && Intent.DANGER}
helperText={<ErrorMessage name='name' {...{errors, touched}} />}
>
<InputGroup
medium={'true'}
intent={errors.name && touched.name && Intent.DANGER}
{...formik.getFieldProps('name')}
intent={(errors.name && touched.name) && Intent.DANGER}
{...getFieldProps('name')}
/>
</FormGroup>
<FormGroup
label={'Organization Industry'}
inline={true}
intent={errors.industry && touched.industry && Intent.DANGER}
helperText={<ErrorMessage name='industry' {...formik} />}
intent={(errors.industry && touched.industry) && Intent.DANGER}
helperText={<ErrorMessage name='industry' {...{errors, touched}} />}
>
<InputGroup
medium={'true'}
intent={errors.industry && touched.industry && Intent.DANGER}
{...formik.getFieldProps('industry')}
intent={(errors.industry && touched.industry) && Intent.DANGER}
{...getFieldProps('industry')}
/>
</FormGroup>
@@ -205,8 +213,8 @@ function GeneralPreferences({
Classes.FILL
)}
inline={true}
helperText={<ErrorMessage name='location' {...formik} />}
intent={errors.location && touched.location && Intent.DANGER}
helperText={<ErrorMessage name='location' {...{errors, touched}} />}
intent={(errors.location && touched.location) && Intent.DANGER}
>
<Select
items={businessLocation}
@@ -234,10 +242,8 @@ function GeneralPreferences({
Classes.FILL
)}
inline={true}
helperText={<ErrorMessage name='base_currency' {...formik} />}
intent={
errors.base_currency && touched.base_currency && Intent.DANGER
}
helperText={<ErrorMessage name='base_currency' {...{ errors, touched }} />}
intent={(errors.base_currency && touched.base_currency) && Intent.DANGER}
>
<Select
items={currencies}
@@ -265,8 +271,8 @@ function GeneralPreferences({
Classes.FILL
)}
inline={true}
helperText={<ErrorMessage name='fiscal_year' {...formik} />}
intent={errors.fiscal_year && touched.fiscal_year && Intent.DANGER}
helperText={<ErrorMessage name='fiscal_year' {...{errors, touched}} />}
intent={(errors.fiscal_year && touched.fiscal_year) && Intent.DANGER}
>
<Select
items={fiscalYear}
@@ -294,8 +300,8 @@ function GeneralPreferences({
'form-group--select-list',
Classes.FILL
)}
intent={errors.language && touched.language && Intent.DANGER}
helperText={<ErrorMessage name='language' {...formik} />}
intent={(errors.language && touched.language) && Intent.DANGER}
helperText={<ErrorMessage name='language' {...{errors, touched}} />}
>
<Select
items={languagesDisplay}
@@ -321,8 +327,8 @@ function GeneralPreferences({
'form-group--select-list',
Classes.FILL
)}
intent={errors.time_zone && touched.time_zone && Intent.DANGER}
helperText={<ErrorMessage name='time_zone' {...formik} />}
intent={(errors.time_zone && touched.time_zone) && Intent.DANGER}
helperText={<ErrorMessage name='time_zone' {...{errors, touched}} />}
>
<TimezonePicker
value={timeZone}
@@ -339,8 +345,8 @@ function GeneralPreferences({
'form-group--select-list',
Classes.FILL
)}
intent={errors.date_format && touched.date_format && Intent.DANGER}
helperText={<ErrorMessage name='date_format' {...formik} />}
intent={(errors.date_format && touched.date_format) && Intent.DANGER}
helperText={<ErrorMessage name='date_format' {...{errors, touched}} />}
>
<Select
items={dateFormat}
@@ -374,4 +380,7 @@ function GeneralPreferences({
);
}
export default compose(SettingsConnect)(GeneralPreferences);
export default compose(
withSettings,
withSettingsActions,
)(GeneralPreferences);

View File

@@ -1,5 +1,5 @@
import React, { useState, useMemo, useCallback } from 'react';
import { useAsync } from 'react-use';
import { useQuery } from 'react-query';
import DataTable from 'components/DataTable';
import {
Alert,
@@ -11,30 +11,42 @@ import {
Position,
Intent,
} from '@blueprintjs/core';
import { snakeCase } from 'lodash';
import Icon from 'components/Icon';
import LoadingIndicator from 'components/LoadingIndicator';
import { snakeCase } from 'lodash';
import UserListConnect from 'connectors/UsersList.connector';
import AppToaster from 'components/AppToaster';
import { compose } from 'utils';
import DialogConnect from 'connectors/Dialog.connector';
import DashboardConnect from 'connectors/Dashboard.connector';
import withDashboard from 'containers/Dashboard/withDashboard';
import withUsers from 'containers/Users/withUsers';
import withUsersActions from 'containers/Users/withUsersActions';
import { compose } from 'utils';
function UsersListPreferences({
requestFetchUsers,
usersList,
// #withDialog
openDialog,
closeDialog,
// #withUsers
usersList,
// #withUsersActions
requestDeleteUser,
requestInactiveUser,
requestFetchUsers,
// #ownProps
onFetchData,
}) {
const [deleteUserState, setDeleteUserState] = useState(false);
const [inactiveUserState, setInactiveUserState] = useState(false);
const asyncHook = useAsync(async () => {
await Promise.all([requestFetchUsers()]);
}, []);
const fetchUsers = useQuery('users-table',
() => requestFetchUsers());
const onInactiveUser = (user) => {
setInactiveUserState(user);
@@ -49,7 +61,6 @@ function UsersListPreferences({
const handleConfirmUserActive = useCallback(() => {
requestInactiveUser(inactiveUserState.id).then(() => {
setInactiveUserState(false);
requestFetchUsers();
AppToaster.show({ message: 'the_user_has_been_inactivated' });
});
}, [inactiveUserState, requestInactiveUser, requestFetchUsers]);
@@ -105,50 +116,47 @@ function UsersListPreferences({
[]
);
const columns = useMemo(
() => [
{
id: 'full_name',
Header: 'Full Name',
accessor: 'full_name',
width: 170,
},
{
id: 'email',
Header: 'Email',
accessor: 'email',
width: 150,
},
{
id: 'phone_number',
Header: 'Phone Number',
accessor: 'phone_number',
width: 150,
},
{
id: 'active',
Header: 'Status',
accessor: (user) =>
user.active ? <span>Active</span> : <span>Inactivate</span>,
width: 50,
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_TOP}
>
<Button icon={<Icon icon='ellipsis-h' />} />
</Popover>
),
className: 'actions',
width: 50,
},
],
[actionMenuList]
);
const columns = useMemo(() => [
{
id: 'full_name',
Header: 'Full Name',
accessor: 'full_name',
width: 170,
},
{
id: 'email',
Header: 'Email',
accessor: 'email',
width: 150,
},
{
id: 'phone_number',
Header: 'Phone Number',
accessor: 'phone_number',
width: 150,
},
{
id: 'active',
Header: 'Status',
accessor: (user) =>
user.active ? <span>Active</span> : <span>Inactivate</span>,
width: 50,
},
{
id: 'actions',
Header: '',
Cell: ({ cell }) => (
<Popover
content={actionMenuList(cell.row.original)}
position={Position.RIGHT_TOP}
>
<Button icon={<Icon icon='ellipsis-h' />} />
</Popover>
),
className: 'actions',
width: 50,
},
], [actionMenuList]);
const handelDataTableFetchData = useCallback(() => {
onFetchData && onFetchData();
@@ -160,6 +168,7 @@ function UsersListPreferences({
columns={columns}
data={usersList}
onFetchData={handelDataTableFetchData()}
loading={fetchUsers.isFetching}
manualSortBy={true}
expandable={false}
/>
@@ -198,7 +207,8 @@ function UsersListPreferences({
}
export default compose(
UserListConnect,
DialogConnect,
DashboardConnect
withDashboard,
withUsers,
withUsersActions,
)(UsersListPreferences);

View File

@@ -1,9 +0,0 @@
import { connect } from 'react-redux';
export const mapStateToProps = (state, props) => {
return {
usersList: state.users.list.results,
};
};
export default connect(mapStateToProps);

View File

@@ -0,0 +1,7 @@
import { connect } from 'react-redux';
export const mapStateToProps = (state, props) => ({
organizationSettings: state.settings.data.organization,
});
export default connect(mapStateToProps);

View File

@@ -0,0 +1,12 @@
import { connect } from 'react-redux';
import {
FetchOptions,
submitOptions,
} from 'store/settings/settings.actions';
export const mapDispatchToProps = (dispatch) => ({
requestSubmitOptions: (form) => dispatch(submitOptions({ form })),
requestFetchOptions: () => dispatch(FetchOptions({})),
});
export default connect(null, mapDispatchToProps);

View File

@@ -0,0 +1,7 @@
import { connect } from 'react-redux';
export const mapStateToProps = (state, props) => ({
usersList: state.users.list.results,
});
export default connect(mapStateToProps);