refactor: vendors alerts.

This commit is contained in:
elforjani3
2021-01-27 21:33:41 +02:00
parent 25d4b558b6
commit 82e0b9c7f0
11 changed files with 203 additions and 118 deletions

View File

@@ -0,0 +1,86 @@
import React, { useCallback, useState } from 'react';
import {
FormattedMessage as T,
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { Intent, Alert } from '@blueprintjs/core';
import { AppToaster } from 'components';
import { transformErrors } from 'containers/Customers/utils';
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
import withAlertActions from 'containers/Alert/withAlertActions';
import withVendorActions from 'containers/Vendors/withVendorActions';
import { compose } from 'utils';
/**
* Vendor delete alert.
*/
function VendorDeleteAlert({
name,
// #withAlertStoreConnect
isOpen,
payload: { vendorId },
// #withVendorActions
requestDeleteVender,
// #withAlertActions
closeAlert,
}) {
const { formatMessage } = useIntl();
const [isLoading, setLoading] = useState(false);
// Handle cancel delete the vendor.
const handleCancelDeleteAlert = () => {
closeAlert(name);
};
// handle confirm delete vendor.
const handleConfirmDeleteVendor = useCallback(() => {
setLoading(true);
requestDeleteVender(vendorId)
.then(() => {
AppToaster.show({
message: formatMessage({
id: 'the_vendor_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS,
});
})
.catch((errors) => {
transformErrors(errors);
})
.finally(() => {
closeAlert(name);
setLoading(false);
});
}, [requestDeleteVender, vendorId, formatMessage]);
return (
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={isOpen}
onCancel={handleCancelDeleteAlert}
onConfirm={handleConfirmDeleteVendor}
loading={isLoading}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_vendor_you_will_able_to_restore_it'}
/>
</p>
</Alert>
);
}
export default compose(
withAlertStoreConnect(),
withAlertActions,
withVendorActions,
)(VendorDeleteAlert);

View File

@@ -31,12 +31,8 @@ function CustomersList({
// #withCustomers // #withCustomers
customersTableQuery, customersTableQuery,
// #withAlertsActions.
openAlert,
// #withCustomersActions // #withCustomersActions
requestFetchCustomers, requestFetchCustomers,
addCustomersTableQueries, addCustomersTableQueries,
}) { }) {
const [tableLoading, setTableLoading] = useState(false); const [tableLoading, setTableLoading] = useState(false);

View File

@@ -14,9 +14,9 @@ import { compose } from 'utils';
function VendorFormPage({ function VendorFormPage({
// #withVendorActions // #withVendorActions
requestFetchVendorsTable, requestFetchVendorsTable,
requsetFetchVendor, requestFetchVendor,
// #wihtCurrenciesActions // #withCurrenciesActions
requestFetchCurrencies, requestFetchCurrencies,
}) { }) {
const { id } = useParams(); const { id } = useParams();
@@ -35,7 +35,7 @@ function VendorFormPage({
// Handle fetch vendor details. // Handle fetch vendor details.
const fetchVendor = useQuery( const fetchVendor = useQuery(
['vendor', id], ['vendor', id],
(_id, vendorId) => requsetFetchVendor(vendorId), (_id, vendorId) => requestFetchVendor(vendorId),
{ enabled: id && id }, { enabled: id && id },
); );

View File

@@ -0,0 +1,10 @@
import React from 'react';
import VendorDeleteAlert from 'containers/Alerts/Vendors/VendorDeleteAlert';
export default function VendorsAlerts() {
return (
<div>
<VendorDeleteAlert name={'vendor-delete'} />
</div>
);
}

View File

@@ -1,26 +1,19 @@
import React, { useEffect, useCallback, useState, useMemo } from 'react'; import React, { useEffect, useState } from 'react';
import { Route, Switch, useHistory } from 'react-router-dom';
import { Intent, Alert } from '@blueprintjs/core';
import { useQuery } from 'react-query'; import { useQuery } from 'react-query';
import { import { FormattedMessage as T, useIntl } from 'react-intl';
FormattedMessage as T,
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import AppToaster from 'components/AppToaster';
import DashboardInsider from 'components/Dashboard/DashboardInsider'; import DashboardInsider from 'components/Dashboard/DashboardInsider';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent'; import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import VendorsTable from './VendorsTable'; import VendorActionsBar from 'containers/Vendors/VendorActionsBar';
import VendorActionsBar from './VendorActionsBar'; import VendorsViewPage from 'containers/Vendors/VendorsViewPage';
import VendorsViewsTabs from './VendorViewsTabs'; import VendorsAlerts from 'containers/Vendors/VendorsAlerts';
import withVendors from './withVendors'; import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withVendorActions from './withVendorActions';
import withResourceActions from 'containers/Resources/withResourcesActions'; import withResourceActions from 'containers/Resources/withResourcesActions';
import withViewsActions from 'containers/Views/withViewsActions'; import withViewsActions from 'containers/Views/withViewsActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions'; import withVendors from 'containers/Vendors/withVendors';
import withVendorActions from 'containers/Vendors/withVendorActions';
import { compose } from 'utils'; import { compose } from 'utils';
@@ -35,15 +28,11 @@ function VendorsList({
vendorTableQuery, vendorTableQuery,
// #withVendorActions // #withVendorActions
requestDeleteVender,
requestFetchVendorsTable, requestFetchVendorsTable,
}) { }) {
const [deleteVendor, setDeleteVendor] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
const [tableLoading, setTableLoading] = useState(false); const [tableLoading, setTableLoading] = useState(false);
const { formatMessage } = useIntl(); const { formatMessage } = useIntl();
const history = useHistory();
useEffect(() => { useEffect(() => {
changePageTitle(formatMessage({ id: 'vendors_list' })); changePageTitle(formatMessage({ id: 'vendors_list' }));
@@ -61,64 +50,6 @@ function VendorsList({
(key, query) => requestFetchVendorsTable({ ...query }), (key, query) => requestFetchVendorsTable({ ...query }),
); );
// Handle Edit vendor data table
const handleEditVendor = useCallback(
(vendor) => {
history.push(`/vendors/${vendor.id}/edit`);
},
[history],
);
// Handle click delete vendor.
const handleDeleteVendor = useCallback(
(vendor) => {
setDeleteVendor(vendor);
},
[setDeleteVendor],
);
// Handle cancel delete the vendor.
const handleCancelDeleteVendor = useCallback(() => {
setDeleteVendor(false);
}, [setDeleteVendor]);
// Transform API errors in toasts messages.
const transformErrors = useCallback((errors) => {
if (errors.some((e) => e.type === 'VENDOR.HAS.BILLS')) {
AppToaster.show({
message: formatMessage({
id: 'vendor_has_bills',
}),
intent: Intent.DANGER,
});
}
}, []);
// handle confirm delete vendor.
const handleConfirmDeleteVendor = useCallback(() => {
requestDeleteVender(deleteVendor.id)
.then(() => {
setDeleteVendor(false);
AppToaster.show({
message: formatMessage({
id: 'the_vendor_has_been_deleted_successfully',
}),
intent: Intent.SUCCESS,
});
})
.catch((errors) => {
setDeleteVendor(false);
transformErrors(errors);
});
}, [requestDeleteVender, deleteVendor, formatMessage]);
// Handle selected rows change.
const handleSelectedRowsChange = useCallback(
(vendor) => {
setSelectedRows(vendor);
},
[setSelectedRows],
);
useEffect(() => { useEffect(() => {
if (tableLoading && !fetchVendors.isFetching) { if (tableLoading && !fetchVendors.isFetching) {
setTableLoading(false); setTableLoading(false);
@@ -130,36 +61,10 @@ function VendorsList({
loading={fetchResourceViews.isFetching} loading={fetchResourceViews.isFetching}
name={'customers-list'} name={'customers-list'}
> >
<VendorActionsBar selectedRows={selectedRows} /> <VendorActionsBar />
<DashboardPageContent> <DashboardPageContent>
<Switch> <VendorsViewPage />
<Route <VendorsAlerts />
exact={true}
path={['/vendors/:custom_view_id/custom_view', '/vendors']}
>
<VendorsViewsTabs />
<VendorsTable
onDeleteVendor={handleDeleteVendor}
onEditVendor={handleEditVendor}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
<Alert
cancelButtonText={<T id={'cancel'} />}
confirmButtonText={<T id={'delete'} />}
icon="trash"
intent={Intent.DANGER}
isOpen={deleteVendor}
onCancel={handleCancelDeleteVendor}
onConfirm={handleConfirmDeleteVendor}
>
<p>
<FormattedHTMLMessage
id={'once_delete_this_vendor_you_will_able_to_restore_it'}
/>
</p>
</Alert>
</DashboardPageContent> </DashboardPageContent>
</DashboardInsider> </DashboardInsider>
); );

View File

@@ -0,0 +1,60 @@
import React, { useCallback } from 'react';
import { Route, Switch, useHistory } from 'react-router-dom';
import VendorsViewsTabs from './VendorViewsTabs';
import VendorsTable from './VendorsTable';
import withVendorActions from './withVendorActions';
import withAlertsActions from 'containers/Alert/withAlertActions';
import { compose } from 'utils';
function VendorsViewPage({
// #withAlertsActions.
openAlert,
// #withVendorActions.
setSelectedRowsVendors,
}) {
const history = useHistory();
// Handle Edit vendor data table
const handleEditVendor = useCallback(
(vendor) => {
history.push(`/vendors/${vendor.id}/edit`);
},
[history],
);
// Handle click delete vendor.
const handleDeleteVendor = useCallback(
({ id }) => {
openAlert('vendor-delete', { vendorId: id });
},
[openAlert],
);
// Handle select vendor rows.
const handleSelectedRowsChange = (selectedRows) => {
const selectedRowsIds = selectedRows.map((r) => r.id);
setSelectedRowsVendors(selectedRowsIds);
};
return (
<Switch>
<Route
exact={true}
path={['/vendors/:custom_view_id/custom_view', '/vendors']}
>
<VendorsViewsTabs />
<VendorsTable
onDeleteVendor={handleDeleteVendor}
onEditVendor={handleEditVendor}
onSelectedRowsChange={handleSelectedRowsChange}
/>
</Route>
</Switch>
);
}
export default compose(withAlertsActions, withVendorActions)(VendorsViewPage);

View File

@@ -0,0 +1,16 @@
import { useCallback } from 'react';
import { formatMessage } from 'services/intl';
import { Intent } from '@blueprintjs/core';
import { AppToaster } from 'components';
// Transform API errors in toasts messages.
export const transformErrors = useCallback((errors) => {
if (errors.some((e) => e.type === 'VENDOR.HAS.BILLS')) {
AppToaster.show({
message: formatMessage({
id: 'vendor_has_bills',
}),
intent: Intent.DANGER,
});
}
}, []);

View File

@@ -8,10 +8,10 @@ import {
} from 'store/vendors/vendors.actions'; } from 'store/vendors/vendors.actions';
import t from 'store/types'; import t from 'store/types';
const mapDipatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({
requestSubmitVendor: (form) => dispatch(submitVendor({ form })), requestSubmitVendor: (form) => dispatch(submitVendor({ form })),
requestEditVendor: (id, form) => dispatch(editVendor({ id, form })), requestEditVendor: (id, form) => dispatch(editVendor({ id, form })),
requsetFetchVendor: (id) => dispatch(fetchVendor({ id })), requestFetchVendor: (id) => dispatch(fetchVendor({ id })),
requestFetchVendorsTable: (query = {}) => requestFetchVendorsTable: (query = {}) =>
dispatch(fetchVendorsTable({ query: { ...query } })), dispatch(fetchVendorsTable({ query: { ...query } })),
requestDeleteVender: (id) => dispatch(deleteVendor({ id })), requestDeleteVender: (id) => dispatch(deleteVendor({ id })),
@@ -25,6 +25,11 @@ const mapDipatchToProps = (dispatch) => ({
type: t.VENDORS_TABLE_QUERIES_ADD, type: t.VENDORS_TABLE_QUERIES_ADD,
payload: { queries }, payload: { queries },
}), }),
setSelectedRowsVendors: (selectedRows) =>
dispatch({
type: t.VENDOR_SELECTED_ROWS_SET,
payload: { selectedRows },
}),
}); });
export default connect(null, mapDipatchToProps); export default connect(null, mapDispatchToProps);

View File

@@ -13,7 +13,7 @@ export default (mapState) => {
const getVendorsPaginationMeta = getVendorsPaginationMetaFactory(); const getVendorsPaginationMeta = getVendorsPaginationMetaFactory();
const getVendorsCurrentViewId = getVendorsCurrentViewIdFactory(); const getVendorsCurrentViewId = getVendorsCurrentViewIdFactory();
const getVendorTableQuery = getVendorTableQueryFactory(); const getVendorTableQuery = getVendorTableQueryFactory();
const mapStateToProps = (state, props) => { const mapStateToProps = (state, props) => {
const query = getVendorTableQuery(state, props); const query = getVendorTableQuery(state, props);
@@ -25,6 +25,7 @@ export default (mapState) => {
vendorsPageination: getVendorsPaginationMeta(state, props, query), vendorsPageination: getVendorsPaginationMeta(state, props, query),
vendorsLoading: state.vendors.loading, vendorsLoading: state.vendors.loading,
vendorsCurrentViewId: getVendorsCurrentViewId(state, props), vendorsCurrentViewId: getVendorsCurrentViewId(state, props),
vendorsSelectedRows: state.vendors.selectedRows,
}; };
return mapState ? mapState(mapped, state, props) : mapped; return mapState ? mapState(mapped, state, props) : mapped;
}; };

View File

@@ -11,7 +11,7 @@ const initialState = {
views: {}, views: {},
loading: false, loading: false,
currentViewId: -1, currentViewId: -1,
selectedRows: [],
tableQuery: { tableQuery: {
page_size: 12, page_size: 12,
page: 1, page: 1,
@@ -72,6 +72,11 @@ export default createReducer(initialState, {
delete state.items[id]; delete state.items[id];
} }
}, },
[t.VENDOR_SELECTED_ROWS_SET]: (state, action) => {
const { selectedRows } = action.payload;
state.selectedRows = selectedRows;
},
...viewPaginationSetReducer(t.VENDORS_PAGINATION_SET), ...viewPaginationSetReducer(t.VENDORS_PAGINATION_SET),
...createTableQueryReducers('VENDORS'), ...createTableQueryReducers('VENDORS'),
}); });

View File

@@ -8,4 +8,5 @@ export default {
VENDORS_BULK_DELETE: 'VENDORS_BULK_DELETE', VENDORS_BULK_DELETE: 'VENDORS_BULK_DELETE',
VENDORS_PAGINATION_SET: 'VENDORS_PAGINATION_SET', VENDORS_PAGINATION_SET: 'VENDORS_PAGINATION_SET',
VENDORS_SET_CURRENT_VIEW: 'VENDORS_SET_CURRENT_VIEW', VENDORS_SET_CURRENT_VIEW: 'VENDORS_SET_CURRENT_VIEW',
VENDOR_SELECTED_ROWS_SET: 'VENDOR_SELECTED_ROWS_SET',
}; };