feat: improve UI experience of resource priting

This commit is contained in:
Ahmed Bouhuolia
2024-05-31 15:30:49 +02:00
parent ba77351e44
commit 958f78e7a4
18 changed files with 184 additions and 101 deletions

View File

@@ -121,7 +121,7 @@ export default {
}, },
balance: { balance: {
name: 'account.field.balance', name: 'account.field.balance',
accessor: 'amount', accessor: 'formattedAmount',
}, },
description: { description: {
name: 'account.field.description', name: 'account.field.description',

View File

@@ -12,13 +12,13 @@ export class ExportPdf {
private chromiumlyTenancy: ChromiumlyTenancy; private chromiumlyTenancy: ChromiumlyTenancy;
/** /**
* *
* @param tenantId * @param tenantId
* @param columns * @param columns
* @param data * @param data
* @param sheetTitle * @param sheetTitle
* @param sheetDescription * @param sheetDescription
* @returns * @returns
*/ */
public async pdf( public async pdf(
tenantId: number, tenantId: number,
@@ -40,7 +40,7 @@ export class ExportPdf {
); );
// Convert the HTML content to PDF // Convert the HTML content to PDF
return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, { return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, {
margins: { top: 0, bottom: 0, left: 0, right: 0 }, margins: { top: 0.2, bottom: 0.2, left: 0.2, right: 0.2 },
landscape: true, landscape: true,
}); });
} }

View File

