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

[TRAH5082] Suisin/trah5082/change traders hub button url based on ff #17916

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions packages/api-v2/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ export { default as useDynamicLeverage } from './useDynamicLeverage';
export { default as useExchangeRateSubscription } from './useExchangeRateSubscription';
export { default as useGetAccountStatus } from './useGetAccountStatus';
export { default as useGetExchangeRate } from './useGetExchangeRate';
export { default as useGrowthbookGetFeatureValue } from './useGrowthbookGetFeatureValue';
export { default as useGrowthbookIsOn } from './useGrowthbookIsOn';
export { default as useIdentityDocumentVerificationAdd } from './useIdentityDocumentVerificationAdd';
export { default as useIsEuRegion } from './useIsEuRegion';
export { default as useIsHubRedirectionEnabled } from './useIsHubRedirectionEnabled';
export { default as useJurisdictionStatus } from './useJurisdictionStatus';
export { default as useLandingCompany } from './useLandingCompany';
export { default as useMT5AccountsList } from './useMT5AccountsList';
Expand Down
41 changes: 41 additions & 0 deletions packages/api-v2/src/hooks/useGrowthbookGetFeatureValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useEffect, useState } from 'react';
import { useIsMounted } from 'usehooks-ts';

import { getFeatureFlag } from '@deriv/utils';
import { Analytics } from '@deriv-com/analytics';

interface UseGrowthbookGetFeatureValueArgs<T> {
featureFlag: string;
defaultValue?: T;
}

const useGrowthbookGetFeatureValue = <T extends string | boolean>({
featureFlag,
defaultValue,
}: UseGrowthbookGetFeatureValueArgs<T>) => {
suisin-deriv marked this conversation as resolved.
Show resolved Hide resolved
const resolvedDefaultValue: T = defaultValue !== undefined ? defaultValue : (false as T);
const [featureFlagValue, setFeatureFlagValue] = useState<boolean>(false);
const [isGBLoaded, setIsGBLoaded] = useState(false);
const isMounted = useIsMounted();

// Required for debugging Growthbook, this will be removed after this is added in the Analytics directly.
if (typeof window !== 'undefined') {
window.Analytics = Analytics;
}

useEffect(() => {
const fetchFeatureFlag = async () => {
const is_enabled = await getFeatureFlag(featureFlag, resolvedDefaultValue);
if (isMounted()) {
setFeatureFlagValue(is_enabled);
setIsGBLoaded(true);
}
};

fetchFeatureFlag();
}, [featureFlag, resolvedDefaultValue, isMounted]);

return [featureFlagValue, isGBLoaded];
};

export default useGrowthbookGetFeatureValue;
34 changes: 34 additions & 0 deletions packages/api-v2/src/hooks/useIsHubRedirectionEnabled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import useClientCountry from './useClientCountry';
import useGrowthbookGetFeatureValue from './useGrowthbookGetFeatureValue';
import useSettings from './useSettings';

type THubEnabledCountryList = {
hub_enabled_country_list: string[];
};

const useIsHubRedirectionEnabled = () => {
suisin-deriv marked this conversation as resolved.
Show resolved Hide resolved
const [hubEnabledCountryList] = useGrowthbookGetFeatureValue({
featureFlag: 'hub_enabled_country_list',
});
const { data: clientCountry } = useClientCountry();
const { data: accountSettings } = useSettings();
const { citizen } = accountSettings;

const isHubRedirectionEnabled =
typeof hubEnabledCountryList === 'object' &&
hubEnabledCountryList !== null &&
Array.isArray((hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list) &&
citizen &&
(hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list.includes(citizen);

const isChangingToHubAppId =
typeof hubEnabledCountryList === 'object' &&
hubEnabledCountryList !== null &&
Array.isArray((hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list) &&
clientCountry &&
(hubEnabledCountryList as THubEnabledCountryList).hub_enabled_country_list.includes(clientCountry);

return { isHubRedirectionEnabled, isChangingToHubAppId };
};

export default useIsHubRedirectionEnabled;
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ type TMockPlatformDropdown = {
}[];
};

jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
useIsHubRedirectionEnabled: () => ({
isHubRedirectionEnabled: false,
}),
}));

const history = createBrowserHistory();
const store = mockStore({});

