Skip to content

Commit

Permalink
Sandeep/bot 398/quick strategy refactor 2 (#10615)
Browse files Browse the repository at this point in the history
* refactor: 🔥 quick strategy refactor -- working on the desktop dialog design

* refactor: working on quick strategy redesign

* refactor: working on quick strategy dynamic form

* refactor: working on QS dynamic form

* refactor: quick strategy finalizing

* refactor: adding missing test coverage and fixed minor issues

* refactor: updated names in the store with the params in the quick strategy

* refactor: adding test cases for the newly added quick strategy components

* chore: reverted changes to the unrelated component

* refactor: working on quick strategy component test coverage

* chore: added back the reverted change

* chore: added back the reverted change

* refactor: added remaining test case for quick strategy

* refactor: added interface for quick-strategy-store-1

* refactor: removed duplicate import statement

* refactor: quick strategy, updated breaking test suits

* refactor: quick strategy fallback to first symbol if default symbol is not available

* refactor: quick strategy -  wrapped qs-input-label with store observer

* refactor: quick-strategy - initialize trade_type and duration_value error on change of symbol

* refactor: quick-strategy - is_strategy_modal_open is replaced with is_open

* refactor: quick-strategy - linked setFormVisibility with dashboard tile

* refactor: quick-strategy cleanup the old store and components

* refactor: quick-strategy updated test cases

* refactor: quick-strategy fixing minor ui issues

* refactor: quick-strategy - updated tooltip messages for unit

* refactor: quick-strategy - fixed minor ui bugs and round off

* refactor: quick-strategy alignment and reset form fix

* refactor: quick-strategy fixed run/edit issue and test update

* refactor: quick-strategy - form field should be required

* refactor: quick-strategy updated qs description

* refactor: quick-strategy - added input mode to stop showing keyboard on mobile responsive

* refactor: quick-strategy - fixed edit button disable issue
  • Loading branch information
sandeep-deriv committed Oct 23, 2023
1 parent 7a92511 commit d15ee12
Show file tree
Hide file tree
Showing 54 changed files with 2,923 additions and 2,332 deletions.
15 changes: 15 additions & 0 deletions packages/bot-skeleton/src/constants/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,19 @@ export const config = {
},
},
default_file_name: localize('Untitled Bot'),
DISABLED_SYMBOLS: ['frxGBPNOK', 'frxUSDNOK', 'frxUSDNEK', 'frxUSDSEK'],
DISABLED_SUBMARKETS: ['energy', 'step_index'],
QUICK_STRATEGY: {
DISABLED: {
SYMBOLS: ['1HZ150V', '1HZ250V'],
SUBMARKETS: ['crash_index', 'non_stable_coin'],
},
DEFAULT: {
symbol: '1HZ100V',
tradetype: 'callput',
durationtype: 't',
size: 2,
unit: 1,
},
},
};
41 changes: 36 additions & 5 deletions packages/bot-skeleton/src/services/api/active-symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { config } from '../../constants/config';
export default class ActiveSymbols {
constructor(ws, trading_times) {
this.active_symbols = [];
this.disabled_markets = [];
this.disabled_symbols = ['frxGBPNOK', 'frxUSDNOK', 'frxUSDNEK', 'frxUSDSEK']; // These are only forward-starting.
this.disabled_submarkets = ['energy', 'step_index'];
this.init_promise = new PendingPromise();
Expand Down Expand Up @@ -50,9 +49,8 @@ export default class ActiveSymbols {
processActiveSymbols() {
return this.active_symbols.reduce((processed_symbols, symbol) => {
if (
this.disabled_markets.includes(symbol.market) ||
this.disabled_symbols.includes(symbol.symbol) ||
this.disabled_submarkets.includes(symbol.submarket)
config.DISABLED_SYMBOLS.includes(symbol.symbol) ||
config.DISABLED_SUBMARKETS.includes(symbol.submarket)
) {
return processed_symbols;
}
Expand Down Expand Up @@ -122,10 +120,43 @@ export default class ActiveSymbols {
});
});
});

this.getSymbolsForBot();
return all_symbols;
}

