refactoring: migrating to react-query to manage service-side state.

This commit is contained in:
a.bouhuolia
2021-02-07 08:10:21 +02:00
parent e093be0663
commit adac2386bb
284 changed files with 8255 additions and 6610 deletions

View File

@@ -1,10 +1,8 @@
import React, { useCallback, useState, useMemo } from 'react';
import React from 'react';
import Icon from 'components/Icon';
import {
Button,
Classes,
Menu,
MenuItem,
Popover,
NavbarDivider,
NavbarGroup,
@@ -14,69 +12,41 @@ import {
} from '@blueprintjs/core';
import classNames from 'classnames';
import { useRouteMatch, useHistory } from 'react-router-dom';
import { useHistory } from 'react-router-dom';
import { FormattedMessage as T, useIntl } from 'react-intl';
import { connect } from 'react-redux';
import FilterDropdown from 'components/FilterDropdown';
import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar';
import { If, DashboardActionViewsList } from 'components';
import withResourceDetail from 'containers/Resources/withResourceDetails';
import withPaymentMade from './withPaymentMade';
import withPaymentMadeActions from './withPaymentMadeActions';
import { usePaymentMadesListContext } from './PaymentMadesListProvider';
import { compose } from 'utils';
/**
* Payment made actions bar.
*/
function PaymentMadeActionsBar({
//#withResourceDetail
resourceFields,
//#withPaymentMades
paymentMadeViews,
//#withPaymentMadesActions
addPaymentMadesTableQueries,
// #own Porps
onFilterChanged,
selectedRows = [],
}) {
const history = useHistory();
const { path } = useRouteMatch();
const [filterCount, setFilterCount] = useState(0);
const { formatMessage } = useIntl();
const handleClickNewPaymentMade = useCallback(() => {
// Payment receives list context.
const { paymentMadesViews } = usePaymentMadesListContext();
// Handle new payment made button click.
const handleClickNewPaymentMade = () => {
history.push('/payment-mades/new');
}, [history]);
// const filterDropdown = FilterDropdown({
// initialCondition: {
// fieldKey: '',
// compatator: 'contains',
// value: '',
// },
// fields: resourceFields,
// onFilterChange: (filterConditions) => {
// addPaymentMadesTableQueries({
// filter_roles: filterConditions || '',
// });
// onFilterChanged && onFilterChanged(filterConditions);
// },
// });
const hasSelectedRows = useMemo(() => selectedRows.length > 0, [
selectedRows,
]);
};
return (
<DashboardActionsBar>
<NavbarGroup>
<DashboardActionViewsList
resourceName={'bill_payments'}
views={paymentMadeViews}
views={paymentMadesViews}
/>
<NavbarDivider />
<Button
@@ -94,16 +64,16 @@ function PaymentMadeActionsBar({
<Button
className={classNames(Classes.MINIMAL)}
text={
filterCount <= 0 ? (
true ? (
<T id={'filter'} />
) : (
`${filterCount} ${formatMessage({ id: 'filters_applied' })}`
`${0} ${formatMessage({ id: 'filters_applied' })}`
)
}
icon={<Icon icon={'filter-16'} iconSize={16} />}
/>
</Popover>
<If condition={hasSelectedRows}>
<If condition={false}>
<Button
className={Classes.MINIMAL}
icon={<Icon icon={'trash-16'} iconSize={16} />}
@@ -132,19 +102,4 @@ function PaymentMadeActionsBar({
);
}
const mapStateToProps = (state, props) => ({
resourceName: 'bill_payments',
});
const withPaymentMadeActionsBar = connect(mapStateToProps);
export default compose(
withPaymentMadeActionsBar,
withResourceDetail(({ resourceFields }) => ({
resourceFields,
})),
withPaymentMade(({ paymentMadeViews }) => ({
paymentMadeViews,
})),
withPaymentMadeActions,
)(PaymentMadeActionsBar);
export default compose(withPaymentMadeActions)(PaymentMadeActionsBar);

View File

@@ -1,164 +1,47 @@
import React, { useEffect, useCallback, useMemo, useState } from 'react';
import { Route, Switch, useHistory } from 'react-router-dom';
import { useQuery, queryCache } from 'react-query';
import { Alert, Intent } from '@blueprintjs/core';
import AppToaster from 'components/AppToaster';
import React, { useEffect } from 'react';
import { FormattedMessage as T, useIntl } from 'react-intl';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import PaymentMadeDataTable from './PaymentMadeDataTable';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import PaymentMadeActionsBar from './PaymentMadeActionsBar';
import PaymentMadeViewTabs from './PaymentMadeViewTabs';
import PaymentMadesAlerts from './PaymentMadesAlerts';
import { PaymentMadesListProvider } from './PaymentMadesListProvider';
import PaymentMadesView from './PaymentMadesView';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withResourceActions from 'containers/Resources/withResourcesActions';
import withPaymentMades from './withPaymentMade';
import withPaymentMadeActions from './withPaymentMadeActions';
import withViewsActions from 'containers/Views/withViewsActions';
import { compose } from 'utils';
/**
* Payment mades list.
*/
function PaymentMadeList({
//#withDashboardActions
// #withDashboardActions
changePageTitle,
//#withViewsActions
requestFetchResourceViews,
requestFetchResourceFields,
//#withPaymentMades
// #withPaymentMades
paymentMadeTableQuery,
//#withPaymentMadesActions
requestFetchPaymentMadesTable,
requestDeletePaymentMade,
addPaymentMadesTableQueries,
}) {
const history = useHistory();
const { formatMessage } = useIntl();
const [deletePaymentMade, setDeletePaymentMade] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
useEffect(() => {
changePageTitle(formatMessage({ id: 'payment_made_list' }));
}, [changePageTitle, formatMessage]);
const fetchResourceViews = useQuery(
['resource-views', 'bill_payments'],
(key, resourceName) => requestFetchResourceViews(resourceName),
);
const fetchResourceFields = useQuery(
['resource-fields', 'bill_payments'],
(key, resourceName) => requestFetchResourceFields(resourceName),
);
const fetchPaymentMades = useQuery(
['paymantMades-table', paymentMadeTableQuery],
() => requestFetchPaymentMadesTable(),
);
//handle dalete Payment Made
const handleDeletePaymentMade = useCallback(
(paymentMade) => {
setDeletePaymentMade(paymentMade);
},
[setDeletePaymentMade],
);
// handle cancel Payment Made
const handleCancelPaymentMadeDelete = useCallback(() => {
setDeletePaymentMade(false);
}, [setDeletePaymentMade]);
// handleConfirm delete payment made
const handleConfirmPaymentMadeDelete = useCallback(() => {
requestDeletePaymentMade(deletePaymentMade.id).then(() => {
AppToaster.show({
message: formatMessage({
id: 'the_payment_made_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS,
});
setDeletePaymentMade(false);
});
}, [deletePaymentMade, requestDeletePaymentMade, formatMessage]);
const handleEditPaymentMade = useCallback((payment) => {
history.push(`/payment-mades/${payment.id}/edit`);
});
// Calculates the selected rows count.
const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [
selectedRows,
]);
// Handle filter change to re-fetch data-table.
const handleFilterChanged = useCallback(() => {}, [fetchPaymentMades]);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
(payment) => {
setSelectedRows(payment);
},
[setSelectedRows],
);
return (
<DashboardInsider
// loading={fetchResourceViews.isFetching || fetchResourceFields.isFetching}
name={'payment_made'}
>
<PaymentMadeActionsBar
// onBulkDelete={}
selectedRows={selectedRows}
onFilterChanged={handleFilterChanged}
/>
<DashboardPageContent>
<Switch>
<Route
exact={true}
path={[
'/payment-mades/:custom_view_id/custom_view',
'/payment-mades',
]}
>
<PaymentMadeViewTabs />
<PaymentMadeDataTable
onDeletePaymentMade={handleDeletePaymentMade}
onEditPaymentMade={handleEditPaymentMade}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
<PaymentMadesListProvider query={paymentMadeTableQuery}>
<PaymentMadeActionsBar />
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon={'trash'}
intent={Intent.DANGER}
isOpen={deletePaymentMade}
onCancel={handleCancelPaymentMadeDelete}
onConfirm={handleConfirmPaymentMadeDelete}
>
<p>
<T
id={'once_delete_this_payment_made_you_will_able_to_restore_it'}
/>
</p>
</Alert>
<DashboardPageContent>
<PaymentMadesView />
<PaymentMadesAlerts />
</DashboardPageContent>
</DashboardInsider>
</PaymentMadesListProvider>
);
}
export default compose(
withResourceActions,
withPaymentMadeActions,
withDashboardActions,
withViewsActions,
withPaymentMades(({ paymentMadeTableQuery }) => ({
paymentMadeTableQuery,
})),

View File

@@ -1,78 +1,38 @@
import React, { useEffect, useRef } from 'react';
import React from 'react';
import { useHistory } from 'react-router';
import { FormattedMessage as T } from 'react-intl';
import { Alignment, Navbar, NavbarGroup } from '@blueprintjs/core';
import { useParams, withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { pick, debounce } from 'lodash';
import { useParams } from 'react-router-dom';
import { pick } from 'lodash';
import { DashboardViewsTabs } from 'components';
import { useUpdateEffect } from 'hooks';
import withPaymentMade from './withPaymentMade';
import { usePaymentMadesListContext } from './PaymentMadesListProvider';
import withPaymentMadeActions from './withPaymentMadeActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withViewDetails from 'containers/Views/withViewDetails';
import { compose } from 'utils';
function PaymentMadeViewTabs({
//#withPaymentMades
paymentMadeViews,
//#withPaymentMadesActions
changePaymentMadeView,
addPaymentMadesTableQueries,
// #withViewDetails
viewItem,
// #withDashboardActions
setTopbarEditView,
changePageSubtitle,
//#Own Props
onViewChanged,
}) {
const history = useHistory();
const { custom_view_id: customViewId = null } = useParams();
useEffect(() => {
changePaymentMadeView(customViewId || -1);
setTopbarEditView(customViewId);
changePageSubtitle(customViewId && viewItem ? viewItem.name : '');
addPaymentMadesTableQueries({
custom_view_id: customViewId,
});
return () => {
setTopbarEditView(null);
changePageSubtitle('');
changePaymentMadeView(null);
};
}, [customViewId, addPaymentMadesTableQueries, changePaymentMadeView]);
useUpdateEffect(() => {
onViewChanged && onViewChanged(customViewId);
}, [customViewId]);
const debounceChangeHistory = useRef(
debounce((toUrl) => {
history.push(toUrl);
}, 250),
);
// Payment receives list context.
const { paymentMadesViews } = usePaymentMadesListContext();
const handleTabsChange = (viewId) => {
const toPath = viewId ? `${viewId}/custom_view` : '';
debounceChangeHistory.current(`/payment-mades/${toPath}`);
setTopbarEditView(viewId);
addPaymentMadesTableQueries({
custom_view_id: viewId || null,
});
};
const tabs = paymentMadeViews.map((view) => ({
const tabs = paymentMadesViews.map((view) => ({
...pick(view, ['name', 'id']),
}));
const handleClickNewView = () => {
setTopbarEditView(null);
history.push('/custom_views/payment-mades/new');
};
@@ -91,19 +51,4 @@ function PaymentMadeViewTabs({
);
}
const mapStateToProps = (state, ownProps) => ({
viewId: ownProps.match.params.custom_view_id,
});
const withPaymentMadesViewTabs = connect(mapStateToProps);
export default compose(
withRouter,
withPaymentMadesViewTabs,
withPaymentMadeActions,
withDashboardActions,
withViewDetails(),
withPaymentMade(({ paymentMadeViews }) => ({
paymentMadeViews,
})),
)(PaymentMadeViewTabs);
export default compose(withPaymentMadeActions)(PaymentMadeViewTabs);

View File

@@ -0,0 +1,10 @@
import React from 'react';
import PaymentMadeDeleteAlert from 'containers/Alerts/PaymentMades/PaymentMadeDeleteAlert';
export default function PaymentMadesAlerts() {
return (
<div>
<PaymentMadeDeleteAlert dialogName={'payment-made-delete'} />
</div>
);
}

View File

@@ -0,0 +1,58 @@
import React, { createContext } from 'react';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import {
useResourceViews,
useResourceFields,
usePaymentReceives,
} from 'hooks/query';
const PaymentMadesListContext = createContext();
/**
* Accounts chart data provider.
*/
function PaymentMadesListProvider({ accountsTableQuery, ...props }) {
// Fetch accounts resource views and fields.
const {
data: paymentMadesViews,
isFetching: isViewsLoading,
} = useResourceViews('bill_payments');
// Fetch the accounts resource fields.
const {
data: paymentMadesFields,
isFetching: isFieldsLoading,
} = useResourceFields('bill_payments');
// Fetch accounts list according to the given custom view id.
const {
data: { paymentMades, pagination },
isFetching: isInvoicesLoading,
} = usePaymentReceives(accountsTableQuery);
// Provider payload.
const provider = {
paymentMades,
pagination,
paymentMadesFields,
paymentMadesViews,
isInvoicesLoading,
isFieldsLoading,
isViewsLoading,
};
return (
<DashboardInsider
loading={isViewsLoading || isFieldsLoading}
name={'payment-mades-list'}
>
<PaymentMadesListContext.Provider value={provider} {...props} />
</DashboardInsider>
);
}
const usePaymentMadesListContext = () =>
React.useContext(PaymentMadesListContext);
export { PaymentMadesListProvider, usePaymentMadesListContext };

View File

@@ -0,0 +1,38 @@
import React, { useEffect } from 'react';
import { Switch, Route } from 'react-router-dom';
import PaymentMadeViewTabs from './PaymentMadeViewTabs';
import withAlertsActions from 'containers/Alert/withAlertActions';
import withDialogActions from 'containers/Dialog/withDialogActions';
import { compose } from 'utils';
/**
* Payment mades view page.
*/
function PaymentMadesViewPage({
// #withAlertActions
openAlert,
}) {
return (
<Switch>
<Route
exact={true}
path={['/payment-mades/:custom_view_id/custom_view', '/payment-mades']}
>
<PaymentMadeViewTabs />
{/* <PaymentMadeDataTable
onDeletePaymentMade={handleDeletePaymentMade}
onEditPaymentMade={handleEditPaymentMade}
onSelectedRowsChange={handleSelectedRowsChange}
/> */}
</Route>
</Switch>
);
}
export default compose(
withAlertsActions,
withDialogActions,
)(PaymentMadesViewPage);

View File

@@ -0,0 +1,52 @@
import React, { createContext } from 'react';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import { useResourceViews, useResourceFields, usePaymentMades } from 'hooks/query';
const PaymentMadesContext = createContext();
/**
* Accounts chart data provider.
*/
function PaymentMadesProvider({ query, ...props }) {
// Fetch accounts resource views and fields.
const { data: paymentsViews, isFetching: isViewsLoading } = useResourceViews(
'bill_payments',
);
// Fetch the accounts resource fields.
const {
data: paymentsFields,
isFetching: isFieldsLoading,
} = useResourceFields('bill_payments');
// Fetch accounts list according to the given custom view id.
const {
data: { paymentMades, pagination },
isFetching: isPaymentsLoading,
} = usePaymentMades(query);
// Provider payload.
const provider = {
paymentMades,
pagination,
paymentsFields,
paymentsViews,
isPaymentsLoading,
isFieldsLoading,
isViewsLoading,
};
return (
<DashboardInsider
loading={isViewsLoading || isFieldsLoading}
name={'payment_made'}
>
<PaymentMadesContext.Provider value={provider} {...props} />
</DashboardInsider>
);
}
const usePaymentMadesContext = () => React.useContext(PaymentMadesContext);
export { PaymentMadesProvider, usePaymentMadesContext };