mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 21:30:31 +00:00
feat: export reports csv and xlsx (#286)
This commit is contained in:
@@ -15,6 +15,7 @@ import { DashboardActionsBar, FormattedMessage as T, Icon } from '@/components';
|
||||
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
|
||||
|
||||
import NumberFormatDropdown from '@/components/NumberFormatDropdown';
|
||||
import { APAgingSummaryExportMenu } from './components';
|
||||
|
||||
import withAPAgingSummary from './withAPAgingSummary';
|
||||
import withAPAgingSummaryActions from './withAPAgingSummaryActions';
|
||||
@@ -106,11 +107,18 @@ function APAgingSummaryActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<APAgingSummaryExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -27,6 +27,7 @@ function APAgingSummaryProvider({ filter, ...props }) {
|
||||
isAPAgingLoading,
|
||||
isAPAgingFetching,
|
||||
refetch,
|
||||
query,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
// @ts-nocheck
|
||||
import React, { useMemo } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { If } from '@/components';
|
||||
import { AppToaster, If, Stack } from '@/components';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { useAPAgingSummaryContext } from './APAgingSummaryProvider';
|
||||
import { agingSummaryDynamicColumns } from '../AgingSummary/dynamicColumns';
|
||||
import {
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
useAPAgingSheetCsvExport,
|
||||
useAPAgingSheetXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
|
||||
/**
|
||||
* Retrieve AP aging summary columns.
|
||||
@@ -29,3 +42,87 @@ export function APAgingSummarySheetLoadingBar() {
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A/P aging summary export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function APAgingSummaryExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useAPAgingSummaryContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useAPAgingSheetXlsxExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useAPAgingSheetCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import withARAgingSummaryActions from './withARAgingSummaryActions';
|
||||
import withARAgingSummary from './withARAgingSummary';
|
||||
|
||||
import { compose, safeInvoke } from '@/utils';
|
||||
import { ARAgingSummaryExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* A/R Aging summary sheet - Actions bar.
|
||||
@@ -107,11 +108,18 @@ function ARAgingSummaryActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<ARAgingSummaryExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,23 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
|
||||
import { useARAgingSummaryContext } from './ARAgingSummaryProvider';
|
||||
import { If, FormattedMessage as T } from '@/components';
|
||||
import { AppToaster, If, Stack, FormattedMessage as T } from '@/components';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { agingSummaryDynamicColumns } from '../AgingSummary/dynamicColumns';
|
||||
import {
|
||||
useARAgingSheetCsvExport,
|
||||
useARAgingSheetXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
|
||||
/**
|
||||
* Retrieve AR aging summary columns.
|
||||
@@ -29,3 +42,88 @@ export function ARAgingSummarySheetLoadingBar() {
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A/R aging summary export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function ARAgingSummaryExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useARAgingSummaryContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useARAgingSheetXlsxExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useARAgingSheetCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import {
|
||||
NavbarGroup,
|
||||
Button,
|
||||
@@ -13,11 +12,12 @@ import classNames from 'classnames';
|
||||
import { DashboardActionsBar, FormattedMessage as T, Icon } from '@/components';
|
||||
|
||||
import NumberFormatDropdown from '@/components/NumberFormatDropdown';
|
||||
import { BalanceSheetExportMenu } from './components';
|
||||
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { useBalanceSheetContext } from './BalanceSheetProvider';
|
||||
import withBalanceSheet from './withBalanceSheet';
|
||||
import withBalanceSheetActions from './withBalanceSheetActions';
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
|
||||
/**
|
||||
* Balance sheet - actions bar.
|
||||
@@ -114,11 +114,18 @@ function BalanceSheetActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<BalanceSheetExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { FormattedMessage as T, Icon, If } from '@/components';
|
||||
import {
|
||||
FormattedMessage as T,
|
||||
Icon,
|
||||
If,
|
||||
Stack,
|
||||
AppToaster,
|
||||
} from '@/components';
|
||||
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { useBalanceSheetContext } from './BalanceSheetProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import { dynamicColumns } from './dynamicColumns';
|
||||
import {
|
||||
useBalanceSheetCsvExport,
|
||||
useBalanceSheetXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
|
||||
/**
|
||||
* Balance sheet alerts.
|
||||
@@ -66,3 +85,88 @@ export const useBalanceSheetColumns = () => {
|
||||
[table],
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the balance sheet export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export const BalanceSheetExportMenu = () => {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useBalanceSheetContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useBalanceSheetXlsxExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useBalanceSheetCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport().then(() => {});
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport().then(() => {});
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ import withCashFlowStatement from './withCashFlowStatement';
|
||||
import withCashFlowStatementActions from './withCashFlowStatementActions';
|
||||
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { CashflowSheetExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* Cash flow statement actions bar.
|
||||
@@ -115,11 +116,18 @@ function CashFlowStatementActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<CashflowSheetExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,27 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { Icon, If, FormattedMessage as T } from '@/components';
|
||||
import {
|
||||
AppToaster,
|
||||
Icon,
|
||||
If,
|
||||
Stack,
|
||||
FormattedMessage as T,
|
||||
} from '@/components';
|
||||
import {
|
||||
useCashFlowStatementCsvExport,
|
||||
useCashFlowStatementXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
import { dynamicColumns } from './dynamicColumns';
|
||||
@@ -65,3 +84,88 @@ export function CashFlowStatementAlerts() {
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cashflow sheet export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function CashflowSheetExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useCashFlowStatementContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useCashFlowStatementXlsxExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useCashFlowStatementCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import withCustomersBalanceSummary from './withCustomersBalanceSummary';
|
||||
import withCustomersBalanceSummaryActions from './withCustomersBalanceSummaryActions';
|
||||
import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider';
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { CustomerBalanceSummaryExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* customer balance summary action bar.
|
||||
@@ -35,7 +36,7 @@ function CustomersBalanceSummaryActionsBar({
|
||||
const { refetch, isCustomersBalanceLoading } =
|
||||
useCustomersBalanceSummaryContext();
|
||||
|
||||
// handle filter toggle click.
|
||||
// Handle filter toggle click.
|
||||
const handleFilterToggleClick = () => {
|
||||
toggleCustomerBalanceFilterDrawer();
|
||||
};
|
||||
@@ -112,11 +113,18 @@ function CustomersBalanceSummaryActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<CustomerBalanceSummaryExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -31,6 +31,7 @@ function CustomersBalanceSummaryProvider({ filter, ...props }) {
|
||||
isCustomersBalanceLoading,
|
||||
|
||||
refetch,
|
||||
query
|
||||
};
|
||||
return (
|
||||
<FinancialReportPage name={'customers-balance-summary'}>
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function CustomersBalanceSummaryTable({
|
||||
>
|
||||
<CustomerBalanceDataTable
|
||||
columns={columns}
|
||||
data={table.data}
|
||||
data={table.rows}
|
||||
rowClassNames={tableRowTypesToClassnames}
|
||||
noInitialFetch={true}
|
||||
sticky={true}
|
||||
|
||||
@@ -1,13 +1,25 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import * as R from 'ramda';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { If } from '@/components';
|
||||
import { AppToaster, If, Stack } from '@/components';
|
||||
import { Align } from '@/constants';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { useCustomersBalanceSummaryContext } from './CustomersBalanceSummaryProvider';
|
||||
|
||||
import {
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
useCustomerBalanceSummaryCsvExport,
|
||||
useCustomerBalanceSummaryXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
|
||||
/**
|
||||
* Retrieve customers balance summary columns.
|
||||
@@ -79,3 +91,89 @@ export function CustomersBalanceLoadingBar() {
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customer balance summary export menu.
|
||||
*/
|
||||
export function CustomerBalanceSummaryExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useCustomersBalanceSummaryContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useCustomerBalanceSummaryXlsxExport(
|
||||
query,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useCustomerBalanceSummaryCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,9 +9,10 @@ import {
|
||||
PopoverInteractionKind,
|
||||
Position,
|
||||
} from '@blueprintjs/core';
|
||||
import { DashboardActionsBar, FormattedMessage as T, Icon } from '@/components';
|
||||
import classNames from 'classnames';
|
||||
import { DashboardActionsBar, FormattedMessage as T, Icon } from '@/components';
|
||||
|
||||
import { CustomersTransactionsExportMenu } from './components';
|
||||
import NumberFormatDropdown from '@/components/NumberFormatDropdown';
|
||||
|
||||
import { useCustomersTransactionsContext } from './CustomersTransactionsProvider';
|
||||
@@ -114,11 +115,18 @@ function CustomersTransactionsActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<CustomersTransactionsExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import { If } from '@/components';
|
||||
import { AppToaster, If, Stack } from '@/components';
|
||||
import { Align } from '@/constants';
|
||||
import { getColumnWidth } from '@/utils';
|
||||
import { useCustomersTransactionsContext } from './CustomersTransactionsProvider';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
import {
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
useCustomersTransactionsCsvExport,
|
||||
useCustomersTransactionsXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
import classNames from 'classnames';
|
||||
|
||||
/**
|
||||
* Retrieve customers transactions columns.
|
||||
@@ -92,3 +104,91 @@ export function CustomersTransactionsLoadingBar() {
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Customers transactions export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function CustomersTransactionsExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useCustomersTransactionsContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useCustomersTransactionsXlsxExport(
|
||||
query,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useCustomersTransactionsCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { DashboardActionsBar, Icon, FormattedMessage as T } from '@/components';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import NumberFormatDropdown from '@/components/NumberFormatDropdown';
|
||||
import { InventoryItemDetailsExportMenu } from './components';
|
||||
|
||||
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
|
||||
import withInventoryItemDetails from './withInventoryItemDetails';
|
||||
@@ -112,11 +113,18 @@ function InventoryItemDetailsActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<InventoryItemDetailsExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,12 +1,32 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import { Icon, If, FormattedMessage as T } from '@/components';
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
AppToaster,
|
||||
Icon,
|
||||
If,
|
||||
Stack,
|
||||
FormattedMessage as T,
|
||||
} from '@/components';
|
||||
|
||||
import { dynamicColumns } from './utils';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import {
|
||||
useInventoryItemDetailsCsvExport,
|
||||
useInventoryItemDetailsXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
import { useInventoryItemDetailsContext } from './InventoryItemDetailsProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import { useInventoryValuationHttpQuery } from './utils2';
|
||||
|
||||
/**
|
||||
* Retrieve inventory item details columns.
|
||||
@@ -70,3 +90,94 @@ export function InventoryItemDetailsAlerts() {
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inventory item details export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function InventoryItemDetailsExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const httpQuery = useInventoryValuationHttpQuery();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useInventoryItemDetailsXlsxExport(
|
||||
httpQuery,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useInventoryItemDetailsCsvExport(
|
||||
httpQuery,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import intl from 'react-intl-universal';
|
||||
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { transformFilterFormToQuery } from '../common';
|
||||
|
||||
/**
|
||||
* Retrieves inventory item details default query.
|
||||
@@ -73,3 +74,13 @@ export const useInventoryValuationQuery = () => {
|
||||
setLocationQuery,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the inventory valuation http query.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export const useInventoryValuationHttpQuery = () => {
|
||||
const { query } = useInventoryValuationQuery();
|
||||
|
||||
return React.useMemo(() => transformFilterFormToQuery(query), [query]);
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ import withProfitLoss from './withProfitLoss';
|
||||
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { useProfitLossSheetContext } from './ProfitLossProvider';
|
||||
import { ProfitLossSheetExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* Profit/Loss sheet actions bar.
|
||||
@@ -110,11 +111,18 @@ function ProfitLossActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<ProfitLossSheetExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// @ts-nocheck
|
||||
import React, { createContext, useContext } from 'react';
|
||||
import React, { createContext, useContext, useMemo } from 'react';
|
||||
import FinancialReportPage from '../FinancialReportPage';
|
||||
import { useProfitLossSheet } from '@/hooks/query';
|
||||
import { transformFilterFormToQuery } from '../common';
|
||||
@@ -11,15 +11,18 @@ const ProfitLossSheetContext = createContext();
|
||||
* @returns {React.JSX}
|
||||
*/
|
||||
function ProfitLossSheetProvider({ query, ...props }) {
|
||||
|
||||
const innerQuery = useMemo(() => {
|
||||
return transformFilterFormToQuery(query);
|
||||
}, [query]);
|
||||
|
||||
const {
|
||||
data: profitLossSheet,
|
||||
isFetching,
|
||||
isLoading,
|
||||
refetch,
|
||||
} = useProfitLossSheet(
|
||||
{
|
||||
...transformFilterFormToQuery(query),
|
||||
},
|
||||
innerQuery,
|
||||
{ keepPreviousData: true },
|
||||
);
|
||||
|
||||
@@ -28,6 +31,7 @@ function ProfitLossSheetProvider({ query, ...props }) {
|
||||
isLoading,
|
||||
isFetching,
|
||||
sheetRefetch: refetch,
|
||||
query: innerQuery
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,29 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import { Icon, If, FormattedMessage as T } from '@/components';
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import {
|
||||
AppToaster,
|
||||
Icon,
|
||||
If,
|
||||
Stack,
|
||||
FormattedMessage as T,
|
||||
} from '@/components';
|
||||
import { useProfitLossSheetContext } from './ProfitLossProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import {
|
||||
useProfitLossSheetCsvExport,
|
||||
useProfitLossSheetXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
import classNames from 'classnames';
|
||||
|
||||
/**
|
||||
* Profit/loss sheet loading bar.
|
||||
@@ -50,3 +68,87 @@ export function ProfitLossSheetAlerts() {
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Profit/loss sheet export menu.
|
||||
*/
|
||||
export const ProfitLossSheetExportMenu = () => {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useProfitLossSheetContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useProfitLossSheetXlsxExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useProfitLossSheetCsvExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -18,6 +18,7 @@ import { compose, saveInvoke } from '@/utils';
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
import withSalesTaxLiabilitySummary from './withSalesTaxLiabilitySummary';
|
||||
import withSalesTaxLiabilitySummaryActions from './withSalesTaxLiabilitySummaryActions';
|
||||
import { SalesTaxLiabilityExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* Sales tax liability summary - actions bar.
|
||||
@@ -113,11 +114,18 @@ function SalesTaxLiabilitySummaryActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<SalesTaxLiabilityExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
|
||||
import { useRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import { useSalesTaxLiabilitySummaryContext } from './SalesTaxLiabilitySummaryBoot';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { AppToaster, Stack } from '@/components';
|
||||
import {
|
||||
useSalesTaxLiabilitySummaryCsvExport,
|
||||
useSalesTaxLiabilitySummaryXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
import { useSalesByItemsContext } from '../SalesByItems/SalesByItemProvider';
|
||||
|
||||
/**
|
||||
* Sales tax liability summary loading bar.
|
||||
@@ -15,3 +29,94 @@ export function SalesTaxLiabilitySummaryLoadingBar() {
|
||||
}
|
||||
return <FinancialLoadingBar />;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function SalesTaxLiabilityExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useSalesTaxLiabilitySummaryContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useSalesTaxLiabilitySummaryXlsxExport(
|
||||
query,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useSalesTaxLiabilitySummaryCsvExport(
|
||||
query,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import withTrialBalance from './withTrialBalance';
|
||||
import withTrialBalanceActions from './withTrialBalanceActions';
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { useTrialBalanceSheetContext } from './TrialBalanceProvider';
|
||||
import { TrialBalanceSheetExportMenu } from './components';
|
||||
|
||||
function TrialBalanceActionsBar({
|
||||
// #withTrialBalance
|
||||
@@ -109,11 +110,18 @@ function TrialBalanceActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<TrialBalanceSheetExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,30 @@
|
||||
// @ts-nocheck
|
||||
import { Button } from '@blueprintjs/core';
|
||||
import { If, Icon, FormattedMessage as T } from '@/components';
|
||||
import { useRef } from 'react';
|
||||
import {
|
||||
Button,
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
import {
|
||||
If,
|
||||
Icon,
|
||||
FormattedMessage as T,
|
||||
Stack,
|
||||
AppToaster,
|
||||
} from '@/components';
|
||||
import { useTrialBalanceSheetContext } from './TrialBalanceProvider';
|
||||
import { FinancialComputeAlert } from '../FinancialReportPage';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import {
|
||||
useTrialBalanceSheetCsvExport,
|
||||
useTrialBalanceSheetXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
import { useTrialBalanceSheetHttpQuery } from './utils';
|
||||
|
||||
/**
|
||||
* Trial balance sheet progress loading bar.
|
||||
@@ -22,11 +43,8 @@ export function TrialBalanceSheetLoadingBar() {
|
||||
* Trial balance sheet alerts.
|
||||
*/
|
||||
export function TrialBalanceSheetAlerts() {
|
||||
const {
|
||||
trialBalanceSheet,
|
||||
isLoading,
|
||||
refetchSheet,
|
||||
} = useTrialBalanceSheetContext();
|
||||
const { trialBalanceSheet, isLoading, refetchSheet } =
|
||||
useTrialBalanceSheetContext();
|
||||
|
||||
// Handle refetch the sheet.
|
||||
const handleRecalcReport = () => {
|
||||
@@ -52,3 +70,89 @@ export function TrialBalanceSheetAlerts() {
|
||||
</FinancialComputeAlert>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trial balance sheet export menu.
|
||||
*/
|
||||
export const TrialBalanceSheetExportMenu = () => {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const httpQuery = useTrialBalanceSheetHttpQuery();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useTrialBalanceSheetXlsxExport(
|
||||
httpQuery,
|
||||
{
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useTrialBalanceSheetCsvExport(httpQuery, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import { castArray } from 'lodash';
|
||||
|
||||
import { useAppQueryString } from '@/hooks';
|
||||
import { transformToForm } from '@/utils';
|
||||
import { transformFilterFormToQuery } from '../common';
|
||||
|
||||
/**
|
||||
* Retrieves the default trial balance query.
|
||||
@@ -56,3 +57,13 @@ export const useTrialBalanceSheetQuery = () => {
|
||||
setLocationQuery,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the trial balance sheet http query.
|
||||
* @returns {object}
|
||||
*/
|
||||
export const useTrialBalanceSheetHttpQuery = () => {
|
||||
const { query } = useTrialBalanceSheetQuery();
|
||||
|
||||
return React.useMemo(() => transformFilterFormToQuery(query), [query]);
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ import withVendorsBalanceSummaryActions from './withVendorsBalanceSummaryActions
|
||||
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
|
||||
|
||||
import { saveInvoke, compose } from '@/utils';
|
||||
import { VendorSummarySheetExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* Vendors balance summary action bar.
|
||||
@@ -106,11 +107,18 @@ function VendorsBalanceSummaryActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<VendorSummarySheetExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ export default function VendorsBalanceSummaryTable({
|
||||
>
|
||||
<VendorBalanceDataTable
|
||||
columns={columns}
|
||||
data={table.data}
|
||||
data={table.rows}
|
||||
rowClassNames={tableRowTypesToClassnames}
|
||||
noInitialFetch={true}
|
||||
sticky={true}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import * as R from 'ramda';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { If } from '@/components';
|
||||
import { Align } from '@/constants';
|
||||
import { AppToaster, If, Stack } from '@/components';
|
||||
import { Align, CLASSES } from '@/constants';
|
||||
import { useVendorsBalanceSummaryContext } from './VendorsBalanceSummaryProvider';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
|
||||
import { Intent, Menu, MenuItem, ProgressBar, Text } from '@blueprintjs/core';
|
||||
import {
|
||||
useVendorBalanceSummaryCsvExport,
|
||||
useVendorBalanceSummaryXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
|
||||
/**
|
||||
* Retrieve vendors balance summary columns.
|
||||
@@ -85,3 +90,86 @@ export function VendorsSummarySheetLoadingBar() {
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor summary sheet export menu.
|
||||
* @returns {JSX.Element}
|
||||
*/
|
||||
export function VendorSummarySheetExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[CLASSES.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useVendorBalanceSummaryXlsxExport({
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useVendorBalanceSummaryCsvExport({
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport().then(() => {});
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport().then(() => {});
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import withVendorsTransaction from './withVendorsTransaction';
|
||||
import withVendorsTransactionsActions from './withVendorsTransactionsActions';
|
||||
|
||||
import { compose, saveInvoke } from '@/utils';
|
||||
import { VendorTransactionsExportMenu } from './components';
|
||||
|
||||
/**
|
||||
* vendors transactions actions bar.
|
||||
@@ -114,11 +115,18 @@ function VendorsTransactionsActionsBar({
|
||||
icon={<Icon icon="print-16" iconSize={16} />}
|
||||
text={<T id={'print'} />}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
<Popover
|
||||
content={<VendorTransactionsExportMenu />}
|
||||
interactionKind={PopoverInteractionKind.CLICK}
|
||||
placement="bottom-start"
|
||||
minimal
|
||||
>
|
||||
<Button
|
||||
className={Classes.MINIMAL}
|
||||
icon={<Icon icon="file-export-16" iconSize={16} />}
|
||||
text={<T id={'export'} />}
|
||||
/>
|
||||
</Popover>
|
||||
</NavbarGroup>
|
||||
</DashboardActionsBar>
|
||||
);
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
// @ts-nocheck
|
||||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import intl from 'react-intl-universal';
|
||||
import {
|
||||
Classes,
|
||||
Intent,
|
||||
Menu,
|
||||
MenuItem,
|
||||
ProgressBar,
|
||||
Text,
|
||||
} from '@blueprintjs/core';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { If } from '@/components';
|
||||
import { AppToaster, If, Stack } from '@/components';
|
||||
import { useVendorsTransactionsContext } from './VendorsTransactionsProvider';
|
||||
import FinancialLoadingBar from '../FinancialLoadingBar';
|
||||
import { getColumnWidth } from '@/utils';
|
||||
import {
|
||||
useVendorsTransactionsCsvExport,
|
||||
useVendorsTransactionsXlsxExport,
|
||||
} from '@/hooks/query';
|
||||
|
||||
/**
|
||||
* Retrieve vendors transactions columns.
|
||||
@@ -77,7 +90,7 @@ export const useVendorsTransactionsColumns = () => {
|
||||
};
|
||||
|
||||
/**
|
||||
* vendors transactions loading bar.
|
||||
* Vendors transactions loading bar.
|
||||
*/
|
||||
export function VendorsTransactionsLoadingBar() {
|
||||
const { isVendorsTransactionFetching } = useVendorsTransactionsContext();
|
||||
@@ -88,3 +101,86 @@ export function VendorsTransactionsLoadingBar() {
|
||||
</If>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor transactions export menu.
|
||||
*/
|
||||
export function VendorTransactionsExportMenu() {
|
||||
const toastKey = useRef(null);
|
||||
const commonToastConfig = {
|
||||
isCloseButtonShown: true,
|
||||
timeout: 2000,
|
||||
};
|
||||
const { query } = useVendorsTransactionsContext();
|
||||
|
||||
const openProgressToast = (amount: number) => {
|
||||
return (
|
||||
<Stack spacing={8}>
|
||||
<Text>The report has been exported successfully.</Text>
|
||||
<ProgressBar
|
||||
className={classNames('toast-progress', {
|
||||
[Classes.PROGRESS_NO_STRIPES]: amount >= 100,
|
||||
})}
|
||||
intent={amount < 100 ? Intent.PRIMARY : Intent.SUCCESS}
|
||||
value={amount / 100}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
// Export the report to xlsx.
|
||||
const { mutateAsync: xlsxExport } = useVendorsTransactionsXlsxExport(query, {
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Export the report to csv.
|
||||
const { mutateAsync: csvExport } = useVendorsTransactionsCsvExport({
|
||||
onDownloadProgress: (xlsxExportProgress: number) => {
|
||||
if (!toastKey.current) {
|
||||
toastKey.current = AppToaster.show({
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
});
|
||||
} else {
|
||||
AppToaster.show(
|
||||
{
|
||||
message: openProgressToast(xlsxExportProgress),
|
||||
...commonToastConfig,
|
||||
},
|
||||
toastKey.current,
|
||||
);
|
||||
}
|
||||
},
|
||||
});
|
||||
// Handle csv export button click.
|
||||
const handleCsvExportBtnClick = () => {
|
||||
csvExport();
|
||||
};
|
||||
// Handle xlsx export button click.
|
||||
const handleXlsxExportBtnClick = () => {
|
||||
xlsxExport();
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu>
|
||||
<MenuItem
|
||||
text={'XLSX (Microsoft Excel)'}
|
||||
onClick={handleXlsxExportBtnClick}
|
||||
/>
|
||||
<MenuItem text={'CSV'} onClick={handleCsvExportBtnClick} />
|
||||
</Menu>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
// @ts-nocheck
|
||||
import { useRequestQuery } from '../useQueryRequest';
|
||||
import {
|
||||
trialBalanceSheetReducer,
|
||||
generalLedgerTableRowsReducer,
|
||||
journalTableRowsReducer,
|
||||
ARAgingSummaryTableRowsMapper,
|
||||
APAgingSummaryTableRowsMapper,
|
||||
inventoryValuationReducer,
|
||||
purchasesByItemsReducer,
|
||||
salesByItemsReducer,
|
||||
} from '@/containers/FinancialStatements/reducers';
|
||||
import t from './types';
|
||||
import { useDownloadFile } from '../useDownloadFile';
|
||||
|
||||
/**
|
||||
* Retrieve balance sheet.
|
||||
@@ -33,6 +31,34 @@ export function useBalanceSheet(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useBalanceSheetXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/balance_sheet',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'balance_sheet.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useBalanceSheetCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/balance_sheet',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'balance_sheet.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve trial balance sheet.
|
||||
*/
|
||||
@@ -54,6 +80,34 @@ export function useTrialBalanceSheet(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useTrialBalanceSheetXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/trial_balance_sheet',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'trial_balance_sheet.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useTrialBalanceSheetCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/trial_balance_sheet',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'trial_balance_sheet.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve profit/loss (P&L) sheet.
|
||||
*/
|
||||
@@ -75,6 +129,34 @@ export function useProfitLossSheet(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useProfitLossSheetXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/profit_loss_sheet',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'profit_loss_sheet.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useProfitLossSheetCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/profit_loss_sheet',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'profit_loss_sheet.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve general ledger (GL) sheet.
|
||||
*/
|
||||
@@ -144,6 +226,34 @@ export function useARAgingSummaryReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useARAgingSheetXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/receivable_aging_summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'receivable_aging_summary.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useARAgingSheetCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/receivable_aging_summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'receivable_aging_summary.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve A/P aging summary report.
|
||||
*/
|
||||
@@ -165,6 +275,34 @@ export function useAPAgingSummaryReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useAPAgingSheetXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/payable_aging_summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'payable_aging_summary.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useAPAgingSheetCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/payable_aging_summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'payable_aging_summary.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve inventory valuation.
|
||||
*/
|
||||
@@ -270,6 +408,34 @@ export function useCustomerBalanceSummaryReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useCustomerBalanceSummaryXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/customer-balance-summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'customer_balance_summary.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCustomerBalanceSummaryCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/customer-balance-summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'customer_balance_summary.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve vendors balance summary report.
|
||||
*/
|
||||
@@ -299,6 +465,36 @@ export function useVendorsBalanceSummaryReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useVendorBalanceSummaryXlsxExport = (args) => {
|
||||
const url = '/financial_statements/vendor-balance-summary';
|
||||
const config = {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
};
|
||||
const filename = 'vendor_balance_summary.xlsx';
|
||||
|
||||
return useDownloadFile({
|
||||
url,
|
||||
config,
|
||||
filename,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useVendorBalanceSummaryCsvExport = (args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/vendor-balance-summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
},
|
||||
filename: 'vendor_balance_summary.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve customers transactions report.
|
||||
*/
|
||||
@@ -327,6 +523,38 @@ export function useCustomersTransactionsReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useCustomersTransactionsXlsxExport = (query, args) => {
|
||||
const url = '/financial_statements/transactions-by-customers';
|
||||
const config = {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
};
|
||||
const filename = 'customers_transactions.xlsx';
|
||||
|
||||
return useDownloadFile({
|
||||
url,
|
||||
config,
|
||||
filename,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCustomersTransactionsCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/transactions-by-customers',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'customers_transactions.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve vendors transactions report.
|
||||
*/
|
||||
@@ -344,7 +572,7 @@ export function useVendorsTransactionsReport(query, props) {
|
||||
{
|
||||
select: (res) => ({
|
||||
data: res.data.table,
|
||||
tableRows: res.data.table.data,
|
||||
tableRows: res.data.table.rows,
|
||||
}),
|
||||
defaultData: {
|
||||
tableRows: [],
|
||||
@@ -355,6 +583,38 @@ export function useVendorsTransactionsReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useVendorsTransactionsXlsxExport = (query, args) => {
|
||||
const url = '/financial_statements/transactions-by-vendors';
|
||||
const config = {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
};
|
||||
const filename = 'transactions_by_vendor.xlsx';
|
||||
|
||||
return useDownloadFile({
|
||||
url,
|
||||
config,
|
||||
filename,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useVendorsTransactionsCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/transactions-by-vendors',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'transactions_by_vendor.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve cash flow statement report.
|
||||
*/
|
||||
@@ -374,7 +634,7 @@ export function useCashFlowStatementReport(query, props) {
|
||||
columns: res.data.table.columns,
|
||||
query: res.data.query,
|
||||
meta: res.data.meta,
|
||||
tableRows: res.data.table.data,
|
||||
tableRows: res.data.table.rows,
|
||||
}),
|
||||
defaultData: {
|
||||
tableRows: [],
|
||||
@@ -387,6 +647,42 @@ export function useCashFlowStatementReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useCashFlowStatementXlsxExport = (query, args) => {
|
||||
const url = '/financial_statements/cash-flow';
|
||||
const config = {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
};
|
||||
const filename = 'cashflow_statement.xlsx';
|
||||
|
||||
return useDownloadFile({
|
||||
url,
|
||||
config,
|
||||
filename,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useCashFlowStatementCsvExport = (query, args) => {
|
||||
const url = '/financial_statements/cash-flow';
|
||||
const config = {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
};
|
||||
const filename = 'cashflow_statement.csv';
|
||||
|
||||
return useDownloadFile({
|
||||
url,
|
||||
config,
|
||||
filename,
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve inventory item detail report.
|
||||
*/
|
||||
@@ -406,7 +702,7 @@ export function useInventoryItemDetailsReport(query, props) {
|
||||
columns: res.data.table.columns,
|
||||
query: res.data.query,
|
||||
meta: res.data.meta,
|
||||
tableRows: res.data.table.data,
|
||||
tableRows: res.data.table.rows,
|
||||
}),
|
||||
defaultData: {
|
||||
tableRows: [],
|
||||
@@ -419,6 +715,34 @@ export function useInventoryItemDetailsReport(query, props) {
|
||||
);
|
||||
}
|
||||
|
||||
export const useInventoryItemDetailsXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/inventory-item-details',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'inventory_item_details.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useInventoryItemDetailsCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/inventory-item-details',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'inventory_item_details.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve transactions by reference report.
|
||||
*/
|
||||
@@ -460,3 +784,31 @@ export function useSalesTaxLiabilitySummary(query, props) {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export const useSalesTaxLiabilitySummaryXlsxExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/sales-tax-liability-summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/xlsx',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'sales_tax_liability_summary.xlsx',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
export const useSalesTaxLiabilitySummaryCsvExport = (query, args) => {
|
||||
return useDownloadFile({
|
||||
url: '/financial_statements/sales-tax-liability-summary',
|
||||
config: {
|
||||
headers: {
|
||||
accept: 'application/csv',
|
||||
},
|
||||
params: query,
|
||||
},
|
||||
filename: 'sales_tax_liability_summary.csv',
|
||||
...args,
|
||||
});
|
||||
};
|
||||
|
||||
72
packages/webapp/src/hooks/useDownloadFile.ts
Normal file
72
packages/webapp/src/hooks/useDownloadFile.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
// @ts-nocheck
|
||||
import axios, { AxiosError, AxiosRequestConfig } from 'axios';
|
||||
import { useState } from 'react';
|
||||
import { useMutation } from 'react-query';
|
||||
import useApiRequest from './useRequest';
|
||||
|
||||
interface IArgs {
|
||||
url: string;
|
||||
filename: string;
|
||||
mime?: string;
|
||||
config?: AxiosRequestConfig;
|
||||
onDownloadProgress?: (progress: number) => void;
|
||||
}
|
||||
|
||||
export const useDownloadFile = (args: IArgs) => {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
const mutation = useMutation<void, AxiosError, IArgs>(() =>
|
||||
apiRequest
|
||||
.get(args.url, {
|
||||
responseType: 'blob',
|
||||
onDownloadProgress: (ev) => {
|
||||
args.onDownloadProgress &&
|
||||
args.onDownloadProgress(Math.round((ev.loaded * 100) / ev.total));
|
||||
},
|
||||
...args.config,
|
||||
})
|
||||
.then((res) => {
|
||||
downloadFile(res.data, args.filename, args.mime);
|
||||
return res;
|
||||
}),
|
||||
);
|
||||
return { ...mutation };
|
||||
};
|
||||
|
||||
export function downloadFile(data, filename, mime, bom) {
|
||||
var blobData = typeof bom !== 'undefined' ? [bom, data] : [data];
|
||||
var blob = new Blob(blobData, { type: mime || 'application/octet-stream' });
|
||||
if (typeof window.navigator.msSaveBlob !== 'undefined') {
|
||||
// IE workaround for "HTML7007: One or more blob URLs were
|
||||
// revoked by closing the blob for which they were created.
|
||||
// These URLs will no longer resolve as the data backing
|
||||
// the URL has been freed."
|
||||
window.navigator.msSaveBlob(blob, filename);
|
||||
} else {
|
||||
var blobURL =
|
||||
window.URL && window.URL.createObjectURL
|
||||
? window.URL.createObjectURL(blob)
|
||||
: window.webkitURL.createObjectURL(blob);
|
||||
var tempLink = document.createElement('a');
|
||||
tempLink.style.display = 'none';
|
||||
tempLink.href = blobURL;
|
||||
tempLink.setAttribute('download', filename);
|
||||
|
||||
// Safari thinks _blank anchor are pop ups. We only want to set _blank
|
||||
// target if the browser does not support the HTML5 download attribute.
|
||||
// This allows you to download files in desktop safari if pop up blocking
|
||||
// is enabled.
|
||||
if (typeof tempLink.download === 'undefined') {
|
||||
tempLink.setAttribute('target', '_blank');
|
||||
}
|
||||
|
||||
document.body.appendChild(tempLink);
|
||||
tempLink.click();
|
||||
|
||||
// Fixes "webkit blob resource error 1"
|
||||
setTimeout(function () {
|
||||
document.body.removeChild(tempLink);
|
||||
window.URL.revokeObjectURL(blobURL);
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user