diff --git a/packages/webapp/src/components/DialogsContainer.tsx b/packages/webapp/src/components/DialogsContainer.tsx index 7f7d2729a..3789a974e 100644 --- a/packages/webapp/src/components/DialogsContainer.tsx +++ b/packages/webapp/src/components/DialogsContainer.tsx @@ -50,6 +50,16 @@ import { DisconnectBankAccountDialog } from '@/containers/CashFlow/AccountTransa import { SharePaymentLinkDialog } from '@/containers/PaymentLink/dialogs/SharePaymentLinkDialog/SharePaymentLinkDialog'; import { SelectPaymentMethodsDialog } from '@/containers/PaymentLink/dialogs/SelectPaymentMethodsDialog/SelectPaymentMethodsDialog'; import ApiKeysGenerateDialog from '@/containers/Dialogs/ApiKeysGenerateDialog'; +import InvoiceBulkDeleteDialog from '@/containers/Dialogs/Invoices/InvoiceBulkDeleteDialog'; +import EstimateBulkDeleteDialog from '@/containers/Dialogs/Estimates/EstimateBulkDeleteDialog'; +import ReceiptBulkDeleteDialog from '@/containers/Dialogs/Receipts/ReceiptBulkDeleteDialog'; +import CreditNoteBulkDeleteDialog from '@/containers/Dialogs/CreditNotes/CreditNoteBulkDeleteDialog'; +import PaymentReceivedBulkDeleteDialog from '@/containers/Dialogs/PaymentsReceived/PaymentReceivedBulkDeleteDialog'; +import BillBulkDeleteDialog from '@/containers/Dialogs/Bills/BillBulkDeleteDialog'; +import VendorCreditBulkDeleteDialog from '@/containers/Dialogs/VendorCredits/VendorCreditBulkDeleteDialog'; +import ManualJournalBulkDeleteDialog from '@/containers/Dialogs/ManualJournals/ManualJournalBulkDeleteDialog'; +import ExpenseBulkDeleteDialog from '@/containers/Dialogs/Expenses/ExpenseBulkDeleteDialog'; +import AccountBulkDeleteDialog from '@/containers/Dialogs/Accounts/AccountBulkDeleteDialog'; /** * Dialogs container. @@ -139,6 +149,24 @@ export default function DialogsContainer() { + + + + + + + + + + { history.push('/make-journal-entry'); }; - // Handle delete button click. + const { + openBulkDeleteDialog, + isValidatingBulkDeleteManualJournals, + } = useBulkDeleteManualJournalsDialog(); + const handleBulkDelete = () => { - openAlert('journals-bulk-delete', { - journalsIds: manualJournalsSelectedRows, - }); + openBulkDeleteDialog(manualJournalsSelectedRows); }; // Handle tab change. @@ -120,6 +119,7 @@ function ManualJournalActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteManualJournals} /> @@ -208,7 +208,6 @@ function ManualJournalActionsBar({ export default compose( withDialogActions, - withAlertActions, withManualJournalsActions, withSettingsActions, withManualJournals(({ manualJournalsTableState, manualJournalsSelectedRows }) => ({ diff --git a/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalsAlerts.tsx b/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalsAlerts.tsx index fe4a242e2..d45132c5a 100644 --- a/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalsAlerts.tsx +++ b/packages/webapp/src/containers/Accounting/JournalsLanding/ManualJournalsAlerts.tsx @@ -8,10 +8,6 @@ const JournalPublishAlert = React.lazy( () => import('@/containers/Alerts/ManualJournals/JournalPublishAlert'), ); -const JournalBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/ManualJournals/JournalBulkDeleteAlert'), -); - /** * Manual journals alerts. */ @@ -19,5 +15,4 @@ const JournalBulkDeleteAlert = React.lazy( export default [ { name: 'journal-delete', component: JournalDeleteAlert }, { name: 'journal-publish', component: JournalPublishAlert }, - { name: 'journals-bulk-delete', component: JournalBulkDeleteAlert }, ]; diff --git a/packages/webapp/src/containers/Accounting/JournalsLanding/hooks/use-bulk-delete-manual-journals-dialog.ts b/packages/webapp/src/containers/Accounting/JournalsLanding/hooks/use-bulk-delete-manual-journals-dialog.ts new file mode 100644 index 000000000..7a507e0fc --- /dev/null +++ b/packages/webapp/src/containers/Accounting/JournalsLanding/hooks/use-bulk-delete-manual-journals-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteManualJournals } from '@/hooks/query/manualJournals'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteManualJournalsDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteManualJournals(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.ManualJournalBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteManualJournals: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Accounts/AccountsActionsBar.tsx b/packages/webapp/src/containers/Accounts/AccountsActionsBar.tsx index 67c316ba2..0859368e1 100644 --- a/packages/webapp/src/containers/Accounts/AccountsActionsBar.tsx +++ b/packages/webapp/src/containers/Accounts/AccountsActionsBar.tsx @@ -34,6 +34,7 @@ import { useHistory } from 'react-router-dom'; import { useRefreshAccounts } from '@/hooks/query/accounts'; import { useAccountsChartContext } from './AccountsChartProvider'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; +import { useBulkDeleteAccountsDialog } from './hooks/use-bulk-delete-accounts-dialog'; import withAccounts from './withAccounts'; import withAccountsTableActions from './withAccountsTableActions'; @@ -78,9 +79,15 @@ function AccountsActionsBar({ // Accounts refresh action. const { refresh } = useRefreshAccounts(); + // Bulk delete accounts dialog. + const { + openBulkDeleteDialog, + isValidatingBulkDeleteAccounts, + } = useBulkDeleteAccountsDialog(); + // Handle bulk accounts delete. const handleBulkDelete = () => { - openAlert('accounts-bulk-delete', { accountsIds: accountsSelectedRows }); + openBulkDeleteDialog(accountsSelectedRows); }; // Handle bulk accounts activate. const handelBulkActivate = () => { @@ -148,6 +155,7 @@ function AccountsActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteAccounts} /> diff --git a/packages/webapp/src/containers/Accounts/AccountsAlerts.tsx b/packages/webapp/src/containers/Accounts/AccountsAlerts.tsx index 8d6d24cc5..4f6f1cfaa 100644 --- a/packages/webapp/src/containers/Accounts/AccountsAlerts.tsx +++ b/packages/webapp/src/containers/Accounts/AccountsAlerts.tsx @@ -10,9 +10,6 @@ const AccountInactivateAlert = React.lazy( const AccountActivateAlert = React.lazy( () => import('@/containers/Alerts/Accounts/AccountActivateAlert'), ); -const AccountBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/Accounts/AccountBulkDeleteAlert'), -); const AccountBulkActivateAlert = React.lazy( () => import('@/containers/Alerts/Accounts/AccountBulkActivateAlert'), ); @@ -24,7 +21,6 @@ export default [ { name: 'account-delete', component: AccountDeleteAlert }, { name: 'account-inactivate', component: AccountInactivateAlert }, { name: 'account-activate', component: AccountActivateAlert }, - { name: 'accounts-bulk-delete', component: AccountBulkDeleteAlert }, { name: 'accounts-bulk-activate', component: AccountBulkActivateAlert }, { name: 'accounts-bulk-inactivate', component: AccountBulkInactivateAlert }, ]; diff --git a/packages/webapp/src/containers/Accounts/hooks/use-bulk-delete-accounts-dialog.ts b/packages/webapp/src/containers/Accounts/hooks/use-bulk-delete-accounts-dialog.ts new file mode 100644 index 000000000..2c69d8180 --- /dev/null +++ b/packages/webapp/src/containers/Accounts/hooks/use-bulk-delete-accounts-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteAccounts } from '@/hooks/query/accounts'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteAccountsDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteAccounts(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.AccountBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteAccounts: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Alerts/Accounts/AccountBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Accounts/AccountBulkDeleteAlert.tsx deleted file mode 100644 index dc889c115..000000000 --- a/packages/webapp/src/containers/Alerts/Accounts/AccountBulkDeleteAlert.tsx +++ /dev/null @@ -1,75 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { handleDeleteErrors } from '@/containers/Accounts/utils'; -import { useBulkDeleteAccounts } from '@/hooks/query/accounts'; - -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Account bulk delete alert. - */ -function AccountBulkDeleteAlert({ - // #ownProps - name, - - // #withAlertStoreConnect - isOpen, - payload: { accountsIds }, - - // #withAlertActions - closeAlert, -}) { - const { mutateAsync: bulkDeleteAccounts, isLoading } = useBulkDeleteAccounts(); - - const handleCancel = () => { - closeAlert(name); - }; - // Handle confirm accounts bulk delete. - const handleConfirmBulkDelete = () => { - bulkDeleteAccounts(accountsIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_accounts_has_been_successfully_deleted'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('accounts-table'); - closeAlert(name); - }) - .catch((errors) => { - handleDeleteErrors(errors); - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(AccountBulkDeleteAlert); diff --git a/packages/webapp/src/containers/Alerts/Bills/BillBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Bills/BillBulkDeleteAlert.tsx deleted file mode 100644 index 8ba15d370..000000000 --- a/packages/webapp/src/containers/Alerts/Bills/BillBulkDeleteAlert.tsx +++ /dev/null @@ -1,69 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteBills } from '@/hooks/query/bills'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Bill bulk delete alert. - */ -function BillBulkDeleteAlert({ - name, - isOpen, - payload: { billsIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteBills, isLoading } = useBulkDeleteBills(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteBills(billsIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_bills_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('bills-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(BillBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Alerts/CreditNotes/CreditNoteBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/CreditNotes/CreditNoteBulkDeleteAlert.tsx deleted file mode 100644 index 3366ed108..000000000 --- a/packages/webapp/src/containers/Alerts/CreditNotes/CreditNoteBulkDeleteAlert.tsx +++ /dev/null @@ -1,69 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteCreditNotes } from '@/hooks/query/creditNote'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Credit note bulk delete alert. - */ -function CreditNoteBulkDeleteAlert({ - name, - isOpen, - payload: { creditNotesIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteCreditNotes, isLoading } = useBulkDeleteCreditNotes(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteCreditNotes(creditNotesIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_credit_notes_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('credit-notes-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(CreditNoteBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Alerts/Estimates/EstimateBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Estimates/EstimateBulkDeleteAlert.tsx deleted file mode 100644 index 797cf19d7..000000000 --- a/packages/webapp/src/containers/Alerts/Estimates/EstimateBulkDeleteAlert.tsx +++ /dev/null @@ -1,69 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteEstimates } from '@/hooks/query/estimates'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Estimate bulk delete alert. - */ -function EstimateBulkDeleteAlert({ - name, - isOpen, - payload: { estimatesIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteEstimates, isLoading } = useBulkDeleteEstimates(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteEstimates(estimatesIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_estimates_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('estimates-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(EstimateBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Alerts/Expenses/ExpenseBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Expenses/ExpenseBulkDeleteAlert.tsx deleted file mode 100644 index 625d352da..000000000 --- a/packages/webapp/src/containers/Alerts/Expenses/ExpenseBulkDeleteAlert.tsx +++ /dev/null @@ -1,68 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteExpenses } from '@/hooks/query/expenses'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Expense bulk delete alert. - */ -function ExpenseBulkDeleteAlert({ - closeAlert, - name, - payload: { expensesIds }, - isOpen, -}) { - const { mutateAsync: bulkDeleteExpenses, isLoading } = useBulkDeleteExpenses(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteExpenses(expensesIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_expenses_have_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('expenses-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(ExpenseBulkDeleteAlert); diff --git a/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx deleted file mode 100644 index 80038bd3e..000000000 --- a/packages/webapp/src/containers/Alerts/Invoices/InvoiceBulkDeleteAlert.tsx +++ /dev/null @@ -1,69 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; - -import { AppToaster } from '@/components'; -import { useBulkDeleteInvoices } from '@/hooks/query/invoices'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Invoice bulk delete alert. - */ -function InvoiceBulkDeleteAlert({ - name, - isOpen, - payload: { invoicesIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteInvoices, isLoading } = useBulkDeleteInvoices(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteInvoices(invoicesIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_invoices_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('invoices-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(InvoiceBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Alerts/ManualJournals/JournalBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/ManualJournals/JournalBulkDeleteAlert.tsx deleted file mode 100644 index e7371dde6..000000000 --- a/packages/webapp/src/containers/Alerts/ManualJournals/JournalBulkDeleteAlert.tsx +++ /dev/null @@ -1,68 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteManualJournals } from '@/hooks/query/manualJournals'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Manual journal bulk delete alert. - */ -function JournalBulkDeleteAlert({ - name, - isOpen, - payload: { journalsIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteManualJournals, isLoading } = useBulkDeleteManualJournals(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteManualJournals(journalsIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_journals_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('manual-journals-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(JournalBulkDeleteAlert); diff --git a/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx deleted file mode 100644 index d65227ece..000000000 --- a/packages/webapp/src/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert.tsx +++ /dev/null @@ -1,68 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeletePaymentReceives } from '@/hooks/query/paymentReceives'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Payment received bulk delete alert. - */ -function PaymentReceivedBulkDeleteAlert({ - name, - isOpen, - payload: { paymentsReceivedIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeletePaymentReceives, isLoading } = useBulkDeletePaymentReceives(); - - const handleCancel = () => { - closeAlert(name); - }; - const handleConfirmBulkDelete = () => { - bulkDeletePaymentReceives(paymentsReceivedIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_payments_received_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('payments-received-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(PaymentReceivedBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Alerts/Receipts/ReceiptBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/Receipts/ReceiptBulkDeleteAlert.tsx deleted file mode 100644 index 3a6d02c66..000000000 --- a/packages/webapp/src/containers/Alerts/Receipts/ReceiptBulkDeleteAlert.tsx +++ /dev/null @@ -1,68 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteReceipts } from '@/hooks/query/receipts'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Receipt bulk delete alert. - */ -function ReceiptBulkDeleteAlert({ - name, - isOpen, - payload: { receiptsIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteReceipts, isLoading } = useBulkDeleteReceipts(); - - const handleCancel = () => { - closeAlert(name); - }; - const handleConfirmBulkDelete = () => { - bulkDeleteReceipts(receiptsIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_receipts_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('sale-receipts-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(ReceiptBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Alerts/VendorCeditNotes/VendorCreditBulkDeleteAlert.tsx b/packages/webapp/src/containers/Alerts/VendorCeditNotes/VendorCreditBulkDeleteAlert.tsx deleted file mode 100644 index 0f860bb0e..000000000 --- a/packages/webapp/src/containers/Alerts/VendorCeditNotes/VendorCreditBulkDeleteAlert.tsx +++ /dev/null @@ -1,69 +0,0 @@ -// @ts-nocheck -import React from 'react'; -import { FormattedMessage as T } from '@/components'; -import intl from 'react-intl-universal'; -import { Intent, Alert } from '@blueprintjs/core'; -import { queryCache } from 'react-query'; -import { AppToaster } from '@/components'; - -import { useBulkDeleteVendorCredits } from '@/hooks/query/vendorCredit'; -import withAlertStoreConnect from '@/containers/Alert/withAlertStoreConnect'; -import withAlertActions from '@/containers/Alert/withAlertActions'; - -import { compose } from '@/utils'; - -/** - * Vendor credit bulk delete alert. - */ -function VendorCreditBulkDeleteAlert({ - name, - isOpen, - payload: { vendorCreditsIds }, - closeAlert, -}) { - const { mutateAsync: bulkDeleteVendorCredits, isLoading } = useBulkDeleteVendorCredits(); - - const handleCancel = () => { - closeAlert(name); - }; - - const handleConfirmBulkDelete = () => { - bulkDeleteVendorCredits(vendorCreditsIds) - .then(() => { - AppToaster.show({ - message: intl.get('the_vendor_credits_has_been_deleted_successfully'), - intent: Intent.SUCCESS, - }); - queryCache.invalidateQueries('vendor-credits-table'); - closeAlert(name); - }) - .catch((errors) => { - // Handle errors - }); - }; - - return ( - } - confirmButtonText={ - - } - icon="trash" - intent={Intent.DANGER} - isOpen={isOpen} - onCancel={handleCancel} - onConfirm={handleConfirmBulkDelete} - loading={isLoading} - > - - - - - ); -} - -export default compose( - withAlertStoreConnect(), - withAlertActions, -)(VendorCreditBulkDeleteAlert); - diff --git a/packages/webapp/src/containers/Dialogs/Accounts/AccountBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/Accounts/AccountBulkDeleteDialog.tsx new file mode 100644 index 000000000..0111f9eb3 --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/Accounts/AccountBulkDeleteDialog.tsx @@ -0,0 +1,103 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteAccounts } from '@/hooks/query/accounts'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withAccountsTableActions from '@/containers/Accounts/withAccountsTableActions'; +import { compose } from '@/utils'; +import { handleDeleteErrors } from '@/containers/Accounts/utils'; + +function AccountBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withAccountsTableActions + setAccountsSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteAccounts, isLoading } = useBulkDeleteAccounts(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteAccounts({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_accounts_has_been_successfully_deleted'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('accounts-table'); + closeDialog(dialogName); + setAccountsSelectedRows([]); + }) + .catch((errors) => { + handleDeleteErrors(errors); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withAccountsTableActions, +)(AccountBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/Bills/BillBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/Bills/BillBulkDeleteDialog.tsx new file mode 100644 index 000000000..a484cb8a9 --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/Bills/BillBulkDeleteDialog.tsx @@ -0,0 +1,105 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteBills } from '@/hooks/query/bills'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withBillsActions from '@/containers/Purchases/Bills/BillsLanding/withBillsActions'; +import { compose } from '@/utils'; + +function BillBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withBillsActions + setBillsSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteBills, isLoading } = useBulkDeleteBills(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteBills({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_bills_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('bills-table'); + closeDialog(dialogName); + setBillsSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withBillsActions, +)(BillBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/CreditNotes/CreditNoteBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/CreditNotes/CreditNoteBulkDeleteDialog.tsx new file mode 100644 index 000000000..731cbcd8e --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/CreditNotes/CreditNoteBulkDeleteDialog.tsx @@ -0,0 +1,106 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteCreditNotes } from '@/hooks/query/creditNote'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withCreditNotesActions from '@/containers/Sales/CreditNotes/CreditNotesLanding/withCreditNotesActions'; +import { compose } from '@/utils'; + +function CreditNoteBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withCreditNotesActions + setCreditNotesSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteCreditNotes, isLoading } = + useBulkDeleteCreditNotes(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteCreditNotes({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_credit_notes_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('credit-notes-table'); + closeDialog(dialogName); + setCreditNotesSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withCreditNotesActions, +)(CreditNoteBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/Estimates/EstimateBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/Estimates/EstimateBulkDeleteDialog.tsx new file mode 100644 index 000000000..95aa299f4 --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/Estimates/EstimateBulkDeleteDialog.tsx @@ -0,0 +1,106 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteEstimates } from '@/hooks/query/estimates'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withEstimatesActions from '@/containers/Sales/Estimates/EstimatesLanding/withEstimatesActions'; +import { compose } from '@/utils'; + +function EstimateBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withEstimatesActions + setEstimatesSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteEstimates, isLoading } = + useBulkDeleteEstimates(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteEstimates({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_estimates_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('estimates-table'); + closeDialog(dialogName); + setEstimatesSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withEstimatesActions, +)(EstimateBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/Expenses/ExpenseBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/Expenses/ExpenseBulkDeleteDialog.tsx new file mode 100644 index 000000000..c8c3d22fe --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/Expenses/ExpenseBulkDeleteDialog.tsx @@ -0,0 +1,106 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteExpenses } from '@/hooks/query/expenses'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withExpensesActions from '@/containers/Expenses/ExpensesLanding/withExpensesActions'; +import { compose } from '@/utils'; + +function ExpenseBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withExpensesActions + setExpensesSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteExpenses, isLoading } = + useBulkDeleteExpenses(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteExpenses({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_expenses_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('expenses-table'); + closeDialog(dialogName); + setExpensesSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withExpensesActions, +)(ExpenseBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/Invoices/InvoiceBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/Invoices/InvoiceBulkDeleteDialog.tsx new file mode 100644 index 000000000..9b13c394b --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/Invoices/InvoiceBulkDeleteDialog.tsx @@ -0,0 +1,110 @@ +// @ts-nocheck +import React from 'react'; +import { FormattedMessage as T } from '@/components'; +import intl from 'react-intl-universal'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { queryCache } from 'react-query'; + +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withInvoiceActions from '@/containers/Sales/Invoices/InvoicesLanding/withInvoiceActions'; +import { useBulkDeleteInvoices } from '@/hooks/query/invoices'; +import { AppToaster } from '@/components'; +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; + +import { compose } from '@/utils'; + +/** + * Invoice bulk delete dialog. + */ +function InvoiceBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withInvoiceActions + resetInvoicesSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteInvoices, isLoading } = + useBulkDeleteInvoices(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteInvoices({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_invoices_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('invoices-table'); + closeDialog(dialogName); + resetInvoicesSelectedRows(); + }) + .catch((errors) => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withInvoiceActions, +)(InvoiceBulkDeleteDialog); diff --git a/packages/webapp/src/containers/Dialogs/ManualJournals/ManualJournalBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/ManualJournals/ManualJournalBulkDeleteDialog.tsx new file mode 100644 index 000000000..643333069 --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/ManualJournals/ManualJournalBulkDeleteDialog.tsx @@ -0,0 +1,108 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteManualJournals } from '@/hooks/query/manualJournals'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withManualJournalsActions from '@/containers/Accounting/JournalsLanding/withManualJournalsActions'; +import { compose } from '@/utils'; + +function ManualJournalBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withManualJournalsActions + setManualJournalsSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteManualJournals, isLoading } = + useBulkDeleteManualJournals(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteManualJournals({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_journals_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('manual-journals-table'); + closeDialog(dialogName); + setManualJournalsSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withManualJournalsActions, +)(ManualJournalBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/PaymentsReceived/PaymentReceivedBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/PaymentsReceived/PaymentReceivedBulkDeleteDialog.tsx new file mode 100644 index 000000000..7ef6743e1 --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/PaymentsReceived/PaymentReceivedBulkDeleteDialog.tsx @@ -0,0 +1,110 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeletePaymentReceives } from '@/hooks/query/paymentReceives'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withPaymentsReceivedActions from '@/containers/Sales/PaymentsReceived/PaymentsLanding/withPaymentsReceivedActions'; +import { compose } from '@/utils'; + +function PaymentReceivedBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withPaymentsReceivedActions + setPaymentReceivesSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeletePaymentReceives, isLoading } = + useBulkDeletePaymentReceives(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeletePaymentReceives({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get( + 'the_payments_received_has_been_deleted_successfully', + ), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('payments-received-table'); + closeDialog(dialogName); + setPaymentReceivesSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withPaymentsReceivedActions, +)(PaymentReceivedBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/Receipts/ReceiptBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/Receipts/ReceiptBulkDeleteDialog.tsx new file mode 100644 index 000000000..e5db5ab96 --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/Receipts/ReceiptBulkDeleteDialog.tsx @@ -0,0 +1,106 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteReceipts } from '@/hooks/query/receipts'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withReceiptsActions from '@/containers/Sales/Receipts/ReceiptsLanding/withReceiptsActions'; +import { compose } from '@/utils'; + +function ReceiptBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withReceiptsActions + setReceiptsSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteReceipts, isLoading } = + useBulkDeleteReceipts(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteReceipts({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get('the_receipts_has_been_deleted_successfully'), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('sale-receipts-table'); + closeDialog(dialogName); + setReceiptsSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withReceiptsActions, +)(ReceiptBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/VendorCredits/VendorCreditBulkDeleteDialog.tsx b/packages/webapp/src/containers/Dialogs/VendorCredits/VendorCreditBulkDeleteDialog.tsx new file mode 100644 index 000000000..27decd9ee --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/VendorCredits/VendorCreditBulkDeleteDialog.tsx @@ -0,0 +1,108 @@ +// @ts-nocheck +import React from 'react'; +import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { FormattedMessage as T, AppToaster } from '@/components'; +import intl from 'react-intl-universal'; +import { queryCache } from 'react-query'; + +import BulkDeleteDialogContent from '@/containers/Dialogs/components/BulkDeleteDialogContent'; +import { useBulkDeleteVendorCredits } from '@/hooks/query/vendorCredit'; +import withDialogRedux from '@/components/DialogReduxConnect'; +import withDialogActions from '@/containers/Dialog/withDialogActions'; +import withVendorsCreditNotesActions from '@/containers/Purchases/CreditNotes/CreditNotesLanding/withVendorsCreditNotesActions'; +import { compose } from '@/utils'; + +function VendorCreditBulkDeleteDialog({ + dialogName, + isOpen, + payload: { + ids = [], + deletableCount = 0, + undeletableCount = 0, + totalSelected = ids.length, + } = {}, + + // #withVendorsCreditNotesActions + setVendorsCreditNoteSelectedRows, + + // #withDialogActions + closeDialog, +}) { + const { mutateAsync: bulkDeleteVendorCredits, isLoading } = + useBulkDeleteVendorCredits(); + + const handleCancel = () => { + closeDialog(dialogName); + }; + + const handleConfirmBulkDelete = () => { + bulkDeleteVendorCredits({ + ids, + skipUndeletable: true, + }) + .then(() => { + AppToaster.show({ + message: intl.get( + 'the_vendor_credits_has_been_deleted_successfully', + ), + intent: Intent.SUCCESS, + }); + queryCache.invalidateQueries('vendor-credits-table'); + closeDialog(dialogName); + setVendorsCreditNoteSelectedRows([]); + }) + .catch(() => { + AppToaster.show({ + message: intl.get('something_went_wrong'), + intent: Intent.DANGER, + }); + }); + }; + + return ( + + } + isOpen={isOpen} + onClose={handleCancel} + canEscapeKeyClose={!isLoading} + canOutsideClickClose={!isLoading} + > + + + + + + + + + + + + + + + ); +} + +export default compose( + withDialogRedux(), + withDialogActions, + withVendorsCreditNotesActions, +)(VendorCreditBulkDeleteDialog); + diff --git a/packages/webapp/src/containers/Dialogs/components/BulkDeleteDialogContent.tsx b/packages/webapp/src/containers/Dialogs/components/BulkDeleteDialogContent.tsx new file mode 100644 index 000000000..6f3068abd --- /dev/null +++ b/packages/webapp/src/containers/Dialogs/components/BulkDeleteDialogContent.tsx @@ -0,0 +1,89 @@ +// @ts-nocheck +import React from 'react'; +import { Classes, Intent, Tag } from '@blueprintjs/core'; +import { FormattedMessage as T } from '@/components'; +import { x } from '@xstyled/emotion'; + +interface BulkDeleteDialogContentProps { + totalSelected: number; + deletableCount: number; + undeletableCount: number; + resourceSingularLabel: string; + resourcePluralLabel: string; +} + +function BulkDeleteDialogContent({ + totalSelected, + deletableCount, + undeletableCount, + resourceSingularLabel, + resourcePluralLabel, +}: BulkDeleteDialogContentProps) { + return ( + + + + + + + + {deletableCount} + + + {' '} + + + + + + + + + {undeletableCount} + + + {' '} + + + + + + + + + + + + + + {':'} + + + + + + + ); +} + +export default BulkDeleteDialogContent; + diff --git a/packages/webapp/src/containers/Expenses/ExpensesAlerts.tsx b/packages/webapp/src/containers/Expenses/ExpensesAlerts.tsx index 9283f2725..5b772b42c 100644 --- a/packages/webapp/src/containers/Expenses/ExpensesAlerts.tsx +++ b/packages/webapp/src/containers/Expenses/ExpensesAlerts.tsx @@ -8,15 +8,10 @@ const ExpensePublishAlert = React.lazy( () => import('@/containers/Alerts/Expenses/ExpensePublishAlert'), ); -const ExpenseBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/Expenses/ExpenseBulkDeleteAlert'), -); - /** * Accounts alert. */ export default [ { name: 'expense-delete', component: ExpenseDeleteAlert }, { name: 'expense-publish', component: ExpensePublishAlert }, - { name: 'expenses-bulk-delete', component: ExpenseBulkDeleteAlert }, ]; diff --git a/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx b/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx index faa460978..3aaa86217 100644 --- a/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx +++ b/packages/webapp/src/containers/Expenses/ExpensesLanding/ExpenseActionsBar.tsx @@ -34,10 +34,10 @@ import withExpensesActions from './withExpensesActions'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; import withSettings from '@/containers/Settings/withSettings'; -import withAlertActions from '@/containers/Alert/withAlertActions'; import { compose } from '@/utils'; import { isEmpty } from 'lodash'; +import { useBulkDeleteExpensesDialog } from './hooks/use-bulk-delete-expenses-dialog'; /** * Expenses actions bar. @@ -58,9 +58,6 @@ function ExpensesActionsBar({ // #withDialogActions openDialog, - - // #withAlertActions - openAlert, }) { // History context. const history = useHistory(); @@ -78,11 +75,14 @@ function ExpensesActionsBar({ const onClickNewExpense = () => { history.push('/expenses/new'); }; + const { + openBulkDeleteDialog, + isValidatingBulkDeleteExpenses, + } = useBulkDeleteExpensesDialog(); + // Handle delete button click. const handleBulkDelete = () => { - openAlert('expenses-bulk-delete', { - expensesIds: expensesSelectedRows, - }); + openBulkDeleteDialog(expensesSelectedRows); }; // Handles the tab chaning. @@ -122,6 +122,7 @@ function ExpensesActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteExpenses} /> @@ -209,7 +210,6 @@ function ExpensesActionsBar({ export default compose( withDialogActions, - withAlertActions, withExpensesActions, withSettingsActions, withExpenses(({ expensesTableState, expensesSelectedRows }) => ({ diff --git a/packages/webapp/src/containers/Expenses/ExpensesLanding/hooks/use-bulk-delete-expenses-dialog.ts b/packages/webapp/src/containers/Expenses/ExpensesLanding/hooks/use-bulk-delete-expenses-dialog.ts new file mode 100644 index 000000000..dcb7c18b2 --- /dev/null +++ b/packages/webapp/src/containers/Expenses/ExpensesLanding/hooks/use-bulk-delete-expenses-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteExpenses } from '@/hooks/query/expenses'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteExpensesDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteExpenses(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.ExpenseBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteExpenses: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsActionsBar.tsx b/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsActionsBar.tsx index 94bdd7bea..3e7e39193 100644 --- a/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsActionsBar.tsx +++ b/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsActionsBar.tsx @@ -29,11 +29,13 @@ import withBillsActions from './withBillsActions'; import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; -import withAlertActions from '@/containers/Alert/withAlertActions'; import { useBillsListContext } from './BillsListProvider'; -import { useRefreshBills } from '@/hooks/query/bills'; +import { + useRefreshBills, +} from '@/hooks/query/bills'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; +import { useBulkDeleteBillsDialog } from './hooks/use-bulk-delete-bills-dialog'; import { compose } from '@/utils'; import { DialogsName } from '@/constants/dialogs'; @@ -58,9 +60,6 @@ function BillActionsBar({ // #withDialogActions openDialog, - - // #withAlertActions - openAlert, }) { const history = useHistory(); @@ -103,9 +102,14 @@ function BillActionsBar({ const handlePrintBtnClick = () => { downloadExportPdf({ resource: 'Bill' }); }; + const { + openBulkDeleteDialog, + isValidatingBulkDeleteBills, + } = useBulkDeleteBillsDialog(); + // Handle bulk delete. const handleBulkDelete = () => { - openAlert('bills-bulk-delete', { billsIds: billsSelectedRows }); + openBulkDeleteDialog(billsSelectedRows); }; if (!isEmpty(billsSelectedRows)) { @@ -118,6 +122,7 @@ function BillActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteBills} /> @@ -214,5 +219,4 @@ export default compose( billsTableSize: billsettings?.tableSize, })), withDialogActions, - withAlertActions, )(BillActionsBar); diff --git a/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsAlerts.tsx b/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsAlerts.tsx index 791cb5cb4..266075f52 100644 --- a/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsAlerts.tsx +++ b/packages/webapp/src/containers/Purchases/Bills/BillsLanding/BillsAlerts.tsx @@ -12,10 +12,6 @@ const BillLocatedLandedCostDeleteAlert = React.lazy( () => import('@/containers/Alerts/Bills/BillLocatedLandedCostDeleteAlert'), ); -const BillBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/Bills/BillBulkDeleteAlert'), -); - export default [ { name: 'bill-delete', component: BillDeleteAlert }, { name: 'bill-open', component: BillOpenAlert }, @@ -23,5 +19,4 @@ export default [ name: 'bill-located-cost-delete', component: BillLocatedLandedCostDeleteAlert, }, - { name: 'bills-bulk-delete', component: BillBulkDeleteAlert }, ]; diff --git a/packages/webapp/src/containers/Purchases/Bills/BillsLanding/hooks/use-bulk-delete-bills-dialog.ts b/packages/webapp/src/containers/Purchases/Bills/BillsLanding/hooks/use-bulk-delete-bills-dialog.ts new file mode 100644 index 000000000..80008c167 --- /dev/null +++ b/packages/webapp/src/containers/Purchases/Bills/BillsLanding/hooks/use-bulk-delete-bills-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteBills } from '@/hooks/query/bills'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteBillsDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteBills(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.BillBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteBills: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteActionsBar.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteActionsBar.tsx index 75bbcacd6..9978092cd 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteActionsBar.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteActionsBar.tsx @@ -1,6 +1,7 @@ // @ts-nocheck import React from 'react'; import { useHistory } from 'react-router-dom'; +import { isEmpty } from 'lodash'; import { Button, Classes, @@ -32,7 +33,6 @@ import { VendorCreditAction, AbilitySubject } from '@/constants/abilityOption'; import withVendorsCreditNotesActions from './withVendorsCreditNotesActions'; import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; -import withVendorsCreditNotes from './withVendorsCreditNotes'; import withDialogActions from '@/containers/Dialog/withDialogActions'; import withVendorActions from './withVendorActions'; import withDrawerActions from '@/containers/Drawer/withDrawerActions'; @@ -40,6 +40,8 @@ import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import { compose } from '@/utils'; import { DialogsName } from '@/constants/dialogs'; import { DRAWERS } from '@/constants/drawers'; +import withVendorsCreditNotes from './withVendorsCreditNotes'; +import { useBulkDeleteVendorCreditsDialog } from './hooks/use-bulk-delete-vendor-credits-dialog'; /** * Vendors Credit note table actions bar. @@ -49,6 +51,7 @@ function VendorsCreditNoteActionsBar({ // #withVendorsCreditNotes vendorCreditFilterRoles, + vendorsCreditNoteSelectedRows, // #withVendorsCreditNotesActions setVendorsCreditNoteTableState, @@ -107,6 +110,32 @@ function VendorsCreditNoteActionsBar({ openDrawer(DRAWERS.CREDIT_NOTE_DETAILS); }; + const { + openBulkDeleteDialog, + isValidatingBulkDeleteVendorCredits, + } = useBulkDeleteVendorCreditsDialog(); + + if (!isEmpty(vendorsCreditNoteSelectedRows)) { + const handleBulkDelete = () => { + openBulkDeleteDialog(vendorsCreditNoteSelectedRows); + }; + + return ( + + + } + text={} + intent={Intent.DANGER} + onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteVendorCredits} + /> + + + ); + } + return ( @@ -199,9 +228,12 @@ export default compose( withVendorsCreditNotesActions, withVendorActions, withSettingsActions, - withVendorsCreditNotes(({ vendorsCreditNoteTableState }) => ({ - vendorCreditFilterRoles: vendorsCreditNoteTableState.filterRoles, - })), + withVendorsCreditNotes( + ({ vendorsCreditNoteTableState, vendorsCreditNoteSelectedRows }) => ({ + vendorCreditFilterRoles: vendorsCreditNoteTableState.filterRoles, + vendorsCreditNoteSelectedRows, + }), + ), withSettings(({ vendorsCreditNoteSetting }) => ({ creditNoteTableSize: vendorsCreditNoteSetting?.tableSize, })), diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteDataTable.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteDataTable.tsx index 8d95d1da4..8d631d26a 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteDataTable.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/CreditNotesLanding/VendorsCreditNoteDataTable.tsx @@ -32,6 +32,7 @@ import { DRAWERS } from '@/constants/drawers'; function VendorsCreditNoteDataTable({ // #withVendorsCreditNotesActions setVendorsCreditNoteTableState, + setVendorsCreditNoteSelectedRows, // #withVendorCredits vendorsCreditNoteTableState, @@ -119,6 +120,11 @@ function VendorsCreditNoteDataTable({ openDialog('reconcile-vendor-credit', { vendorCreditId: id }); }; + const handleSelectedRowsChange = (selectedFlatRows) => { + const selectedIds = selectedFlatRows?.map((row) => row.original.id) || []; + setVendorsCreditNoteSelectedRows(selectedIds); + }; + return ( { + const validateBulkDeleteMutation = useValidateBulkDeleteVendorCredits(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.VendorCreditBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteVendorCredits: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Purchases/CreditNotes/VendorCreditNotesAlerts.tsx b/packages/webapp/src/containers/Purchases/CreditNotes/VendorCreditNotesAlerts.tsx index 91ed133b0..d5ebabcd3 100644 --- a/packages/webapp/src/containers/Purchases/CreditNotes/VendorCreditNotesAlerts.tsx +++ b/packages/webapp/src/containers/Purchases/CreditNotes/VendorCreditNotesAlerts.tsx @@ -23,11 +23,6 @@ const ReconcileVendorCreditDeleteAlert = React.lazy( ), ); -const VendorCreditBulkDeleteAlert = React.lazy( - () => - import('@/containers/Alerts/VendorCeditNotes/VendorCreditBulkDeleteAlert'), -); - /** * Vendor Credit notes alerts. */ @@ -48,8 +43,4 @@ export default [ name: 'reconcile-vendor-delete', component: ReconcileVendorCreditDeleteAlert, }, - { - name: 'vendor-credits-bulk-delete', - component: VendorCreditBulkDeleteAlert, - }, ]; diff --git a/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesAlerts.tsx b/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesAlerts.tsx index a2c8631e0..01c20a7c6 100644 --- a/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesAlerts.tsx +++ b/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesAlerts.tsx @@ -18,10 +18,6 @@ const ReconcileCreditDeleteAlert = React.lazy( import('@/containers/Alerts/CreditNotes/ReconcileCreditNoteDeleteAlert'), ); -const CreditNoteBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/CreditNotes/CreditNoteBulkDeleteAlert'), -); - /** * Credit notes alerts. */ @@ -42,8 +38,4 @@ export default [ name: 'reconcile-credit-delete', component: ReconcileCreditDeleteAlert, }, - { - name: 'credit-notes-bulk-delete', - component: CreditNoteBulkDeleteAlert, - }, ]; diff --git a/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesActionsBar.tsx b/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesActionsBar.tsx index 2c574e6b4..f78751b31 100644 --- a/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesActionsBar.tsx +++ b/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/CreditNotesActionsBar.tsx @@ -36,11 +36,11 @@ import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; import withDrawerActions from '@/containers/Drawer/withDrawerActions'; -import withAlertActions from '@/containers/Alert/withAlertActions'; import { DialogsName } from '@/constants/dialogs'; import { compose } from '@/utils'; import { DRAWERS } from '@/constants/drawers'; +import { useBulkDeleteCreditNotesDialog } from './hooks/use-bulk-delete-credit-notes-dialog'; /** * Credit note table actions bar. @@ -64,9 +64,6 @@ function CreditNotesActionsBar({ // #withDrawerActions openDrawer, - - // #withAlertActions - openAlert, }) { const history = useHistory(); @@ -111,10 +108,15 @@ function CreditNotesActionsBar({ openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'CreditNote' }); } + const { + openBulkDeleteDialog, + isValidatingBulkDeleteCreditNotes, + } = useBulkDeleteCreditNotesDialog(); + // Show bulk delete button when rows are selected. if (!isEmpty(creditNotesSelectedRows)) { const handleBulkDelete = () => { - openAlert('credit-notes-bulk-delete', { creditNotesIds: creditNotesSelectedRows }); + openBulkDeleteDialog(creditNotesSelectedRows); }; return ( @@ -125,6 +127,7 @@ function CreditNotesActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteCreditNotes} /> @@ -231,5 +234,4 @@ export default compose( })), withDialogActions, withDrawerActions, - withAlertActions, )(CreditNotesActionsBar); diff --git a/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/hooks/use-bulk-delete-credit-notes-dialog.ts b/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/hooks/use-bulk-delete-credit-notes-dialog.ts new file mode 100644 index 000000000..a2eb9aed9 --- /dev/null +++ b/packages/webapp/src/containers/Sales/CreditNotes/CreditNotesLanding/hooks/use-bulk-delete-credit-notes-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteCreditNotes } from '@/hooks/query/creditNote'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteCreditNotesDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteCreditNotes(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.CreditNoteBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteCreditNotes: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimatesAlerts.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimatesAlerts.tsx index 09c702651..730ad3043 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimatesAlerts.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimatesAlerts.tsx @@ -14,10 +14,6 @@ const EstimateRejectAlert = React.lazy( () => import('@/containers/Alerts/Estimates/EstimateRejectAlert'), ); -const EstimateBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/Estimates/EstimateBulkDeleteAlert'), -); - /** * Estimates alert. */ @@ -26,5 +22,4 @@ export default [ { name: 'estimate-deliver', component: EstimateDeliveredAlert }, { name: 'estimate-Approve', component: EstimateApproveAlert }, { name: 'estimate-reject', component: EstimateRejectAlert }, - { name: 'estimates-bulk-delete', component: EstimateBulkDeleteAlert }, ]; diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/EstimatesActionsBar.tsx b/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/EstimatesActionsBar.tsx index 19d20d0f9..568759a9e 100644 --- a/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/EstimatesActionsBar.tsx +++ b/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/EstimatesActionsBar.tsx @@ -33,11 +33,13 @@ import withEstimatesActions from './withEstimatesActions'; import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; -import withAlertActions from '@/containers/Alert/withAlertActions'; import { useEstimatesListContext } from './EstimatesListProvider'; -import { useRefreshEstimates } from '@/hooks/query/estimates'; +import { + useRefreshEstimates, +} from '@/hooks/query/estimates'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; +import { useBulkDeleteEstimatesDialog } from './hooks/use-bulk-delete-estimates-dialog'; import { SaleEstimateAction, AbilitySubject } from '@/constants/abilityOption'; import { compose } from '@/utils'; @@ -72,9 +74,6 @@ function EstimateActionsBar({ // #withSettingsActions addSetting, - - // #withAlertActions - openAlert, }) { const history = useHistory(); @@ -122,13 +121,16 @@ function EstimateActionsBar({ openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'SaleEstimate' }); }; + const { + openBulkDeleteDialog, + isValidatingBulkDeleteEstimates, + } = useBulkDeleteEstimatesDialog(); + // Handle bulk estimates delete. const handleBulkDelete = () => { - openAlert('estimates-bulk-delete', { estimatesIds: estimatesSelectedRows }); + openBulkDeleteDialog(estimatesSelectedRows); }; - console.log(estimatesSelectedRows, 'estimatesSelectedRows'); - if (!isEmpty(estimatesSelectedRows)) { return ( @@ -139,6 +141,7 @@ function EstimateActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteEstimates} /> @@ -238,7 +241,6 @@ function EstimateActionsBar({ export default compose( withEstimatesActions, withSettingsActions, - withAlertActions, withEstimates(({ estimatesTableState, estimatesSelectedRows }) => ({ estimatesFilterRoles: estimatesTableState.filterRoles, estimatesSelectedRows: estimatesSelectedRows || [], diff --git a/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/hooks/use-bulk-delete-estimates-dialog.ts b/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/hooks/use-bulk-delete-estimates-dialog.ts new file mode 100644 index 000000000..b6ee56ef7 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Estimates/EstimatesLanding/hooks/use-bulk-delete-estimates-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteEstimates } from '@/hooks/query/estimates'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteEstimatesDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteEstimates(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.EstimateBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteEstimates: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoicesAlerts.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoicesAlerts.tsx index 0e5d0eb08..d337f0222 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoicesAlerts.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoicesAlerts.tsx @@ -12,10 +12,6 @@ const CancelBadDebtAlert = React.lazy( () => import('@/containers/Alerts/Invoices/CancelBadDebtAlert'), ); -const InvoiceBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/Invoices/InvoiceBulkDeleteAlert'), -); - /** * Invoices alert. */ @@ -23,5 +19,4 @@ export default [ { name: 'invoice-delete', component: InvoiceDeleteAlert }, { name: 'invoice-deliver', component: InvoiceDeliverAlert }, { name: 'cancel-bad-debt', component: CancelBadDebtAlert }, - { name: 'invoices-bulk-delete', component: InvoiceBulkDeleteAlert }, ]; diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/InvoicesActionsBar.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/InvoicesActionsBar.tsx index 5faede56f..7de18ebf4 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/InvoicesActionsBar.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/InvoicesActionsBar.tsx @@ -29,12 +29,12 @@ import { SaleInvoiceAction, AbilitySubject } from '@/constants/abilityOption'; import { useRefreshInvoices } from '@/hooks/query/invoices'; import { useInvoicesListContext } from './InvoicesListProvider'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; +import { useBulkDeleteInvoicesDialog } from '../hooks/use-bulk-delete-accounts-dialog'; import withInvoices from './withInvoices'; import withInvoiceActions from './withInvoiceActions'; import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; -import withAlertActions from '@/containers/Alert/withAlertActions'; import { compose } from '@/utils'; import withDialogActions from '@/containers/Dialog/withDialogActions'; import { DialogsName } from '@/constants/dialogs'; @@ -65,10 +65,12 @@ function InvoiceActionsBar({ // #withDrawerActions openDrawer, - // #withAlertActions - openAlert, }) { const history = useHistory(); + const { + openBulkDeleteDialog, + isValidatingBulkDeleteInvoices, + } = useBulkDeleteInvoicesDialog(); // Sale invoices list context. const { invoicesViews, invoicesFields } = useInvoicesListContext(); @@ -120,7 +122,7 @@ function InvoiceActionsBar({ // Handle bulk invoices delete. const handleBulkDelete = () => { - openAlert('invoices-bulk-delete', { invoicesIds: invoicesSelectedRows }); + openBulkDeleteDialog(invoicesSelectedRows); }; if (!isEmpty(invoicesSelectedRows)) { @@ -133,6 +135,7 @@ function InvoiceActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteInvoices} /> @@ -229,7 +232,6 @@ function InvoiceActionsBar({ export default compose( withInvoiceActions, withSettingsActions, - withAlertActions, withInvoices(({ invoicesTableState, invoicesSelectedRows }) => ({ invoicesFilterRoles: invoicesTableState.filterRoles, invoicesSelectedRows, diff --git a/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/withInvoiceActions.tsx b/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/withInvoiceActions.tsx index 17d7d0209..3b10bcf25 100644 --- a/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/withInvoiceActions.tsx +++ b/packages/webapp/src/containers/Sales/Invoices/InvoicesLanding/withInvoiceActions.tsx @@ -4,12 +4,14 @@ import { setInvoicesTableState, resetInvoicesTableState, setInvoicesSelectedRows, + resetInvoicesSelectedRows, } from '@/store/Invoice/invoices.actions'; const mapDipatchToProps = (dispatch) => ({ setInvoicesTableState: (queries) => dispatch(setInvoicesTableState(queries)), resetInvoicesTableState: () => dispatch(resetInvoicesTableState()), setInvoicesSelectedRows: (selectedRows) => dispatch(setInvoicesSelectedRows(selectedRows)), + resetInvoicesSelectedRows: () => dispatch(resetInvoicesSelectedRows()), }); export default connect(null, mapDipatchToProps); diff --git a/packages/webapp/src/containers/Sales/Invoices/hooks/use-bulk-delete-accounts-dialog.ts b/packages/webapp/src/containers/Sales/Invoices/hooks/use-bulk-delete-accounts-dialog.ts new file mode 100644 index 000000000..4069d9f32 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Invoices/hooks/use-bulk-delete-accounts-dialog.ts @@ -0,0 +1,19 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteInvoices } from '@/hooks/query/invoices'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteInvoicesDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteInvoices(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.InvoiceBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteInvoices: isValidatingBulkDelete, + }; +}; \ No newline at end of file diff --git a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx index 1f4ed0c54..cc8a9fb9e 100644 --- a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx +++ b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/PaymentsReceivedActionsBar.tsx @@ -27,7 +27,6 @@ import { DashboardActionsBar, } from '@/components'; -import withAlertsActions from '@/containers/Alert/withAlertActions'; import withPaymentsReceived from './withPaymentsReceived'; import withPaymentsReceivedActions from './withPaymentsReceivedActions'; import withSettings from '@/containers/Settings/withSettings'; @@ -46,6 +45,7 @@ import { compose } from '@/utils'; import { DialogsName } from '@/constants/dialogs'; import withDrawerActions from '@/containers/Drawer/withDrawerActions'; import { DRAWERS } from '@/constants/drawers'; +import { useBulkDeletePaymentReceivesDialog } from './hooks/use-bulk-delete-payment-receives-dialog'; /** * Payment receives actions bar. @@ -69,9 +69,6 @@ function PaymentsReceivedActionsBar({ // #withDrawerActions openDrawer, - - // #withAlertsActions - openAlert, }) { // History context. const history = useHistory(); @@ -119,9 +116,14 @@ function PaymentsReceivedActionsBar({ openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'PaymentReceive' }); }; + const { + openBulkDeleteDialog, + isValidatingBulkDeletePaymentReceives, + } = useBulkDeletePaymentReceivesDialog(); + if (!isEmpty(paymentReceivesSelectedRows)) { const handleBulkDelete = () => { - openAlert('payments-received-bulk-delete', { paymentsReceivedIds: paymentReceivesSelectedRows }); + openBulkDeleteDialog(paymentReceivesSelectedRows); }; return ( @@ -132,6 +134,7 @@ function PaymentsReceivedActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeletePaymentReceives} /> @@ -237,5 +240,4 @@ export default compose( })), withDialogActions, withDrawerActions, - withAlertsActions, )(PaymentsReceivedActionsBar); diff --git a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/hooks/use-bulk-delete-payment-receives-dialog.ts b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/hooks/use-bulk-delete-payment-receives-dialog.ts new file mode 100644 index 000000000..7a75e784b --- /dev/null +++ b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsLanding/hooks/use-bulk-delete-payment-receives-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeletePaymentReceives } from '@/hooks/query/paymentReceives'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeletePaymentReceivesDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeletePaymentReceives(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.PaymentReceivedBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeletePaymentReceives: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsReceivedAlerts.tsx b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsReceivedAlerts.tsx index 027d52436..304ae7f2c 100644 --- a/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsReceivedAlerts.tsx +++ b/packages/webapp/src/containers/Sales/PaymentsReceived/PaymentsReceivedAlerts.tsx @@ -5,18 +5,9 @@ const PaymentReceivedDeleteAlert = React.lazy( () => import('@/containers/Alerts/PaymentReceived/PaymentReceivedDeleteAlert'), ); -const PaymentReceivedBulkDeleteAlert = React.lazy( - () => - import('@/containers/Alerts/PaymentReceived/PaymentReceivedBulkDeleteAlert'), -); - /** * PaymentReceives alert. */ export default [ { name: 'payment-received-delete', component: PaymentReceivedDeleteAlert }, - { - name: 'payments-received-bulk-delete', - component: PaymentReceivedBulkDeleteAlert, - }, ]; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptsAlerts.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptsAlerts.tsx index f2503466b..a7dec7a36 100644 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptsAlerts.tsx +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptsAlerts.tsx @@ -7,15 +7,10 @@ const ReceiptDeleteAlert = React.lazy( const ReceiptCloseAlert = React.lazy( () => import('@/containers/Alerts/Receipts/ReceiptCloseAlert'), ); -const ReceiptBulkDeleteAlert = React.lazy( - () => import('@/containers/Alerts/Receipts/ReceiptBulkDeleteAlert'), -); - /** * Receipts alerts. */ export default [ { name: 'receipt-delete', component: ReceiptDeleteAlert }, { name: 'receipt-close', component: ReceiptCloseAlert }, - { name: 'receipts-bulk-delete', component: ReceiptBulkDeleteAlert }, ]; diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptActionsBar.tsx b/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptActionsBar.tsx index 02c3596b3..ce8476135 100644 --- a/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptActionsBar.tsx +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/ReceiptActionsBar.tsx @@ -35,12 +35,14 @@ import withReceiptsActions from './withReceiptsActions'; import withSettings from '@/containers/Settings/withSettings'; import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withDialogActions from '@/containers/Dialog/withDialogActions'; -import withAlertActions from '@/containers/Alert/withAlertActions'; import { useReceiptsListContext } from './ReceiptsListProvider'; -import { useRefreshReceipts } from '@/hooks/query/receipts'; +import { + useRefreshReceipts, +} from '@/hooks/query/receipts'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption'; +import { useBulkDeleteReceiptsDialog } from './hooks/use-bulk-delete-receipts-dialog'; import { DialogsName } from '@/constants/dialogs'; import { compose } from '@/utils'; @@ -71,9 +73,6 @@ function ReceiptActionsBar({ // #withSettingsActions addSetting, - - // #withAlertActions - openAlert, }) { const history = useHistory(); @@ -125,9 +124,14 @@ function ReceiptActionsBar({ openDrawer(DRAWERS.BRANDING_TEMPLATES, { resource: 'SaleReceipt' }); }; + const { + openBulkDeleteDialog, + isValidatingBulkDeleteReceipts, + } = useBulkDeleteReceiptsDialog(); + if (!isEmpty(receiptSelectedRows)) { const handleBulkDelete = () => { - openAlert('receipts-bulk-delete', { receiptsIds: receiptSelectedRows }); + openBulkDeleteDialog(receiptSelectedRows); }; return ( @@ -138,6 +142,7 @@ function ReceiptActionsBar({ text={} intent={Intent.DANGER} onClick={handleBulkDelete} + disabled={isValidatingBulkDeleteReceipts} /> @@ -254,5 +259,4 @@ export default compose( })), withDialogActions, withDrawerActions, - withAlertActions, )(ReceiptActionsBar); diff --git a/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/hooks/use-bulk-delete-receipts-dialog.ts b/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/hooks/use-bulk-delete-receipts-dialog.ts new file mode 100644 index 000000000..d5305b7c9 --- /dev/null +++ b/packages/webapp/src/containers/Sales/Receipts/ReceiptsLanding/hooks/use-bulk-delete-receipts-dialog.ts @@ -0,0 +1,20 @@ +// @ts-nocheck +import { DialogsName } from '@/constants/dialogs'; +import { useValidateBulkDeleteReceipts } from '@/hooks/query/receipts'; +import { useBulkDeleteDialog } from '@/hooks/dialogs/useBulkDeleteDialog'; + +export const useBulkDeleteReceiptsDialog = () => { + const validateBulkDeleteMutation = useValidateBulkDeleteReceipts(); + const { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete, + } = useBulkDeleteDialog(DialogsName.ReceiptBulkDelete, validateBulkDeleteMutation); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDeleteReceipts: isValidatingBulkDelete, + }; +}; + diff --git a/packages/webapp/src/hooks/dialogs/useBulkDeleteDialog.ts b/packages/webapp/src/hooks/dialogs/useBulkDeleteDialog.ts new file mode 100644 index 000000000..dbbdd2ae1 --- /dev/null +++ b/packages/webapp/src/hooks/dialogs/useBulkDeleteDialog.ts @@ -0,0 +1,43 @@ +// @ts-nocheck +import { useCallback } from 'react'; +import { DialogsName } from '@/constants/dialogs'; +import { useDialogActions } from '@/hooks/state'; + +export const useBulkDeleteDialog = ( + dialogName: DialogsName, + validateBulkDeleteMutation, +) => { + const { openDialog, closeDialog } = useDialogActions(); + const { mutateAsync: validateBulkDelete, isLoading } = + validateBulkDeleteMutation; + + const openBulkDeleteDialog = useCallback( + async (ids: number[]) => { + if (!ids?.length) { + return; + } + const { deletableCount = 0, nonDeletableCount = 0 } = + await validateBulkDelete(ids); + + const totalSelected = deletableCount + nonDeletableCount || ids.length; + + openDialog(dialogName, { + ids, + deletableCount, + undeletableCount: nonDeletableCount, + totalSelected, + }); + }, + [dialogName, openDialog, validateBulkDelete], + ); + + const closeBulkDeleteDialog = useCallback(() => { + closeDialog(dialogName); + }, [closeDialog, dialogName]); + + return { + openBulkDeleteDialog, + closeBulkDeleteDialog, + isValidatingBulkDelete: isLoading, + }; +}; diff --git a/packages/webapp/src/hooks/query/accounts.tsx b/packages/webapp/src/hooks/query/accounts.tsx index b1485b748..da4e3bef0 100644 --- a/packages/webapp/src/hooks/query/accounts.tsx +++ b/packages/webapp/src/hooks/query/accounts.tsx @@ -158,7 +158,22 @@ export function useBulkDeleteAccounts(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('accounts/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'accounts/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. diff --git a/packages/webapp/src/hooks/query/bills.tsx b/packages/webapp/src/hooks/query/bills.tsx index e4fca9491..290548432 100644 --- a/packages/webapp/src/hooks/query/bills.tsx +++ b/packages/webapp/src/hooks/query/bills.tsx @@ -140,6 +140,20 @@ export function useBulkDeleteBills(props) { ); } +export function useValidateBulkDeleteBills(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('bills/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + const transformBillsResponse = (response) => ({ bills: response.data.bills, pagination: transformPagination(response.data.pagination), diff --git a/packages/webapp/src/hooks/query/creditNote.tsx b/packages/webapp/src/hooks/query/creditNote.tsx index 77802a0c6..e88406498 100644 --- a/packages/webapp/src/hooks/query/creditNote.tsx +++ b/packages/webapp/src/hooks/query/creditNote.tsx @@ -119,7 +119,22 @@ export function useBulkDeleteCreditNotes(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('credit-notes/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'credit-notes/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -130,6 +145,20 @@ export function useBulkDeleteCreditNotes(props) { ); } +export function useValidateBulkDeleteCreditNotes(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('credit-notes/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + const transformCreditNotes = (res) => ({ creditNotes: res.data.credit_notes, pagination: transformPagination(res.data.pagination), diff --git a/packages/webapp/src/hooks/query/estimates.tsx b/packages/webapp/src/hooks/query/estimates.tsx index 27b004418..486f3c34a 100644 --- a/packages/webapp/src/hooks/query/estimates.tsx +++ b/packages/webapp/src/hooks/query/estimates.tsx @@ -132,7 +132,22 @@ export function useBulkDeleteEstimates(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('sale-estimates/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'sale-estimates/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -143,6 +158,20 @@ export function useBulkDeleteEstimates(props) { ); } +export function useValidateBulkDeleteEstimates(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('sale-estimates/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + /** * Mark the given estimate as delivered. */ diff --git a/packages/webapp/src/hooks/query/expenses.tsx b/packages/webapp/src/hooks/query/expenses.tsx index e473da6c0..3e1e3d11d 100644 --- a/packages/webapp/src/hooks/query/expenses.tsx +++ b/packages/webapp/src/hooks/query/expenses.tsx @@ -110,7 +110,22 @@ export function useBulkDeleteExpenses(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('expenses/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'expenses/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -121,6 +136,20 @@ export function useBulkDeleteExpenses(props) { ); } +export function useValidateBulkDeleteExpenses(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('expenses/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + /** * Edits the given expense. */ diff --git a/packages/webapp/src/hooks/query/invoices.tsx b/packages/webapp/src/hooks/query/invoices.tsx index eca7a2667..bd8f2272f 100644 --- a/packages/webapp/src/hooks/query/invoices.tsx +++ b/packages/webapp/src/hooks/query/invoices.tsx @@ -133,7 +133,22 @@ export function useBulkDeleteInvoices(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('sale-invoices/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'sale-invoices/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -144,6 +159,35 @@ export function useBulkDeleteInvoices(props) { ); } +export interface ValidateBulkDeleteInvoicesResponse { + deletableCount: number; + nonDeletableCount: number; + deletableIds: number[]; + nonDeletableIds: number[]; +} + +export function useValidateBulkDeleteInvoices( + props?: UseMutationOptions< + ValidateBulkDeleteInvoicesResponse, + Error, + number[] + >, +) { + const apiRequest = useApiRequest(); + + return useMutation< + ValidateBulkDeleteInvoicesResponse, + Error, + number[] + >( + (ids) => + apiRequest + .post('sale-invoices/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + props, + ); +} + const transformInvoices = (res) => ({ invoices: res.data.sales_invoices, pagination: transformPagination(res.data.pagination), diff --git a/packages/webapp/src/hooks/query/manualJournals.tsx b/packages/webapp/src/hooks/query/manualJournals.tsx index a4384e061..0f3f3d95e 100644 --- a/packages/webapp/src/hooks/query/manualJournals.tsx +++ b/packages/webapp/src/hooks/query/manualJournals.tsx @@ -96,7 +96,22 @@ export function useBulkDeleteManualJournals(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('manual-journals/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'manual-journals/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -107,6 +122,20 @@ export function useBulkDeleteManualJournals(props) { ); } +export function useValidateBulkDeleteManualJournals(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('manual-journals/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + /** * Publishes the given manual journal. */ diff --git a/packages/webapp/src/hooks/query/paymentReceives.tsx b/packages/webapp/src/hooks/query/paymentReceives.tsx index cb4a844c1..dfa8e663b 100644 --- a/packages/webapp/src/hooks/query/paymentReceives.tsx +++ b/packages/webapp/src/hooks/query/paymentReceives.tsx @@ -158,7 +158,22 @@ export function useBulkDeletePaymentReceives(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('payments-received/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'payments-received/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -169,6 +184,20 @@ export function useBulkDeletePaymentReceives(props) { ); } +export function useValidateBulkDeletePaymentReceives(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('payments-received/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + /** * Retrieve specific payment receive. * @param {number} id - Payment receive. diff --git a/packages/webapp/src/hooks/query/receipts.tsx b/packages/webapp/src/hooks/query/receipts.tsx index 2643cf3f3..8e7a52c6a 100644 --- a/packages/webapp/src/hooks/query/receipts.tsx +++ b/packages/webapp/src/hooks/query/receipts.tsx @@ -112,7 +112,22 @@ export function useBulkDeleteReceipts(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('sale-receipts/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'sale-receipts/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -123,6 +138,20 @@ export function useBulkDeleteReceipts(props) { ); } +export function useValidateBulkDeleteReceipts(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('sale-receipts/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + /** * Deletes the given sale invoice. */ diff --git a/packages/webapp/src/hooks/query/vendorCredit.tsx b/packages/webapp/src/hooks/query/vendorCredit.tsx index ddc2bf410..82a36db88 100644 --- a/packages/webapp/src/hooks/query/vendorCredit.tsx +++ b/packages/webapp/src/hooks/query/vendorCredit.tsx @@ -121,7 +121,22 @@ export function useBulkDeleteVendorCredits(props) { const apiRequest = useApiRequest(); return useMutation( - (ids: number[]) => apiRequest.post('vendor-credits/bulk-delete', { ids }), + ({ + ids, + skipUndeletable = false, + }: { + ids: number[]; + skipUndeletable?: boolean; + }) => + apiRequest.post( + 'vendor-credits/bulk-delete', + { ids }, + { + params: skipUndeletable + ? { skip_undeletable: true } + : undefined, + }, + ), { onSuccess: () => { // Common invalidate queries. @@ -132,6 +147,20 @@ export function useBulkDeleteVendorCredits(props) { ); } +export function useValidateBulkDeleteVendorCredits(props) { + const apiRequest = useApiRequest(); + + return useMutation( + (ids: number[]) => + apiRequest + .post('vendor-credits/validate-bulk-delete', { ids }) + .then((res) => transformToCamelCase(res.data)), + { + ...props, + }, + ); +} + const transformVendorCreditsResponse = (response) => ({ vendorCredits: response.data.vendor_credits, pagination: transformPagination(response.data.pagination), diff --git a/packages/webapp/src/hooks/state/dashboard.tsx b/packages/webapp/src/hooks/state/dashboard.tsx index ec1f6f6e3..9b500e12e 100644 --- a/packages/webapp/src/hooks/state/dashboard.tsx +++ b/packages/webapp/src/hooks/state/dashboard.tsx @@ -77,9 +77,13 @@ export const useSidebarSubmenu = () => { * Dialogs actions. */ export const useDialogActions = () => { + const dispatch = useDispatch(); + return { - openDialog: useDispatchAction(openDialog), - closeDialog: useDispatchAction(closeDialog), + openDialog: (name: string, payload?: {}) => + dispatch(openDialog(name, payload)), + closeDialog: (name: string, payload?: {}) => + dispatch(closeDialog(name, payload)), }; }; diff --git a/packages/webapp/src/lang/ar/index.json b/packages/webapp/src/lang/ar/index.json index 5e6f7bb1f..ce8b03662 100644 --- a/packages/webapp/src/lang/ar/index.json +++ b/packages/webapp/src/lang/ar/index.json @@ -482,6 +482,36 @@ "include_accounts_and_exclude_zero_balance": "قم بتضمين الحسابات واستبعاد تلك التي لديها رصيد صفري.", "all_accounts_including_with_zero_balance": "جميع الحسابات ، بما في ذلك تلك الحسابات لديها رصيد صفر.", "notifications": "إشعارات", + "bulk_delete_dialog_title": "Delete {resourcePlural}", + "bulk_delete_selected_summary": "You have selected {count} {resourcePlural} to be deleted:", + "bulk_delete_delete_row_prefix": "{resourceSingular} will be", + "bulk_delete_delete_row_status": "Deleted", + "bulk_delete_archive_row_prefix": "{resourceSingular} cannot be deleted so it will be", + "bulk_delete_archive_row_status": "Archived", + "bulk_delete_selected_description": "These {resourcePlural} will be removed from any contacts or workflows using them as a default document.", + "bulk_delete_note_description": "Deleting {resourcePlural} is permanent and cannot be undone. Archived {resourcePlural} can be restored at any time.", + "resource_invoice_singular": "Invoice", + "resource_invoice_plural": "Invoices", + "resource_estimate_singular": "Estimate", + "resource_estimate_plural": "Estimates", + "resource_receipt_singular": "Receipt", + "resource_receipt_plural": "Receipts", + "resource_credit_note_singular": "Credit Note", + "resource_credit_note_plural": "Credit Notes", + "resource_payment_received_singular": "Payment Received", + "resource_payment_received_plural": "Payments Received", + "resource_bill_singular": "Bill", + "resource_bill_plural": "Bills", + "resource_vendor_credit_singular": "Vendor Credit", + "resource_vendor_credit_plural": "Vendor Credits", + "resource_payment_made_singular": "Payment Made", + "resource_payment_made_plural": "Payments Made", + "resource_manual_journal_singular": "Manual Journal", + "resource_manual_journal_plural": "Manual Journals", + "resource_expense_singular": "Expense", + "resource_expense_plural": "Expenses", + "resource_account_singular": "Account", + "resource_account_plural": "Accounts", "you_could_not_delete_account_has_child_accounts": "لا يمكنك حذف حساب لديه حسابات فرعية.", "journal_entry": "القيد", "estimate": "رقم العرض", diff --git a/packages/webapp/src/lang/en/index.json b/packages/webapp/src/lang/en/index.json index 87a3b7bdc..9eb3ba5ce 100644 --- a/packages/webapp/src/lang/en/index.json +++ b/packages/webapp/src/lang/en/index.json @@ -527,6 +527,36 @@ "the_invoices_has_been_deleted_successfully": "The invoices have been deleted successfully.", "once_delete_this_invoice_you_will_able_to_restore_it": "Once you delete this invoice, you won't be able to restore it later. Are you sure you want to delete this invoice?", "once_delete_these_invoices_you_will_not_able_restore_them": "Once you delete these invoices, you won't be able to retrieve them later. Are you sure you want to delete them?", + "bulk_delete_dialog_title": "Delete {resourcePlural}", + "bulk_delete_selected_summary": "You have selected {count} {resourcePlural} to be deleted:", + "bulk_delete_delete_row_prefix": "{resourceSingular} will be", + "bulk_delete_delete_row_status": "Deleted", + "bulk_delete_archive_row_prefix": "{resourceSingular} cannot be deleted so it will be", + "bulk_delete_archive_row_status": "Archived", + "bulk_delete_selected_description": "These {resourcePlural} will be removed from any contacts or workflows using them as a default document.", + "bulk_delete_note_description": "Deleting {resourcePlural} is permanent and cannot be undone. Archived {resourcePlural} can be restored at any time.", + "resource_invoice_singular": "Invoice", + "resource_invoice_plural": "Invoices", + "resource_estimate_singular": "Estimate", + "resource_estimate_plural": "Estimates", + "resource_receipt_singular": "Receipt", + "resource_receipt_plural": "Receipts", + "resource_credit_note_singular": "Credit Note", + "resource_credit_note_plural": "Credit Notes", + "resource_payment_received_singular": "Payment Received", + "resource_payment_received_plural": "Payments Received", + "resource_bill_singular": "Bill", + "resource_bill_plural": "Bills", + "resource_vendor_credit_singular": "Vendor Credit", + "resource_vendor_credit_plural": "Vendor Credits", + "resource_payment_made_singular": "Payment Made", + "resource_payment_made_plural": "Payments Made", + "resource_manual_journal_singular": "Manual Journal", + "resource_manual_journal_plural": "Manual Journals", + "resource_expense_singular": "Expense", + "resource_expense_plural": "Expenses", + "resource_account_singular": "Account", + "resource_account_plural": "Accounts", "receipts_list": "Receipts List", "receipts": "Receipts", "receipt": "Receipt #", diff --git a/packages/webapp/src/lang/es/index.json b/packages/webapp/src/lang/es/index.json index b50351108..177d325b5 100644 --- a/packages/webapp/src/lang/es/index.json +++ b/packages/webapp/src/lang/es/index.json @@ -482,6 +482,36 @@ "include_accounts_and_exclude_zero_balance": "Incluir cuentas y excluir aquellas con saldo cero.", "all_accounts_including_with_zero_balance": "Todas las cuentas, incluidas aquellas con saldo cero.", "notifications": "Notificaciones", + "bulk_delete_dialog_title": "Delete {resourcePlural}", + "bulk_delete_selected_summary": "You have selected {count} {resourcePlural} to be deleted:", + "bulk_delete_delete_row_prefix": "{resourceSingular} will be", + "bulk_delete_delete_row_status": "Deleted", + "bulk_delete_archive_row_prefix": "{resourceSingular} cannot be deleted so it will be", + "bulk_delete_archive_row_status": "Archived", + "bulk_delete_selected_description": "These {resourcePlural} will be removed from any contacts or workflows using them as a default document.", + "bulk_delete_note_description": "Deleting {resourcePlural} is permanent and cannot be undone. Archived {resourcePlural} can be restored at any time.", + "resource_invoice_singular": "Invoice", + "resource_invoice_plural": "Invoices", + "resource_estimate_singular": "Estimate", + "resource_estimate_plural": "Estimates", + "resource_receipt_singular": "Receipt", + "resource_receipt_plural": "Receipts", + "resource_credit_note_singular": "Credit Note", + "resource_credit_note_plural": "Credit Notes", + "resource_payment_received_singular": "Payment Received", + "resource_payment_received_plural": "Payments Received", + "resource_bill_singular": "Bill", + "resource_bill_plural": "Bills", + "resource_vendor_credit_singular": "Vendor Credit", + "resource_vendor_credit_plural": "Vendor Credits", + "resource_payment_made_singular": "Payment Made", + "resource_payment_made_plural": "Payments Made", + "resource_manual_journal_singular": "Manual Journal", + "resource_manual_journal_plural": "Manual Journals", + "resource_expense_singular": "Expense", + "resource_expense_plural": "Expenses", + "resource_account_singular": "Account", + "resource_account_plural": "Accounts", "you_could_not_delete_account_has_child_accounts": "No pudiste eliminar la cuenta que tiene cuentas secundarias.", "journal_entry": "Asiento de diario", "estimate": "Estimación #", diff --git a/packages/webapp/src/lang/sv/index.json b/packages/webapp/src/lang/sv/index.json index 99e830bc8..33e984274 100644 --- a/packages/webapp/src/lang/sv/index.json +++ b/packages/webapp/src/lang/sv/index.json @@ -472,6 +472,36 @@ "include_accounts_and_exclude_zero_balance": "Inkludera konton och exkludera de som har nollbalans.", "all_accounts_including_with_zero_balance": "Alla konton, inklusive det kontot, har nollbalans.", "notifications": "Meddelanden", + "bulk_delete_dialog_title": "Delete {resourcePlural}", + "bulk_delete_selected_summary": "You have selected {count} {resourcePlural} to be deleted:", + "bulk_delete_delete_row_prefix": "{resourceSingular} will be", + "bulk_delete_delete_row_status": "Deleted", + "bulk_delete_archive_row_prefix": "{resourceSingular} cannot be deleted so it will be", + "bulk_delete_archive_row_status": "Archived", + "bulk_delete_selected_description": "These {resourcePlural} will be removed from any contacts or workflows using them as a default document.", + "bulk_delete_note_description": "Deleting {resourcePlural} is permanent and cannot be undone. Archived {resourcePlural} can be restored at any time.", + "resource_invoice_singular": "Invoice", + "resource_invoice_plural": "Invoices", + "resource_estimate_singular": "Estimate", + "resource_estimate_plural": "Estimates", + "resource_receipt_singular": "Receipt", + "resource_receipt_plural": "Receipts", + "resource_credit_note_singular": "Credit Note", + "resource_credit_note_plural": "Credit Notes", + "resource_payment_received_singular": "Payment Received", + "resource_payment_received_plural": "Payments Received", + "resource_bill_singular": "Bill", + "resource_bill_plural": "Bills", + "resource_vendor_credit_singular": "Vendor Credit", + "resource_vendor_credit_plural": "Vendor Credits", + "resource_payment_made_singular": "Payment Made", + "resource_payment_made_plural": "Payments Made", + "resource_manual_journal_singular": "Manual Journal", + "resource_manual_journal_plural": "Manual Journals", + "resource_expense_singular": "Expense", + "resource_expense_plural": "Expenses", + "resource_account_singular": "Account", + "resource_account_plural": "Accounts", "journal_entry": "Journalanteckning", "estimate": "Uppskattning #", "estimate_date": "Uppskattning Datum", diff --git a/packages/webapp/src/store/Invoice/invoices.actions.tsx b/packages/webapp/src/store/Invoice/invoices.actions.tsx index 1a5bebded..d941fb5b6 100644 --- a/packages/webapp/src/store/Invoice/invoices.actions.tsx +++ b/packages/webapp/src/store/Invoice/invoices.actions.tsx @@ -20,3 +20,9 @@ export const setInvoicesSelectedRows = (selectedRows) => { payload: selectedRows, }; }; + +export const resetInvoicesSelectedRows = () => { + return { + type: 'INVOICES/RESET_SELECTED_ROWS', + }; +}; \ No newline at end of file diff --git a/packages/webapp/src/store/Invoice/invoices.reducer.tsx b/packages/webapp/src/store/Invoice/invoices.reducer.tsx index f31643543..f853dd214 100644 --- a/packages/webapp/src/store/Invoice/invoices.reducer.tsx +++ b/packages/webapp/src/store/Invoice/invoices.reducer.tsx @@ -32,6 +32,10 @@ const reducerInstance = createReducer(initialState, { state.selectedRows = action.payload; }, + [`INVOICES/RESET_SELECTED_ROWS`]: (state) => { + state.selectedRows = []; + }, + [t.RESET]: () => { purgeStoredState(CONFIG); }, diff --git a/packages/webapp/src/store/PaymentReceives/paymentReceives.actions.tsx b/packages/webapp/src/store/PaymentReceives/paymentReceives.actions.tsx index da7bdec0b..d39ba7202 100644 --- a/packages/webapp/src/store/PaymentReceives/paymentReceives.actions.tsx +++ b/packages/webapp/src/store/PaymentReceives/paymentReceives.actions.tsx @@ -20,3 +20,4 @@ export const setPaymentReceivesSelectedRows = (selectedRows) => { payload: selectedRows, }; }; + diff --git a/packages/webapp/src/store/dashboard/dashboard.reducer.tsx b/packages/webapp/src/store/dashboard/dashboard.reducer.tsx index eacbbba7b..56e418192 100644 --- a/packages/webapp/src/store/dashboard/dashboard.reducer.tsx +++ b/packages/webapp/src/store/dashboard/dashboard.reducer.tsx @@ -89,7 +89,7 @@ const reducerInstance = createReducer(initialState, { isOpen: false, }; }, - [t.CLOSE_ALL_DIALOGS]: (state, action) => {}, + [t.CLOSE_ALL_DIALOGS]: (state, action) => { }, [t.SET_TOPBAR_EDIT_VIEW]: (state, action) => { state.topbarEditViewId = action.id;
- -