@@ -30,7 +30,7 @@ import withSettings from '@/containers/Settings/withSettings';
import withSettingsActions from '@/containers/Settings/withSettingsActions'; import withSettingsActions from '@/containers/Settings/withSettingsActions';
import withDialogActions from '@/containers/Dialog/withDialogActions'; import withDialogActions from '@/containers/Dialog/withDialogActions';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
@@ -59,9 +59,8 @@ function ManualJournalActionsBar({
// Manual journals context. // Manual journals context.
const { journalsViews, fields } = useManualJournalsContext(); const { journalsViews, fields } = useManualJournalsContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Manual journals refresh action. // Manual journals refresh action.
const { refresh } = useRefreshJournals(); const { refresh } = useRefreshJournals();
@@ -98,7 +97,7 @@ function ManualJournalActionsBar({
// Handle the pdf print button click. // Handle the pdf print button click.
const handlePdfPrintBtnSubmit = () => { const handlePdfPrintBtnSubmit = () => {
exportPdf({ resource: 'ManualJournal' }); downloadExportPdf({ resource: 'ManualJournal' });
}; };
return ( return (
@@ -150,7 +149,6 @@ function ManualJournalActionsBar({
icon={<Icon icon="print-16" iconSize={16} />} icon={<Icon icon="print-16" iconSize={16} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePdfPrintBtnSubmit} onClick={handlePdfPrintBtnSubmit}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -1,6 +1,6 @@
// @ts-nocheck // @ts-nocheck
import React from 'react'; import React from 'react';
import { isEmpty } from 'lodash'; import { isEmpty, isUndefined } from 'lodash';
import { import {
Button, Button,
NavbarGroup, NavbarGroup,
@@ -9,7 +9,11 @@ import {
Intent, Intent,
Switch, Switch,
Alignment, Alignment,
ProgressBar,
ToastProps,
Text,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import clsx from 'classnames';
import { import {
AdvancedFilterPopover, AdvancedFilterPopover,
@@ -29,7 +33,7 @@ import { DialogsName } from '@/constants/dialogs';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useRefreshAccounts } from '@/hooks/query/accounts'; import { useRefreshAccounts } from '@/hooks/query/accounts';
import { useAccountsChartContext } from './AccountsChartProvider'; import { useAccountsChartContext } from './AccountsChartProvider';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import withAccounts from './withAccounts'; import withAccounts from './withAccounts';
import withAccountsTableActions from './withAccountsTableActions'; import withAccountsTableActions from './withAccountsTableActions';
@@ -68,8 +72,8 @@ function AccountsActionsBar({
const { resourceViews, fields } = useAccountsChartContext(); const { resourceViews, fields } = useAccountsChartContext();
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = // Exports pdf document.
useResourceExportPdf(); const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
// Accounts refresh action. // Accounts refresh action.
const { refresh } = useRefreshAccounts(); const { refresh } = useRefreshAccounts();
@@ -115,7 +119,7 @@ function AccountsActionsBar({
}; };
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'Account' }); downloadExportPdf({ resource: 'Account' });
}; };
// Handle click new account. // Handle click new account.
const onClickNewAccount = () => { const onClickNewAccount = () => {
@@ -184,7 +188,6 @@ function AccountsActionsBar({
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon="print-16" iconSize={16} />} icon={<Icon icon="print-16" iconSize={16} />}
text={<T id={'print'} />} text={<T id={'print'} />}
disabled={isExportPdfLoading}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
/> />
<Button <Button

View File

@@ -25,7 +25,7 @@ import {
import { useCustomersListContext } from './CustomersListProvider'; import { useCustomersListContext } from './CustomersListProvider';
import { useRefreshCustomers } from '@/hooks/query/customers'; import { useRefreshCustomers } from '@/hooks/query/customers';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import withCustomers from './withCustomers'; import withCustomers from './withCustomers';
import withCustomersActions from './withCustomersActions'; import withCustomersActions from './withCustomersActions';
@@ -71,9 +71,8 @@ function CustomerActionsBar({
// Customers refresh action. // Customers refresh action.
const { refresh } = useRefreshCustomers(); const { refresh } = useRefreshCustomers();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
const onClickNewCustomer = () => { const onClickNewCustomer = () => {
history.push('/customers/new'); history.push('/customers/new');
@@ -116,7 +115,7 @@ function CustomerActionsBar({
}; };
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'Customer' }); downloadExportPdf({ resource: 'Customer' });
}; };
return ( return (
@@ -168,7 +167,6 @@ function CustomerActionsBar({
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon="print-16" iconSize={16} />} icon={<Icon icon="print-16" iconSize={16} />}
text={<T id={'print'} />} text={<T id={'print'} />}
disabled={isExportPdfLoading}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
/> />
<Button <Button

View File

@@ -27,7 +27,7 @@ import { DialogsName } from '@/constants/dialogs';
import { useRefreshExpenses } from '@/hooks/query/expenses'; import { useRefreshExpenses } from '@/hooks/query/expenses';
import { useExpensesListContext } from './ExpensesListProvider'; import { useExpensesListContext } from './ExpensesListProvider';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import withExpenses from './withExpenses'; import withExpenses from './withExpenses';
import withExpensesActions from './withExpensesActions'; import withExpensesActions from './withExpensesActions';
@@ -62,9 +62,8 @@ function ExpensesActionsBar({
// Expenses list context. // Expenses list context.
const { expensesViews, fields } = useExpensesListContext(); const { expensesViews, fields } = useExpensesListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Expenses refresh action. // Expenses refresh action.
const { refresh } = useRefreshExpenses(); const { refresh } = useRefreshExpenses();
@@ -100,7 +99,7 @@ function ExpensesActionsBar({
}; };
// Handles the print button click. // Handles the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'Expense' }); downloadExportPdf({ resource: 'Expense' });
}; };
return ( return (
@@ -151,7 +150,6 @@ function ExpensesActionsBar({
icon={<Icon icon="print-16" iconSize={16} />} icon={<Icon icon="print-16" iconSize={16} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -27,7 +27,7 @@ import {
import { ItemAction, AbilitySubject } from '@/constants/abilityOption'; import { ItemAction, AbilitySubject } from '@/constants/abilityOption';
import { useItemsListContext } from './ItemsListProvider'; import { useItemsListContext } from './ItemsListProvider';
import { useRefreshItems } from '@/hooks/query/items'; import { useRefreshItems } from '@/hooks/query/items';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import withItems from './withItems'; import withItems from './withItems';
import withItemsActions from './withItemsActions'; import withItemsActions from './withItemsActions';
@@ -66,9 +66,8 @@ function ItemsActionsBar({
// Items list context. // Items list context.
const { itemsViews, fields } = useItemsListContext(); const { itemsViews, fields } = useItemsListContext();
// // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Items refresh action. // Items refresh action.
const { refresh } = useRefreshItems(); const { refresh } = useRefreshItems();
@@ -116,7 +115,7 @@ function ItemsActionsBar({
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'Item' }); downloadExportPdf({ resource: 'Item' });
}; };
return ( return (
@@ -167,7 +166,6 @@ function ItemsActionsBar({
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
disabled={isExportPdfLoading}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
/> />
<Button <Button

View File

@@ -32,7 +32,7 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
import { useBillsListContext } from './BillsListProvider'; import { useBillsListContext } from './BillsListProvider';
import { useRefreshBills } from '@/hooks/query/bills'; import { useRefreshBills } from '@/hooks/query/bills';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
@@ -64,9 +64,8 @@ function BillActionsBar({
// Bills list context. // Bills list context.
const { billsViews, fields } = useBillsListContext(); const { billsViews, fields } = useBillsListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handle click a new bill. // Handle click a new bill.
const handleClickNewBill = () => { const handleClickNewBill = () => {
@@ -96,7 +95,7 @@ function BillActionsBar({
}; };
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'Bill' }); downloadExportPdf({ resource: 'Bill' });
}; };
return ( return (
@@ -146,7 +145,6 @@ function BillActionsBar({
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
disabled={isExportPdfLoading}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
/> />
<Button <Button

View File

@@ -21,7 +21,7 @@ import {
} from '@/components'; } from '@/components';
import { useVendorsCreditNoteListContext } from './VendorsCreditNoteListProvider'; import { useVendorsCreditNoteListContext } from './VendorsCreditNoteListProvider';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { VendorCreditAction, AbilitySubject } from '@/constants/abilityOption'; import { VendorCreditAction, AbilitySubject } from '@/constants/abilityOption';
import withVendorsCreditNotesActions from './withVendorsCreditNotesActions'; import withVendorsCreditNotesActions from './withVendorsCreditNotesActions';
@@ -61,9 +61,8 @@ function VendorsCreditNoteActionsBar({
const { VendorCreditsViews, fields, refresh } = const { VendorCreditsViews, fields, refresh } =
useVendorsCreditNoteListContext(); useVendorsCreditNoteListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handle click a new Vendor. // Handle click a new Vendor.
const handleClickNewVendorCredit = () => { const handleClickNewVendorCredit = () => {
@@ -91,7 +90,7 @@ function VendorsCreditNoteActionsBar({
}; };
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'VendorCredit' }); downloadExportPdf({ resource: 'VendorCredit' });
}; };
return ( return (
@@ -132,7 +131,6 @@ function VendorsCreditNoteActionsBar({
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -31,7 +31,7 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
import { usePaymentMadesListContext } from './PaymentMadesListProvider'; import { usePaymentMadesListContext } from './PaymentMadesListProvider';
import { useRefreshPaymentMades } from '@/hooks/query/paymentMades'; import { useRefreshPaymentMades } from '@/hooks/query/paymentMades';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
import { compose } from '@/utils'; import { compose } from '@/utils';
@@ -57,9 +57,8 @@ function PaymentMadeActionsBar({
}) { }) {
const history = useHistory(); const history = useHistory();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Payment receives list context. // Payment receives list context.
const { paymentMadesViews, fields } = usePaymentMadesListContext(); const { paymentMadesViews, fields } = usePaymentMadesListContext();
@@ -93,7 +92,7 @@ function PaymentMadeActionsBar({
}; };
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'PaymentMade' }); downloadExportPdf({ resource: 'PaymentMade' });
}; };
return ( return (
@@ -142,7 +141,6 @@ function PaymentMadeActionsBar({
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -20,7 +20,7 @@ import {
} from '@/components'; } from '@/components';
import { useCreditNoteListContext } from './CreditNotesListProvider'; import { useCreditNoteListContext } from './CreditNotesListProvider';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { CreditNoteAction, AbilitySubject } from '@/constants/abilityOption'; import { CreditNoteAction, AbilitySubject } from '@/constants/abilityOption';
import withCreditNotes from './withCreditNotes'; import withCreditNotes from './withCreditNotes';
@@ -56,9 +56,8 @@ function CreditNotesActionsBar({
// credit note list context. // credit note list context.
const { CreditNotesView, fields, refresh } = useCreditNoteListContext(); const { CreditNotesView, fields, refresh } = useCreditNoteListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handle view tab change. // Handle view tab change.
const handleTabChange = (view) => { const handleTabChange = (view) => {
@@ -88,7 +87,7 @@ function CreditNotesActionsBar({
}; };
// Handle print button click. // Handle print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'CreditNote' }); downloadExportPdf({ resource: 'CreditNote' });
}; };
return ( return (
@@ -141,7 +140,6 @@ function CreditNotesActionsBar({
icon={<Icon icon={'file-export-16'} iconSize={'16'} />} icon={<Icon icon={'file-export-16'} iconSize={'16'} />}
text={<T id={'export'} />} text={<T id={'export'} />}
onClick={handleExportBtnClick} onClick={handleExportBtnClick}
disabled={isExportPdfLoading}
/> />
<NavbarDivider /> <NavbarDivider />
<DashboardRowsHeightButton <DashboardRowsHeightButton

View File

@@ -30,7 +30,7 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
import { useEstimatesListContext } from './EstimatesListProvider'; import { useEstimatesListContext } from './EstimatesListProvider';
import { useRefreshEstimates } from '@/hooks/query/estimates'; import { useRefreshEstimates } from '@/hooks/query/estimates';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { SaleEstimateAction, AbilitySubject } from '@/constants/abilityOption'; import { SaleEstimateAction, AbilitySubject } from '@/constants/abilityOption';
import { compose } from '@/utils'; import { compose } from '@/utils';
@@ -60,9 +60,8 @@ function EstimateActionsBar({
// Estimates list context. // Estimates list context.
const { estimatesViews, fields } = useEstimatesListContext(); const { estimatesViews, fields } = useEstimatesListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handle click a new sale estimate. // Handle click a new sale estimate.
const onClickNewEstimate = () => { const onClickNewEstimate = () => {
@@ -95,7 +94,7 @@ function EstimateActionsBar({
}; };
// Handles the print button click. // Handles the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'SaleEstimate' }); downloadExportPdf({ resource: 'SaleEstimate' });
}; };
return ( return (
@@ -146,7 +145,6 @@ function EstimateActionsBar({
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -23,7 +23,7 @@ import { SaleInvoiceAction, AbilitySubject } from '@/constants/abilityOption';
import { useRefreshInvoices } from '@/hooks/query/invoices'; import { useRefreshInvoices } from '@/hooks/query/invoices';
import { useInvoicesListContext } from './InvoicesListProvider'; import { useInvoicesListContext } from './InvoicesListProvider';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import withInvoices from './withInvoices'; import withInvoices from './withInvoices';
import withInvoiceActions from './withInvoiceActions'; import withInvoiceActions from './withInvoiceActions';
@@ -57,9 +57,8 @@ function InvoiceActionsBar({
// Sale invoices list context. // Sale invoices list context.
const { invoicesViews, invoicesFields } = useInvoicesListContext(); const { invoicesViews, invoicesFields } = useInvoicesListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handle new invoice button click. // Handle new invoice button click.
const handleClickNewInvoice = () => { const handleClickNewInvoice = () => {
@@ -95,7 +94,7 @@ function InvoiceActionsBar({
}; };
// Handles the print button click. // Handles the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'SaleInvoice' }); downloadExportPdf({ resource: 'SaleInvoice' });
}; };
return ( return (
@@ -144,7 +143,6 @@ function InvoiceActionsBar({
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -31,11 +31,13 @@ import {
PaymentReceiveAction, PaymentReceiveAction,
AbilitySubject, AbilitySubject,
} from '@/constants/abilityOption'; } from '@/constants/abilityOption';
import { usePaymentReceivesListContext } from './PaymentReceiptsListProvider'; import { usePaymentReceivesListContext } from './PaymentReceiptsListProvider';
import { useRefreshPaymentReceive } from '@/hooks/query/paymentReceives'; import { useRefreshPaymentReceive } from '@/hooks/query/paymentReceives';
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
/** /**
* Payment receives actions bar. * Payment receives actions bar.
@@ -62,9 +64,8 @@ function PaymentReceiveActionsBar({
// Payment receives list context. // Payment receives list context.
const { paymentReceivesViews, fields } = usePaymentReceivesListContext(); const { paymentReceivesViews, fields } = usePaymentReceivesListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handle new payment button click. // Handle new payment button click.
const handleClickNewPaymentReceive = () => { const handleClickNewPaymentReceive = () => {
@@ -98,7 +99,7 @@ function PaymentReceiveActionsBar({
}; };
// Handles the print button click. // Handles the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'PaymentReceive' }); downloadExportPdf({ resource: 'PaymentReceive' });
}; };
return ( return (
@@ -147,7 +148,6 @@ function PaymentReceiveActionsBar({
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -33,7 +33,7 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
import { useReceiptsListContext } from './ReceiptsListProvider'; import { useReceiptsListContext } from './ReceiptsListProvider';
import { useRefreshReceipts } from '@/hooks/query/receipts'; import { useRefreshReceipts } from '@/hooks/query/receipts';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf'; import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption'; import { SaleReceiptAction, AbilitySubject } from '@/constants/abilityOption';
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
@@ -63,8 +63,8 @@ function ReceiptActionsBar({
// Sale receipts list context. // Sale receipts list context.
const { receiptsViews, fields } = useReceiptsListContext(); const { receiptsViews, fields } = useReceiptsListContext();
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = // Exports pdf document.
useResourceExportPdf(); const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
// Handle new receipt button click. // Handle new receipt button click.
const onClickNewReceipt = () => { const onClickNewReceipt = () => {
@@ -101,7 +101,7 @@ function ReceiptActionsBar({
}; };
// Handle print button click. // Handle print button click.
const handlePrintButtonClick = () => { const handlePrintButtonClick = () => {
exportPdf({ resource: 'SaleReceipt' }); downloadExportPdf({ resource: 'SaleReceipt' });
}; };
return ( return (
@@ -152,7 +152,6 @@ function ReceiptActionsBar({
icon={<Icon icon={'print-16'} iconSize={'16'} />} icon={<Icon icon={'print-16'} iconSize={'16'} />}
text={<T id={'print'} />} text={<T id={'print'} />}
onClick={handlePrintButtonClick} onClick={handlePrintButtonClick}
disabled={isExportPdfLoading}
/> />
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}

View File

@@ -22,10 +22,12 @@ import {
AdvancedFilterPopover, AdvancedFilterPopover,
} from '@/components'; } from '@/components';
import { useRefreshVendors } from '@/hooks/query/vendors';
import { VendorAction, AbilitySubject } from '@/constants/abilityOption'; import { VendorAction, AbilitySubject } from '@/constants/abilityOption';
import { useRefreshVendors } from '@/hooks/query/vendors';
import { useVendorsListContext } from './VendorsListProvider'; import { useVendorsListContext } from './VendorsListProvider';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useDownloadExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
import withVendors from './withVendors'; import withVendors from './withVendors';
import withVendorsActions from './withVendorsActions'; import withVendorsActions from './withVendorsActions';
@@ -35,7 +37,6 @@ import withDialogActions from '@/containers/Dialog/withDialogActions';
import { compose } from '@/utils'; import { compose } from '@/utils';
import { DialogsName } from '@/constants/dialogs'; import { DialogsName } from '@/constants/dialogs';
import { useResourceExportPdf } from '@/hooks/query/FinancialReports/use-export-pdf';
/** /**
* Vendors actions bar. * Vendors actions bar.
@@ -62,9 +63,8 @@ function VendorActionsBar({
// Vendors list context. // Vendors list context.
const { vendorsViews, fields } = useVendorsListContext(); const { vendorsViews, fields } = useVendorsListContext();
// Exports the given resource into pdf. // Exports pdf document.
const { mutateAsync: exportPdf, isLoading: isExportPdfLoading } = const { downloadAsync: downloadExportPdf } = useDownloadExportPdf();
useResourceExportPdf();
// Handles new vendor button click. // Handles new vendor button click.
const onClickNewVendor = () => { const onClickNewVendor = () => {
@@ -99,7 +99,7 @@ function VendorActionsBar({
}; };
// Handle the print button click. // Handle the print button click.
const handlePrintBtnClick = () => { const handlePrintBtnClick = () => {
exportPdf({ resource: 'Vendor' }); downloadExportPdf({ resource: 'Vendor' });
}; };
return ( return (
@@ -148,7 +148,6 @@ function VendorActionsBar({
className={Classes.MINIMAL} className={Classes.MINIMAL}
icon={<Icon icon="print-16" iconSize={16} />} icon={<Icon icon="print-16" iconSize={16} />}
text={<T id={'print'} />} text={<T id={'print'} />}
disabled={isExportPdfLoading}
onClick={handlePrintBtnClick} onClick={handlePrintBtnClick}
/> />
<Button <Button

View File

@@ -3,6 +3,7 @@ import { downloadFile } from '@/hooks/useDownloadFile';
import useApiRequest from '@/hooks/useRequest'; import useApiRequest from '@/hooks/useRequest';
import { AxiosError } from 'axios'; import { AxiosError } from 'axios';
import { useMutation } from 'react-query'; import { useMutation } from 'react-query';
import { asyncToastProgress } from '@/utils/async-toast-progress';
interface ResourceExportValues { interface ResourceExportValues {
resource: string; resource: string;
@@ -13,12 +14,13 @@ interface ResourceExportValues {
* @param {Object} args - Additional configurations for the download. * @param {Object} args - Additional configurations for the download.
* @returns {Function} A function to trigger the file download. * @returns {Function} A function to trigger the file download.
*/ */
export const useResourceExportPdf = () => { export const useResourceExportPdf = (props) => {
const apiRequest = useApiRequest(); const apiRequest = useApiRequest();
return useMutation<void, AxiosError, any>((data: ResourceExportValues) => { return useMutation<void, AxiosError, any>((data: ResourceExportValues) => {
return apiRequest return apiRequest.get(
.get('/export', { '/export',
{
responseType: 'blob', responseType: 'blob',
headers: { headers: {
accept: 'application/pdf', accept: 'application/pdf',
@@ -27,10 +29,34 @@ export const useResourceExportPdf = () => {
resource: data.resource, resource: data.resource,
format: data.format, format: data.format,
}, },
}) },
.then((res) => { props,
downloadFile(res.data, `${data.resource}.pdf`); );
return res;
});
}); });
}; };
export const useDownloadExportPdf = () => {
const { startProgress, stopProgress } = asyncToastProgress();
const resourceExportPdfMutation = useResourceExportPdf({
onMutate: () => {},
});
const { mutateAsync, isLoading: isExportPdfLoading } =
resourceExportPdfMutation;
const downloadAsync = (values) => {
if (!isExportPdfLoading) {
startProgress();
return mutateAsync(values).then((res) => {
downloadFile(res.data, `${values.resource}.pdf`);
stopProgress();
return res;
});
}
};
return {
...resourceExportPdfMutation,
downloadAsync,
};
};

View File

@@ -0,0 +1,76 @@
import { isUndefined } from 'lodash';
import clsx from 'classnames';
import {
Classes,
Intent,
ProgressBar,
Text,
ToastProps,
} from '@blueprintjs/core';
import { AppToaster } from '@/components';
interface AsyncToastProgress {
renderProgressProps?: (amount: number) => ToastProps;
}
export function asyncToastProgress({
renderProgressProps,
}: AsyncToastProgress = {}) {
let progressToastInterval: number;
let progress = 0;
let key: string = '';
const renderProgress = (amount: number): ToastProps => {
const customProgressProps = !isUndefined(renderProgressProps)
? renderProgressProps(amount)
: {};
return {
icon: 'hand',
message: (
<>
<Text style={{ fontSize: 12, marginBottom: 6 }}>
Preparing the document.
</Text>
<ProgressBar
className={clsx({
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
})}
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
value={amount / 100}
/>
</>
),
onDismiss: (didTimeoutExpire: boolean) => {
if (!didTimeoutExpire) {
// user dismissed toast with click
window.clearInterval(progressToastInterval);
}
},
timeout: amount < 100 ? 0 : 2000,
...customProgressProps,
};
};
const startProgress = () => {
key = AppToaster.show(renderProgress(0));
progressToastInterval = window.setInterval(() => {
if (progress > 100) {
window.clearInterval(progressToastInterval);
} else {
progress += 10 + Math.random() * 20;
progress = Math.min(progress, 95); // Ensure progress never reaches 100
AppToaster.show(renderProgress(progress), key);
}
}, 1000);
};
const stopProgress = () => {
progress = 100;
AppToaster.show(renderProgress(progress), key);
window.clearInterval(progressToastInterval);
};
return { startProgress, stopProgress };
}