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
customersTableQuery,
// #withAlertsActions.
openAlert,
// #withCustomersActions
requestFetchCustomers,
addCustomersTableQueries,
}) {
const [tableLoading, setTableLoading] = useState(false);

View File

@@ -14,9 +14,9 @@ import { compose } from 'utils';
function VendorFormPage({
// #withVendorActions
requestFetchVendorsTable,
requsetFetchVendor,
requestFetchVendor,
// #wihtCurrenciesActions
// #withCurrenciesActions
requestFetchCurrencies,
}) {
const { id } = useParams();
@@ -35,7 +35,7 @@ function VendorFormPage({
// Handle fetch vendor details.
const fetchVendor = useQuery(
['vendor', id],
(_id, vendorId) => requsetFetchVendor(vendorId),
(_id, vendorId) => requestFetchVendor(vendorId),
{ 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 { Route, Switch, useHistory } from 'react-router-dom';
import { Intent, Alert } from '@blueprintjs/core';
import React, { useEffect, useState } from 'react';
import { useQuery } from 'react-query';
import {
FormattedMessage as T,
FormattedHTMLMessage,
useIntl,
} from 'react-intl';
import { FormattedMessage as T, useIntl } from 'react-intl';
import AppToaster from 'components/AppToaster';
import DashboardInsider from 'components/Dashboard/DashboardInsider';
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
import VendorsTable from './VendorsTable';
import VendorActionsBar from './VendorActionsBar';
import VendorsViewsTabs from './VendorViewsTabs';
import VendorActionsBar from 'containers/Vendors/VendorActionsBar';
import VendorsViewPage from 'containers/Vendors/VendorsViewPage';
import VendorsAlerts from 'containers/Vendors/VendorsAlerts';
import withVendors from './withVendors';
import withVendorActions from './withVendorActions';
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
import withResourceActions from 'containers/Resources/withResourcesActions';
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';
@@ -35,15 +28,11 @@ function VendorsList({
vendorTableQuery,
// #withVendorActions
requestDeleteVender,
requestFetchVendorsTable,
}) {
const [deleteVendor, setDeleteVendor] = useState(false);
const [selectedRows, setSelectedRows] = useState([]);
const [tableLoading, setTableLoading] = useState(false);
const { formatMessage } = useIntl();
const history = useHistory();
useEffect(() => {
changePageTitle(formatMessage({ id: 'vendors_list' }));
@@ -61,64 +50,6 @@ function VendorsList({
(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(() => {
if (tableLoading && !fetchVendors.isFetching) {
setTableLoading(false);
@@ -130,36 +61,10 @@ function VendorsList({
loading={fetchResourceViews.isFetching}
name={'customers-list'}
>
<VendorActionsBar selectedRows={selectedRows} />
<VendorActionsBar />
<DashboardPageContent>
<Switch>
<Route
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>
<VendorsViewPage />
<VendorsAlerts />
</DashboardPageContent>
</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';
import t from 'store/types';
const mapDipatchToProps = (dispatch) => ({
const mapDispatchToProps = (dispatch) => ({
requestSubmitVendor: (form) => dispatch(submitVendor({ form })),
requestEditVendor: (id, form) => dispatch(editVendor({ id, form })),
requsetFetchVendor: (id) => dispatch(fetchVendor({ id })),
requestFetchVendor: (id) => dispatch(fetchVendor({ id })),
requestFetchVendorsTable: (query = {}) =>
dispatch(fetchVendorsTable({ query: { ...query } })),
requestDeleteVender: (id) => dispatch(deleteVendor({ id })),
@@ -25,6 +25,11 @@ const mapDipatchToProps = (dispatch) => ({
type: t.VENDORS_TABLE_QUERIES_ADD,
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 getVendorsCurrentViewId = getVendorsCurrentViewIdFactory();
const getVendorTableQuery = getVendorTableQueryFactory();
const mapStateToProps = (state, props) => {
const query = getVendorTableQuery(state, props);
@@ -25,6 +25,7 @@ export default (mapState) => {
vendorsPageination: getVendorsPaginationMeta(state, props, query),
vendorsLoading: state.vendors.loading,
vendorsCurrentViewId: getVendorsCurrentViewId(state, props),
vendorsSelectedRows: state.vendors.selectedRows,
};
return mapState ? mapState(mapped, state, props) : mapped;
};