mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-23 08:10:32 +00:00
refactor: Inovices alerts.
This commit is contained in:
89
client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js
Normal file
89
client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import React, { useCallback, useState } from 'react';
|
||||||
|
import {
|
||||||
|
FormattedMessage as T,
|
||||||
|
FormattedHTMLMessage,
|
||||||
|
useIntl,
|
||||||
|
} from 'react-intl';
|
||||||
|
import { Intent, Alert } from '@blueprintjs/core';
|
||||||
|
import { queryCache } from 'react-query';
|
||||||
|
import { AppToaster } from 'components';
|
||||||
|
|
||||||
|
import { handleDeleteErrors } from 'containers/Sales/Invoice/components';
|
||||||
|
|
||||||
|
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
|
||||||
|
import withAlertActions from 'containers/Alert/withAlertActions';
|
||||||
|
import withInvoiceActions from 'containers/Sales/Invoice/withInvoiceActions';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice delete alert.
|
||||||
|
*/
|
||||||
|
function InvoiceDeleteAlert({
|
||||||
|
name,
|
||||||
|
|
||||||
|
// #withAlertStoreConnect
|
||||||
|
isOpen,
|
||||||
|
payload: { invoiceId },
|
||||||
|
|
||||||
|
// #withInvoiceActions
|
||||||
|
requestDeleteInvoice,
|
||||||
|
|
||||||
|
// #withAlertActions
|
||||||
|
closeAlert,
|
||||||
|
}) {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
// handle cancel delete invoice alert.
|
||||||
|
const handleCancelDeleteAlert = () => {
|
||||||
|
closeAlert(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
// handleConfirm delete invoice
|
||||||
|
const handleConfirmInvoiceDelete = useCallback(() => {
|
||||||
|
setLoading(true);
|
||||||
|
requestDeleteInvoice(invoiceId)
|
||||||
|
.then(() => {
|
||||||
|
AppToaster.show({
|
||||||
|
message: formatMessage({
|
||||||
|
id: 'the_invoice_has_been_deleted_successfully',
|
||||||
|
}),
|
||||||
|
intent: Intent.SUCCESS,
|
||||||
|
});
|
||||||
|
queryCache.invalidateQueries('invoices-table');
|
||||||
|
})
|
||||||
|
.catch((errors) => {
|
||||||
|
handleDeleteErrors(errors);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
closeAlert(name);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, [invoiceId, requestDeleteInvoice, formatMessage]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert
|
||||||
|
cancelButtonText={<T id={'cancel'} />}
|
||||||
|
confirmButtonText={<T id={'delete'} />}
|
||||||
|
icon="trash"
|
||||||
|
intent={Intent.DANGER}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onCancel={handleCancelDeleteAlert}
|
||||||
|
onConfirm={handleConfirmInvoiceDelete}
|
||||||
|
loading={isLoading}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
<FormattedHTMLMessage
|
||||||
|
id={'once_delete_this_invoice_you_will_able_to_restore_it'}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withAlertStoreConnect(),
|
||||||
|
withAlertActions,
|
||||||
|
withInvoiceActions,
|
||||||
|
)(InvoiceDeleteAlert);
|
||||||
78
client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js
Normal file
78
client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import React, { useCallback, useState } from 'react';
|
||||||
|
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||||
|
import { Intent, Alert } from '@blueprintjs/core';
|
||||||
|
import { queryCache } from 'react-query';
|
||||||
|
import { AppToaster } from 'components';
|
||||||
|
|
||||||
|
import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect';
|
||||||
|
import withAlertActions from 'containers/Alert/withAlertActions';
|
||||||
|
import withInvoiceActions from 'containers/Sales/Invoice/withInvoiceActions';
|
||||||
|
|
||||||
|
import { compose } from 'utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoice alert.
|
||||||
|
*/
|
||||||
|
function InvoiceDeliverAlert({
|
||||||
|
name,
|
||||||
|
|
||||||
|
// #withAlertStoreConnect
|
||||||
|
isOpen,
|
||||||
|
payload: { invoiceId },
|
||||||
|
|
||||||
|
// #withInvoiceActions
|
||||||
|
requestDeliverInvoice,
|
||||||
|
|
||||||
|
// #withAlertActions
|
||||||
|
closeAlert,
|
||||||
|
}) {
|
||||||
|
const { formatMessage } = useIntl();
|
||||||
|
const [isLoading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
// handle cancel delete deliver alert.
|
||||||
|
const handleCancelDeleteAlert = () => {
|
||||||
|
closeAlert(name);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle confirm invoice deliver.
|
||||||
|
const handleConfirmInvoiceDeliver = useCallback(() => {
|
||||||
|
setLoading(true);
|
||||||
|
requestDeliverInvoice(invoiceId)
|
||||||
|
.then(() => {
|
||||||
|
AppToaster.show({
|
||||||
|
message: formatMessage({
|
||||||
|
id: 'the_invoice_has_been_delivered_successfully',
|
||||||
|
}),
|
||||||
|
intent: Intent.SUCCESS,
|
||||||
|
});
|
||||||
|
queryCache.invalidateQueries('invoices-table');
|
||||||
|
})
|
||||||
|
.catch((error) => {})
|
||||||
|
.finally(() => {
|
||||||
|
closeAlert(name);
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}, [invoiceId, requestDeliverInvoice, formatMessage]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Alert
|
||||||
|
cancelButtonText={<T id={'cancel'} />}
|
||||||
|
confirmButtonText={<T id={'deliver'} />}
|
||||||
|
intent={Intent.WARNING}
|
||||||
|
isOpen={isOpen}
|
||||||
|
onCancel={handleCancelDeleteAlert}
|
||||||
|
onConfirm={handleConfirmInvoiceDeliver}
|
||||||
|
loading={isLoading}
|
||||||
|
>
|
||||||
|
<p>
|
||||||
|
<T id={'are_sure_to_deliver_this_invoice'} />
|
||||||
|
</p>
|
||||||
|
</Alert>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
withAlertStoreConnect(),
|
||||||
|
withAlertActions,
|
||||||
|
withInvoiceActions,
|
||||||
|
)(InvoiceDeliverAlert);
|
||||||
15
client/src/containers/Sales/Invoice/InvoicesAlerts.js
Normal file
15
client/src/containers/Sales/Invoice/InvoicesAlerts.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import InvoiceDeleteAlert from 'containers/Alerts/Invoices/InvoiceDeleteAlert';
|
||||||
|
import InvoiceDeliverAlert from 'containers/Alerts/Invoices/InvoiceDeliverAlert';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoices alert.
|
||||||
|
*/
|
||||||
|
export default function ItemsAlerts() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<InvoiceDeleteAlert name={'invoice-delete'} />
|
||||||
|
<InvoiceDeliverAlert name={'invoice-deliver'} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,25 +1,24 @@
|
|||||||
import React, { useEffect, useCallback, useMemo, useState } from 'react';
|
import React, { useEffect, useCallback, useMemo, useState } from 'react';
|
||||||
import { Route, Switch, useHistory } from 'react-router-dom';
|
import { Route, Switch, useHistory } from 'react-router-dom';
|
||||||
import { useQuery, queryCache } from 'react-query';
|
import { useQuery} from 'react-query';
|
||||||
import { Alert, Intent } from '@blueprintjs/core';
|
|
||||||
|
|
||||||
import 'style/pages/SaleInvoice/List.scss';
|
import 'style/pages/SaleInvoice/List.scss';
|
||||||
|
|
||||||
import AppToaster from 'components/AppToaster';
|
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl'
|
|
||||||
;
|
|
||||||
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
|
import DashboardPageContent from 'components/Dashboard/DashboardPageContent';
|
||||||
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
import DashboardInsider from 'components/Dashboard/DashboardInsider';
|
||||||
|
|
||||||
import InvoicesDataTable from './InvoicesDataTable';
|
import InvoicesDataTable from './InvoicesDataTable';
|
||||||
import InvoiceActionsBar from './InvoiceActionsBar';
|
import InvoiceActionsBar from './InvoiceActionsBar';
|
||||||
import InvoiceViewTabs from './InvoiceViewTabs';
|
import InvoiceViewTabs from './InvoiceViewTabs';
|
||||||
|
import InvoicesAlerts from './InvoicesAlerts';
|
||||||
|
|
||||||
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
import withDashboardActions from 'containers/Dashboard/withDashboardActions';
|
||||||
import withResourceActions from 'containers/Resources/withResourcesActions';
|
import withResourceActions from 'containers/Resources/withResourcesActions';
|
||||||
import withInvoices from './withInvoices';
|
import withInvoices from './withInvoices';
|
||||||
import withInvoiceActions from './withInvoiceActions';
|
import withInvoiceActions from 'containers/Sales/Invoice/withInvoiceActions';
|
||||||
import withViewsActions from 'containers/Views/withViewsActions';
|
import withViewsActions from 'containers/Views/withViewsActions';
|
||||||
|
import withAlertsActions from 'containers/Alert/withAlertActions';
|
||||||
|
|
||||||
import { compose } from 'utils';
|
import { compose } from 'utils';
|
||||||
|
|
||||||
@@ -38,17 +37,17 @@ function InvoicesList({
|
|||||||
invoicesTableQuery,
|
invoicesTableQuery,
|
||||||
invoicesViews,
|
invoicesViews,
|
||||||
|
|
||||||
|
// #withAlertsActions.
|
||||||
|
openAlert,
|
||||||
|
|
||||||
//#withInvoiceActions
|
//#withInvoiceActions
|
||||||
requestFetchInvoiceTable,
|
requestFetchInvoiceTable,
|
||||||
requestDeleteInvoice,
|
|
||||||
requestDeliverInvoice,
|
|
||||||
addInvoiceTableQueries,
|
addInvoiceTableQueries,
|
||||||
}) {
|
}) {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { formatMessage } = useIntl();
|
const { formatMessage } = useIntl();
|
||||||
const [deleteInvoice, setDeleteInvoice] = useState(false);
|
const [selectedRows, setSelectedRows] = useState([]);
|
||||||
const [deliverInvoice, setDeliverInvoice] = useState(false);
|
|
||||||
const [selectedRows, setSelectedRows] = useState([]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
changePageTitle(formatMessage({ id: 'invoices_list' }));
|
changePageTitle(formatMessage({ id: 'invoices_list' }));
|
||||||
@@ -68,89 +67,27 @@ function InvoicesList({
|
|||||||
['invoices-table', invoicesTableQuery],
|
['invoices-table', invoicesTableQuery],
|
||||||
(key, query) => requestFetchInvoiceTable({ ...query }),
|
(key, query) => requestFetchInvoiceTable({ ...query }),
|
||||||
);
|
);
|
||||||
//handle dalete Invoice
|
//handle delete Invoice
|
||||||
const handleDeleteInvoice = useCallback(
|
const handleDeleteInvoice = useCallback(
|
||||||
(invoice) => {
|
({ id }) => {
|
||||||
setDeleteInvoice(invoice);
|
openAlert('invoice-delete', { invoiceId: id });
|
||||||
},
|
},
|
||||||
[setDeleteInvoice],
|
[openAlert],
|
||||||
);
|
);
|
||||||
|
|
||||||
// handle cancel Invoice
|
|
||||||
const handleCancelInvoiceDelete = useCallback(() => {
|
|
||||||
setDeleteInvoice(false);
|
|
||||||
}, [setDeleteInvoice]);
|
|
||||||
|
|
||||||
const handleDeleteErrors = (errors) => {
|
|
||||||
if (
|
|
||||||
errors.find(
|
|
||||||
(error) => error.type === 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES',
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
AppToaster.show({
|
|
||||||
message: formatMessage({
|
|
||||||
id: 'the_invoice_cannot_be_deleted',
|
|
||||||
}),
|
|
||||||
intent: Intent.DANGER,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// handleConfirm delete invoice
|
|
||||||
const handleConfirmInvoiceDelete = useCallback(() => {
|
|
||||||
requestDeleteInvoice(deleteInvoice.id)
|
|
||||||
.then(() => {
|
|
||||||
setDeleteInvoice(false);
|
|
||||||
AppToaster.show({
|
|
||||||
message: formatMessage({
|
|
||||||
id: 'the_invoice_has_been_deleted_successfully',
|
|
||||||
}),
|
|
||||||
intent: Intent.SUCCESS,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((errors) => {
|
|
||||||
handleDeleteErrors(errors);
|
|
||||||
setDeleteInvoice(false);
|
|
||||||
});
|
|
||||||
}, [deleteInvoice, requestDeleteInvoice, formatMessage]);
|
|
||||||
|
|
||||||
// Handle cancel/confirm invoice deliver.
|
// Handle cancel/confirm invoice deliver.
|
||||||
const handleDeliverInvoice = useCallback((invoice) => {
|
const handleDeliverInvoice = useCallback(
|
||||||
setDeliverInvoice(invoice);
|
({id}) => {
|
||||||
}, []);
|
openAlert('invoice-deliver', { invoiceId: id });
|
||||||
|
},
|
||||||
|
[openAlert],
|
||||||
|
);
|
||||||
|
|
||||||
// Handle cancel deliver invoice alert.
|
|
||||||
const handleCancelDeliverInvoice = useCallback(() => {
|
|
||||||
setDeliverInvoice(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Handle confirm invoiec deliver.
|
|
||||||
const handleConfirmInvoiceDeliver = useCallback(() => {
|
|
||||||
requestDeliverInvoice(deliverInvoice.id)
|
|
||||||
.then(() => {
|
|
||||||
setDeliverInvoice(false);
|
|
||||||
AppToaster.show({
|
|
||||||
message: formatMessage({
|
|
||||||
id: 'the_invoice_has_been_delivered_successfully',
|
|
||||||
}),
|
|
||||||
intent: Intent.SUCCESS,
|
|
||||||
});
|
|
||||||
queryCache.invalidateQueries('invoices-table');
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
// setDeliverInvoice(false);
|
|
||||||
});
|
|
||||||
}, [deliverInvoice, requestDeliverInvoice, formatMessage]);
|
|
||||||
|
|
||||||
const handleEditInvoice = useCallback((invoice) => {
|
const handleEditInvoice = useCallback((invoice) => {
|
||||||
history.push(`/invoices/${invoice.id}/edit`);
|
history.push(`/invoices/${invoice.id}/edit`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Calculates the selected rows count.
|
|
||||||
const selectedRowsCount = useMemo(() => Object.values(selectedRows).length, [
|
|
||||||
selectedRows,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Handle filter change to re-fetch data-table.
|
// Handle filter change to re-fetch data-table.
|
||||||
const handleFilterChanged = useCallback(() => {}, []);
|
const handleFilterChanged = useCallback(() => {}, []);
|
||||||
|
|
||||||
@@ -167,7 +104,6 @@ function InvoicesList({
|
|||||||
name={'sales-invoices-list'}
|
name={'sales-invoices-list'}
|
||||||
>
|
>
|
||||||
<InvoiceActionsBar
|
<InvoiceActionsBar
|
||||||
// onBulkDelete={}
|
|
||||||
selectedRows={selectedRows}
|
selectedRows={selectedRows}
|
||||||
onFilterChanged={handleFilterChanged}
|
onFilterChanged={handleFilterChanged}
|
||||||
/>
|
/>
|
||||||
@@ -187,31 +123,7 @@ function InvoicesList({
|
|||||||
</Route>
|
</Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
<Alert
|
<InvoicesAlerts />
|
||||||
cancelButtonText={<T id={'cancel'} />}
|
|
||||||
confirmButtonText={<T id={'delete'} />}
|
|
||||||
icon={'trash'}
|
|
||||||
intent={Intent.DANGER}
|
|
||||||
isOpen={deleteInvoice}
|
|
||||||
onCancel={handleCancelInvoiceDelete}
|
|
||||||
onConfirm={handleConfirmInvoiceDelete}
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
<T id={'once_delete_this_invoice_you_will_able_to_restore_it'} />
|
|
||||||
</p>
|
|
||||||
</Alert>
|
|
||||||
<Alert
|
|
||||||
cancelButtonText={<T id={'cancel'} />}
|
|
||||||
confirmButtonText={<T id={'deliver'} />}
|
|
||||||
intent={Intent.WARNING}
|
|
||||||
isOpen={deliverInvoice}
|
|
||||||
onCancel={handleCancelDeliverInvoice}
|
|
||||||
onConfirm={handleConfirmInvoiceDeliver}
|
|
||||||
>
|
|
||||||
<p>
|
|
||||||
<T id={'are_sure_to_deliver_this_invoice'} />
|
|
||||||
</p>
|
|
||||||
</Alert>
|
|
||||||
</DashboardPageContent>
|
</DashboardPageContent>
|
||||||
</DashboardInsider>
|
</DashboardInsider>
|
||||||
);
|
);
|
||||||
@@ -225,4 +137,5 @@ export default compose(
|
|||||||
withInvoices(({ invoicesTableQuery }) => ({
|
withInvoices(({ invoicesTableQuery }) => ({
|
||||||
invoicesTableQuery,
|
invoicesTableQuery,
|
||||||
})),
|
})),
|
||||||
|
withAlertsActions,
|
||||||
)(InvoicesList);
|
)(InvoicesList);
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import React from 'react';
|
|||||||
import { Intent, Tag, ProgressBar } from '@blueprintjs/core';
|
import { Intent, Tag, ProgressBar } from '@blueprintjs/core';
|
||||||
import { Choose, If, Icon } from 'components';
|
import { Choose, If, Icon } from 'components';
|
||||||
import { FormattedMessage as T, useIntl } from 'react-intl';
|
import { FormattedMessage as T, useIntl } from 'react-intl';
|
||||||
|
import { AppToaster } from 'components';
|
||||||
|
import { formatMessage } from 'services/intl';
|
||||||
|
|
||||||
const calculateStatus = (paymentAmount, balanceAmount) =>
|
const calculateStatus = (paymentAmount, balanceAmount) =>
|
||||||
paymentAmount / balanceAmount;
|
paymentAmount / balanceAmount;
|
||||||
@@ -60,3 +62,18 @@ export const statusAccessor = (row) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const handleDeleteErrors = (errors) => {
|
||||||
|
if (
|
||||||
|
errors.find(
|
||||||
|
(error) => error.type === 'INVOICE_HAS_ASSOCIATED_PAYMENT_ENTRIES',
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
AppToaster.show({
|
||||||
|
message: formatMessage({
|
||||||
|
id: 'the_invoice_cannot_be_deleted',
|
||||||
|
}),
|
||||||
|
intent: Intent.DANGER,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user