Expand Down Expand Up @@ -81,19 +88,19 @@ describe('PlatformDropdown component', () => {
expect(screen.getByTestId('dt_platform_dropdown_link')).toBeInTheDocument();
expect(screen.getByText(tradershub_redirect)).toBeInTheDocument();
});
it('should update URL when clicking on another (non-selected) platform', () => {
it('should update URL when clicking on another (non-selected) platform', async () => {
history.push(routes.bot);
render(<MockPlatformDropdown platform_config={[dtrader_platform_config]} />);

userEvent.click(screen.getByText(dtrader_description));
await userEvent.click(screen.getByText(dtrader_description));
expect(history.location.pathname).toBe(routes.trade);
expect(history.location.search).toBe('');
});
it('should not update URL when clicking on an already selected platform', () => {
it('should not update URL when clicking on an already selected platform', async () => {
history.push(routes.trade + dtrader_url_params);
render(<MockPlatformDropdown platform_config={[dtrader_platform_config]} />);

userEvent.click(screen.getByText(dtrader_description));
await userEvent.click(screen.getByText(dtrader_description));
expect(history.location.pathname).toBe(routes.trade);
expect(history.location.search).toBe(dtrader_url_params);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { Div100vhContainer, Icon, useOnClickOutside, Text } from '@deriv/components';
import { routes, getActivePlatform } from '@deriv/shared';
import { routes, getActivePlatform, platforms } from '@deriv/shared';
import { BinaryLink } from 'App/Components/Routes';
import 'Sass/app/_common/components/platform-dropdown.scss';
import { Localize } from '@deriv/translations';
import { useHistory } from 'react-router';
import { useDevice } from '@deriv-com/ui';
import { useIsHubRedirectionEnabled } from '@deriv/hooks';
import { useStore } from '@deriv/stores';

const PlatformBox = ({ platform: { icon, description } }) => (
<React.Fragment>
Expand Down Expand Up @@ -50,12 +52,20 @@ const PlatformDropdownContent = ({ platform, app_routing_history }) => {
const PlatformDropdown = ({ app_routing_history, closeDrawer, platform_config, setTogglePlatformType }) => {
const history = useHistory();
const { isDesktop } = useDevice();
const { isHubRedirectionEnabled } = useIsHubRedirectionEnabled();
const { client } = useStore();
const { account_settings } = client;
const { trading_hub } = account_settings;

const TradersHubRedirect = () => {
return (
<div className='platform-dropdown__cta'>
<BinaryLink
onClick={() => {
if (isHubRedirectionEnabled || !!trading_hub) {
window.location.assign(platforms.tradershub_os.url);
return;
}
if (!isDesktop) {
history.push(routes.traders_hub);
setTogglePlatformType('cfd');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ jest.mock('@deriv/hooks', () => ({
useWalletAccountsList: jest.fn(() => ({
data: [{ loginid: 'CR007', dtrade_loginid: 'CR008' }],
})),
useIsHubRedirectionEnabled: jest.fn(() => ({
isHubRedirectionEnabled: false,
})),
}));

jest.mock('react-router', () => ({
Expand Down Expand Up @@ -93,7 +96,7 @@ describe('AccountSwitcherWalletMobile', () => {
expect(screen.getByText('AccountSwitcherWalletList')).toBeInTheDocument();
});

it('should toggle the switcher on footer click', () => {
it('should toggle the switcher on footer click', async () => {
const store = mockStore({
client: {
accounts: {
Expand All @@ -107,7 +110,7 @@ describe('AccountSwitcherWalletMobile', () => {
});
render(<AccountSwitcherWalletMobile {...props} />, { wrapper: wrapper(store) });
const footer = screen.getByText('Looking for CFDs? Go to Trader’s Hub');
userEvent.click(footer);
await userEvent.click(footer);
expect(props.toggle).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ jest.mock('react-router', () => ({
}),
}));

jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
useIsHubRedirectionEnabled: () => ({
isHubRedirectionEnabled: false,
}),
}));

jest.mock('../account-switcher-wallet-list', () => ({
AccountSwitcherWalletList: () => <div>AccountSwitcherWalletList</div>,
}));
Expand Down Expand Up @@ -74,12 +81,12 @@ describe('AccountSwitcherWalletComponent', () => {
expect(screen.getByText('AccountSwitcherWalletList')).toBeInTheDocument();
});

it('should toggle the switcher on button click', () => {
it('should toggle the switcher on button click', async () => {
const mock = mockStore({});

render(<AccountSwitcherWallet {...props} />, { wrapper: wrapper(mock) });
const button = screen.getByTestId('dt_go_to_arrow');
userEvent.click(button);
await userEvent.click(button);
expect(props.toggle).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import { useHistory } from 'react-router';
import { Button, Icon, MobileDialog, Text } from '@deriv/components';
import { routes } from '@deriv/shared';
import { platforms, routes } from '@deriv/shared';
import { Localize } from '@deriv/translations';
import { AccountSwitcherWalletList } from './account-switcher-wallet-list';
import { useIsRtl, useStoreWalletAccountsList } from '@deriv/hooks';
import { observer } from '@deriv/stores';
import { useIsHubRedirectionEnabled, useIsRtl, useStoreWalletAccountsList } from '@deriv/hooks';
import { observer, useStore } from '@deriv/stores';
import './account-switcher-wallet-mobile.scss';

type TAccountSwitcherWalletMobile = {
Expand All @@ -18,14 +18,22 @@ export const AccountSwitcherWalletMobile = observer(({ is_visible, toggle, login
const history = useHistory();
const isRtl = useIsRtl();
const { data: wallet_list } = useStoreWalletAccountsList();
const { client } = useStore();
const { account_settings } = client;
const { trading_hub } = account_settings;

const dtrade_account_wallets = wallet_list?.filter(wallet => wallet.dtrade_loginid);
const { isHubRedirectionEnabled } = useIsHubRedirectionEnabled();

const closeAccountsDialog = React.useCallback(() => {
toggle(false);
}, [toggle]);

const handleTradersHubRedirect = () => {
if (isHubRedirectionEnabled || !!trading_hub) {
window.location.assign(platforms.tradershub_os.url);
return;
}
closeAccountsDialog();
history.push(routes.traders_hub);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';
import { useHistory } from 'react-router';
import { Icon, Text, ThemedScrollbars, useOnClickOutside } from '@deriv/components';
import { routes } from '@deriv/shared';
import { observer } from '@deriv/stores';
import { platforms, routes } from '@deriv/shared';
import { observer, useStore } from '@deriv/stores';
import { Localize } from '@deriv/translations';
import { useStoreWalletAccountsList } from '@deriv/hooks';
import { useIsHubRedirectionEnabled, useStoreWalletAccountsList } from '@deriv/hooks';
import { AccountSwitcherWalletList } from './account-switcher-wallet-list';
import './account-switcher-wallet.scss';

Expand All @@ -18,8 +18,12 @@ export const AccountSwitcherWallet = observer(({ is_visible, toggle }: TAccountS
const dtrade_account_wallets = wallet_list?.filter(wallet => wallet.dtrade_loginid);

const history = useHistory();
const { client } = useStore();
const { account_settings } = client;
const { trading_hub } = account_settings;

const wrapper_ref = React.useRef<HTMLDivElement>(null);
const { isHubRedirectionEnabled } = useIsHubRedirectionEnabled();

const validateClickOutside = (event: MouseEvent) => {
const checkAllParentNodes = (node: HTMLElement): boolean => {
Expand All @@ -39,6 +43,10 @@ export const AccountSwitcherWallet = observer(({ is_visible, toggle }: TAccountS
useOnClickOutside(wrapper_ref, closeAccountsDialog, validateClickOutside);

const handleTradersHubRedirect = async () => {
if (isHubRedirectionEnabled || !!trading_hub) {
window.location.assign(platforms.tradershub_os.url);
return;
}
closeAccountsDialog();
history.push(routes.traders_hub);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const ConfirmEmailModal = observer(
const [is_modal_open, setIsModalOpen] = React.useState(is_open);

const { client } = useStore();
const { verification_code, setVerificationCode } = client;
const { verification_code, setVerificationCode, setPreventRedirectToHub } = client;

const handleSubmit = () => {
const api_request: TSocketRequest<'change_email'> = {
Expand Down Expand Up @@ -57,7 +57,10 @@ export const ConfirmEmailModal = observer(
return (
<SentEmailModal
is_open={is_send_email_modal_open}
onClose={() => setIsSendEmailModalOpen(false)}
onClose={() => {
setIsSendEmailModalOpen(false);
setPreventRedirectToHub(false);
}}
identifier_title={'Change_Email'}
onClickSendEmail={resendEmail}
has_live_chat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import { Localize, localize } from '@deriv/translations';
import EmailResent from './email-resent';

const LinkExpiredModal = observer(() => {
const { ui } = useStore();
const { ui, client } = useStore();
const { setPreventRedirectToHub } = client;
const { enableApp, disableApp, is_link_expired_modal_visible: is_visible, toggleLinkExpiredModal } = ui;

const { send, error: verify_error, data: verify_data } = useVerifyEmail('reset_password');
Expand Down Expand Up @@ -60,7 +61,10 @@ const LinkExpiredModal = observer(() => {
enableApp={enableApp}
title={is_email_sent ? '' : localize('Link expired')}
has_close_icon
onConfirm={() => toggleLinkExpiredModal(false)}
onConfirm={() => {
toggleLinkExpiredModal(false);
setPreventRedirectToHub(false);
}}
>
<div className='link-expired'>
{is_email_sent ? (
Expand Down Expand Up @@ -94,7 +98,10 @@ const LinkExpiredModal = observer(() => {
<FormSubmitButton
has_cancel
cancel_label={localize('Close')}
onCancel={() => toggleLinkExpiredModal(false)}
onCancel={() => {
toggleLinkExpiredModal(false);
setPreventRedirectToHub(false);
}}
is_disabled={!values.email || !!errors.email || isSubmitting}
is_loading={isSubmitting}
label={localize('Resend email')}
Expand Down
Loading
Loading