-
Notifications
You must be signed in to change notification settings - Fork 69
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
Add Transaction Details dispute footer for disputes not awaiting a response #7047
Merged
Jinksi
merged 82 commits into
develop
from
add/6927-dispute-details-not-awaiting-response
Sep 19, 2023
Merged
Changes from all commits
Commits
Show all changes
82 commits
Select commit
Hold shift + click to select a range
a69c6d7
Add dispute notice to transactions page
brucealdridge ec813fb
Add isAwaitingResponse dispute helper
brucealdridge 5090921
Merge branch 'develop' into add/6923-dispute-details-notice
shendy-a8c 3990811
Fix padding in dispute details on transaction details page.
shendy-a8c 625274f
Merge branch 'add/6923-dispute-details-notice' of github.com:Automatt…
shendy-a8c 065f0f4
Fix moment library import
Jinksi 1e805b6
Merge branch 'develop' into add/6923-dispute-details-notice
shendy-a8c 1dd9101
Merge remote-tracking branch 'origin/develop' into add/6923-dispute-d…
brucealdridge 294f025
Adding inquiry text
brucealdridge e00704a
Merge branch 'develop' into add/6923-dispute-details-notice
shendy-a8c 45bd7fb
Add dispute IssuerEvidence type
Jinksi d6a74bc
Add metadata key/values to Dispute TS interface
Jinksi 3697992
Add reporting_category to BalanceTransaction TS type
Jinksi bf60ee3
Init DisputeFooter element
Jinksi ee4d692
Add buttonLabel and onClick handler
Jinksi a737326
Rename variable to `message`
Jinksi 9f910c1
Fix switch statement
Jinksi b4da52c
Fix under review submission date
Jinksi 18b78ce
Add custom background colours and styles
Jinksi c4f0787
Only render DisputeFooter for supported statuses
Jinksi e1c1930
Alter text for inquires
brucealdridge fe0cee4
removing unneeded import
brucealdridge dee17ad
Adding link details to translators note
brucealdridge 8fa0cf6
Merge branch 'add/6923-dispute-details-notice' into add/6927-dispute-…
Jinksi 0f246e3
Simplify logic for determining non/actionable dispute details
Jinksi 0586881
Add tracks event for footer button click
Jinksi da4e5ec
Merge branch 'develop' into add/6923-dispute-details-notice
Jinksi fd9fc97
Merge branch 'develop' into add/6923-dispute-details-notice
Jinksi 33a090f
Merge branch 'add/6923-dispute-details-notice' into add/6927-dispute-…
Jinksi ef9d697
Re-order imports to improve code readability
Jinksi 958a2fd
Change `ExternalLink` → `<a />` to match design
Jinksi cb738d4
Add message for `Inquiry: Under Review`
Jinksi 069f54c
Create date formatting util func to improve code readability
Jinksi a6c7984
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 850b3b8
Fix redundant imports after merge
Jinksi 8b925f5
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 2a5e672
Add changelog entry
Jinksi 7298ab7
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi faab3ca
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 229e804
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi cb29af6
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi beeb5c2
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 7168b03
Fix import and TS issues after merge conflict resolution
Jinksi fbdfb97
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi f9048d3
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 4539ee8
Remove issuer_evidence additions, no longer in PR scope
Jinksi 2db2172
Use shared util function `getDisputeFee`
Jinksi d72f66d
Remove redundant <div>
Jinksi 936c17c
Leave inquiries out of PR scope
Jinksi dd50429
Add tests for non-awaiting-response dispute messages
Jinksi bb492db
Hoist up conditional for rendering DIsputeFooter to improve code read…
Jinksi 2389724
Don't render details button if no challenge submitted
Jinksi 38c50a7
Remove redundant test property definition
Jinksi a129715
Tidy up file formatting
Jinksi 2307832
Fix tracks event name
Jinksi f754c66
Add tests for expected button visibility
Jinksi 62f8c55
Test for correct fee in footer message
Jinksi 3c00b06
Use '-' fallback for undefined string variables
Jinksi 00254a1
Tests: use different timestamps for submitted/closed dates
Jinksi 01e5c03
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi e81a61d
Remove redundant CSS (from legacy BannerNotice component)
Jinksi 56a1d63
Simplify code to improve readability
Jinksi 9b4dea5
Add responsive styles for small viewports
Jinksi 05f086a
Hoist logic for DisputeFooter to parent component
Jinksi dcae9a7
Rename component to DisputeResolvedMessage
Jinksi d20f023
Refactor DisputeResolvedMessage logic to PaymentDetailsSummary
Jinksi 2682ee0
Move DIsputeDetails tests to PaymentDetailsSummary test suite
Jinksi 1be791e
Revert changes to unrelated component DisputeDetails
Jinksi 7523a8d
Rename tracks event to give more context
Jinksi 03b464c
Fix typo in staged dispute challenge notice
Jinksi d532d23
Refactor each dispute footer type to own component
Jinksi ba5829d
Rename DisputeDetails comp to clarify intended use
Jinksi 0a6eb66
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 814fdcd
Remove redundant component `DisputeResolvedMessage`
Jinksi 6f78871
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi b167054
Revert "Fix typo in staged dispute challenge notice"
Jinksi fa71276
Use `Link` element to allow native browser navigation
Jinksi e6e38ea
Ensure tracks event is recorded when CMD+clicking link
Jinksi d414429
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 4712f3e
Merge branch 'develop' into add/6927-dispute-details-not-awaiting-res…
Jinksi 582655a
Add getDisputeFeeFormatted util function
Jinksi 4910837
Explicitly import DisputeResolutionFooter styles
Jinksi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Significance: patch | ||
Type: add | ||
|
||
Behind a feature flag: dispute message added to transactions screen for disputes not needing a response. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
292 changes: 292 additions & 0 deletions
292
client/payment-details/dispute-details/dispute-resolution-footer.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,292 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React from 'react'; | ||
import moment from 'moment'; | ||
import { dateI18n } from '@wordpress/date'; | ||
import { __, sprintf } from '@wordpress/i18n'; | ||
import { Link } from '@woocommerce/components'; | ||
import { createInterpolateElement } from '@wordpress/element'; | ||
import { Button, CardFooter, Flex, FlexItem } from '@wordpress/components'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import type { Dispute } from 'wcpay/types/disputes'; | ||
import wcpayTracks from 'tracks'; | ||
import { getAdminUrl } from 'wcpay/utils'; | ||
import { getDisputeFeeFormatted, isInquiry } from 'wcpay/disputes/utils'; | ||
import './style.scss'; | ||
|
||
const DisputeUnderReviewFooter: React.FC< { | ||
dispute: Dispute; | ||
} > = ( { dispute } ) => { | ||
const submissionDateFormatted = dispute.metadata.__evidence_submitted_at | ||
? dateI18n( | ||
'M j, Y', | ||
moment | ||
.unix( | ||
parseInt( dispute.metadata.__evidence_submitted_at, 10 ) | ||
) | ||
.toISOString() | ||
) | ||
: '-'; | ||
|
||
return ( | ||
<CardFooter className="transaction-details-dispute-footer transaction-details-dispute-footer--primary"> | ||
<Flex justify="space-between"> | ||
<FlexItem> | ||
{ createInterpolateElement( | ||
sprintf( | ||
isInquiry( dispute ) | ||
? /* Translators: %s - formatted date, <a> - link to documentation page */ | ||
__( | ||
'You submitted evidence for this inquiry on %s. The cardholder’s bank is reviewing the case, which can take 120 days or more. You will be alerted when they make their final decision. <a>Learn more</a>.', | ||
'woocommerce-payments' | ||
) | ||
: /* Translators: %s - formatted date, <a> - link to documentation page */ | ||
__( | ||
'You submitted evidence for this dispute on %s. The cardholder’s bank is reviewing the case, which can take 60 days or more. You will be alerted when they make their final decision. <a>Learn more about the dispute process</a>.', | ||
'woocommerce-payments' | ||
), | ||
submissionDateFormatted | ||
), | ||
{ | ||
a: ( | ||
// eslint-disable-next-line jsx-a11y/anchor-has-content -- Link content is provided by createInterpolateElement | ||
<a | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
href="https://woocommerce.com/document/woopayments/fraud-and-disputes/" | ||
/> | ||
), | ||
} | ||
) } | ||
</FlexItem> | ||
<FlexItem className="transaction-details-dispute-footer__actions"> | ||
<Link | ||
href={ getAdminUrl( { | ||
page: 'wc-admin', | ||
path: '/payments/disputes/challenge', | ||
id: dispute?.id, | ||
} ) } | ||
> | ||
<Button | ||
variant="secondary" | ||
onClick={ () => { | ||
wcpayTracks.recordEvent( | ||
wcpayTracks.events | ||
.PAYMENT_DETAILS_VIEW_DISPUTE_EVIDENCE_BUTTON_CLICK, | ||
{ | ||
dispute_status: dispute.status, | ||
} | ||
); | ||
} } | ||
> | ||
{ __( | ||
'View submitted evidence', | ||
'woocommerce-payments' | ||
) } | ||
</Button> | ||
</Link> | ||
</FlexItem> | ||
</Flex> | ||
</CardFooter> | ||
); | ||
}; | ||
|
||
const DisputeWonFooter: React.FC< { | ||
dispute: Dispute; | ||
} > = ( { dispute } ) => { | ||
const closedDateFormatted = dispute?.metadata.__dispute_closed_at | ||
? dateI18n( | ||
'M j, Y', | ||
moment | ||
.unix( | ||
parseInt( dispute.metadata.__dispute_closed_at, 10 ) | ||
) | ||
.toISOString() | ||
) | ||
: '-'; | ||
|
||
return ( | ||
<CardFooter className="transaction-details-dispute-footer"> | ||
<Flex justify="space-between"> | ||
<FlexItem> | ||
{ createInterpolateElement( | ||
sprintf( | ||
/* Translators: %s - formatted date, <a> - link to documentation page */ | ||
__( | ||
'Good news! You won this dispute on %s. The disputed amount and the dispute fee have been credited back to your account. <a>Learn more about preventing disputes</a>.', | ||
'woocommerce-payments' | ||
), | ||
closedDateFormatted | ||
), | ||
{ | ||
a: ( | ||
// eslint-disable-next-line jsx-a11y/anchor-has-content -- Link content is provided by createInterpolateElement | ||
<a | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
href="https://woocommerce.com/document/woopayments/fraud-and-disputes/" | ||
/> | ||
), | ||
} | ||
) } | ||
</FlexItem> | ||
<FlexItem className="transaction-details-dispute-footer__actions"> | ||
<Link | ||
href={ getAdminUrl( { | ||
page: 'wc-admin', | ||
path: '/payments/disputes/challenge', | ||
id: dispute?.id, | ||
} ) } | ||
> | ||
<Button | ||
variant="secondary" | ||
onClick={ () => { | ||
wcpayTracks.recordEvent( | ||
wcpayTracks.events | ||
.PAYMENT_DETAILS_VIEW_DISPUTE_EVIDENCE_BUTTON_CLICK, | ||
{ | ||
dispute_status: dispute.status, | ||
} | ||
); | ||
} } | ||
> | ||
{ __( | ||
'View dispute details', | ||
'woocommerce-payments' | ||
) } | ||
</Button> | ||
</Link> | ||
</FlexItem> | ||
</Flex> | ||
</CardFooter> | ||
); | ||
}; | ||
|
||
const DisputeLostFooter: React.FC< { | ||
dispute: Dispute; | ||
} > = ( { dispute } ) => { | ||
const isSubmitted = !! dispute?.metadata.__evidence_submitted_at; | ||
const isAccepted = dispute?.metadata.__closed_by_merchant === '1'; | ||
const disputeFeeFormatted = getDisputeFeeFormatted( dispute ) ?? '-'; | ||
|
||
const closedDateFormatted = dispute?.metadata.__dispute_closed_at | ||
? dateI18n( | ||
'M j, Y', | ||
moment | ||
.unix( | ||
parseInt( dispute.metadata.__dispute_closed_at, 10 ) | ||
) | ||
.toISOString() | ||
) | ||
: '-'; | ||
|
||
let messagePrefix = sprintf( | ||
/* Translators: %1$s - formatted date */ | ||
__( | ||
'This dispute was lost on %1$s due to non-response.', | ||
'woocommerce-payments' | ||
), | ||
closedDateFormatted | ||
); | ||
|
||
if ( isAccepted ) { | ||
messagePrefix = sprintf( | ||
/* Translators: %1$s - formatted date */ | ||
__( | ||
'This dispute was accepted and lost on %1$s.', | ||
'woocommerce-payments' | ||
), | ||
closedDateFormatted | ||
); | ||
} | ||
|
||
if ( isSubmitted ) { | ||
messagePrefix = sprintf( | ||
/* Translators: %1$s - formatted date */ | ||
__( 'This dispute was lost on %1$s.', 'woocommerce-payments' ), | ||
closedDateFormatted | ||
); | ||
} | ||
|
||
return ( | ||
<CardFooter className="transaction-details-dispute-footer"> | ||
<Flex justify="space-between"> | ||
<FlexItem> | ||
{ messagePrefix }{ ' ' } | ||
{ createInterpolateElement( | ||
sprintf( | ||
/* Translators: %1$s – the formatted dispute fee amount, <a> - link to documentation page */ | ||
__( | ||
'The %1$s fee has been deducted from your account, and the disputed amount returned to the cardholder. <a>Learn more about preventing disputes</a>.', | ||
'woocommerce-payments' | ||
), | ||
disputeFeeFormatted | ||
), | ||
{ | ||
a: ( | ||
// eslint-disable-next-line jsx-a11y/anchor-has-content -- Link content is provided by createInterpolateElement | ||
<a | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
href="https://woocommerce.com/document/woopayments/fraud-and-disputes/" | ||
/> | ||
), | ||
} | ||
) } | ||
</FlexItem> | ||
|
||
{ isSubmitted && ( | ||
<FlexItem className="transaction-details-dispute-footer__actions"> | ||
<Link | ||
href={ getAdminUrl( { | ||
page: 'wc-admin', | ||
path: '/payments/disputes/challenge', | ||
id: dispute?.id, | ||
} ) } | ||
> | ||
<Button | ||
variant="secondary" | ||
onClick={ () => { | ||
wcpayTracks.recordEvent( | ||
wcpayTracks.events | ||
.PAYMENT_DETAILS_VIEW_DISPUTE_EVIDENCE_BUTTON_CLICK, | ||
{ | ||
dispute_status: dispute.status, | ||
} | ||
); | ||
} } | ||
> | ||
{ __( | ||
'View dispute details', | ||
'woocommerce-payments' | ||
) } | ||
</Button> | ||
</Link> | ||
</FlexItem> | ||
) } | ||
</Flex> | ||
</CardFooter> | ||
); | ||
}; | ||
|
||
const DisputeResolutionFooter: React.FC< { | ||
dispute: Dispute; | ||
} > = ( { dispute } ) => { | ||
if ( dispute.status === 'under_review' ) { | ||
return <DisputeUnderReviewFooter dispute={ dispute } />; | ||
} | ||
if ( dispute.status === 'won' ) { | ||
return <DisputeWonFooter dispute={ dispute } />; | ||
} | ||
if ( dispute.status === 'lost' ) { | ||
return <DisputeLostFooter dispute={ dispute } />; | ||
} | ||
|
||
return null; | ||
Jinksi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
export default DisputeResolutionFooter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: this util function is also used in the WIP PRs #7118 and #7093