-
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 a new page component for redirecting disputes => details: #7310
Changes from 14 commits
86e8a85
1409a10
55c3f5a
8d3a244
466877d
83054c8
bf4eee8
83dcc37
73b5a8f
416c7ed
74267c0
341e7f6
1520273
d5d7a2e
042880f
500b176
8986b83
9fe73b5
e977712
1a2f772
c97fb30
2c4dbfc
ad9a2ee
45349c1
9a3df78
1a76dce
54ac2ce
bec0846
5e006f8
6111fac
6b00887
6216ae0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,11 +27,19 @@ const DisputeDetails = ( { | |
query: { id: disputeId }, | ||
}: { | ||
query: { id: string }; | ||
} ): JSX.Element => { | ||
} ): JSX.Element | null => { | ||
const { dispute, isLoading, doAccept } = useDispute( disputeId ); | ||
const disputeObject = dispute || ( {} as Dispute ); | ||
const disputeIsAvailable = ! isLoading && dispute && disputeObject.id; | ||
|
||
// Bail early and return nothing if the feature flag is not enabled. | ||
// Here as a hint/reminder to delete this file when the feature flag is removed. | ||
const isDisputeOnTransactionPageEnabled = | ||
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. Hmm.. I think this is not necessary because this component does not need to know the business logic of when it will be rendered or not. You already check the feature flag when registering the page, ie when feature flag is on, you register I cannot find any reference to this If the purpose of this change is as a reminder to remove this legacy dispute details component, I'd say we can just mentioned it in #7289. What do you think? |
||
wcpaySettings.featureFlags.isDisputeOnTransactionPageEnabled; | ||
Jinksi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if ( isDisputeOnTransactionPageEnabled ) { | ||
return null; | ||
} | ||
|
||
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. Added this so when we're working on #7289 we find this class (search for feature flag) and remember to delete it. 🐘 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. To be explicit, I just added one check item in #7289:
|
||
const actions = disputeIsAvailable && ( | ||
<Actions | ||
id={ disputeObject.id } | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import React from 'react'; | ||
import { getHistory } from '@woocommerce/navigation'; | ||
import { Notice, Spinner, Flex, FlexItem } from '@wordpress/components'; | ||
|
||
/** | ||
* Internal dependencies. | ||
*/ | ||
import Page from 'components/page'; | ||
import { useDispute } from 'data/index'; | ||
import { Charge } from 'wcpay/types/charges'; | ||
import { Dispute } from 'wcpay/types/disputes'; | ||
import { getAdminUrl } from 'wcpay/utils'; | ||
|
||
const RedirectToTransactionDetails = ( { | ||
query: { id: disputeId }, | ||
}: { | ||
query: { id: string }; | ||
} ): JSX.Element | null => { | ||
const { dispute, isLoading } = useDispute( disputeId ); | ||
const disputeObject = dispute || ( {} as Dispute ); | ||
const disputeIsAvailable = ! isLoading && dispute && disputeObject.id; | ||
// Dispute type allows charge as nested object or string ID, | ||
// so we have to hint we expect a Charge object here. | ||
const chargeObject = disputeObject.charge as Charge; | ||
|
||
let transactionDetailsUrl = ''; | ||
if ( disputeIsAvailable ) { | ||
transactionDetailsUrl = getAdminUrl( { | ||
page: 'wc-admin', | ||
path: '/payments/transactions/details', | ||
id: chargeObject.payment_intent, | ||
transaction_id: chargeObject.balance_transaction, | ||
type: 'dispute', | ||
} ); | ||
getHistory().replace( transactionDetailsUrl ); | ||
return null; | ||
} | ||
|
||
return ( | ||
<Page> | ||
<Notice status="info" isDismissible={ false }> | ||
<Flex justify="left"> | ||
<FlexItem> | ||
<Spinner /> | ||
</FlexItem> | ||
<FlexItem> | ||
<span>Redirecting to payment details…</span> | ||
</FlexItem> | ||
</Flex> | ||
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. Happy days using core components to get a nice, consistent look out of the box! |
||
</Notice> | ||
</Page> | ||
); | ||
}; | ||
|
||
export default RedirectToTransactionDetails; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ import TransactionsPage from 'transactions'; | |
import PaymentDetailsPage from 'payment-details'; | ||
import DisputesPage from 'disputes'; | ||
import DisputeDetailsPage from 'disputes/details'; | ||
import RedirectToTransactionDetails from 'disputes/redirect-to-transaction-details'; | ||
import DisputeEvidencePage from 'disputes/evidence'; | ||
import AdditionalMethodsPage from 'wcpay/additional-methods-setup'; | ||
import MultiCurrencySetupPage from 'wcpay/multi-currency-setup'; | ||
|
@@ -150,24 +151,51 @@ addFilter( | |
}, | ||
capability: 'manage_woocommerce', | ||
} ); | ||
pages.push( { | ||
container: DisputeDetailsPage, | ||
path: '/payments/disputes/details', | ||
wpOpenMenu: menuID, | ||
breadcrumbs: [ | ||
rootLink, | ||
[ | ||
'/payments/disputes', | ||
__( 'Disputes', 'woocommerce-payments' ), | ||
], | ||
__( 'Dispute details', 'woocommerce-payments' ), | ||
], | ||
navArgs: { | ||
id: 'wc-payments-disputes-details', | ||
parentPath: '/payments/disputes', | ||
}, | ||
capability: 'manage_woocommerce', | ||
} ); | ||
|
||
// If disputes on transaction page feature is enabled, set up a soft | ||
// redirect component; otherwise register the (legacy) dispute details page. | ||
const isDisputeOnTransactionPageEnabled = | ||
window.wcpaySettings.featureFlags.isDisputeOnTransactionPageEnabled; | ||
pages.push( | ||
isDisputeOnTransactionPageEnabled | ||
? { | ||
container: RedirectToTransactionDetails, | ||
path: '/payments/disputes/details', | ||
wpOpenMenu: menuID, | ||
breadcrumbs: [ | ||
rootLink, | ||
[ | ||
'/payments/disputes', | ||
__( 'Disputes', 'woocommerce-payments' ), | ||
], | ||
__( 'Dispute details', 'woocommerce-payments' ), | ||
], | ||
navArgs: { | ||
id: 'wc-payments-disputes-details-legacy-redirect', | ||
parentPath: '/payments/disputes', | ||
}, | ||
capability: 'manage_woocommerce', | ||
} | ||
: { | ||
container: DisputeDetailsPage, | ||
path: '/payments/disputes/details', | ||
wpOpenMenu: menuID, | ||
breadcrumbs: [ | ||
rootLink, | ||
[ | ||
'/payments/disputes', | ||
__( 'Disputes', 'woocommerce-payments' ), | ||
], | ||
__( 'Dispute details', 'woocommerce-payments' ), | ||
], | ||
navArgs: { | ||
id: 'wc-payments-disputes-details', | ||
parentPath: '/payments/disputes', | ||
}, | ||
capability: 'manage_woocommerce', | ||
} | ||
); | ||
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. I was expecting only the Why Also, not sure what the correlation between this page registration in Javascript and in PHP. Per the docs, react powered page needs to be registered both in Javascript and PHP. |
||
|
||
pages.push( { | ||
container: DisputeEvidencePage, | ||
path: '/payments/disputes/challenge', | ||
|
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.
I'm (now) in the habit of declaring React components as
Element | null
, consistent with classic React. As I understand, returning null is totally fine way to not render anything.Question for front end experts – is this a good approach? Should we have a standard type for this? What does the TypeScript React community do?
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.
Not a frontend expert but since as of currently, there is a possibility this component will return null, this
| null
addition is necessary.However, I have my opinion that checking for feature flag and returning null is not necessary here. Read along =)
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 that when we use
React.FC
/React.FunctionComponent
, the return type is implicit and we don't have to define it (see TS guidelines doc).I've switched this to
React.FC
in 2c4dbfc.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.
Aha! Now I'm a fan of
React.FC
and will use from here on in. Can we encourage that pattern with a linter or tooling?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.
Looking at the doc, we might be able to distil this to a principle:
Use React.FC type for React components