diff --git a/client/src/containers/Alerts/AccountActivateAlert.js b/client/src/containers/Alerts/AccountActivateAlert.js index 8d895f01a..a106cc1c6 100644 --- a/client/src/containers/Alerts/AccountActivateAlert.js +++ b/client/src/containers/Alerts/AccountActivateAlert.js @@ -1,8 +1,5 @@ -import React from 'react'; -import { - FormattedMessage as T, - useIntl, -} from 'react-intl'; +import React, { 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'; @@ -24,9 +21,10 @@ function AccountActivateAlert({ // #withAlertActions closeAlert, - requestActivateAccount + requestActivateAccount, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); // Handle alert cancel. const handleCancel = () => { @@ -35,9 +33,9 @@ function AccountActivateAlert({ // Handle activate account confirm. const handleConfirmAccountActivate = () => { + setLoading(true); requestActivateAccount(accountId) .then(() => { - closeAlert('account-activate'); AppToaster.show({ message: formatMessage({ id: 'the_account_has_been_successfully_activated', @@ -46,8 +44,10 @@ function AccountActivateAlert({ }); queryCache.invalidateQueries('accounts-table'); }) - .catch((error) => { + .catch((error) => {}) + .finally(() => { closeAlert('account-activate'); + setLoading(false); }); }; @@ -59,6 +59,7 @@ function AccountActivateAlert({ isOpen={isOpen} onCancel={handleCancel} onConfirm={handleConfirmAccountActivate} + loading={isLoading} >

@@ -70,5 +71,5 @@ function AccountActivateAlert({ export default compose( withAlertStoreConnect(), withAlertActions, - withAccountsActions + withAccountsActions, )(AccountActivateAlert); diff --git a/client/src/containers/Alerts/AccountBulkActivateAlert.js b/client/src/containers/Alerts/AccountBulkActivateAlert.js index e3ba21c02..3cb367b67 100644 --- a/client/src/containers/Alerts/AccountBulkActivateAlert.js +++ b/client/src/containers/Alerts/AccountBulkActivateAlert.js @@ -1,8 +1,8 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage as T, FormattedHTMLMessage, - useIntl + useIntl, } from 'react-intl'; import { Intent, Alert } from '@blueprintjs/core'; import { queryCache } from 'react-query'; @@ -22,22 +22,22 @@ function AccountBulkActivateAlert({ // #withAlertActions closeAlert, - requestBulkActivateAccounts + requestBulkActivateAccounts, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); const selectedRowsCount = 0; // Handle alert cancel. const handleClose = () => { closeAlert(name); - } + }; // Handle Bulk activate account confirm. const handleConfirmBulkActivate = () => { + setLoading(true); requestBulkActivateAccounts(accountsIds) .then(() => { - closeAlert(name); - AppToaster.show({ message: formatMessage({ id: 'the_accounts_has_been_successfully_activated', @@ -46,7 +46,9 @@ function AccountBulkActivateAlert({ }); queryCache.invalidateQueries('accounts-table'); }) - .catch((errors) => { + .catch((errors) => {}) + .finally(() => { + setLoading(false); closeAlert(name); }); }; @@ -61,6 +63,7 @@ function AccountBulkActivateAlert({ isOpen={isOpen} onCancel={handleClose} onConfirm={handleConfirmBulkActivate} + loading={isLoading} >

@@ -72,5 +75,5 @@ function AccountBulkActivateAlert({ export default compose( withAlertStoreConnect(), withAlertActions, - withAccountsActions -)(AccountBulkActivateAlert); \ No newline at end of file + withAccountsActions, +)(AccountBulkActivateAlert); diff --git a/client/src/containers/Alerts/AccountBulkDeleteAlert.js b/client/src/containers/Alerts/AccountBulkDeleteAlert.js index bb5da79b0..663d1858e 100644 --- a/client/src/containers/Alerts/AccountBulkDeleteAlert.js +++ b/client/src/containers/Alerts/AccountBulkDeleteAlert.js @@ -1,8 +1,5 @@ -import React from 'react'; -import { - FormattedMessage as T, - useIntl -} from 'react-intl'; +import React, { 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'; @@ -27,9 +24,11 @@ function AccountBulkDeleteAlert({ closeAlert, // #withAccountsActions - requestDeleteBulkAccounts + requestDeleteBulkAccounts, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + const selectedRowsCount = 0; const handleCancel = () => { @@ -37,9 +36,9 @@ function AccountBulkDeleteAlert({ }; // Handle confirm accounts bulk delete. const handleConfirmBulkDelete = () => { + setLoading(true); requestDeleteBulkAccounts(accountsIds) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_accounts_has_been_successfully_deleted', @@ -49,8 +48,11 @@ function AccountBulkDeleteAlert({ queryCache.invalidateQueries('accounts-table'); }) .catch((errors) => { - closeAlert(name); handleDeleteErrors(errors); + }) + .finally(() => { + setLoading(false); + closeAlert(name); }); }; @@ -65,6 +67,7 @@ function AccountBulkDeleteAlert({ isOpen={isOpen} onCancel={handleCancel} onConfirm={handleConfirmBulkDelete} + loading={isLoading} >

@@ -76,5 +79,5 @@ function AccountBulkDeleteAlert({ export default compose( withAlertStoreConnect(), withAlertActions, - withAccountsActions -)(AccountBulkDeleteAlert); \ No newline at end of file + withAccountsActions, +)(AccountBulkDeleteAlert); diff --git a/client/src/containers/Alerts/AccountBulkInactivateAlert.js b/client/src/containers/Alerts/AccountBulkInactivateAlert.js index fa98e1d33..bb58a7072 100644 --- a/client/src/containers/Alerts/AccountBulkInactivateAlert.js +++ b/client/src/containers/Alerts/AccountBulkInactivateAlert.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage as T, useIntl } from 'react-intl'; import { Intent, Alert } from '@blueprintjs/core'; import { queryCache } from 'react-query'; @@ -21,6 +21,7 @@ function AccountBulkInactivateAlert({ closeAlert, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); const selectedRowsCount = 0; // Handle alert cancel. @@ -29,10 +30,9 @@ function AccountBulkInactivateAlert({ }; // Handle Bulk Inactive accounts confirm. const handleConfirmBulkInactive = () => { + setLoading(true); requestBulkInactiveAccounts(accountsIds) .then(() => { - closeAlert(name); - AppToaster.show({ message: formatMessage({ id: 'the_accounts_have_been_successfully_inactivated', @@ -41,7 +41,9 @@ function AccountBulkInactivateAlert({ }); queryCache.invalidateQueries('accounts-table'); }) - .catch((errors) => { + .catch((errors) => {}) + .finally(() => { + setLoading(false); closeAlert(name); }); }; @@ -56,6 +58,7 @@ function AccountBulkInactivateAlert({ isOpen={isOpen} onCancel={handleCancel} onConfirm={handleConfirmBulkInactive} + loading={isLoading} >

diff --git a/client/src/containers/Alerts/AccountDeleteAlert.js b/client/src/containers/Alerts/AccountDeleteAlert.js index 6984f84ed..89da81058 100644 --- a/client/src/containers/Alerts/AccountDeleteAlert.js +++ b/client/src/containers/Alerts/AccountDeleteAlert.js @@ -1,8 +1,8 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage as T, FormattedHTMLMessage, - useIntl + useIntl, } from 'react-intl'; import { Intent, Alert } from '@blueprintjs/core'; import { queryCache } from 'react-query'; @@ -30,9 +30,10 @@ function AccountDeleteAlert({ requestDeleteAccount, // #withAlertActions - closeAlert + closeAlert, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); // handle cancel delete account alert. const handleCancelAccountDelete = () => { @@ -41,9 +42,9 @@ function AccountDeleteAlert({ // Handle confirm account delete. const handleConfirmAccountDelete = () => { + setLoading(true); requestDeleteAccount(accountId) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_account_has_been_successfully_deleted', @@ -54,6 +55,9 @@ function AccountDeleteAlert({ }) .catch((errors) => { handleDeleteErrors(errors); + }) + .finally(() => { + setLoading(false); closeAlert(name); }); }; @@ -67,6 +71,7 @@ function AccountDeleteAlert({ isOpen={isOpen} onCancel={handleCancelAccountDelete} onConfirm={handleConfirmAccountDelete} + loading={isLoading} >

- ) + ); } export default compose( withAlertStoreConnect(), withAlertActions, - withAccountsActions -)(AccountDeleteAlert); \ No newline at end of file + withAccountsActions, +)(AccountDeleteAlert); diff --git a/client/src/containers/Alerts/AccountInactivateAlert.js b/client/src/containers/Alerts/AccountInactivateAlert.js index 3a1cb57c4..996b22197 100644 --- a/client/src/containers/Alerts/AccountInactivateAlert.js +++ b/client/src/containers/Alerts/AccountInactivateAlert.js @@ -1,8 +1,5 @@ -import React from 'react'; -import { - FormattedMessage as T, - useIntl, -} from 'react-intl'; +import React, { 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'; @@ -23,18 +20,18 @@ function AccountInactivateAlert({ // #withAccountsActions requestInactiveAccount, - }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); const handleCancelInactiveAccount = () => { closeAlert('account-inactivate'); }; const handleConfirmAccountActive = () => { + setLoading(true); requestInactiveAccount(accountId) .then(() => { - closeAlert('account-inactivate'); AppToaster.show({ message: formatMessage({ id: 'the_account_has_been_successfully_inactivated', @@ -43,7 +40,9 @@ function AccountInactivateAlert({ }); queryCache.invalidateQueries('accounts-table'); }) - .catch((error) => { + .catch((error) => {}) + .finally(() => { + setLoading(false); closeAlert('account-inactivate'); }); }; @@ -56,6 +55,7 @@ function AccountInactivateAlert({ isOpen={isOpen} onCancel={handleCancelInactiveAccount} onConfirm={handleConfirmAccountActive} + loading={isLoading} >

@@ -67,5 +67,5 @@ function AccountInactivateAlert({ export default compose( withAlertStoreConnect(), withAlertActions, - withAccountsActions + withAccountsActions, )(AccountInactivateAlert); diff --git a/client/src/containers/Alerts/Customers/CustomerBulkDeleteAlert.js b/client/src/containers/Alerts/Customers/CustomerBulkDeleteAlert.js new file mode 100644 index 000000000..253f04016 --- /dev/null +++ b/client/src/containers/Alerts/Customers/CustomerBulkDeleteAlert.js @@ -0,0 +1,81 @@ +import React, { useCallback, useState } from 'react'; +import { FormattedMessage as T, 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 withCustomersActions from 'containers/Customers/withCustomersActions'; + +import { compose } from 'utils'; + +/** + * Customer bulk delete alert. + */ +function CustomerBulkDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { customersIds }, + // #withCustomersActions + requestDeleteBulkCustomers, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // handle cancel delete alert. + const handleCancelDeleteAlert = () => { + closeAlert(name); + }; + + console.log(customersIds, 'EE'); + + // Handle confirm customers bulk delete. + const handleConfirmBulkDelete = useCallback(() => { + setLoading(true); + requestDeleteBulkCustomers(customersIds) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_customers_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + }) + .catch((errors) => { + transformErrors(errors); + }) + .finally(() => { + setLoading(false); + closeAlert(name); + }); + }, [requestDeleteBulkCustomers, customersIds, formatMessage]); + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmBulkDelete} + loading={isLoading} + > +

+ +

+ + ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withCustomersActions, +)(CustomerBulkDeleteAlert); diff --git a/client/src/containers/Alerts/Customers/CustomerDeleteAlert.js b/client/src/containers/Alerts/Customers/CustomerDeleteAlert.js new file mode 100644 index 000000000..c90da2124 --- /dev/null +++ b/client/src/containers/Alerts/Customers/CustomerDeleteAlert.js @@ -0,0 +1,87 @@ +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 { transformErrors } from 'containers/Customers/utils'; + +import withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; +import withCustomersActions from 'containers/Customers/withCustomersActions'; + +import { compose } from 'utils'; + +/** + * Customer delete alert. + */ +function CustomerDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { customerId }, + // #withCustomersActions + requestDeleteCustomer, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // handle cancel delete alert. + const handleCancelDeleteAlert = () => { + closeAlert(name); + }; + + // handle confirm delete customer. + const handleConfirmDeleteCustomer = useCallback(() => { + setLoading(true); + requestDeleteCustomer(customerId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_customer_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('customers-table'); + }) + .catch((errors) => { + transformErrors(errors); + }) + .finally(() => { + setLoading(false); + closeAlert(name); + }); + }, [requestDeleteCustomer, customerId, formatMessage]); + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmDeleteCustomer} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withCustomersActions, +)(CustomerDeleteAlert); diff --git a/client/src/containers/Alerts/Estimates/EstimateApproveAlert.js b/client/src/containers/Alerts/Estimates/EstimateApproveAlert.js new file mode 100644 index 000000000..33c819adf --- /dev/null +++ b/client/src/containers/Alerts/Estimates/EstimateApproveAlert.js @@ -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 withEstimateActions from 'containers/Sales/Estimate/withEstimateActions'; + +import { compose } from 'utils'; + +/** + * Estimate Approve alert. + */ +function EstimateApproveAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { estimateId }, + + // #withEstimateActions + requestApproveEstimate, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // handle cancel approve alert. + const handleCancelApproveEstimate = () => { + closeAlert(name); + }; + // Handle confirm estimate approve. + const handleConfirmEstimateApprove = useCallback(() => { + setLoading(true); + requestApproveEstimate(estimateId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_estimate_has_been_approved_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('estimates-table'); + }) + .catch((error) => {}) + .finally(() => { + setLoading(false); + closeAlert(name); + }); + }, [estimateId, requestApproveEstimate, formatMessage]); + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.WARNING} + isOpen={isOpen} + loading={isLoading} + onCancel={handleCancelApproveEstimate} + onConfirm={handleConfirmEstimateApprove} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withEstimateActions, +)(EstimateApproveAlert); diff --git a/client/src/containers/Alerts/Estimates/EstimateDeleteAlert.js b/client/src/containers/Alerts/Estimates/EstimateDeleteAlert.js new file mode 100644 index 000000000..0a1b55cf2 --- /dev/null +++ b/client/src/containers/Alerts/Estimates/EstimateDeleteAlert.js @@ -0,0 +1,85 @@ +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 withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; +import withEstimateActions from 'containers/Sales/Estimate/withEstimateActions'; + +import { compose } from 'utils'; + +/** + * Estimate delete alert. + */ +function EstimateDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { estimateId }, + + // #withEstimateActions + requestDeleteEstimate, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // handle cancel delete alert. + const handleCancelEstimateDelete = () => { + closeAlert(name); + }; + + // handle confirm delete estimate + const handleConfirmEstimateDelete = useCallback(() => { + setLoading(true); + requestDeleteEstimate(estimateId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_estimate_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('estimates-table'); + }) + .catch(({ errors }) => {}) + .finally(() => { + setLoading(false); + closeAlert(name); + }); + }, [requestDeleteEstimate, formatMessage, estimateId]); + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + loading={isLoading} + onCancel={handleCancelEstimateDelete} + onConfirm={handleConfirmEstimateDelete} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withEstimateActions, +)(EstimateDeleteAlert); diff --git a/client/src/containers/Alerts/Estimates/EstimateDeliveredAlert.js b/client/src/containers/Alerts/Estimates/EstimateDeliveredAlert.js new file mode 100644 index 000000000..6c78ff76d --- /dev/null +++ b/client/src/containers/Alerts/Estimates/EstimateDeliveredAlert.js @@ -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 withEstimateActions from 'containers/Sales/Estimate/withEstimateActions'; + +import { compose } from 'utils'; + +/** + * Estimate delivered alert. + */ +function EstimateDeliveredAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { estimateId }, + + // #withEstimateActions + requestDeliveredEstimate, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // Handle cancel delivered estimate alert. + const handleCancelDeliveredEstimate = () => { + closeAlert(name); + }; + + // Handle confirm estimate delivered. + const handleConfirmEstimateDelivered = useCallback(() => { + setLoading(true); + requestDeliveredEstimate(estimateId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_estimate_has_been_delivered_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('estimates-table'); + }) + .catch((error) => {}) + .finally(() => { + closeAlert(name); + setLoading(false); + }); + }, [estimateId, requestDeliveredEstimate, formatMessage]); + + return ( + } + confirmButtonText={} + intent={Intent.WARNING} + isOpen={isOpen} + onCancel={handleCancelDeliveredEstimate} + onConfirm={handleConfirmEstimateDelivered} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withEstimateActions, +)(EstimateDeliveredAlert); diff --git a/client/src/containers/Alerts/Estimates/EstimateRejectAlert.js b/client/src/containers/Alerts/Estimates/EstimateRejectAlert.js new file mode 100644 index 000000000..58a069752 --- /dev/null +++ b/client/src/containers/Alerts/Estimates/EstimateRejectAlert.js @@ -0,0 +1,77 @@ +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 withEstimateActions from 'containers/Sales/Estimate/withEstimateActions'; + +import { compose } from 'utils'; + +/** + * Estimate reject delete alerts. + */ +function EstimateRejectAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { estimateId }, + + // #withEstimateActions + requestRejectEstimate, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + // Handle cancel reject estimate alert. + const handleCancelRejectEstimate = () => { + closeAlert(name); + }; + + // Handle confirm estimate reject. + const handleConfirmEstimateReject = useCallback(() => { + setLoading(true); + requestRejectEstimate(estimateId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_estimate_has_been_rejected_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('estimates-table'); + }) + .catch((error) => {}) + .finally(() => { + setLoading(false); + closeAlert(name); + }); + }, [estimateId, requestRejectEstimate, formatMessage]); + + return ( + } + confirmButtonText={} + intent={Intent.WARNING} + isOpen={isOpen} + onCancel={handleCancelRejectEstimate} + onConfirm={handleConfirmEstimateReject} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withEstimateActions, +)(EstimateRejectAlert); diff --git a/client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js b/client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js new file mode 100644 index 000000000..3aba617c8 --- /dev/null +++ b/client/src/containers/Alerts/Invoices/InvoiceDeleteAlert.js @@ -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 ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmInvoiceDelete} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withInvoiceActions, +)(InvoiceDeleteAlert); diff --git a/client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js b/client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js new file mode 100644 index 000000000..d8f3f8263 --- /dev/null +++ b/client/src/containers/Alerts/Invoices/InvoiceDeliverAlert.js @@ -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 ( + } + confirmButtonText={} + intent={Intent.WARNING} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmInvoiceDeliver} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withInvoiceActions, +)(InvoiceDeliverAlert); diff --git a/client/src/containers/Alerts/Item/InventoryAdjustmentDeleteAlert.js b/client/src/containers/Alerts/Items/InventoryAdjustmentDeleteAlert.js similarity index 90% rename from client/src/containers/Alerts/Item/InventoryAdjustmentDeleteAlert.js rename to client/src/containers/Alerts/Items/InventoryAdjustmentDeleteAlert.js index 57f862073..e538e095f 100644 --- a/client/src/containers/Alerts/Item/InventoryAdjustmentDeleteAlert.js +++ b/client/src/containers/Alerts/Items/InventoryAdjustmentDeleteAlert.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage as T, FormattedHTMLMessage, @@ -30,6 +30,7 @@ function InventoryAdjustmentDeleteAlert({ closeAlert, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); // handle cancel delete alert. const handleCancelInventoryAdjustmentDelete = () => { @@ -37,9 +38,9 @@ function InventoryAdjustmentDeleteAlert({ }; const handleConfirmInventoryAdjustmentDelete = () => { + setLoading(true); requestDeleteInventoryAdjustment(inventoryId) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_adjustment_has_been_deleted_successfully', @@ -48,7 +49,9 @@ function InventoryAdjustmentDeleteAlert({ }); queryCache.invalidateQueries('inventory-adjustment-list'); }) - .catch((errors) => { + .catch((errors) => {}) + .finally(() => { + setLoading(false); closeAlert(name); }); }; @@ -62,6 +65,7 @@ function InventoryAdjustmentDeleteAlert({ isOpen={isOpen} onCancel={handleCancelInventoryAdjustmentDelete} onConfirm={handleConfirmInventoryAdjustmentDelete} + loading={isLoading} >

{ closeAlert(name); @@ -38,9 +36,9 @@ function ItemActivateAlert({ // Handle confirm item activated. const handleConfirmItemActivate = () => { + setLoading(true); requestActivateItem(itemId) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_item_has_been_activated_successfully', @@ -49,8 +47,10 @@ function ItemActivateAlert({ }); queryCache.invalidateQueries('items-table'); }) - .catch((error) => { + .catch((error) => {}) + .finally(() => { closeAlert(name); + setLoading(false); }); }; @@ -62,6 +62,7 @@ function ItemActivateAlert({ isOpen={isOpen} onCancel={handleCancelActivateItem} onConfirm={handleConfirmItemActivate} + loading={isLoading} >

diff --git a/client/src/containers/Alerts/Item/ItemBulkDeleteAlert.js b/client/src/containers/Alerts/Items/ItemBulkDeleteAlert.js similarity index 88% rename from client/src/containers/Alerts/Item/ItemBulkDeleteAlert.js rename to client/src/containers/Alerts/Items/ItemBulkDeleteAlert.js index 0aa178eb5..7da176ab3 100644 --- a/client/src/containers/Alerts/Item/ItemBulkDeleteAlert.js +++ b/client/src/containers/Alerts/Items/ItemBulkDeleteAlert.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage as T, useIntl } from 'react-intl'; import { Intent, Alert } from '@blueprintjs/core'; import { AppToaster } from 'components'; @@ -26,6 +26,7 @@ function ItemBulkDeleteAlert({ closeAlert, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); // handle cancel item bulk delete alert. const handleCancelBulkDelete = () => { @@ -33,9 +34,9 @@ function ItemBulkDeleteAlert({ }; // Handle confirm items bulk delete. const handleConfirmBulkDelete = () => { + setLoading(true); requestDeleteBulkItems(itemsIds) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_items_has_been_deleted_successfully', @@ -43,11 +44,12 @@ function ItemBulkDeleteAlert({ intent: Intent.SUCCESS, }); }) - .catch((errors) => { + .catch((errors) => {}) + .finally(() => { + setLoading(false); closeAlert(name); }); }; - return ( } @@ -59,6 +61,7 @@ function ItemBulkDeleteAlert({ isOpen={isOpen} onCancel={handleCancelBulkDelete} onConfirm={handleConfirmBulkDelete} + loading={isLoading} >

diff --git a/client/src/containers/Alerts/Item/ItemCategoryBulkDeleteAlert.js b/client/src/containers/Alerts/Items/ItemCategoryBulkDeleteAlert.js similarity index 89% rename from client/src/containers/Alerts/Item/ItemCategoryBulkDeleteAlert.js rename to client/src/containers/Alerts/Items/ItemCategoryBulkDeleteAlert.js index 644ca020d..3bdee7dc1 100644 --- a/client/src/containers/Alerts/Item/ItemCategoryBulkDeleteAlert.js +++ b/client/src/containers/Alerts/Items/ItemCategoryBulkDeleteAlert.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FormattedMessage as T, FormattedHTMLMessage, @@ -30,6 +30,7 @@ function ItemCategoryBulkDeleteAlert({ closeAlert, }) { const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); // handle cancel bulk delete alert. const handleCancelBulkDelete = () => { @@ -38,9 +39,9 @@ function ItemCategoryBulkDeleteAlert({ // handle confirm itemCategories bulk delete. const handleConfirmBulkDelete = () => { + setLoading(true); requestDeleteBulkItemCategories(itemCategoriesIds) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_item_categories_has_been_deleted_successfully', @@ -48,8 +49,10 @@ function ItemCategoryBulkDeleteAlert({ intent: Intent.SUCCESS, }); }) - .catch((errors) => { + .catch((errors) => {}) + .finally(() => { closeAlert(name); + setLoading(false); }); }; return ( @@ -63,6 +66,7 @@ function ItemCategoryBulkDeleteAlert({ isOpen={isOpen} onCancel={handleCancelBulkDelete} onConfirm={handleConfirmBulkDelete} + loading={isLoading} >

{ @@ -39,9 +40,9 @@ function ItemCategoryDeleteAlert({ // Handle alert confirm delete item category. const handleConfirmItemDelete = () => { + setLoading(true); requestDeleteItemCategory(itemCategoryId) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_item_category_has_been_deleted_successfully', @@ -50,7 +51,9 @@ function ItemCategoryDeleteAlert({ }); queryCache.invalidateQueries('items-categories-list'); }) - .catch(() => { + .catch(() => {}) + .finally(() => { + setLoading(false); closeAlert(name); }); }; @@ -64,6 +67,7 @@ function ItemCategoryDeleteAlert({ isOpen={isOpen} onCancel={handleCancelItemCategoryDelete} onConfirm={handleConfirmItemDelete} + loading={isLoading} >

{ @@ -40,9 +41,9 @@ function ItemDeleteAlert({ }; const handleConfirmDeleteItem = () => { + setLoading(true); requestDeleteItem(itemId) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_item_has_been_deleted_successfully', @@ -53,7 +54,10 @@ function ItemDeleteAlert({ }) .catch(({ errors }) => { handleDeleteErrors(errors); + }) + .finally(() => { closeAlert(name); + setLoading(false); }); }; @@ -66,6 +70,7 @@ function ItemDeleteAlert({ isOpen={isOpen} onCancel={handleCancelItemDelete} onConfirm={handleConfirmDeleteItem} + loading={isLoading} >

{ @@ -38,9 +36,9 @@ function ItemInactivateAlert({ // Handle confirm item Inactive. const handleConfirmItemInactive = () => { + setLoading(true); requestInactiveItem(itemId) .then(() => { - closeAlert(name); AppToaster.show({ message: formatMessage({ id: 'the_item_has_been_inactivated_successfully', @@ -49,7 +47,9 @@ function ItemInactivateAlert({ }); queryCache.invalidateQueries('items-table'); }) - .catch((error) => { + .catch((error) => {}) + .finally(() => { + setLoading(false); closeAlert(name); }); }; @@ -62,6 +62,7 @@ function ItemInactivateAlert({ isOpen={isOpen} onCancel={handleCancelInactivateItem} onConfirm={handleConfirmItemInactive} + loading={isLoading} >

diff --git a/client/src/containers/Alerts/PaymentReceives/PaymentReceiveDeleteAlert.js b/client/src/containers/Alerts/PaymentReceives/PaymentReceiveDeleteAlert.js new file mode 100644 index 000000000..1a64ae5d1 --- /dev/null +++ b/client/src/containers/Alerts/PaymentReceives/PaymentReceiveDeleteAlert.js @@ -0,0 +1,85 @@ +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 withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; +import withPaymentReceivesActions from 'containers/Sales/PaymentReceive/withPaymentReceivesActions'; + +import { compose } from 'utils'; + +/** + * Payment receive delete alert. + */ +function PaymentReceiveDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { paymentReceiveId }, + + // #withPaymentReceivesActions + requestDeletePaymentReceive, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // Handle cancel payment Receive. + const handleCancelDeleteAlert = () => { + closeAlert(name); + }; + + // Handle confirm delete payment receive. + const handleConfirmPaymentReceiveDelete = useCallback(() => { + setLoading(true); + requestDeletePaymentReceive(paymentReceiveId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_payment_receive_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('paymentReceives-table'); + }) + .catch(() => {}) + .finally(() => { + closeAlert(name); + setLoading(false); + }); + }, [paymentReceiveId, requestDeletePaymentReceive, formatMessage]); + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmPaymentReceiveDelete} + loading={isLoading} + > +

+ +

+ + ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withPaymentReceivesActions, +)(PaymentReceiveDeleteAlert); diff --git a/client/src/containers/Alerts/Receipts/ReceiptCloseAlert.js b/client/src/containers/Alerts/Receipts/ReceiptCloseAlert.js new file mode 100644 index 000000000..4057942e3 --- /dev/null +++ b/client/src/containers/Alerts/Receipts/ReceiptCloseAlert.js @@ -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 withReceiptActions from 'containers/Sales/Receipt/withReceiptActions'; + +import { compose } from 'utils'; + +/** + * Receipt close alert. + */ +function ReceiptCloseAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { receiptId }, + + // #withReceiptActions + requestCloseReceipt, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // handle cancel delete alert. + const handleCancelDeleteAlert = () => { + closeAlert(name); + }; + + // Handle confirm receipt close. + const handleConfirmReceiptClose = useCallback(() => { + setLoading(true); + requestCloseReceipt(receiptId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_receipt_has_been_closed_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('receipts-table'); + }) + .catch((error) => {}) + .finally(() => { + closeAlert(name); + setLoading(false); + }); + }, [receiptId, requestCloseReceipt, formatMessage]); + + return ( + } + confirmButtonText={} + intent={Intent.WARNING} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmReceiptClose} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withReceiptActions, +)(ReceiptCloseAlert); diff --git a/client/src/containers/Alerts/Receipts/ReceiptDeleteAlert.js b/client/src/containers/Alerts/Receipts/ReceiptDeleteAlert.js new file mode 100644 index 000000000..0aa3703b0 --- /dev/null +++ b/client/src/containers/Alerts/Receipts/ReceiptDeleteAlert.js @@ -0,0 +1,85 @@ +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 withAlertStoreConnect from 'containers/Alert/withAlertStoreConnect'; +import withAlertActions from 'containers/Alert/withAlertActions'; +import withReceiptActions from 'containers/Sales/Receipt/withReceiptActions'; + +import { compose } from 'utils'; + +/** + * Invoice alert. + */ +function NameDeleteAlert({ + name, + + // #withAlertStoreConnect + isOpen, + payload: { receiptId }, + + // #withReceiptActions + requestDeleteReceipt, + + // #withAlertActions + closeAlert, +}) { + const { formatMessage } = useIntl(); + const [isLoading, setLoading] = useState(false); + + // handle cancel delete alert. + const handleCancelDeleteAlert = () => { + closeAlert(name); + }; + + // handle confirm delete receipt + const handleConfirmReceiptDelete = useCallback(() => { + setLoading(true); + requestDeleteReceipt(receiptId) + .then(() => { + AppToaster.show({ + message: formatMessage({ + id: 'the_receipt_has_been_deleted_successfully', + }), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('receipts-table'); + }) + .catch(() => {}) + .finally(() => { + setLoading(false); + closeAlert(name); + }); + }, [receiptId, requestDeleteReceipt, formatMessage]); + + return ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmReceiptDelete} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withReceiptActions, +)(NameDeleteAlert); diff --git a/client/src/containers/Alerts/Vendors/VendorDeleteAlert.js b/client/src/containers/Alerts/Vendors/VendorDeleteAlert.js new file mode 100644 index 000000000..5e2d5b08e --- /dev/null +++ b/client/src/containers/Alerts/Vendors/VendorDeleteAlert.js @@ -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 ( + } + confirmButtonText={} + icon="trash" + intent={Intent.DANGER} + isOpen={isOpen} + onCancel={handleCancelDeleteAlert} + onConfirm={handleConfirmDeleteVendor} + loading={isLoading} + > +

+ +

+
+ ); +} + +export default compose( + withAlertStoreConnect(), + withAlertActions, + withVendorActions, +)(VendorDeleteAlert); diff --git a/client/src/containers/Customers/CustomerActionsBar.js b/client/src/containers/Customers/CustomerActionsBar.js index aaf60526c..678b5ff10 100644 --- a/client/src/containers/Customers/CustomerActionsBar.js +++ b/client/src/containers/Customers/CustomerActionsBar.js @@ -14,33 +14,31 @@ import classNames from 'classnames'; import { connect } from 'react-redux'; import { useHistory } from 'react-router-dom'; -import Icon from 'components/Icon'; import DashboardActionsBar from 'components/Dashboard/DashboardActionsBar'; -import FilterDropdown from 'components/FilterDropdown'; -import { If, DashboardActionViewsList } from 'components'; +import { If, Icon, DashboardActionViewsList } from 'components'; import withResourceDetail from 'containers/Resources/withResourceDetails'; import withCustomers from 'containers/Customers/withCustomers'; import withCustomersActions from 'containers/Customers/withCustomersActions'; +import withAlertActions from 'containers/Alert/withAlertActions'; + import { compose } from 'utils'; const CustomerActionsBar = ({ - // #withResourceDetail - resourceFields, - // #withCustomers customersViews, + customersSelectedRows, //#withCustomersActions addCustomersTableQueries, changeCustomerView, + // #withAlertActions + openAlert, + // #ownProps - selectedRows = [], onFilterChanged, - onBulkDelete, }) => { - const [filterCount, setFilterCount] = useState(0); const history = useHistory(); const { formatMessage } = useIntl(); @@ -48,14 +46,10 @@ const CustomerActionsBar = ({ history.push('/customers/new'); }, [history]); - - const hasSelectedRows = useMemo(() => selectedRows.length > 0, [ - selectedRows, - ]); - - const handleBulkDelete = useCallback(() => { - onBulkDelete && onBulkDelete(selectedRows.map((r) => r.id)); - }, [onBulkDelete, selectedRows]); + // Handle Customers bulk delete button click., + const handleBulkDelete = () => { + openAlert('customers-bulk-delete', { customersIds: customersSelectedRows }); + }; const handleTabChange = (viewId) => { changeCustomerView(viewId.id || -1); @@ -88,18 +82,12 @@ const CustomerActionsBar = ({ >