Skip to content

Transactions Download functionality Improvements #10211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
18537e7
Initial commit - a polling and fallback implementation on the export job
Jan 21, 2025
7dd5899
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 22, 2025
36b63a1
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 22, 2025
a83b63c
added changelog
Jan 22, 2025
8e0e5ff
Add useReportExport hook to encapsulate polling logic for PR 10211 (#…
Jinksi Jan 22, 2025
5b6f19f
Bug fixes & Changes for DownloadURLResponse
Jan 22, 2025
6f07d37
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 23, 2025
bb4ef71
Deleted tests relating to the removed JS CSV download functionality.
Jan 23, 2025
7844339
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 23, 2025
1147a9a
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 23, 2025
af1565e
Added checks for status in response.
Jan 24, 2025
41761af
Merge branch 'develop' into update/9969-poll-async-job
Jan 27, 2025
2ab9414
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 28, 2025
0b192b5
Should handle the error if downloadURL API sends 500 error.
Jan 28, 2025
f873f02
Merge branch 'update/9969-poll-async-job' of https://github.com/Autom…
Jan 28, 2025
c35c46f
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Jan 28, 2025
d6c0187
Removed some unused variables in the test file.
Jan 28, 2025
85ab388
Merge branch 'develop' into update/9969-poll-async-job
shendy-a8c Jan 28, 2025
57378fc
Add test for report export hook
Jan 29, 2025
b09a259
Merge branch 'develop' into update/9969-poll-async-job
Jan 29, 2025
bfc7cb1
Merge branch 'develop' into update/9969-poll-async-job
Jan 30, 2025
456eab1
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Feb 3, 2025
568023b
Remove labelInCsv as it was used only for the
Feb 3, 2025
c899e42
Added a new event wcpay_transactions_download_csv_in_browser. Registered
Feb 3, 2025
8b3e2f2
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Feb 3, 2025
99972d4
Merge branch 'develop' into update/9969-poll-async-job
shendy-a8c Feb 4, 2025
7417922
Merge branch 'develop' into update/9969-poll-async-job
jessy-p Feb 5, 2025
0fe8490
Address review comments
Feb 5, 2025
dde44da
Merge branch 'update/9969-poll-async-job' of https://github.com/Autom…
Feb 5, 2025
d7e1f6d
Changed to a single notice.
Feb 5, 2025
4c65152
Merge branch 'develop' into update/9969-poll-async-job
shendy-a8c Feb 5, 2025
7e10a7d
Fix unit test after createNotice() call for success case is removed f…
shendy-a8c Feb 5, 2025
cfead56
Remove unused sprintf import from use-report-export hook
Jinksi Feb 6, 2025
d0c1395
Merge branch 'develop' into update/9969-poll-async-job
Jinksi Feb 6, 2025
b068840
Add documentation for export response interfaces in use-report-export…
Jinksi Feb 6, 2025
b52e61f
Add isBusy prop to DownloadButton component for export progress indic…
Jinksi Feb 6, 2025
b6eb6dc
Merge branch 'develop' into update/9969-poll-async-job
Feb 7, 2025
4b815ae
Rename 'Download' button label to 'Export'
Feb 7, 2025
3b84602
Change icon on Export button
Feb 7, 2025
291610c
Merge branch 'develop' into update/9969-poll-async-job
Feb 7, 2025
4354fe3
Update snackbar notice
Feb 7, 2025
ef7b796
Update changelog
Feb 7, 2025
0545283
Merge branch 'develop' into update/9969-poll-async-job
Feb 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/update-9969-poll-async-job
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: update

Improve CSV export experience and deliver consistent reports via async transact platform service-based CSV exports.
22 changes: 19 additions & 3 deletions client/components/download-button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
import { Button } from '@wordpress/components';
import CloudDownloadIcon from 'gridicons/dist/cloud-download';

/**
* Internal dependencies
Expand All @@ -15,21 +14,38 @@ import './style.scss';

interface DownloadButtonProps {
isDisabled: boolean;
isBusy?: boolean;
onClick: ( event: any ) => void;
}

const DownloadButton: React.FunctionComponent< DownloadButtonProps > = ( {
isDisabled,
isBusy,
onClick,
} ) => (
<Button
className="woocommerce-table__download-button"
disabled={ isDisabled }
onClick={ onClick }
isBusy={ isBusy }
>
<CloudDownloadIcon />
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M18.5 15v5H20v-5h-1.5zM4 15v5h1.5v-5H4zm0 5h16v-1.5H4V20z" />
<path
d="M12.25 16L6.5 10.75M12.25 16V3M12.25 16l5.25-5.25"
stroke="currentColor"
strokeWidth="1.5"
fill="none"
/>
</svg>
<span className="woocommerce-table__download-button__label">
{ __( 'Download', 'woocommerce-payments' ) }
{ __( 'Export', 'woocommerce-payments' ) }
</span>
</Button>
);
Expand Down
36 changes: 22 additions & 14 deletions client/components/download-button/test/__snapshots__/index.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,26 @@ exports[`DownloadButton renders a disabled button 1`] = `
type="button"
>
<svg
class="gridicon gridicons-cloud-download"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M18 9c-.009 0-.017.002-.025.003A6.496 6.496 0 005 9.5a6.5 6.5 0 00.186 1.519C5.123 11.016 5.064 11 5 11a4 4 0 00-4 4c0 1.202.541 2.267 1.38 3h18.593C22.196 17.089 23 15.643 23 14a5 5 0 00-5-5zm-6 7l-4-5h3V8h2v3h3l-4 5z"
/>
</g>
<path
d="M18.5 15v5H20v-5h-1.5zM4 15v5h1.5v-5H4zm0 5h16v-1.5H4V20z"
/>
<path
d="M12.25 16L6.5 10.75M12.25 16V3M12.25 16l5.25-5.25"
fill="none"
stroke="currentColor"
stroke-width="1.5"
/>
</svg>
<span
class="woocommerce-table__download-button__label"
>
Download
Export
</span>
</button>
</div>
Expand All @@ -36,22 +40,26 @@ exports[`DownloadButton renders an active button 1`] = `
type="button"
>
<svg
class="gridicon gridicons-cloud-download"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M18 9c-.009 0-.017.002-.025.003A6.496 6.496 0 005 9.5a6.5 6.5 0 00.186 1.519C5.123 11.016 5.064 11 5 11a4 4 0 00-4 4c0 1.202.541 2.267 1.38 3h18.593C22.196 17.089 23 15.643 23 14a5 5 0 00-5-5zm-6 7l-4-5h3V8h2v3h3l-4 5z"
/>
</g>
<path
d="M18.5 15v5H20v-5h-1.5zM4 15v5h1.5v-5H4zm0 5h16v-1.5H4V20z"
/>
<path
d="M12.25 16L6.5 10.75M12.25 16V3M12.25 16l5.25-5.25"
fill="none"
stroke="currentColor"
stroke-width="1.5"
/>
</svg>
<span
class="woocommerce-table__download-button__label"
>
Download
Export
</span>
</button>
</div>
Expand Down
5 changes: 3 additions & 2 deletions client/data/transactions/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,10 @@ export function* getTransactions( query ) {
}
}

export function getTransactionsCSV( query ) {
export const transactionsDownloadEndpoint = `${ NAMESPACE }/transactions/download`;
export function getTransactionsCSVRequestURL( query ) {
const path = addQueryArgs(
`${ NAMESPACE }/transactions/download`,
transactionsDownloadEndpoint,
formatQueryFilters( query )
);

Expand Down
36 changes: 22 additions & 14 deletions client/deposits/list/test/__snapshots__/index.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,26 @@ exports[`Deposits list renders correctly a single deposit 1`] = `
type="button"
>
<svg
class="gridicon gridicons-cloud-download"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M18 9c-.009 0-.017.002-.025.003A6.496 6.496 0 005 9.5a6.5 6.5 0 00.186 1.519C5.123 11.016 5.064 11 5 11a4 4 0 00-4 4c0 1.202.541 2.267 1.38 3h18.593C22.196 17.089 23 15.643 23 14a5 5 0 00-5-5zm-6 7l-4-5h3V8h2v3h3l-4 5z"
/>
</g>
<path
d="M18.5 15v5H20v-5h-1.5zM4 15v5h1.5v-5H4zm0 5h16v-1.5H4V20z"
/>
<path
d="M12.25 16L6.5 10.75M12.25 16V3M12.25 16l5.25-5.25"
fill="none"
stroke="currentColor"
stroke-width="1.5"
/>
</svg>
<span
class="woocommerce-table__download-button__label"
>
Download
Export
</span>
</button>
</div>
Expand Down Expand Up @@ -796,22 +800,26 @@ exports[`Deposits list renders correctly with multiple currencies 1`] = `
type="button"
>
<svg
class="gridicon gridicons-cloud-download"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M18 9c-.009 0-.017.002-.025.003A6.496 6.496 0 005 9.5a6.5 6.5 0 00.186 1.519C5.123 11.016 5.064 11 5 11a4 4 0 00-4 4c0 1.202.541 2.267 1.38 3h18.593C22.196 17.089 23 15.643 23 14a5 5 0 00-5-5zm-6 7l-4-5h3V8h2v3h3l-4 5z"
/>
</g>
<path
d="M18.5 15v5H20v-5h-1.5zM4 15v5h1.5v-5H4zm0 5h16v-1.5H4V20z"
/>
<path
d="M12.25 16L6.5 10.75M12.25 16V3M12.25 16l5.25-5.25"
fill="none"
stroke="currentColor"
stroke-width="1.5"
/>
</svg>
<span
class="woocommerce-table__download-button__label"
>
Download
Export
</span>
</button>
</div>
Expand Down
14 changes: 7 additions & 7 deletions client/deposits/list/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,15 @@ describe( 'Deposits list', () => {
expect( tableSummary ).toHaveLength( 1 );
} );

describe( 'Download button', () => {
describe( 'Export button', () => {
test( 'renders when there are one or more deposits', () => {
mockUseDeposits.mockReturnValue( {
deposits: mockDeposits,
isLoading: false,
} as CachedDeposits );

const { queryByRole } = render( <DepositsList /> );
const button = queryByRole( 'button', { name: 'Download' } );
const button = queryByRole( 'button', { name: 'Export' } );

expect( button ).not.toBeNull();
} );
Expand All @@ -266,7 +266,7 @@ describe( 'Deposits list', () => {
} as CachedDeposits );

const { queryByRole } = render( <DepositsList /> );
const button = queryByRole( 'button', { name: 'Download' } );
const button = queryByRole( 'button', { name: 'Export' } );

expect( button ).toBeNull();
} );
Expand All @@ -291,7 +291,7 @@ describe( 'Deposits list', () => {

test( 'should render expected columns in CSV when the download button is clicked', () => {
const { getByRole } = render( <DepositsList /> );
getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

const expected = [
'"Payout Id"',
Expand All @@ -310,7 +310,7 @@ describe( 'Deposits list', () => {

test( 'should match the visible rows', () => {
const { getByRole, getAllByRole } = render( <DepositsList /> );
getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

const csvContent = mockDownloadCSVFile.mock.calls[ 0 ][ 1 ];
const csvRows = csvContent.split( os.EOL );
Expand Down Expand Up @@ -363,7 +363,7 @@ describe( 'Deposits list', () => {

const { getByRole } = render( <DepositsList /> );

getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

expect( window.confirm ).toHaveBeenCalledTimes( 1 );
expect( window.confirm ).toHaveBeenCalledWith(
Expand Down Expand Up @@ -392,7 +392,7 @@ describe( 'Deposits list', () => {

const { getByRole } = render( <DepositsList /> );

getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

expect( window.confirm ).toHaveBeenCalledTimes( 1 );
expect( window.confirm ).toHaveBeenCalledWith(
Expand Down
18 changes: 11 additions & 7 deletions client/disputes/test/__snapshots__/index.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -79,22 +79,26 @@ exports[`Disputes list renders correctly 1`] = `
type="button"
>
<svg
class="gridicon gridicons-cloud-download"
fill="currentColor"
height="24"
viewBox="0 0 24 24"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<g>
<path
d="M18 9c-.009 0-.017.002-.025.003A6.496 6.496 0 005 9.5a6.5 6.5 0 00.186 1.519C5.123 11.016 5.064 11 5 11a4 4 0 00-4 4c0 1.202.541 2.267 1.38 3h18.593C22.196 17.089 23 15.643 23 14a5 5 0 00-5-5zm-6 7l-4-5h3V8h2v3h3l-4 5z"
/>
</g>
<path
d="M18.5 15v5H20v-5h-1.5zM4 15v5h1.5v-5H4zm0 5h16v-1.5H4V20z"
/>
<path
d="M12.25 16L6.5 10.75M12.25 16V3M12.25 16l5.25-5.25"
fill="none"
stroke="currentColor"
stroke-width="1.5"
/>
</svg>
<span
class="woocommerce-table__download-button__label"
>
Download
Export
</span>
</button>
</div>
Expand Down
10 changes: 5 additions & 5 deletions client/disputes/test/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ describe( 'Disputes list', () => {
} );

const { queryByRole } = render( <DisputesList /> );
const button = queryByRole( 'button', { name: 'Download' } );
const button = queryByRole( 'button', { name: 'Export' } );

expect( button ).not.toBeNull();
} );
Expand All @@ -290,7 +290,7 @@ describe( 'Disputes list', () => {
} );

const { queryByRole } = render( <DisputesList /> );
const button = queryByRole( 'button', { name: 'Download' } );
const button = queryByRole( 'button', { name: 'Export' } );

expect( button ).toBeNull();
} );
Expand Down Expand Up @@ -323,7 +323,7 @@ describe( 'Disputes list', () => {

const { getByRole } = render( <DisputesList /> );

getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

expect( window.confirm ).toHaveBeenCalledTimes( 1 );
expect( window.confirm ).toHaveBeenCalledWith(
Expand All @@ -342,7 +342,7 @@ describe( 'Disputes list', () => {

test( 'should render expected columns in CSV when the download button is clicked ', () => {
const { getByRole } = render( <DisputesList /> );
getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

const expected = [
'"Dispute Id"',
Expand All @@ -366,7 +366,7 @@ describe( 'Disputes list', () => {

test( 'should match the visible rows', () => {
const { getByRole, getAllByRole } = render( <DisputesList /> );
getByRole( 'button', { name: 'Download' } ).click();
getByRole( 'button', { name: 'Export' } ).click();

const csvContent = mockDownloadCSVFile.mock.calls[ 0 ][ 1 ];
const csvRows = csvContent.split( os.EOL );
Expand Down
Loading
Loading