Skip to content
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

maryia/78839/complete_sold_labels #23

Merged
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
38 changes: 19 additions & 19 deletions packages/shared/src/utils/helpers/dummy_accumulators_data.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
/* eslint-disable no-unused-vars */
/* eslint-disable prefer-const */
const dummy_current_time = 1665675860; // should be an epoch of some real tick!
const dummy_current_time = 1666100508; // should be an epoch of some real tick!
const dummy_start_time = dummy_current_time - 7;
const dummy_end_time = dummy_current_time + 6;

const high_barrier = 6509;
const low_barrier = 6508;
const high_barrier = 6487.9;
const low_barrier = 6487.5;
const tick_1_price = low_barrier + 0.1;
const tick_2_price = low_barrier + 0.15;
const tick_3_price = low_barrier + 0.5;
Expand Down Expand Up @@ -62,26 +62,26 @@ let is_sold = 0; // 0 || 1
// const winLoseAndOpenContractInSec = (ms1, ms2, ms3) => {
// setInterval(() => {
// setTimeout(() => {
contract_status = 'won'; // 'lost', 'won' or 'open'
position_status = 'profit'; // 'profit' or 'loss'
result = 'won'; // 'won' or 'lost'
profit = +0.15;
profit_percentage = +1.5;
// contract_status = 'won'; // 'lost', 'won' or 'open'
// position_status = 'profit'; // 'profit' or 'loss'
// result = 'won'; // 'won' or 'lost'
// profit = +0.15;
// profit_percentage = +1.5;
// is_sold = 1; // 0 || 1
// exit_tick = current_spot;
// exit_tick_display_value = `${current_spot}`;
// exit_tick_time = dummy_current_time;
// }, ms1);
// setTimeout(() => {
contract_status = 'lost'; // 'lost', 'won' or 'open'
position_status = 'loss'; // 'profit' or 'loss'
result = 'lost'; // 'won' or 'lost'
profit = -10;
profit_percentage = -100;
is_sold = 1; // 0 || 1
exit_tick = current_spot;
exit_tick_display_value = `${current_spot}`;
exit_tick_time = dummy_current_time;
// }, ms1);
// setTimeout(() => {
// contract_status = 'lost'; // 'lost', 'won' or 'open'
// position_status = 'loss'; // 'profit' or 'loss'
// result = 'lost'; // 'won' or 'lost'
// profit = -100;
// profit_percentage = -100;
// is_sold = 1; // 0 || 1
// exit_tick = low_barrier + 0.49;
// exit_tick_display_value = `${exit_tick}`;
// exit_tick_time = dummy_end_time;
// }, ms2);
// setTimeout(() => {
// contract_status = 'open'; // 'lost', 'won' or 'open'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { expect } from 'chai';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import AccumulatorsProfitLossTooltip from '../accumulators-profit-loss-tooltip.jsx';

configure({ adapter: new Adapter() });

describe('AccumulatorsProfitLossTooltip', () => {
const props = {
contract_info: {
currency: 'USD',
exit_tick: 6468.95,
exit_tick_time: 1666091856,
profit: +0.15,
},
className: 'profit-loss-tooltip',
};

it('should render with an arrow on the left', () => {
const wrapper = shallow(<AccumulatorsProfitLossTooltip {...props} />);
expect(wrapper.find('.profit-loss-tooltip').exists()).to.be.true;
expect(wrapper.find('.profit-loss-tooltip__spot-circle').exists()).to.be.true;
expect(wrapper.find('.profit-loss-tooltip__content').render()[0].attribs.class).to.include('arrow-left');
});
});
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import { Icon, Text } from '@deriv/components';
import { localize } from '@deriv/translations';
import { FastMarker } from 'Modules/SmartChart';