/**
*
* @returns {Array} Symbols and their submarkets + markets for deriv-bot
*/
getSymbolsForBot() {
const { DISABLED } = config.QUICK_STRATEGY;
const symbols_for_bot = [];
Object.keys(this.processed_symbols).forEach(market_name => {
if (this.isMarketClosed(market_name)) return;

const market = this.processed_symbols[market_name];
const { submarkets } = market;

Object.keys(submarkets).forEach(submarket_name => {
if (DISABLED.SUBMARKETS.includes(submarket_name)) return;
const submarket = submarkets[submarket_name];
const { symbols } = submarket;

Object.keys(symbols).forEach(symbol_name => {
if (DISABLED.SYMBOLS.includes(symbol_name)) return;
const symbol = symbols[symbol_name];
symbols_for_bot.push({
group: submarket.display_name,
text: symbol.display_name,
value: symbol_name,
});
});
});
});

return symbols_for_bot;
}

getMarketDropdownOptions() {
const market_options = [];

Expand Down
80 changes: 80 additions & 0 deletions packages/bot-skeleton/src/services/api/contracts-for.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,86 @@ export default class ContractsFor {
return dropdown_options;
}

getHiddenCategories = trade_types => {
// TODO: Temporary filtering of barrier + prediction types. Should later
// render more inputs for these types. We should only filter out trade type
// categories which only feature prediction/barrier trade types. e.g.
// in Digits category, users can still purchase Even/Odd types.
let hidden_categories = 0;

for (let j = 0; j < trade_types.length; j++) {
const trade_type = trade_types[j];
const has_barrier = config.BARRIER_TRADE_TYPES.includes(trade_type.value);
const has_prediction = config.PREDICTION_TRADE_TYPES.includes(trade_type.value);

if (has_barrier || has_prediction) {
hidden_categories++;
}
}

return hidden_categories;
};

getTradeTypeOptions = (trade_types, trade_type_category) => {
const trade_type_options = [];
trade_types.forEach(trade_type => {
const has_barrier = config.BARRIER_TRADE_TYPES.includes(trade_type.value);
const has_prediction = config.PREDICTION_TRADE_TYPES.includes(trade_type.value);
const is_muliplier = ['multiplier'].includes(trade_type.value);

// TODO: Render extra inputs for barrier + prediction and multiplier types.
if (!has_barrier && !has_prediction && !is_muliplier) {
trade_type_options.push({
text: trade_type.name,
value: trade_type.value,
group: trade_type_category[0],
icon: trade_type.icon,
});
}
});
return trade_type_options;
};

async getTradeTypesForQuickStrategy(symbol) {
const trade_type_options = [];
const filtered_trade_type_categories = [];
const market = await this.getMarketBySymbol(symbol);
const submarket = await this.getSubmarketBySymbol(symbol);
const trade_type_categories = await this.getTradeTypeCategories(market, submarket, symbol);

for (let i = 0; i < trade_type_categories.length; i++) {
const trade_type_category = trade_type_categories[i];
// eslint-disable-next-line no-await-in-loop
const trade_types = await this.getTradeTypeByTradeCategory(
market,
submarket,
symbol,
trade_type_category[1]
);

const hidden_categories = this.getHiddenCategories(trade_types);

if (hidden_categories < trade_types.length) {
filtered_trade_type_categories.push(trade_type_category);
}
}

for (let i = 0; i < filtered_trade_type_categories.length; i++) {
const trade_type_category = filtered_trade_type_categories[i]; // e.g. ['Up/Down', 'callput']
// eslint-disable-next-line no-await-in-loop
const trade_types = await this.getTradeTypeByTradeCategory(
market,
submarket,
symbol,
trade_type_category[1]
);

trade_type_options.push(...this.getTradeTypeOptions(trade_types, trade_type_category));
}

return trade_type_options;
}

async getTradeTypeCategories(market, submarket, symbol) {
const { TRADE_TYPE_CATEGORY_NAMES, NOT_AVAILABLE_DROPDOWN_OPTIONS } = config;
const contracts = await this.getContractsFor(symbol);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { Localize } from '@deriv/translations';
import BotSnackbar from 'Components/bot-snackbar';
import { useDBotStore } from '../../../stores/useDBotStore';
import LoadModal from '../../load-modal';
import QuickStrategy1 from '../../quick-strategy';
import SaveModal from '../dashboard-component/load-bot-preview/save-modal';
import BotBuilderTourHandler from '../dbot-tours/bot-builder-tour';
import QuickStrategy from '../quick-strategy';
import WorkspaceWrapper from './workspace-wrapper';

const BotBuilder = observer(() => {
const { dashboard, app, run_panel, toolbar } = useDBotStore();
const { dashboard, app, run_panel, toolbar, quick_strategy } = useDBotStore();
const { active_tab, active_tour, is_preview_on_popup } = dashboard;
const { is_open } = quick_strategy;
const { is_running } = run_panel;
const is_blockly_listener_registered = React.useRef(false);
const [show_snackbar, setShowSnackbar] = React.useState(false);
Expand All @@ -23,7 +24,7 @@ const BotBuilder = observer(() => {
React.useEffect(() => {
onMount();
return () => onUnmount();
}, []);
}, [onMount, onUnmount]);

const handleBlockChangeOnBotRun = (e: Event) => {
const { is_reset_button_clicked, setResetButtonState } = toolbar;
Expand Down Expand Up @@ -90,7 +91,7 @@ const BotBuilder = observer(() => {
{/* removed this outside from toolbar becuase it needs to loaded seperately without dependency */}
<LoadModal />
<SaveModal />
<QuickStrategy />
{is_open && <QuickStrategy1 />}
</>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ const mockDbotStore = {
onZoomInOutClick: jest.fn(),
is_dialog_open: false,
},
quick_strategy: {},
quick_strategy: {
setFormVisibility: jest.fn(),
},
dashboard: {},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ const Toolbar = observer(() => {
} = toolbar;
const { toggleSaveModal } = save_modal;
const { toggleLoadModal } = load_modal;
const { loadDataStrategy } = quick_strategy;
const { is_running } = run_panel;

const { setFormVisibility } = quick_strategy;
const confirm_button_text = is_running ? localize('Yes') : localize('OK');
const cancel_button_text = is_running ? localize('No') : localize('Cancel');

const handleQuickStrategyOpen = () => {
setFormVisibility(true);
};
return (
<React.Fragment>
<div className='toolbar dashboard__toolbar' data-testid='dashboard__toolbar'>
Expand All @@ -39,7 +40,7 @@ const Toolbar = observer(() => {
popover_message={localize('Click here to start building your Deriv Bot.')}
button_id='db-toolbar__get-started-button'
button_classname='toolbar__btn toolbar__btn--icon toolbar__btn--start'
buttonOnClick={loadDataStrategy}
buttonOnClick={handleQuickStrategyOpen}
button_text={localize('Quick strategy')}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const mockDbotStore = {
setVisibility: jest.fn(),
},
quick_strategy: {
loadDataStrategy: jest.fn(),
setFormVisibility: jest.fn(),
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const Toolbox = observer(() => {
toolbox_dom,
} = toolbox;

const { setFormVisibility } = quick_strategy;
const { setVisibility, selected_category } = flyout;
const { loadDataStrategy } = quick_strategy;

const toolbox_ref = React.useRef(ToolboxItems);
const [is_open, setOpen] = React.useState(true);
Expand All @@ -37,14 +37,18 @@ const Toolbox = observer(() => {
return () => onUnmount();
}, []);

const handleQuickStrategyOpen = () => {
setFormVisibility(true);
};

if (!isMobile()) {
return (
<div className='dashboard__toolbox' data-testid='dashboard__toolbox'>
<ToolbarButton
popover_message={localize('Click here to start building your Deriv Bot.')}
button_id='db-toolbar__get-started-button'
button_classname='toolbar__btn toolbar__btn--icon toolbar__btn--start'
buttonOnClick={loadDataStrategy}
buttonOnClick={handleQuickStrategyOpen}
button_text={localize('Quick strategy')}
/>
<div id='gtm-toolbox' className='db-toolbox__content'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const Cards = observer(({ is_mobile, has_dashboard_strategies }: TCardProps) =>
showVideoDialog,
} = dashboard;
const { handleFileChange, loadFileFromLocal } = load_modal;
const { loadDataStrategy } = quick_strategy;
const { setFormVisibility } = quick_strategy;

const [is_file_supported, setIsFileSupported] = React.useState<boolean>(true);
const file_input_ref = React.useRef<HTMLInputElement | null>(null);
Expand Down Expand Up @@ -69,7 +69,7 @@ const Cards = observer(({ is_mobile, has_dashboard_strategies }: TCardProps) =>
content: localize('Quick strategy'),
method: () => {
setActiveTab(DBOT_TABS.BOT_BUILDER);
loadDataStrategy();
setFormVisibility(true);
},
},
];
Expand Down
8 changes: 2 additions & 6 deletions packages/bot-web-ui/src/components/dashboard/dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useEffect } from 'react';
import classNames from 'classnames';

import { updateWorkspaceName } from '@deriv/bot-skeleton';
import dbot from '@deriv/bot-skeleton/src/scratch/dbot';
import { initTrashCan } from '@deriv/bot-skeleton/src/scratch/hooks/trashcan';
Expand All @@ -9,13 +8,10 @@ import { DesktopWrapper, Dialog, MobileWrapper, Tabs } from '@deriv/components';
import { isMobile } from '@deriv/shared';
import { observer, useStore } from '@deriv/stores';
import { localize } from '@deriv/translations';

import Chart from 'Components/chart';
import { DBOT_TABS, TAB_IDS } from 'Constants/bot-contents';
import { useDBotStore } from 'Stores/useDBotStore';

import RunPanel from '../run-panel';

import RunStrategy from './dashboard-component/run-strategy';
import { tour_list } from './dbot-tours/utils';
import DashboardComponent from './dashboard-component';
Expand All @@ -28,7 +24,7 @@ const Dashboard = observer(() => {
const { onEntered, dashboard_strategies } = load_modal;
const { is_dialog_open, is_drawer_open, dialog_options, onCancelButtonClick, onCloseDialog, onOkButtonClick } =
run_panel;
const { is_strategy_modal_open } = quick_strategy;
const { is_open } = quick_strategy;
const { clear } = summary_card;
const { DASHBOARD, BOT_BUILDER } = DBOT_TABS;
const is_mobile = isMobile();
Expand Down Expand Up @@ -152,7 +148,7 @@ const Dashboard = observer(() => {
<RunPanel />
</div>
</DesktopWrapper>
<MobileWrapper>{!is_strategy_modal_open && <RunPanel />}</MobileWrapper>
<MobileWrapper>{!is_open && <RunPanel />}</MobileWrapper>
<Dialog
cancel_button_text={dialog_options.cancel_button_text || localize('Cancel')}
className={'dc-dialog__wrapper--fixed'}
Expand Down
Loading

1 comment on commit d15ee12

@vercel
Copy link

@vercel vercel bot commented on d15ee12 Oct 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

deriv-app – ./

deriv-app.vercel.app
binary.sx
deriv-app-git-master.binary.sx
deriv-app.binary.sx

Please sign in to comment.