Skip to content

Commit

Permalink
[DTRA] Maryia/DTRA-1471/feat: [V2] Implement Growth rate trade param …
Browse files Browse the repository at this point in the history
…functionality + Accumulator trade features updates (binary-com#16365)

* feat: add bottom sheet to Growth rate trade param

* feat: initial - add wheel picker for growth rate

* chore: styles + close action sheet upon saving growth rate

* chore: finalize wheel picker styles

* feat: make proposal request when the wheel stops turning

* test: GrowthRate

* feat: remove Max ticks from AccumulatorsInformation

* feat: update purchase button (buy & close) for accu

* fix: make disabled purchase buttons non-transparent + growth rate feature style and tests fixes
  • Loading branch information
maryia-deriv committed Aug 9, 2024
1 parent abf00f3 commit a01a34d
Show file tree
Hide file tree
Showing 25 changed files with 594 additions and 115 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/account/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@deriv-com/utils": "^0.0.25",
"@deriv-com/ui": "1.29.9",
"@deriv/api": "^1.0.0",
"@deriv-com/quill-ui": "1.13.27",
"@deriv-com/quill-ui": "1.13.36",
"@deriv/components": "^1.0.0",
"@deriv/hooks": "^1.0.0",
"@deriv/integration": "1.0.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@
"@datadog/browser-rum": "^5.11.0",
"@deriv-com/analytics": "1.11.0",
"@deriv-com/quill-tokens": "^2.0.4",
"@deriv-com/quill-ui": "1.13.27",
"@deriv-com/quill-ui": "1.13.36",
"@deriv-com/translations": "1.3.4",
"@deriv-com/ui": "1.29.9",
"@deriv-com/utils": "^0.0.25",
Expand Down
2 changes: 1 addition & 1 deletion packages/trader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@
"dependencies": {
"@deriv-com/analytics": "1.11.0",
"@deriv-com/quill-tokens": "^2.0.4",
"@deriv-com/quill-ui": "1.13.27",
"@deriv-com/quill-ui": "1.13.36",
"@deriv-com/utils": "^0.0.25",
"@deriv-com/ui": "1.29.9",
"@deriv/api-types": "1.0.172",
Expand Down
6 changes: 4 additions & 2 deletions packages/trader/src/AppV2/Components/Carousel/carousel.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import React from 'react';
import CarouselHeader from './carousel-header';
import clsx from 'clsx';

type TCarousel = {
classname?: string;
header: typeof CarouselHeader;
pages: { id: number; component: JSX.Element }[];
title?: React.ReactNode;
current_index?: number;
setCurrentIndex?: (arg: number) => void;
};

const Carousel = ({ header, pages, current_index, setCurrentIndex, title }: TCarousel) => {
const Carousel = ({ classname, header, pages, current_index, setCurrentIndex, title }: TCarousel) => {
const [internalIndex, setInternalIndex] = React.useState(0);

const HeaderComponent = header;
Expand All @@ -35,7 +37,7 @@ const Carousel = ({ header, pages, current_index, setCurrentIndex, title }: TCar
onPrevClick={handlePrevClick}
title={title}
/>
<ul className='carousel'>
<ul className={clsx('carousel', classname)} data-testid='dt_carousel'>
{pages.map(({ component, id }) => (
<li className='carousel__item' style={{ transform: `translateX(-${index * 100}%)` }} key={id}>
{component}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ describe('PositionsContent', () => {
default_mock_store.modules.trade.is_accumulator = true;
mockPurchaseButton();

const sell_button = screen.getByText('Sell');
const sell_button = screen.getByText('Close 19.32 USD');
expect(sell_button).toBeInTheDocument();
expect(default_mock_store.portfolio.onClickSell).not.toBeCalled();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
&:nth-child(2):not(.purchase-button--loading) {
align-items: flex-start;
}

&--single {
align-items: center;
justify-content: center;
Expand All @@ -18,11 +17,9 @@
gap: var(--core-spacing-400);
}
}

&--loading {
align-items: center;
}

&__information {
&__wrapper {
width: 100%;
Expand All @@ -43,15 +40,27 @@
color: var(--core-color-solid-slate-50);
}
}

&__wrapper {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0px var(--core-spacing-400) var(--core-spacing-400) var(--core-spacing-400);
padding: 0 var(--core-spacing-400) var(--core-spacing-400);
gap: var(--core-spacing-400);
position: sticky;
z-index: 2; // chart has z-index: 1, it should not push purchase buttons down
bottom: 0;
}
&--disabled-background {
position: absolute;
background-color: var(--core-color-solid-slate-50);
top: 0;
left: var(--core-spacing-400);
width: calc(100% - var(--core-spacing-800));
height: calc(100% - var(--core-spacing-400));
border-radius: var(--component-button-border-radius-lg);
z-index: -1;
}
&:disabled {
opacity: var(--core-opacity-300); // disabled button opacity in quill-ui is 0.48 (var(--core-opacity-600))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useTraderStore } from 'Stores/useTraderStores';
import { Button, useNotifications } from '@deriv-com/quill-ui';
import { useDevice } from '@deriv-com/ui';
import {
getCardLabelsV2,
getContractTypeDisplay,
getIndicativePrice,
hasContractEntered,
Expand All @@ -14,7 +15,6 @@ import {
isOpen,
isValidToSell,
} from '@deriv/shared';
import { Localize } from '@deriv/translations';
import PurchaseButtonContent from './purchase-button-content';
import { getTradeTypeTabsList } from 'AppV2/Utils/trade-params-utils';
import { StandaloneStopwatchRegularIcon } from '@deriv/quill-icons';
Expand Down Expand Up @@ -77,6 +77,7 @@ const PurchaseButton = observer(() => {
: false;
const current_stake =
(is_valid_to_sell && active_accu_contract && getIndicativePrice(active_accu_contract.contract_info)) || null;
const cardLabels = getCardLabelsV2();

const getButtonType = (index: number, trade_type: string) => {
const tab_index = getTradeTypeTabsList(contract_type).findIndex(tab => tab.contract_type === trade_type);
Expand All @@ -95,25 +96,23 @@ const PurchaseButton = observer(() => {
}, [is_purchase_enabled]);

if (is_accumulator && has_open_accu_contract) {
const info = proposal_info?.[trade_types_array[0]] || {};
const is_accu_sell_disabled = !is_valid_to_sell || active_accu_contract?.is_sell_requested;
return (
<div className='purchase-button__wrapper'>
<Button
color='black'
variant='secondary'
size='lg'
label={<Localize i18n_default_text='Sell' />}
label={
is_accu_sell_disabled
? `${cardLabels.CLOSE}`
: `${cardLabels.CLOSE} ${current_stake} ${currency}`
}
fullWidth
className='purchase-button purchase-button--single'
disabled={!is_valid_to_sell || active_accu_contract?.is_sell_requested}
disabled={is_accu_sell_disabled}
onClick={() => onClickSell(active_accu_contract?.contract_info.contract_id)}
>
<PurchaseButtonContent
{...purchase_button_content_props}
info={info}
current_stake={current_stake}
/>
</Button>
/>
{is_accu_sell_disabled && <div className='purchase-button purchase-button--disabled-background' />}
</div>
);
}
Expand All @@ -127,32 +126,36 @@ const PurchaseButton = observer(() => {
const is_disabled = !is_trade_enabled || is_proposal_empty || !info.id || !is_purchase_enabled;

return (
<Button
key={trade_type}
color={getButtonType(index, trade_type)}
size='lg'
label={getContractTypeDisplay(trade_type, { isHighLow: is_high_low, showButtonName: true })}
fullWidth
className={clsx(
'purchase-button',
is_loading && 'purchase-button--loading',
is_single_button && 'purchase-button--single'
<React.Fragment key={trade_type}>
<Button
color={getButtonType(index, trade_type)}
size='lg'
label={getContractTypeDisplay(trade_type, { isHighLow: is_high_low, showButtonName: true })}
fullWidth
className={clsx(
'purchase-button',
is_loading && 'purchase-button--loading',
is_single_button && 'purchase-button--single'
)}
isLoading={is_loading}
disabled={is_disabled && !is_loading}
onClick={() => {
setLoadingButtonIndex(index);
onPurchase(info.id, info.stake, trade_type, isMobile, addNotificationBannerCallback);
}}
>
{!is_loading && !is_accumulator && (
<PurchaseButtonContent
{...purchase_button_content_props}
info={info}
is_reverse={!!index}
/>
)}
</Button>
{is_disabled && !is_loading && (
<div className='purchase-button purchase-button--disabled-background' />
)}
isLoading={is_loading}
disabled={is_disabled && !is_loading}
onClick={() => {
setLoadingButtonIndex(index);
onPurchase(info.id, info.stake, trade_type, isMobile, addNotificationBannerCallback);
}}
>
{!is_loading && (
<PurchaseButtonContent
{...purchase_button_content_props}
info={info}
is_reverse={!!index}
/>
)}
</Button>
</React.Fragment>
);
})}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import TradeParamDefinition from '../trade-param-definition';

describe('TradeParamDefinition', () => {
it('should not render if description is not passed', () => {
const { container } = render(<TradeParamDefinition />);

expect(container).toBeEmptyDOMElement();
});

it('should render description that is provided', () => {
render(<TradeParamDefinition description='test description' />);

expect(screen.getByText('test description')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import './trade-param-definition.scss';
import TradeParamDefinition from './trade-param-definition';

export default TradeParamDefinition;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
$HANDLEBAR_HEIGHT: var(--core-size-1000);
$HEADER_TITLE_HEIGHT: var(--core-size-3200);

.trade-param-definition {
height: calc(400px - $HANDLEBAR_HEIGHT - $HEADER_TITLE_HEIGHT);
padding-block-start: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { ActionSheet, Text } from '@deriv-com/quill-ui';

type TTradeParamDefinitionProps = {
description?: React.ReactNode;
};

const TradeParamDefinition = ({ description }: TTradeParamDefinitionProps) => {
if (!description) return null;
return (
<ActionSheet.Content className='trade-param-definition'>
<Text>{description}</Text>
</ActionSheet.Content>
);
};

export default TradeParamDefinition;
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { mockStore } from '@deriv/stores';
import AccumulatorsInformation from '../accumulators-information';
import ModulesProvider from 'Stores/Providers/modules-providers';
import TraderProviders from '../../../../../trader-providers';

describe('AccumulatorsInformation', () => {
let default_mock_store: ReturnType<typeof mockStore>;

beforeEach(
() =>
(default_mock_store = mockStore({
modules: {
trade: {
...mockStore({}),
currency: 'USD',
maximum_payout: 4000,
},
},
}))
);

const mockAccumulatorsInformation = (props?: React.ComponentProps<typeof AccumulatorsInformation>) =>
render(
<TraderProviders store={default_mock_store}>
<ModulesProvider store={default_mock_store}>
<AccumulatorsInformation {...props} />
</ModulesProvider>
</TraderProviders>
);
it('should not render if description is not passed', () => {
const { container } = mockAccumulatorsInformation({ is_minimized: true });

expect(container).toBeEmptyDOMElement();
});

it('should render description that is provided', () => {
mockAccumulatorsInformation();

expect(screen.getByText('Max. payout')).toBeInTheDocument();
expect(screen.getByText('4,000.00 USD')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
.accumulators-info {
&__wrapper {
width: 100%;
}
&__row {
display: flex;
justify-content: space-between;
align-items: center;
padding-block: var(--component-badge-notification-spacing-padding-sm);
}
&__title {
border-bottom: var(--core-borderWidth-75) dotted var(--component-textIcon-normal-default);
Expand Down
Loading

0 comments on commit a01a34d

Please sign in to comment.