const AccumulatorsProfitLossTooltip = ({ currency, exit_tick = 0, exit_tick_time = 0, profit }) => {
// TODO:
// - implement different coloring of elements for won/lost contract
// - add top, bottom arrows & dependency to select one of 4 arrows
// - show AccumulatorsProfitLossTooltip for all closed contracts on the chart, not only the last one
const AccumulatorsProfitLossTooltip = ({
alignment = 'right',
className = 'sc-accumulators-profit-loss-tooltip',
currency,
exit_tick = 0,
exit_tick_time = 0,
profit,
}) => {
const [is_tooltip_open, setIsTooltipOpen] = React.useState(true);
const className = 'sc-accumulators-profit-loss-tooltip';
const won = profit > 0;
const sign = won ? '+' : '';

const getOppositeArrowPosition = React.useCallback(() => {
const horizontal = ['left', 'right'];
const vertical = ['top', 'bottom'];
return horizontal.includes(alignment)
? horizontal.find(el => el !== alignment)
: vertical.find(el => el !== alignment);
}, [alignment]);

const onRef = ref => {
if (ref) {
// NOTE: null price (exit_tick) means vertical line.
if (!exit_tick) {
ref.div.style.height = `calc(100% - 24px)`;
ref.div.style.zIndex = '-1';
// this call will hide the marker:
ref.setPosition({ epoch: null, price: null });
}
ref.setPosition({
epoch: +exit_tick_time,
Expand All @@ -28,13 +39,13 @@ const AccumulatorsProfitLossTooltip = ({ currency, exit_tick = 0, exit_tick_time
};

return (
<FastMarker markerRef={onRef} className={className}>
<FastMarker markerRef={onRef} className={classNames(className, won ? 'won' : 'lost')}>
<span
className={`${className}__spot-circle ${won ? 'won' : 'lost'}`}
className={`${className}__spot-circle`}
onMouseEnter={() => !is_tooltip_open && setIsTooltipOpen(true)}
/>
{is_tooltip_open && (
<div className={`${className}__content arrow-left`} data-tooltip-pos='right'>
<div className={classNames(`${className}__content`, `arrow-${getOppositeArrowPosition()}`)}>
<Text size='xxs' className={`${className}__text`}>
{localize('Total profit/loss:')}
</Text>
Expand All @@ -55,10 +66,12 @@ const AccumulatorsProfitLossTooltip = ({ currency, exit_tick = 0, exit_tick_time
};

AccumulatorsProfitLossTooltip.propTypes = {
alignment: PropTypes.string,
className: PropTypes.string,
currency: PropTypes.string,
exit_tick: PropTypes.number,
exit_tick_time: PropTypes.number,
profit: PropTypes.number,
};

export default AccumulatorsProfitLossTooltip;
export default React.memo(AccumulatorsProfitLossTooltip);
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,15 @@ const TickContract = RawMarkerMaker(
zoom: exit.zoom,
icon: ICONS.END.with_color(color, getColor({ status: 'bg', is_dark_theme })),
});
if (is_accumulators_contract) {
// draw dashed line from end icon to exit tick:
ctx.strokeStyle = color + opacity;
ctx.setLineDash([2, 2]);
ctx.beginPath();
ctx.moveTo(exit.left, entry.top);
ctx.lineTo(exit.left, exit.top);
ctx.stroke();
}
}
ctx.restore();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const TakeProfit = ({
removeToast,
currency,
current_focus,
has_info,
has_info = true,
has_take_profit,
is_single_currency,
onChange,
Expand Down
29 changes: 21 additions & 8 deletions packages/trader/src/Modules/Trading/Containers/trade.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ const Trade = ({
topWidgets={topWidgets}
charts_ref={charts_ref}
bottomWidgets={show_digits_stats ? bottomWidgets : undefined}
show_accumulators_stats={show_accumulators_stats}
/>
</SwipeableWrapper>
</MobileWrapper>
Expand Down Expand Up @@ -258,6 +259,7 @@ export default connect(({ client, common, modules, ui }) => ({
/* eslint-disable */
import { SmartChart } from 'Modules/SmartChart';
import classNames from 'classnames';
import { filterByContractType } from 'App/Components/Elements/PositionsDrawer/helpers/positions-helper.js';

const SmartChartWithRef = React.forwardRef((props, ref) => <SmartChart innerRef={ref} {...props} />);

Expand Down Expand Up @@ -287,6 +289,7 @@ const ChartMarkers = connect(({ ui, client, contract_trade }) => ({

const Chart = props => {
const {
all_positions,
topWidgets,
charts_ref,
updateGranularity,
Expand Down Expand Up @@ -351,6 +354,13 @@ const Chart = props => {

if (!symbol || active_symbols.length === 0) return null;

const accumulators_positions = all_positions.filter(
p =>
p.contract_info &&
symbol === p.contract_info.underlying &&
filterByContractType(p.contract_info, 'accumulator')
);

return (
<SmartChartWithRef
ref={charts_ref}
Expand Down Expand Up @@ -403,14 +413,20 @@ const Chart = props => {
}}
>
<ChartMarkers />
{show_accumulators_stats && props.last_contract.is_ended && (
<AccumulatorsProfitLossTooltip {...props.last_contract} />
)}
{show_accumulators_stats &&
accumulators_positions.map(({ contract_info }) => {
return (
contract_info.is_sold && (
<AccumulatorsProfitLossTooltip key={contract_info.contract_id} {...contract_info} />
)
);
})}
</SmartChartWithRef>
);
};

Chart.propTypes = {
all_positions: PropTypes.array,
topWidgets: PropTypes.func,
charts_ref: PropTypes.object,
bottomWidgets: PropTypes.func,
Expand All @@ -435,7 +451,8 @@ Chart.propTypes = {
wsSubscribe: PropTypes.func,
};

const ChartTrade = connect(({ modules, ui, common, contract_trade }) => ({
const ChartTrade = connect(({ modules, ui, common, contract_trade, portfolio }) => ({
all_positions: portfolio.all_positions,
is_socket_opened: common.is_socket_opened,
granularity: contract_trade.granularity,
chart_type: contract_trade.chart_type,
Expand All @@ -451,12 +468,8 @@ const ChartTrade = connect(({ modules, ui, common, contract_trade }) => ({
theme: ui.is_dark_mode_on ? 'dark' : 'light',
},
last_contract: {
currency: contract_trade.last_contract.contract_info?.currency,
is_digit_contract: contract_trade.last_contract.is_digit_contract,
is_ended: contract_trade.last_contract.is_ended,
exit_tick: contract_trade.last_contract.contract_info?.exit_tick,
exit_tick_time: contract_trade.last_contract.contract_info?.exit_tick_time,
profit: contract_trade.last_contract.contract_info?.profit,
},
is_trade_enabled: modules.trade.is_trade_enabled,
main_barrier: modules.trade.main_barrier_flattened,
Expand Down
Loading