From ef9d754becc9a0546bec966d47b63a197aee1271 Mon Sep 17 00:00:00 2001 From: Sandeep Rajput <90243468+sandeep-deriv@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:40:45 +0800 Subject: [PATCH] fix: :bug: fixed stop bot warning inherited from quick-strategy form (#16715) --- .../add-bot/__tests__/add-bot.spec.tsx | 22 +---- .../add-bot/__tests__/form.spec.tsx | 14 +-- .../pages/server-side-bot/add-bot/add-bot.tsx | 14 ++- .../pages/server-side-bot/add-bot/config.ts | 4 +- .../__tests__/desktop-form-wrapper.spec.tsx | 17 ---- .../__tests__/mobile-form-wrapper.spec.tsx | 7 +- ...ler.spec.tsx => useSubmitHandler.spec.tsx} | 45 +++++---- .../form-wrappers/desktop-form-wrapper.tsx | 94 +++++++++---------- .../form-wrappers/mobile-form-wrapper.tsx | 8 +- .../form-wrappers/useQsSubmitHandler.tsx | 71 -------------- .../form-wrappers/useSubmitHandler.tsx | 44 +++++++++ .../pages/server-side-bot/add-bot/form.tsx | 5 +- .../add-bot/inputs/add-input.tsx | 4 +- .../__tests__/loss-threshold-warning.spec.tsx | 10 +- .../parts/loss-threshold-warning-dialog.tsx | 9 +- .../add-bot/selects/contract-type.tsx | 4 +- .../add-bot/selects/duration-type.tsx | 4 +- .../add-bot/selects/symbol.tsx | 4 +- .../add-bot/selects/trade-type.tsx | 4 +- .../src/pages/server-side-bot/config.ts | 16 ++++ .../src/stores/server-side-bot-store.ts | 63 ++++++++++++- 21 files changed, 234 insertions(+), 229 deletions(-) rename packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/{useQsSubmitHandler.spec.tsx => useSubmitHandler.spec.tsx} (62%) delete mode 100644 packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useQsSubmitHandler.tsx create mode 100644 packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useSubmitHandler.tsx create mode 100644 packages/bot-web-ui/src/pages/server-side-bot/config.ts diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/add-bot.spec.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/add-bot.spec.tsx index 1d3703cc8e32..f4f8c60863bf 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/add-bot.spec.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/add-bot.spec.tsx @@ -67,22 +67,6 @@ jest.mock('@deriv/bot-skeleton', () => ({ }, }, }, - config: { - ...jest.requireActual('@deriv/bot-skeleton').config, - QUICK_STRATEGY: { - DISABLED: { - SYMBOLS: ['1HZ150V', '1HZ250V'], - SUBMARKETS: ['crash_index', 'non_stable_coin'], - }, - DEFAULT: { - symbol: '1HZ100V', - tradetype: 'callput', - durationtype: 't', - size: 2, - unit: 1, - }, - }, - }, })); jest.mock('../../../../xml/martingale.xml', () => ''); @@ -190,9 +174,9 @@ describe('', () => { const mock_dbot_store = mockDBotStore(mock_store, mock_ws); beforeEach(() => { - mock_dbot_store?.quick_strategy?.setValue('durationtype', 't'); - mock_dbot_store?.quick_strategy?.setSelectedStrategy('MARTINGALE'); - mock_dbot_store?.quick_strategy?.setFormVisibility(true); + mock_dbot_store?.server_bot?.setValue('durationtype', 't'); + mock_dbot_store?.server_bot?.setSelectedStrategy('MARTINGALE'); + wrapper = ({ children }: { children: JSX.Element }) => ( diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/form.spec.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/form.spec.tsx index 4d41ddf81977..be0a15fe559c 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/form.spec.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/__tests__/form.spec.tsx @@ -73,9 +73,9 @@ window.Blockly = { jest.mock('../config', () => ({ STRATEGIES: { - RSI: { - name: 'RSI', - label: 'RSI', + MARTINGALE: { + name: 'MARTINGALE', + label: 'MARTINGALE', description: 'test', fields: [ [ @@ -197,7 +197,7 @@ jest.mock('../config', () => ({ }, })); -describe('', () => { +describe('', () => { let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element, mock_dbot_store: RootStore | undefined; const mock_store = mockStore({ ui: { @@ -207,7 +207,7 @@ describe('', () => { beforeEach(() => { mock_dbot_store = mockDBotStore(mock_store, mock_ws); - mock_dbot_store?.quick_strategy?.setSelectedStrategy('RSI'); + mock_dbot_store?.server_bot?.setSelectedStrategy('MARTINGALE'); const mockOnSubmit = jest.fn(); const initial_value = { tradetype: 'callput', @@ -247,8 +247,8 @@ describe('', () => { }); it('should render the form with existing duration values and possitive last digit prediction', () => { - mock_dbot_store?.quick_strategy?.setCurrentDurationMinMax(1, 2); - mock_dbot_store?.quick_strategy?.setValue('last_digit_prediction', 5); + mock_dbot_store?.server_bot?.setCurrentDurationMinMax(1, 2); + mock_dbot_store?.server_bot?.setValue('last_digit_prediction', 5); const { container } = render(, { wrapper, }); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/add-bot.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/add-bot.tsx index 6f474b124b14..7b85a8c5cda1 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/add-bot.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/add-bot.tsx @@ -1,11 +1,11 @@ import React, { useRef, useState } from 'react'; import { Form as FormikForm, Formik } from 'formik'; import * as Yup from 'yup'; -import { config as qs_config } from '@deriv/bot-skeleton'; import { MobileFullPageModal, Modal } from '@deriv/components'; import { observer, useStore } from '@deriv/stores'; import { localize } from '@deriv/translations'; import { useDBotStore } from 'Stores/useDBotStore'; +import { SERVER_BOT_CONFIG } from '../config'; import DesktopFormWrapper from './form-wrappers/desktop-form-wrapper'; import MobileFormWrapper from './form-wrappers/mobile-form-wrapper'; import LossThresholdWarningDialog from './parts/loss-threshold-warning-dialog'; @@ -39,13 +39,11 @@ const getErrorMessage = (dir: 'MIN' | 'MAX', value: number, type = 'DEFAULT') => }; export const FormikWrapper: React.FC = observer(({ children, setFormVisibility }) => { - const { quick_strategy, server_bot } = useDBotStore(); - const { selected_strategy, form_data, current_duration_min_max, initializeLossThresholdWarningData, setValue } = - quick_strategy; + const { server_bot } = useDBotStore(); + const { selected_strategy, current_duration_min_max, initializeLossThresholdWarningData, createBot } = server_bot; const config: TConfigItem[][] = STRATEGIES[selected_strategy]?.fields; const [dynamic_schema, setDynamicSchema] = useState(Yup.object().shape({})); const is_mounted = useRef(true); - const { createBot } = server_bot; let initial_value: TFormData | null = null; @@ -63,15 +61,15 @@ export const FormikWrapper: React.FC = observer(({ children, set const data = getSavedValues(); initial_value = { name: data?.name ?? 'Martingale', - symbol: data?.symbol ?? qs_config.QUICK_STRATEGY.DEFAULT.symbol, + symbol: data?.symbol ?? SERVER_BOT_CONFIG.DEFAULT.symbol, tradetype: data?.tradetype ?? '', type: data?.type ?? '', - durationtype: data?.durationtype ?? qs_config.QUICK_STRATEGY.DEFAULT.durationtype, + durationtype: data?.durationtype ?? SERVER_BOT_CONFIG.DEFAULT.durationtype, duration: data?.duration ?? '1', stake: data?.stake ?? '1', loss: data?.loss ?? '', profit: data?.profit ?? '', - size: data?.size ?? String(qs_config.QUICK_STRATEGY.DEFAULT.size), + size: data?.size ?? String(SERVER_BOT_CONFIG.DEFAULT.size), max_stake: data?.max_stake ?? 10, }; return initial_value; diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/config.ts b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/config.ts index ac6ac68be690..ca498fdf29b9 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/config.ts +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/config.ts @@ -1,6 +1,6 @@ -import { config as qs_config } from '@deriv/bot-skeleton'; import { localize } from '@deriv/translations'; import { MARTINGALE } from '../../../constants/quick-strategies'; +import { SERVER_BOT_CONFIG } from '../config'; import { TConfigItem, TStrategies, TValidationItem } from './types'; export const FORM_TABS = [ @@ -130,7 +130,7 @@ const SIZE: TConfigItem = { 'floor', { type: 'min', - value: String(qs_config.QUICK_STRATEGY.DEFAULT.size), + value: String(SERVER_BOT_CONFIG.DEFAULT.size), getMessage: (min: string | number) => localize('The value must be equal or greater than {{ min }}', { min }), }, diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/desktop-form-wrapper.spec.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/desktop-form-wrapper.spec.tsx index 5551ebfa616b..21cf29972bc7 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/desktop-form-wrapper.spec.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/desktop-form-wrapper.spec.tsx @@ -6,7 +6,6 @@ import userEvent from '@testing-library/user-event'; import { mock_ws } from 'Utils/mock'; import RootStore from 'Stores/root-store'; import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; -import { quick_strategy_content } from '../../../../tutorials/constants'; import DesktopFormWrapper from '../desktop-form-wrapper'; jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => jest.fn()); @@ -66,7 +65,6 @@ describe('', () => { const mock_store = mockStore({}); mock_dbot_store = mockDBotStore(mock_store, mock_ws); const initial_value = {}; - mock_dbot_store?.quick_strategy.setFormVisibility(true); wrapper = ({ children }: { children: JSX.Element }) => ( @@ -101,7 +99,6 @@ describe('', () => { wrapper, } ); - expect(mock_dbot_store?.quick_strategy.is_open).toBeTruthy(); const close_button = screen.getByTestId('qs-desktop-close-button'); userEvent.click(close_button); @@ -110,19 +107,6 @@ describe('', () => { expect(onClickClose).toBeCalled(); }); - it('should change the selected strategy', () => { - mock_dbot_store?.quick_strategy.setSelectedStrategy(quick_strategy_content[0].qs_name); - render( - -
test
-
, - { - wrapper, - } - ); - expect(mock_dbot_store?.quick_strategy.selected_strategy).toBe(quick_strategy_content[0].qs_name); - }); - it('should submit the form', async () => { render( @@ -134,7 +118,6 @@ describe('', () => { wrapper, } ); - expect(mock_dbot_store?.quick_strategy.is_open).toBeTruthy(); const submit_button = screen.getByRole('button', { name: 'Add' }); userEvent.click(submit_button); await waitFor(() => expect(mockOnSubmit).toBeCalled()); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/mobile-form-wrapper.spec.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/mobile-form-wrapper.spec.tsx index 275c8e541f7c..ea01e966d37b 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/mobile-form-wrapper.spec.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/mobile-form-wrapper.spec.tsx @@ -41,7 +41,6 @@ describe('', () => { const mock_store = mockStore({}); mock_dbot_store = mockDBotStore(mock_store, mock_ws); const initial_value = {}; - mock_dbot_store?.quick_strategy.setFormVisibility(true); wrapper = ({ children }: { children: JSX.Element }) => ( @@ -68,7 +67,7 @@ describe('', () => { }); it('should change the selected strategy', () => { - mock_dbot_store?.quick_strategy.setSelectedStrategy('MARTINGALE'); + mock_dbot_store?.server_bot.setSelectedStrategy('MARTINGALE'); render(
test
@@ -77,7 +76,7 @@ describe('', () => { wrapper, } ); - expect(mock_dbot_store?.quick_strategy.selected_strategy).toBe('MARTINGALE'); + expect(mock_dbot_store?.server_bot.selected_strategy).toBe('MARTINGALE'); }); it('should submit the form', async () => { @@ -91,7 +90,7 @@ describe('', () => { wrapper, } ); - expect(mock_dbot_store?.quick_strategy.is_open).toBeTruthy(); + const submit_button = screen.getByRole('button', { name: /Add/i }); userEvent.click(submit_button); await waitFor(() => expect(mockOnSubmit).toBeCalled()); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/useQsSubmitHandler.spec.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/useSubmitHandler.spec.tsx similarity index 62% rename from packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/useQsSubmitHandler.spec.tsx rename to packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/useSubmitHandler.spec.tsx index d23d63e22e60..2a93e17c0733 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/useQsSubmitHandler.spec.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/__tests__/useSubmitHandler.spec.tsx @@ -5,7 +5,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { mock_ws } from 'Utils/mock'; import RootStore from 'Stores/root-store'; import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; -import useQsSubmitHandler from '../useQsSubmitHandler'; +import useSubmitHandler from '../useSubmitHandler'; jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => jest.fn()); @@ -63,7 +63,7 @@ jest.mock('@deriv/bot-skeleton', () => ({ jest.mock('../../../../../xml/martingale_max-stake.xml', () => ''); -describe('useQsSubmitHandler hook', () => { +describe('useSubmitHandler hook', () => { let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element, mock_dbot_store: RootStore | undefined; const mock_store = mockStore({}); @@ -71,11 +71,9 @@ describe('useQsSubmitHandler hook', () => { mock_dbot_store = mockDBotStore(mock_store, mock_ws); mock_dbot_store = { ...mock_dbot_store, - quick_strategy: { - ...mock_dbot_store.quick_strategy, + server_bot: { + ...mock_dbot_store.server_bot, setLossThresholdWarningData: jest.fn(), - onSubmit: jest.fn(), - toggleStopBotDialog: jest.fn(), }, }; const mockOnSubmit = jest.fn(); @@ -92,9 +90,9 @@ describe('useQsSubmitHandler hook', () => { ); }); - it('should call useQsSubmitHandler hook', async () => { + it('should call useSubmitHandler hook', async () => { mock_store.client.is_logged_in = true; - const { result } = renderHook(() => useQsSubmitHandler(), { wrapper }); + const { result } = renderHook(() => useSubmitHandler(), { wrapper }); result.current.handleSubmit(); const { handleSubmit, proceedFormSubmission } = result.current; @@ -103,49 +101,48 @@ describe('useQsSubmitHandler hook', () => { expect(typeof proceedFormSubmission).toBe('function'); }); - it('useQsSubmitHandler hook should not call setLossThresholdWarningData() when is_logged_in equals false', () => { + it('useSubmitHandler hook should not call setLossThresholdWarningData() when is_logged_in equals false', () => { mock_store.client.is_logged_in = false; - const { result } = renderHook(() => useQsSubmitHandler(), { wrapper }); + const { result } = renderHook(() => useSubmitHandler(), { wrapper }); result.current.handleSubmit(); - expect(mock_dbot_store?.quick_strategy.setLossThresholdWarningData).not.toHaveBeenCalled(); + expect(mock_dbot_store?.server_bot.setLossThresholdWarningData).not.toHaveBeenCalled(); }); - it('useQsSubmitHandler hook should not call setLossThresholdWarningData() when bot is running handle toggleStopBotDialog() and make it false', () => { + it('useSubmitHandler hook should not call setLossThresholdWarningData() when bot is running handle toggleStopBotDialog() and make it false', () => { mock_dbot_store?.run_panel?.setIsRunning(true); mock_store.client.is_logged_in = false; - const { result } = renderHook(() => useQsSubmitHandler(), { wrapper }); + const { result } = renderHook(() => useSubmitHandler(), { wrapper }); result.current.handleSubmit(); - expect(mock_dbot_store?.quick_strategy.is_open).toBeFalsy(); - expect(mock_dbot_store?.quick_strategy.setLossThresholdWarningData).not.toHaveBeenCalled(); + expect(mock_dbot_store?.server_bot.setLossThresholdWarningData).not.toHaveBeenCalled(); }); - it('useQsSubmitHandler hook should not call setLossThresholdWarningData() when the balance not less than loss and loss not bigger than profit', () => { + it('useSubmitHandler hook should not call setLossThresholdWarningData() when the balance not less than loss and loss not bigger than profit', () => { mock_store.client.balance = undefined; - const { result } = renderHook(() => useQsSubmitHandler(), { wrapper }); + const { result } = renderHook(() => useSubmitHandler(), { wrapper }); result.current.handleSubmit(); - expect(mock_dbot_store?.quick_strategy.setLossThresholdWarningData).not.toHaveBeenCalled(); + expect(mock_dbot_store?.server_bot.setLossThresholdWarningData).not.toHaveBeenCalled(); }); - it('useQsSubmitHandler hook should not call setLossThresholdWarningData() when the balance more than loss and loss not bigger than profit', () => { + it('useSubmitHandler hook should not call setLossThresholdWarningData() when the balance more than loss and loss not bigger than profit', () => { mock_store.client.balance = 100000000; - const { result } = renderHook(() => useQsSubmitHandler(), { wrapper }); + const { result } = renderHook(() => useSubmitHandler(), { wrapper }); result.current.handleSubmit(); - expect(mock_dbot_store?.quick_strategy.setLossThresholdWarningData).not.toHaveBeenCalled(); + expect(mock_dbot_store?.server_bot.setLossThresholdWarningData).not.toHaveBeenCalled(); }); - it('useQsSubmitHandler hook should call setLossThresholdWarningData() when is_logged_in equals true and balance is less than loss', () => { + it('useSubmitHandler hook should call setLossThresholdWarningData() when is_logged_in equals true and balance is less than loss', () => { mock_store.client.is_logged_in = true; mock_store.client.balance = -1; - const { result } = renderHook(() => useQsSubmitHandler(), { wrapper }); + const { result } = renderHook(() => useSubmitHandler(), { wrapper }); result.current.handleSubmit(); - expect(mock_dbot_store?.quick_strategy.setLossThresholdWarningData).toHaveBeenCalled(); + expect(mock_dbot_store?.server_bot.setLossThresholdWarningData).toHaveBeenCalled(); }); }); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/desktop-form-wrapper.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/desktop-form-wrapper.tsx index 4ce79e5d8b07..f8874d498b9a 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/desktop-form-wrapper.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/desktop-form-wrapper.tsx @@ -6,7 +6,7 @@ import { observer } from '@deriv/stores'; import { Localize, localize } from '@deriv/translations'; import { useDBotStore } from 'Stores/useDBotStore'; import { TFormValues } from '../types'; -import useQsSubmitHandler from './useQsSubmitHandler'; +import useSubmitHandler from './useSubmitHandler'; import '../add-bot.scss'; type TDesktopFormWrapper = { @@ -17,10 +17,10 @@ type TDesktopFormWrapper = { const FormWrapper: React.FC = observer(({ children, onClickClose }) => { const scroll_ref = React.useRef(null); const { isValid, validateForm } = useFormikContext(); - const { quick_strategy } = useDBotStore(); - const { selected_strategy, is_stop_bot_dialog_open } = quick_strategy; + const { server_bot } = useDBotStore(); + const { selected_strategy } = server_bot; - const { handleSubmit } = useQsSubmitHandler(); + const { handleSubmit } = useSubmitHandler(); React.useEffect(() => { validateForm(); @@ -31,55 +31,53 @@ const FormWrapper: React.FC = observer(({ children, onClick }; return ( - !is_stop_bot_dialog_open && ( -
-
- {localize('Add Bot')} -
- { - if (e.key === 'Enter') { - onClickClose(); - } - }} - > - - -
+
+
+ {localize('Add Bot')} +
+ { + if (e.key === 'Enter') { + onClickClose(); + } + }} + > + +
-
-
- -
- - - - - - -
-
{children}
-
-
- +
+
+
+ +
+ + + + + +
+
{children}
+
+
+
- ) +
); }); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/mobile-form-wrapper.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/mobile-form-wrapper.tsx index 816b838d4ac1..adc39f7af3d5 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/mobile-form-wrapper.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/mobile-form-wrapper.tsx @@ -5,7 +5,7 @@ import { observer } from '@deriv/stores'; import { Localize } from '@deriv/translations'; import { useDBotStore } from 'Stores/useDBotStore'; import { TFormValues } from '../types'; -import useQsSubmitHandler from './useQsSubmitHandler'; +import useSubmitHandler from './useSubmitHandler'; import '../add-bot.scss'; type TMobileFormWrapper = { @@ -14,9 +14,9 @@ type TMobileFormWrapper = { const MobileFormWrapper: React.FC = observer(({ children }) => { const { isValid, validateForm } = useFormikContext(); - const { quick_strategy } = useDBotStore(); - const { selected_strategy } = quick_strategy; - const { handleSubmit } = useQsSubmitHandler(); + const { server_bot } = useDBotStore(); + const { selected_strategy } = server_bot; + const { handleSubmit } = useSubmitHandler(); React.useEffect(() => { validateForm(); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useQsSubmitHandler.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useQsSubmitHandler.tsx deleted file mode 100644 index f5fe0ecabfe0..000000000000 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useQsSubmitHandler.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { useFormikContext } from 'formik'; -import { useStore } from '@deriv/stores'; -import { useDBotStore } from 'Stores/useDBotStore'; -import { rudderStackSendQsRunStrategyEvent } from '../../../../analytics/rudderstack-quick-strategy'; -import { SERVER_BOT_LOSS_THRESHOLD_WARNING } from '../constants'; -import { TFormValues } from '../types'; - -const useQsSubmitHandler = () => { - const { client } = useStore(); - const { currency, balance, is_logged_in } = client; - const { submitForm, setFieldValue, values, isValid, validateForm } = useFormikContext(); - const { quick_strategy, run_panel } = useDBotStore(); - const { - toggleStopBotDialog, - setLossThresholdWarningData, - selected_strategy, - loss_threshold_warning_data, - onSubmit, - } = quick_strategy; - - const handleSubmit = async () => { - const loss_amount = Number(values?.loss ?? 0); - const profit_threshold = Number(values?.profit ?? 0); - const stored_dont_show_warning_value = localStorage?.getItem(SERVER_BOT_LOSS_THRESHOLD_WARNING); - const dont_show_warning = JSON.parse(stored_dont_show_warning_value ?? 'false'); - if ( - !loss_threshold_warning_data.already_shown && - (loss_amount > 0.5 * Number(balance ?? 0) || loss_amount > 2 * profit_threshold) && - is_logged_in && - !dont_show_warning - ) { - setLossThresholdWarningData({ - show: true, - loss_amount, - currency, - already_shown: true, - }); - } else { - proceedFormSubmission(); - } - }; - - const proceedFormSubmission = async () => { - if (run_panel.is_running) { - await setFieldValue('action', 'EDIT'); - validateForm(); - submitForm(); - toggleStopBotDialog(); - rudderStackSendQsRunStrategyEvent({ - form_values: values, - selected_strategy, - }); - } else { - await setFieldValue('action', 'RUN'); - validateForm(); - submitForm().then((form_data: TFormValues | void) => { - if (isValid && form_data) { - rudderStackSendQsRunStrategyEvent({ - form_values: values, - selected_strategy, - }); - onSubmit(form_data); - } - }); - } - }; - - return { handleSubmit, proceedFormSubmission }; -}; - -export default useQsSubmitHandler; diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useSubmitHandler.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useSubmitHandler.tsx new file mode 100644 index 000000000000..3dae2bdcb096 --- /dev/null +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form-wrappers/useSubmitHandler.tsx @@ -0,0 +1,44 @@ +import { useFormikContext } from 'formik'; +import { useStore } from '@deriv/stores'; +import { useDBotStore } from 'Stores/useDBotStore'; +import { SERVER_BOT_LOSS_THRESHOLD_WARNING } from '../constants'; +import { TFormValues } from '../types'; + +const useSubmitHandler = () => { + const { client } = useStore(); + const { currency, balance, is_logged_in } = client; + const { submitForm, values, validateForm } = useFormikContext(); + const { server_bot } = useDBotStore(); + const { setLossThresholdWarningData, loss_threshold_warning_data } = server_bot; + + const handleSubmit = async () => { + const loss_amount = Number(values?.loss ?? 0); + const profit_threshold = Number(values?.profit ?? 0); + const stored_dont_show_warning_value = localStorage?.getItem(SERVER_BOT_LOSS_THRESHOLD_WARNING); + const dont_show_warning = JSON.parse(stored_dont_show_warning_value ?? 'false'); + if ( + !loss_threshold_warning_data.already_shown && + (loss_amount > 0.5 * Number(balance ?? 0) || loss_amount > 2 * profit_threshold) && + is_logged_in && + !dont_show_warning + ) { + setLossThresholdWarningData({ + show: true, + loss_amount, + currency, + already_shown: true, + }); + } else { + proceedFormSubmission(); + } + }; + + const proceedFormSubmission = () => { + validateForm(); + submitForm(); + }; + + return { handleSubmit, proceedFormSubmission }; +}; + +export default useSubmitHandler; diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form.tsx index ae1ea042965e..ffc2d00f747c 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/form.tsx @@ -17,12 +17,11 @@ import './add-bot.scss'; const QuickStrategyForm = observer(() => { const { ui } = useStore(); - const { quick_strategy } = useDBotStore(); - const { selected_strategy, setValue, form_data } = quick_strategy; + const { server_bot } = useDBotStore(); + const { selected_strategy, setValue, form_data, current_duration_min_max } = server_bot; const config: TConfigItem[][] = STRATEGIES[selected_strategy]?.fields; const { is_desktop } = ui; const { values, setFieldTouched, setFieldValue } = useFormikContext(); - const { current_duration_min_max } = quick_strategy; const [isEnabledToggleSwitch, setIsEnabledToggleSwitch] = React.useState(false); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/inputs/add-input.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/inputs/add-input.tsx index 8f1b6f36fe48..d8da73cd56ba 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/inputs/add-input.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/inputs/add-input.tsx @@ -32,8 +32,8 @@ const QSInput: React.FC = observer( ui: { is_desktop }, client: { currency }, } = useStore(); - const { quick_strategy } = useDBotStore(); - const { loss_threshold_warning_data } = quick_strategy; + const { server_bot } = useDBotStore(); + const { loss_threshold_warning_data } = server_bot; const [has_focus, setFocus] = React.useState(false); const { setFieldValue, setFieldTouched } = useFormikContext(); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/__tests__/loss-threshold-warning.spec.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/__tests__/loss-threshold-warning.spec.tsx index 6bfda2c77058..fbac68ee3332 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/__tests__/loss-threshold-warning.spec.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/__tests__/loss-threshold-warning.spec.tsx @@ -55,7 +55,7 @@ describe('LossThresholdWarningDialog', () => { }); it('should handle edit the amount button click', () => { - mock_dbot_store?.quick_strategy.setLossThresholdWarningData({ + mock_dbot_store?.server_bot.setLossThresholdWarningData({ show: true, }); render(, { @@ -63,11 +63,11 @@ describe('LossThresholdWarningDialog', () => { }); const edit_amount_btn = screen.getByRole('button', { name: /Edit the amount/i }); userEvent.click(edit_amount_btn); - expect(mock_dbot_store?.quick_strategy.loss_threshold_warning_data.show).toBeFalsy(); + expect(mock_dbot_store?.server_bot.loss_threshold_warning_data.show).toBeFalsy(); }); it('should handle continue button click', async () => { - mock_dbot_store?.quick_strategy.setLossThresholdWarningData({ + mock_dbot_store?.server_bot.setLossThresholdWarningData({ show: true, }); render(, { @@ -76,12 +76,12 @@ describe('LossThresholdWarningDialog', () => { const continue_btn = screen.getByRole('button', { name: /Yes, continue/i }); userEvent.click(continue_btn); await waitFor(() => { - expect(mock_dbot_store?.quick_strategy.loss_threshold_warning_data.show).toBeFalsy(); + expect(mock_dbot_store?.server_bot.loss_threshold_warning_data.show).toBeFalsy(); }); }); it('should handle dont show again checkbox click', () => { - mock_dbot_store?.quick_strategy.setLossThresholdWarningData({ + mock_dbot_store?.server_bot.setLossThresholdWarningData({ show: true, }); render(, { diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/loss-threshold-warning-dialog.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/loss-threshold-warning-dialog.tsx index f9bf5e8140cd..4f906de6f1ce 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/loss-threshold-warning-dialog.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/parts/loss-threshold-warning-dialog.tsx @@ -4,16 +4,15 @@ import { observer } from '@deriv/stores'; import { Localize, localize } from '@deriv/translations'; import { useDBotStore } from 'Stores/useDBotStore'; import { SERVER_BOT_LOSS_THRESHOLD_WARNING } from '../constants'; -import useQsSubmitHandler from '../form-wrappers/useQsSubmitHandler'; +import useSubmitHandler from '../form-wrappers/useSubmitHandler'; import './loss-threshold-warning-dialog.scss'; const base_classname = 'loss-threshold-warning-dialog'; const LossThresholdWarningDialog = observer(() => { - const { quick_strategy } = useDBotStore(); - const { loss_threshold_warning_data, setLossThresholdWarningData, initializeLossThresholdWarningData } = - quick_strategy; - const { proceedFormSubmission } = useQsSubmitHandler(); + const { server_bot } = useDBotStore(); + const { loss_threshold_warning_data, setLossThresholdWarningData, initializeLossThresholdWarningData } = server_bot; + const { proceedFormSubmission } = useSubmitHandler(); const handleAmountEdit = () => { setLossThresholdWarningData({ diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/contract-type.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/contract-type.tsx index 31a872f9e7f0..551024bbbe0c 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/contract-type.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/contract-type.tsx @@ -17,8 +17,8 @@ const ContractTypes: React.FC = observer(({ name }) => { const { ui } = useStore(); const { is_desktop } = ui; const [list, setList] = React.useState([]); - const { quick_strategy } = useDBotStore(); - const { setValue } = quick_strategy; + const { server_bot } = useDBotStore(); + const { setValue } = server_bot; const { setFieldValue, values } = useFormikContext(); const { symbol, tradetype } = values; diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/duration-type.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/duration-type.tsx index b2c1f94dbd3f..f6ca30756386 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/duration-type.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/duration-type.tsx @@ -15,8 +15,8 @@ const DurationUnit: React.FC = ({ attached }: TDurationUnit) => { const [list, setList] = React.useState([]); const [prevSymbol, setPrevSymbol] = React.useState(''); const [prevTradeType, setPrevTradeType] = React.useState(''); - const { quick_strategy } = useDBotStore(); - const { setValue, setCurrentDurationMinMax } = quick_strategy; + const { server_bot } = useDBotStore(); + const { setValue, setCurrentDurationMinMax } = server_bot; const { setFieldValue, validateForm, values } = useFormikContext(); const { symbol, tradetype } = values; diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/symbol.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/symbol.tsx index b897f8683e81..7997beeb59b2 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/symbol.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/symbol.tsx @@ -28,11 +28,11 @@ const MarketOption: React.FC = ({ symbol }) => ( ); const SymbolSelect: React.FC = () => { - const { quick_strategy } = useDBotStore(); + const { server_bot } = useDBotStore(); const { ui: { is_desktop }, } = useStore(); - const { setValue } = quick_strategy; + const { setValue } = server_bot; const [active_symbols, setActiveSymbols] = React.useState([]); const [is_input_started, setIsInputStarted] = useState(false); const [input_value, setInputValue] = useState({ text: '', value: '' }); diff --git a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/trade-type.tsx b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/trade-type.tsx index 9ad9c02096c3..09e836969f10 100644 --- a/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/trade-type.tsx +++ b/packages/bot-web-ui/src/pages/server-side-bot/add-bot/selects/trade-type.tsx @@ -28,8 +28,8 @@ const TradeTypeOption: React.FC = ({ trade_type: { value, icon const TradeTypeSelect: React.FC = () => { const [trade_types, setTradeTypes] = React.useState([]); const { setFieldValue, values, validateForm } = useFormikContext(); - const { quick_strategy } = useDBotStore(); - const { setValue } = quick_strategy; + const { server_bot } = useDBotStore(); + const { setValue } = server_bot; React.useEffect(() => { if (values?.symbol) { diff --git a/packages/bot-web-ui/src/pages/server-side-bot/config.ts b/packages/bot-web-ui/src/pages/server-side-bot/config.ts new file mode 100644 index 000000000000..81a0a34ce668 --- /dev/null +++ b/packages/bot-web-ui/src/pages/server-side-bot/config.ts @@ -0,0 +1,16 @@ +export const SERVER_BOT_CONFIG = { + DISABLED: { + SYMBOLS: ['1HZ150V', '1HZ250V'], + SUBMARKETS: ['crash_index', 'non_stable_coin', 'step_index'], + BARRIER_TRADE_TYPES: ['higherlower', 'touchnotouch', 'endsinout', 'staysinout', 'callputspread', 'accumulator'], + PREDICTION_TRADE_TYPES: ['highlowticks'], + }, + DEFAULT: { + symbol: '1HZ100V', + tradetype: 'callput', + durationtype: 't', + size: 1, + unit: 1, + prediction: 0, + }, +}; diff --git a/packages/bot-web-ui/src/stores/server-side-bot-store.ts b/packages/bot-web-ui/src/stores/server-side-bot-store.ts index f7ab3cb0c6ce..006f7f7ee9e6 100644 --- a/packages/bot-web-ui/src/stores/server-side-bot-store.ts +++ b/packages/bot-web-ui/src/stores/server-side-bot-store.ts @@ -6,6 +6,7 @@ import { isEnded } from '@deriv/shared'; import { localize } from '@deriv/translations'; import { botNotification } from 'Components/bot-notification/bot-notification'; import { downloadFile } from 'Utils/download'; +import { SERVER_BOT_CONFIG } from '../pages/server-side-bot/config'; import RootStore from './root-store'; export type TFormData = { @@ -85,6 +86,14 @@ export type TJournalItem = { time?: string; }; +export type TLossThresholdWarningData = { + show: boolean; + loss_amount?: string | number; + currency?: string; + highlight_field?: Array; + already_shown?: boolean; +}; + export const getDate = (epoch: number) => { const DATE_TIME_FORMAT_WITH_OFFSET = 'YYYY-MM-DD HH:mm:ss Z'; return moment.unix(epoch).utc().local().format(DATE_TIME_FORMAT_WITH_OFFSET); @@ -107,6 +116,20 @@ export default class ServerBotStore { pocs: { [key: string]: ProposalOpenContract } = {}; should_subscribe = true; + loss_threshold_warning_data: TLossThresholdWarningData = { + show: false, + }; + current_duration_min_max = { + min: 0, + max: 10, + }; + selected_strategy = 'MARTINGALE'; + form_data: TFormData = { + symbol: SERVER_BOT_CONFIG.DEFAULT.symbol, + tradetype: SERVER_BOT_CONFIG.DEFAULT.tradetype, + durationtype: SERVER_BOT_CONFIG.DEFAULT.durationtype, + action: 'RUN', + }; constructor(root_store: RootStore) { this.root_store = root_store; @@ -119,6 +142,10 @@ export default class ServerBotStore { pocs: observable, journal: observable, should_subscribe: observable, + selected_strategy: observable, + form_data: observable, + current_duration_min_max: observable, + loss_threshold_warning_data: observable, setShouldSubscribe: action, performance: computed, setListLoading: action, @@ -136,6 +163,10 @@ export default class ServerBotStore { setJournal: action, setBotList: action, setActiveBotId: action, + setLossThresholdWarningData: action, + initializeLossThresholdWarningData: action, + setCurrentDurationMinMax: action, + setSelectedStrategy: action, }); } @@ -188,8 +219,6 @@ export default class ServerBotStore { const { msg_type, echo_req } = data; if (data?.error) { - // eslint-disable-next-line no-console - console.info(data.error); if (data.error.message) { this.onJournalMessage(JOURNAL_TYPE.ERROR, { msg: data.error.message, @@ -574,4 +603,34 @@ export default class ServerBotStore { console.dir(error); } }; + + setLossThresholdWarningData = (data: TLossThresholdWarningData) => { + this.loss_threshold_warning_data = { + ...this.loss_threshold_warning_data, + ...data, + }; + }; + + initializeLossThresholdWarningData = () => { + this.loss_threshold_warning_data = { + show: false, + highlight_field: [], + already_shown: false, + }; + }; + + setCurrentDurationMinMax = (min = 0, max = 10) => { + this.current_duration_min_max = { + min, + max, + }; + }; + + setValue = (name: string, value: string | number | boolean) => { + this.form_data[name as keyof TFormData] = value; + }; + + setSelectedStrategy = (strategy: string) => { + this.selected_strategy = strategy; + }; }