Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
110 changes: 79 additions & 31 deletions apps/cowswap-frontend/src/locales/en-US.po

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ export function AccountModal(): ReactNode {
return (
<Dialog onOpenChange={handleOpenChange} isOpen={displayOrdersPanel}>
<Modal.Root>
<ModalHeader sticky title={<Trans>Account</Trans>} titleAs={Dialog.Title} onClose={closeAccountModal} />
<ModalHeader
sticky
title={<Trans>Account</Trans>}
titleAs={Dialog.Title}
onClose={closeAccountModal}
closeOnEscape={false}
/>

<Modal.Content>
<AccountDetails
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import { PendingOrdersPrices } from 'modules/orders'
import { useIsProviderNetworkDeprecated } from 'common/hooks/useIsProviderNetworkDeprecated'
import { calculatePrice } from 'utils/orderUtils/calculatePrice'

import { getReceiptCancellationAction } from './getReceiptCancellationAction'
import { useCloseReceiptModal, useGetAlternativeOrderModalContext, useSelectedOrder } from './OrdersReceiptModal.hooks'

import { useOrderActions } from '../../hooks/useOrderActions'
import { ReceiptModal } from '../../pure/ReceiptModal/ReceiptModal.modal'

interface OrdersReceiptModalProps {
Expand All @@ -24,7 +26,7 @@ interface OrdersReceiptModalProps {
export function OrdersReceiptModal({ pendingOrdersPrices }: OrdersReceiptModalProps): ReactNode {
// TODO: can we get selected order from URL by id?
const selectedOrder = useSelectedOrder()
// Keep the last order after close so DrawerOrDialog can animate out with content still mounted.
// Keep the last order after close so BottomDrawerOrDialog can animate out with content still mounted.
const lastOrderRef = useLatestNonNullRef(selectedOrder)
const order = selectedOrder ?? lastOrderRef.current
const isOpen = selectedOrder !== null
Expand All @@ -40,6 +42,8 @@ export function OrdersReceiptModal({ pendingOrdersPrices }: OrdersReceiptModalPr
const isChainIdDeprecated = useIsProviderNetworkDeprecated()
const alternativeOrderModalContextFromHook = useGetAlternativeOrderModalContext(order)
const alternativeOrderModalContext = isChainIdDeprecated ? undefined : alternativeOrderModalContextFromHook
const orderActions = useOrderActions()
const showCancellationModal = getReceiptCancellationAction(order, orderActions.getShowCancellationModal)

if (!chainId || !order) {
return <ReceiptModal isOpen={false} onDismiss={closeReceiptModal} order={null} />
Expand Down Expand Up @@ -80,6 +84,7 @@ export function OrdersReceiptModal({ pendingOrdersPrices }: OrdersReceiptModalPr
isOpen={isOpen}
onDismiss={closeReceiptModal}
alternativeOrderModalContext={alternativeOrderModalContext}
showCancellationModal={showCancellationModal}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ParsedOrder } from 'utils/orderUtils/parseOrder'

import { getReceiptCancellationAction } from './getReceiptCancellationAction'

describe('getReceiptCancellationAction', () => {
it('suppresses unsupported EOA TWAP cancellation', () => {
const getCancellationAction = jest.fn(() => jest.fn())
const order = { isEoaTwapOrder: true } as ParsedOrder

expect(getReceiptCancellationAction(order, getCancellationAction)).toBeNull()
expect(getCancellationAction).not.toHaveBeenCalled()
})

it('returns the existing cancellation action for supported orders', () => {
const action = jest.fn()
const getCancellationAction = jest.fn(() => action)
const order = { isEoaTwapOrder: false } as ParsedOrder

expect(getReceiptCancellationAction(order, getCancellationAction)).toBe(action)
expect(getCancellationAction).toHaveBeenCalledWith(order)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Command } from '@cowprotocol/types'

import { ParsedOrder } from 'utils/orderUtils/parseOrder'

export function getReceiptCancellationAction(
order: ParsedOrder | null,
getCancellationAction: (order: ParsedOrder) => Command | null,
): Command | null {
// Whole-order EOA TWAP cancellation is not implemented. Do not offer an action that fails after confirmation.
if (!order || order.isEoaTwapOrder) return null

return getCancellationAction(order)
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,37 @@ import { Edit, FileText, MoreVertical, Repeat, Trash2 } from 'react-feather'
import { AlternativeOrderModalContext } from '../../state/ordersTable.types'

export interface OrderContextMenuProps {
openReceipt: Command
openReceipt?: Command
activityUrl: string | undefined
showCancellationModal: Command | null
alternativeOrderModalContext?: AlternativeOrderModalContext
ariaLabel?: string
triggerSize?: number
}

export function OrderContextMenu({
openReceipt,
activityUrl,
showCancellationModal,
alternativeOrderModalContext,
ariaLabel,
triggerSize,
}: OrderContextMenuProps): ReactNode {
return (
<ContextMenuTooltip
ariaLabel={ariaLabel}
disableHoverBackground
triggerSize={triggerSize}
content={
<>
<ContextMenuItemButton onClick={openReceipt}>
<FileText size={16} />
<span>
<Trans>Order receipt</Trans>
</span>
</ContextMenuItemButton>
{openReceipt ? (
<ContextMenuItemButton onClick={openReceipt}>
<FileText size={16} />
<span>
<Trans>Order receipt</Trans>
</span>
</ContextMenuItemButton>
) : null}
{activityUrl && <ContextMenuExternalLink href={activityUrl} label={t`View on explorer`} />}
{alternativeOrderModalContext && (
<ContextMenuItemButton onClick={alternativeOrderModalContext.showAlternativeOrderModal}>
Expand Down
Loading
Loading