diff --git a/packages/core/src/App/Containers/Layout/header/__tests__/dtrader-contract-details-header.spec.tsx b/packages/core/src/App/Containers/Layout/header/__tests__/dtrader-contract-details-header.spec.tsx
index a587b56adf2e..85854d8314c2 100644
--- a/packages/core/src/App/Containers/Layout/header/__tests__/dtrader-contract-details-header.spec.tsx
+++ b/packages/core/src/App/Containers/Layout/header/__tests__/dtrader-contract-details-header.spec.tsx
@@ -1,22 +1,39 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
-import '@testing-library/jest-dom';
-import { Router } from 'react-router-dom';
-import { createMemoryHistory } from 'history';
+import { BrowserRouter, useHistory, useLocation } from 'react-router-dom';
import DTraderContractDetailsHeader from '../dtrader-v2-contract-detail-header';
import userEvent from '@testing-library/user-event';
+import { StoreProvider, mockStore } from '@deriv/stores';
jest.mock('@deriv-com/quill-ui', () => ({
Text: () =>
Contract Details
,
}));
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useLocation: jest.fn().mockReturnValue({ pathname: '' }),
+ useHistory: jest.fn().mockReturnValue({
+ goBack: jest.fn(),
+ }),
+}));
describe('DTraderV2Header', () => {
+ const mock_store = mockStore({
+ contract_replay: {
+ onClickCancel: jest.fn(),
+ onClickSell: jest.fn(),
+ is_sell_requested: false,
+ },
+ common: {
+ routeBackInApp: jest.fn(),
+ },
+ });
test('renders the header with localized text and an icon', () => {
- const history = createMemoryHistory();
render(
-
-
-
+
+
+
+
+
);
expect(screen.getByText('Contract Details')).toBeInTheDocument();
@@ -25,19 +42,39 @@ describe('DTraderV2Header', () => {
expect(icon).toBeInTheDocument();
});
- test('clicking the back arrow calls history.goBack', () => {
- const history = createMemoryHistory();
+ test('clicking the back arrow calls routeBackInApp from DTrader page', () => {
+ render(
+
+
+
+
+
+ );
- history.goBack = jest.fn();
+ userEvent.click(screen.getByTestId('arrow'));
+
+ expect(mock_store.common.routeBackInApp).toHaveBeenCalled();
+ });
+ test('clicking the back arrow calls history go back from Reports page', () => {
+ const historyMock = {
+ goBack: jest.fn(),
+ };
+ (useLocation as jest.Mock).mockReturnValue({
+ pathname: '',
+ state: { from_table_row: true },
+ });
+ (useHistory as jest.Mock).mockReturnValue(historyMock);
render(
-
-
-
+
+
+
+
+
);
userEvent.click(screen.getByTestId('arrow'));
- expect(history.goBack).toHaveBeenCalled();
+ expect(historyMock.goBack).toHaveBeenCalled();
});
});
diff --git a/packages/core/src/App/Containers/Layout/header/dtrader-v2-contract-detail-header.tsx b/packages/core/src/App/Containers/Layout/header/dtrader-v2-contract-detail-header.tsx
index f7aaf1372b3a..9f481e7b9e8a 100644
--- a/packages/core/src/App/Containers/Layout/header/dtrader-v2-contract-detail-header.tsx
+++ b/packages/core/src/App/Containers/Layout/header/dtrader-v2-contract-detail-header.tsx
@@ -1,12 +1,21 @@
import React from 'react';
-import { observer } from '@deriv/stores';
+import { observer, useStore } from '@deriv/stores';
import { Text } from '@deriv-com/quill-ui';
import { LabelPairedArrowLeftSmBoldIcon } from '@deriv/quill-icons';
import { Localize } from '@deriv/translations';
-import { useHistory } from 'react-router-dom';
+import { useHistory, useLocation } from 'react-router-dom';
+import { isEmptyObject } from '@deriv/shared';
const DTraderContractDetailsHeader = observer(() => {
+ const { state } = useLocation();
const history = useHistory();
+ const { common } = useStore();
+ const { routeBackInApp } = common;
+
+ const handleBack = () => {
+ const is_from_table_row = !isEmptyObject(state) ? state.from_table_row : false;
+ return is_from_table_row ? history.goBack() : routeBackInApp(history);
+ };
return (
@@ -16,7 +25,7 @@ const DTraderContractDetailsHeader = observer(() => {
width='13px'
className='arrow'
data-testid='arrow'
- onClick={() => history.goBack()}
+ onClick={handleBack}
/>
diff --git a/packages/core/src/sass/app/_common/layout/header.scss b/packages/core/src/sass/app/_common/layout/header.scss
index 3aa2ba26793b..02fc57f2ea47 100644
--- a/packages/core/src/sass/app/_common/layout/header.scss
+++ b/packages/core/src/sass/app/_common/layout/header.scss
@@ -437,6 +437,7 @@
padding: var(--core-spacing-600) var(--core-spacing-50);
.arrow {
position: absolute;
+ cursor: pointer;
left: var(--core-size-1200);
}
}
diff --git a/packages/shared/src/utils/constants/contract.ts b/packages/shared/src/utils/constants/contract.ts
index 913b703a7f78..65d5764a96bd 100644
--- a/packages/shared/src/utils/constants/contract.ts
+++ b/packages/shared/src/utils/constants/contract.ts
@@ -312,6 +312,59 @@ export const getCardLabels = () =>
WON: localize('Won'),
} as const);
+export const getCardLabelsV2 = () =>
+ ({
+ APPLY: localize('Apply'),
+ BARRIER: localize('Barrier'),
+ BUY_PRICE: localize('Buy price'),
+ CANCEL: localize('Cancel'),
+ CLOSE: localize('Close'),
+ CLOSED: localize('Closed'),
+ COMMISSION: localize('Commission'),
+ CONTRACT_COST: localize('Contract cost'),
+ CONTRACT_VALUE: localize('Contract value'),
+ CURRENT_STAKE: localize('Current stake'),
+ DAY: localize('day'),
+ DAYS: localize('days'),
+ DEAL_CANCEL_FEE: localize('Deal cancel. fee'),
+ DECREMENT_VALUE: localize('Decrement value'),
+ DONT_SHOW_THIS_AGAIN: localize("Don't show this again"),
+ DURATION: localize('Duration'),
+ ENTRY_SPOT: localize('Entry spot'),
+ GROWTH_RATE: localize('Growth rate'),
+ INCREMENT_VALUE: localize('Increment value'),
+ INDICATIVE_PRICE: localize('Indicative price'),
+ INITIAL_STAKE: localize('Initial stake'),
+ LOST: localize('Lost'),
+ MULTIPLIER: localize('Multiplier'),
+ NOT_AVAILABLE: localize('N/A'),
+ NOT_SET: localize('Not set'),
+ PAYOUT: localize('Sell price'),
+ PAYOUT_PER_POINT: localize('Payout per point'),
+ POTENTIAL_PAYOUT: localize('Potential payout'),
+ POTENTIAL_PROFIT_LOSS: localize('Potential profit/loss'),
+ PROFIT_LOSS: localize('Profit/Loss'),
+ PURCHASE_PRICE: localize('Buy price'),
+ REFERENCE_ID: localize('Reference ID'),
+ RESALE_NOT_OFFERED: localize('Resale not offered'),
+ SELL: localize('Sell'),
+ STAKE: localize('Stake'),
+ STOP_LOSS: localize('Stop loss'),
+ STOP_OUT_LEVEL: localize('Stop out level'),
+ STRIKE: localize('Strike'),
+ STRIKE_PRICE: localize('Strike Price'),
+ TAKE_PROFIT: localize('Take profit'),
+ TAKE_PROFIT_IS_NOT_AVAILABLE: localize("Take profit can't be adjusted for ongoing accumulator contracts."),
+ TAKE_PROFIT_LOSS_NOT_AVAILABLE: localize(
+ 'Take profit and/or stop loss are not available while deal cancellation is active.'
+ ),
+ TARGET: localize('Target'),
+ TICK: localize('Tick'),
+ TICKS: localize('Ticks'),
+ TOTAL_PROFIT_LOSS: localize('Total profit/loss'),
+ WON: localize('Won'),
+ } as const);
+
export const getMarketNamesMap = () =>
({
FRXAUDCAD: localize('AUD/CAD'),
diff --git a/packages/trader/src/AppV2/Components/ContractDetailsFooter/__tests__/contract-details-footer.spec.tsx b/packages/trader/src/AppV2/Components/ContractDetailsFooter/__tests__/contract-details-footer.spec.tsx
index 588632321b50..649b33ea53a4 100644
--- a/packages/trader/src/AppV2/Components/ContractDetailsFooter/__tests__/contract-details-footer.spec.tsx
+++ b/packages/trader/src/AppV2/Components/ContractDetailsFooter/__tests__/contract-details-footer.spec.tsx
@@ -2,13 +2,12 @@ import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import { StoreProvider, mockStore } from '@deriv/stores';
-import { getCardLabels, isValidToSell, isValidToCancel, isMultiplierContract } from '@deriv/shared';
+import { isValidToSell, isValidToCancel, isMultiplierContract } from '@deriv/shared';
import ContractDetailsFooter from '../contract-details-footer';
import userEvent from '@testing-library/user-event';
jest.mock('@deriv/shared', () => ({
...jest.requireActual('@deriv/shared'),
- getCardLabels: jest.fn(),
isValidToSell: jest.fn(),
isValidToCancel: jest.fn(),
isMultiplierContract: jest.fn(),
@@ -34,15 +33,6 @@ describe('ContractDetailsFooter', () => {
},
});
- beforeEach(() => {
- (getCardLabels as jest.Mock).mockImplementation(() => ({
- CLOSE: 'Close',
- CANCEL: 'Cancel',
- RESALE_NOT_OFFERED: 'Resale not offered',
- }));
- jest.clearAllMocks();
- });
-
const renderFooter = () => {
render(
@@ -94,6 +84,16 @@ describe('ContractDetailsFooter', () => {
expect(mock_store.contract_replay.onClickSell).toHaveBeenCalledWith(1);
});
+ it('should not call onClickSell if not valid to sell', () => {
+ (isMultiplierContract as jest.Mock).mockImplementation(() => false);
+ (isValidToSell as jest.Mock).mockImplementation(() => false);
+
+ renderFooter();
+
+ const closeButton = screen.queryByRole('button');
+ expect(closeButton).toBeDisabled();
+ });
+
it('should disable cancel button when profit is non-negative', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => true);
(isValidToCancel as jest.Mock).mockImplementation(() => true);
@@ -114,20 +114,6 @@ describe('ContractDetailsFooter', () => {
expect(cancelButton).not.toBeInTheDocument();
});
- it('should not call onClickSell if not valid to sell', () => {
- (isMultiplierContract as jest.Mock).mockImplementation(() => false);
- (isValidToSell as jest.Mock).mockImplementation(() => false);
-
- renderFooter();
-
- const closeButton = screen.queryByRole('button', { name: /close @ 100.00 usd/i });
- if (closeButton) {
- userEvent.click(closeButton);
- }
-
- expect(mock_store.contract_replay.onClickSell).not.toHaveBeenCalled();
- });
-
it('should render correct button label for non-multiplier contract when not valid to sell', () => {
(isMultiplierContract as jest.Mock).mockImplementation(() => false);
(isValidToSell as jest.Mock).mockImplementation(() => false);
diff --git a/packages/trader/src/AppV2/Components/ContractDetailsFooter/contract-details-footer.tsx b/packages/trader/src/AppV2/Components/ContractDetailsFooter/contract-details-footer.tsx
index 28e55ac41399..63ad62ac6820 100644
--- a/packages/trader/src/AppV2/Components/ContractDetailsFooter/contract-details-footer.tsx
+++ b/packages/trader/src/AppV2/Components/ContractDetailsFooter/contract-details-footer.tsx
@@ -1,10 +1,11 @@
import { Button, TButtonColor, TButtonVariant } from '@deriv-com/quill-ui';
import { RemainingTime } from '@deriv/components';
-import { TContractInfo, getCardLabels, isMultiplierContract, isValidToCancel, isValidToSell } from '@deriv/shared';
+import { TContractInfo, getCardLabels, getCardLabelsV2, isMultiplierContract, isValidToCancel, isValidToSell } from '@deriv/shared';
import { useStore } from '@deriv/stores';
import React from 'react';
import { observer } from 'mobx-react';
import { TRegularSizesWithExtraLarge } from '@deriv-com/quill-ui/dist/types';
+import { FormatUtils } from '@deriv-com/utils';
type ContractInfoProps = {
contract_info: TContractInfo;
@@ -34,7 +35,7 @@ const ContractDetailsFooter = observer(({ contract_info }: ContractInfoProps) =>
const is_valid_to_cancel = isValidToCancel(contract_info);
const is_multiplier = isMultiplierContract(contract_type);
- const cardLabels = getCardLabels();
+ const cardLabels = getCardLabelsV2();
const bidDetails = !is_valid_to_cancel ? `@${bid_price} ${currency}` : '';
const label = `${cardLabels.CLOSE} ${bidDetails}`;
@@ -61,14 +62,14 @@ const ContractDetailsFooter = observer(({ contract_info }: ContractInfoProps) =>
onClick={() => onClickCancel(contract_id)}
label={
<>
- {getCardLabels().CANCEL}
+ {cardLabels.CANCEL}
{' '}
>
@@ -82,8 +83,8 @@ const ContractDetailsFooter = observer(({ contract_info }: ContractInfoProps) =>