From 8623b8a7632168f23ea0b38969a63b30a860ab27 Mon Sep 17 00:00:00 2001 From: Hamid Date: Fri, 21 Jul 2023 11:23:08 +0330 Subject: [PATCH 01/52] hamid/WALL-250/withdraw-hooks-refactor (#8776) * feat: add useaccountplatformdetails hook * feat: add useneedpoi hook * fix: fix failed test --------- Co-authored-by: Bahar --- .../__tests__/crypto-withdraw-form.spec.tsx | 10 ++++- .../crypto-withdraw-form.tsx | 5 ++- .../stores/__tests__/withdraw-store.spec.ts | 4 -- packages/cashier/src/stores/withdraw-store.ts | 8 ---- .../useCurrentAccountDetails.spec.tsx | 35 +++++++++++++++ .../hooks/src/__tests__/useNeedPOI.spec.tsx | 44 +++++++++++++++++++ packages/hooks/src/index.ts | 4 +- .../hooks/src/useCurrentAccountDetails.ts | 10 +++++ packages/hooks/src/useNeedPOI.ts | 10 +++++ 9 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 packages/hooks/src/__tests__/useCurrentAccountDetails.spec.tsx create mode 100644 packages/hooks/src/__tests__/useNeedPOI.spec.tsx create mode 100644 packages/hooks/src/useCurrentAccountDetails.ts create mode 100644 packages/hooks/src/useNeedPOI.ts diff --git a/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/__tests__/crypto-withdraw-form.spec.tsx b/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/__tests__/crypto-withdraw-form.spec.tsx index 7789c9d325c8..3f0a30d4845f 100644 --- a/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/__tests__/crypto-withdraw-form.spec.tsx +++ b/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/__tests__/crypto-withdraw-form.spec.tsx @@ -1,11 +1,20 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { useCurrentAccountDetails } from '@deriv/hooks'; import CryptoWithdrawForm from '../crypto-withdraw-form'; import CashierProviders from '../../../../cashier-providers'; import { mockStore } from '@deriv/stores'; +jest.mock('@deriv/hooks', () => ({ + ...jest.requireActual('@deriv/hooks'), + useCurrentAccountDetails: jest.fn(() => { + 'icon'; + }), +})); + describe('', () => { + (useCurrentAccountDetails as jest.Mock).mockReturnValue({ icon: 'icon' }); let mockRootStore: ReturnType; beforeEach(() => { mockRootStore = mockStore({ @@ -27,7 +36,6 @@ describe('', () => { onMount: jest.fn(), }, withdraw: { - account_platform_icon: 'icon', blockchain_address: 'tb1ql7w62elx9ucw4pj5lgw4l028hmuw80sndtntxt', onMountCryptoWithdraw: jest.fn(), requestWithdraw: jest.fn(), diff --git a/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/crypto-withdraw-form.tsx b/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/crypto-withdraw-form.tsx index 41c9942bd215..1c362a4c90d0 100644 --- a/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/crypto-withdraw-form.tsx +++ b/packages/cashier/src/pages/withdrawal/crypto-withdraw-form/crypto-withdraw-form.tsx @@ -5,6 +5,7 @@ import { Button, Icon, Input, Loading, MobileWrapper, Text } from '@deriv/compon import { CryptoConfig, getCurrencyName, isCryptocurrency, isMobile } from '@deriv/shared'; import { localize, Localize } from '@deriv/translations'; import { useStore, observer } from '@deriv/stores'; +import { useCurrentAccountDetails } from '@deriv/hooks'; import CryptoFiatConverter from '../../../components/crypto-fiat-converter'; import PercentageSelector from '../../../components/percentage-selector'; import RecentTransaction from '../../../components/recent-transaction'; @@ -58,7 +59,6 @@ const CryptoWithdrawForm = observer(() => { const { crypto_fiat_converter, general_store, transaction_history, withdraw } = useCashierStore(); const crypto_currency = currency; const { - account_platform_icon, blockchain_address, onMountCryptoWithdraw: onMountWithdraw, requestWithdraw, @@ -77,6 +77,7 @@ const CryptoWithdrawForm = observer(() => { } = crypto_fiat_converter; const { is_loading, percentage, percentageSelectorSelectionStatus, should_percentage_reset } = general_store; const { crypto_transactions, onMount: recentTransactionOnMount } = transaction_history; + const account_details = useCurrentAccountDetails(); React.useEffect(() => { recentTransactionOnMount(); @@ -108,7 +109,7 @@ const CryptoWithdrawForm = observer(() => {
{!isMobile() &&
}
- +
{isMobile() &&
} { withdraw_store.validateWithdrawToAmount(); expect(setConverterToError).toHaveBeenCalledWith(error_message); }); - - it('should get account_platform_icon', () => { - expect(withdraw_store.account_platform_icon).toBe('icon'); - }); }); diff --git a/packages/cashier/src/stores/withdraw-store.ts b/packages/cashier/src/stores/withdraw-store.ts index 57115d19b350..93acb20ef962 100644 --- a/packages/cashier/src/stores/withdraw-store.ts +++ b/packages/cashier/src/stores/withdraw-store.ts @@ -34,7 +34,6 @@ export default class WithdrawStore { setWithdrawPercentageSelectorResult: action.bound, validateWithdrawFromAmount: action.bound, validateWithdrawToAmount: action.bound, - account_platform_icon: computed, }); this.root_store = root_store; @@ -385,11 +384,4 @@ export default class WithdrawStore { setConverterToError(error_message); } - - get account_platform_icon() { - const { account_list, loginid } = this.root_store.client; - const platform_icon = account_list.find(acc => loginid === acc.loginid)?.icon; - - return platform_icon; - } } diff --git a/packages/hooks/src/__tests__/useCurrentAccountDetails.spec.tsx b/packages/hooks/src/__tests__/useCurrentAccountDetails.spec.tsx new file mode 100644 index 000000000000..527907ca49c6 --- /dev/null +++ b/packages/hooks/src/__tests__/useCurrentAccountDetails.spec.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { StoreProvider, mockStore } from '@deriv/stores'; +import { renderHook } from '@testing-library/react-hooks'; +import useCurrentAccountDetails from '../useCurrentAccountDetails'; + +describe('useCurrentAccountDetails', () => { + test('should return the account info of the current loginid', async () => { + const mockRootStore = mockStore({ + client: { + account_list: [ + { + account: { + balance: 10000, + currency: 'USD', + disabled: false, + is_crypto: false, + }, + icon: 'icon', + is_dark_mode_on: false, + loginid: 'loginid', + title: 'title', + }, + ], + loginid: 'loginid', + }, + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + const { result } = renderHook(() => useCurrentAccountDetails(), { wrapper }); + + expect(result.current).toStrictEqual(mockRootStore.client.account_list[0]); + }); +}); diff --git a/packages/hooks/src/__tests__/useNeedPOI.spec.tsx b/packages/hooks/src/__tests__/useNeedPOI.spec.tsx new file mode 100644 index 000000000000..8156f3ddf0a8 --- /dev/null +++ b/packages/hooks/src/__tests__/useNeedPOI.spec.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import { StoreProvider, mockStore } from '@deriv/stores'; +import { renderHook } from '@testing-library/react-hooks'; +import useNeedPOI from '../useNeedPOI'; + +describe('useNeedPOI', () => { + test('should be true if authentication?.needs_verification includes identity', async () => { + const mockRootStore = mockStore({ + client: { + account_status: { + authentication: { + needs_verification: ['identity'], + }, + }, + }, + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + const { result } = renderHook(() => useNeedPOI(), { wrapper }); + + expect(result.current).toBe(true); + }); + + test("should be false if authentication?.needs_verification doesn't include identity", async () => { + const mockRootStore = mockStore({ + client: { + account_status: { + authentication: { + needs_verification: [], + }, + }, + }, + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + const { result } = renderHook(() => useNeedPOI(), { wrapper }); + + expect(result.current).toBe(false); + }); +}); diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts index 438f66bed0b9..4442969638f9 100644 --- a/packages/hooks/src/index.ts +++ b/packages/hooks/src/index.ts @@ -1,10 +1,11 @@ export { default as useAccountTransferVisible } from './useAccountTransferVisible'; +export { default as useCashierLocked } from './useCashierLocked'; export { default as useCFDAccounts } from './useCFDAccounts'; export { default as useCFDAllAccounts } from './useCFDAllAccounts'; export { default as useCFDDemoAccounts } from './useCFDDemoAccounts'; export { default as useCFDRealAccounts } from './useCFDRealAccounts'; -export { default as useCashierLocked } from './useCashierLocked'; export { default as useCountdown } from './useCountdown'; +export { default as useCurrentAccountDetails } from './useCurrentAccountDetails'; export { default as useCurrencyConfig } from './useCurrencyConfig'; export { default as useCurrentCurrencyConfig } from './useCurrentCurrencyConfig'; export { default as useDepositCryptoAddress } from './useDepositCryptoAddress'; @@ -29,6 +30,7 @@ export { default as useIsRealAccountNeededForCashier } from './useIsRealAccountN export { default as useIsSystemMaintenance } from './useIsSystemMaintenance'; export { default as useNeedAuthentication } from './useNeedAuthentication'; export { default as useNeedFinancialAssessment } from './useNeedFinancialAssessment'; +export { default as useNeedPOI } from './useNeedPOI'; export { default as useNeedTNC } from './useNeedTNC'; export { default as useOnrampVisible } from './useOnrampVisible'; export { default as useP2PNotificationCount } from './useP2PNotificationCount'; diff --git a/packages/hooks/src/useCurrentAccountDetails.ts b/packages/hooks/src/useCurrentAccountDetails.ts new file mode 100644 index 000000000000..eaff8de26d2e --- /dev/null +++ b/packages/hooks/src/useCurrentAccountDetails.ts @@ -0,0 +1,10 @@ +import { useStore } from '@deriv/stores'; + +const useCurrentAccountDetails = () => { + const { client } = useStore(); + const { account_list, loginid } = client; + + return account_list.find(account => loginid === account.loginid); +}; + +export default useCurrentAccountDetails; diff --git a/packages/hooks/src/useNeedPOI.ts b/packages/hooks/src/useNeedPOI.ts new file mode 100644 index 000000000000..f55c2239654c --- /dev/null +++ b/packages/hooks/src/useNeedPOI.ts @@ -0,0 +1,10 @@ +import { useStore } from '@deriv/stores'; + +const useNeedPOI = () => { + const { client } = useStore(); + const authentication = client.account_status?.authentication; + + return authentication?.needs_verification.includes('identity'); +}; + +export default useNeedPOI; From 7b4ba8f9f19389cbd65144b1b419a07f7a574f54 Mon Sep 17 00:00:00 2001 From: shontzu <108507236+shontzu-deriv@users.noreply.github.com> Date: Fri, 21 Jul 2023 16:48:01 +0800 Subject: [PATCH 02/52] shontzu/WALL-865/Incorrect-total-asset-amount (#9217) * fix: attemp #3 * chore: remove irrelevant check * chore: unit test * chore: unit test fail * chore: fixes based on review * chore: empty commit * chore: code revie fixes * chore: revert test case changes * chore: rename type to TUseTotalAccountBalance * chore: format doc and added test case for multiple accounts in different currencies --------- Co-authored-by: Ali(Ako) Hosseini --- .../__tests__/useTotalAccountBalance.spec.tsx | 79 +++++++++++++++++++ packages/hooks/src/useTotalAccountBalance.ts | 10 ++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/packages/hooks/src/__tests__/useTotalAccountBalance.spec.tsx b/packages/hooks/src/__tests__/useTotalAccountBalance.spec.tsx index 943a2d1e1a47..1c02c5aa6262 100644 --- a/packages/hooks/src/__tests__/useTotalAccountBalance.spec.tsx +++ b/packages/hooks/src/__tests__/useTotalAccountBalance.spec.tsx @@ -15,6 +15,85 @@ describe('useTotalAccountBalance', () => { expect(result.current.balance).toBe(0); }); + test('should return total balance correctly when user has one account', () => { + const mock = mockStore({ + client: { + active_accounts: [ + { + balance: 10000, + currency: 'USD', + account_type: 'real', + }, + ], + }, + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + const { result } = renderHook(() => useTotalAccountBalance(mock.client.active_accounts), { wrapper }); + expect(result.current.balance).toBe(10000); + }); + + test('should return total balance correctly when user has multiple accounts in same currency', () => { + const mock = mockStore({ + client: { + active_accounts: [ + { + balance: 10000, + currency: 'USD', + account_type: 'demo', + }, + { + balance: 10000, + currency: 'USD', + account_type: 'demo', + }, + ], + }, + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + const { result } = renderHook(() => useTotalAccountBalance(mock.client.active_accounts), { wrapper }); + expect(result.current.balance).toBe(20000); + }); + + test('should return total balance correctly when user has multiple accounts in different currencies', () => { + const mock = mockStore({ + exchange_rates: { + data: { + rates: { + EUR: 2, + USD: 1, + }, + }, + }, + client: { + active_accounts: [ + { + balance: 10000, + currency: 'USD', + account_type: 'demo', + }, + { + balance: 10000, + currency: 'EUR', + account_type: 'demo', + }, + ], + }, + }); + + const wrapper = ({ children }: { children: JSX.Element }) => ( + {children} + ); + const { result } = renderHook(() => useTotalAccountBalance(mock.client.active_accounts), { wrapper }); + expect(result.current.balance).not.toBe(20000); + expect(result.current.balance).toBe(15000); + }); + test('should return total balance correctly when user has multiple accounts', async () => { const mock = mockStore({ exchange_rates: { diff --git a/packages/hooks/src/useTotalAccountBalance.ts b/packages/hooks/src/useTotalAccountBalance.ts index 5ab91f88ecaf..44fdc175d1c4 100644 --- a/packages/hooks/src/useTotalAccountBalance.ts +++ b/packages/hooks/src/useTotalAccountBalance.ts @@ -1,21 +1,25 @@ import useRealTotalAssetCurrency from './useTotalAssetCurrency'; import useExchangeRate from './useExchangeRate'; - /** * we can use this hook to get the total balance of the given accounts list. * it loops through the accounts list and adds the balance of each account * to the total balance, it also converts the balance to the currency of the * first account in the list */ +type TUseTotalAccountBalance = { + balance?: number; + currency?: string; + account_type?: string; +}; -const useTotalAccountBalance = (accounts: { balance?: number; currency?: string }[]) => { +const useTotalAccountBalance = (accounts: TUseTotalAccountBalance[]) => { const total_assets_real_currency = useRealTotalAssetCurrency(); const { getRate } = useExchangeRate(); if (!accounts.length) return { balance: 0, currency: total_assets_real_currency }; const balance = accounts.reduce((total, account) => { - const base_rate = getRate(total_assets_real_currency || ''); + const base_rate = account?.account_type === 'demo' ? 1 : getRate(total_assets_real_currency || ''); const rate = getRate(account.currency || total_assets_real_currency || ''); const exchange_rate = base_rate / rate; From a0d6c6f1fa9e1ca9bf09197f5354deb3e3367601 Mon Sep 17 00:00:00 2001 From: Farabi <102643568+farabi-deriv@users.noreply.github.com> Date: Fri, 21 Jul 2023 16:52:30 +0800 Subject: [PATCH 03/52] Farabi/bot 317/translation fixes for dbot homepage (#9108) * fix: translation issues * redeploy: vercel retrigger --------- Co-authored-by: Ali(Ako) Hosseini --- .../src/scratch/blocks/Math/math_modulo.js | 2 +- .../load-bot-preview/recent.tsx | 4 +-- .../components/dashboard/joyride-config.tsx | 2 -- .../data/data-fields.ts | 15 +++++------ .../dashboard/tour-trigger-dialog.tsx | 25 ++++++++----------- 5 files changed, 22 insertions(+), 26 deletions(-) diff --git a/packages/bot-skeleton/src/scratch/blocks/Math/math_modulo.js b/packages/bot-skeleton/src/scratch/blocks/Math/math_modulo.js index 004e1af2c7c6..05c0d983084d 100755 --- a/packages/bot-skeleton/src/scratch/blocks/Math/math_modulo.js +++ b/packages/bot-skeleton/src/scratch/blocks/Math/math_modulo.js @@ -34,7 +34,7 @@ Blockly.Blocks.math_modulo = { meta() { return { display_name: localize('Remainder after division'), - description: localize(' Returns the remainder after the division of the given numbers.'), + description: localize('Returns the remainder after the division of the given numbers.'), }; }, getRequiredValueInputs() { diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/recent.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/recent.tsx index 3652b6931f24..4ec5accfdb37 100644 --- a/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/recent.tsx +++ b/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/recent.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import { getSavedWorkspaces } from '@deriv/bot-skeleton'; import { MobileWrapper, Text } from '@deriv/components'; import { isMobile } from '@deriv/shared'; -import { Localize } from '@deriv/translations'; +import { Localize, localize } from '@deriv/translations'; import { connect } from 'Stores/connect'; import RootStore from 'Stores/index'; import { TWorkspace } from 'Stores/load-modal-store'; @@ -19,7 +19,7 @@ type TRecentComponent = { strategy_save_type: string; }; -const HEADERS = ['Bot name', 'Last modified', 'Status']; +const HEADERS = [localize('Bot name'), localize('Last modified'), localize('Status')]; const RecentComponent = ({ dashboard_strategies, diff --git a/packages/bot-web-ui/src/components/dashboard/joyride-config.tsx b/packages/bot-web-ui/src/components/dashboard/joyride-config.tsx index 96cad2a8f764..59c832983d2a 100644 --- a/packages/bot-web-ui/src/components/dashboard/joyride-config.tsx +++ b/packages/bot-web-ui/src/components/dashboard/joyride-config.tsx @@ -184,7 +184,6 @@ export const DBOT_ONBOARDING = [ step_index={6} /> ), - locale: { last: localize('Next') }, ...joyride_props, disableOverlay: false, }, @@ -457,7 +456,6 @@ export const BOT_BUILDER_TOUR = [ { target: '.animation__wrapper', content: , - locale: { last: localize('Next') }, ...joyride_props, }, ]; diff --git a/packages/bot-web-ui/src/components/dashboard/quick-strategy/quick-strategy-components/data/data-fields.ts b/packages/bot-web-ui/src/components/dashboard/quick-strategy/quick-strategy-components/data/data-fields.ts index 7f9ab8d5a313..3ea8562ec529 100644 --- a/packages/bot-web-ui/src/components/dashboard/quick-strategy/quick-strategy-components/data/data-fields.ts +++ b/packages/bot-web-ui/src/components/dashboard/quick-strategy/quick-strategy-components/data/data-fields.ts @@ -1,3 +1,4 @@ +import { localize } from '@deriv/translations'; import { TDropdownItems, TInputBaseFields, TInputsFieldNames, TSelectsFieldNames } from '../../quick-strategy.types'; import { common_inputs_properties } from '..'; import { TCommonInputsProperties } from './common-input-properties'; @@ -30,28 +31,28 @@ const data_fields: ReadonlyArray = [ field_name: 'quick-strategy__symbol', className: 'quick-strategy__dropdown quick-strategy__leading', select_value: 'symbol', - label: 'Asset', + label: localize('Asset'), }, { id: 'trade-type', field_name: 'quick-strategy__trade-type', className: 'quick-strategy__dropdown quick-strategy__leading', select_value: 'trade-type', - label: 'Trade type', + label: localize('Trade type'), }, { id: 'duration-unit', field_name: 'quick-strategy__duration-unit', className: '', select_value: 'duration-unit', - label: 'Duration unit', + label: localize('Duration unit'), is_able_disabled: true, }, { id: 'duration-value', field_name: 'quick-strategy__duration-value', input_value: 'input_duration_value', - label: 'Duration value', + label: localize('Duration value'), placeholder: '5', trailing_icon_message: 'The trade length of your purchased contract.', ...common_inputs_properties, @@ -60,7 +61,7 @@ const data_fields: ReadonlyArray = [ id: 'stake', field_name: 'quick-strategy__stake', input_value: 'input_stake', - label: 'Initial stake', + label: localize('Initial stake'), placeholder: '10', trailing_icon_message: 'The amount that you pay to enter a trade.', ...common_inputs_properties, @@ -69,7 +70,7 @@ const data_fields: ReadonlyArray = [ id: 'loss', field_name: 'quick-strategy__loss', input_value: 'input_loss', - label: 'Loss threshold', + label: localize('Loss threshold'), placeholder: '5000', trailing_icon_message: getMessage('loss'), ...common_inputs_properties, @@ -84,7 +85,7 @@ const data_fields: ReadonlyArray = [ id: 'profit', field_name: 'quick-strategy__profit', input_value: 'input_profit', - label: 'Profit threshold', + label: localize('Profit threshold'), placeholder: '5000', trailing_icon_message: getMessage('profit'), ...common_inputs_properties, diff --git a/packages/bot-web-ui/src/components/dashboard/tour-trigger-dialog.tsx b/packages/bot-web-ui/src/components/dashboard/tour-trigger-dialog.tsx index e7959c304a5a..fa11c0c6ab24 100644 --- a/packages/bot-web-ui/src/components/dashboard/tour-trigger-dialog.tsx +++ b/packages/bot-web-ui/src/components/dashboard/tour-trigger-dialog.tsx @@ -61,13 +61,21 @@ const TourTriggrerDialog = ({ const getTourHeaders = (tour_check: boolean, tab_id: number) => { let text; if (!tour_check) { - if (tab_id === 1) text = localize(is_mobile ? 'Bot Builder guide' : "Let's build a Bot!"); + if (tab_id === 1) text = is_mobile ? localize('Bot Builder guide') : localize("Let's build a Bot!"); else text = localize('Get started on Deriv Bot'); } else if (tab_id === 1) text = localize('Congratulations'); else text = localize('Want to retake the tour?'); return text; }; + const tourDialogInfo = is_mobile + ? 'Here’s a quick guide on how to use Deriv Bot on the go.' + : 'Learn how to build your bot from scratch using a simple strategy.'; + + const tourDialogAction = is_mobile + ? 'You can import a bot from your mobile device or from Google drive, see a preview in the bot builder, and start trading by running the bot.' + : 'Hit the <0>Start button to begin and follow the tutorial.'; + const getTourContent = (type: string) => { return ( <> @@ -78,23 +86,12 @@ const TourTriggrerDialog = ({ (!has_tour_ended ? ( <>
- +
Start button to begin and follow the tutorial.' - } + i18n_default_text={tourDialogAction} components={[]} />
From 3c1faa9271ac340ab6c3a1219d105af26ac86780 Mon Sep 17 00:00:00 2001 From: Shahzaib Date: Fri, 21 Jul 2023 16:57:52 +0800 Subject: [PATCH 04/52] shahzaib / KYC-270 / fix POI flow after IDV failure and retries (#9222) * chore: fix POI flow after IDV failure and retries * chore: fix onfido infinite trigger for nigeria clients * chore: fix onfido trigger if submission left is zero or less * style: fix manual upload card content alignment * chore: rename prop to default_enabled * fix: nimc slip document step check * chore: add comment to define the use of added prop --- .../status/unsupported/detail-component.tsx | 2 ++ .../poi/status/unsupported/documents.tsx | 25 +++++++++++-------- .../poi/status/unsupported/unsupported.scss | 3 +++ .../poi/status/unsupported/unsupported.tsx | 14 ++++++++++- .../onfido-sdk-view-container.tsx | 10 ++++++++ .../Verification/ProofOfIdentity/onfido.jsx | 5 ++++ .../proof-of-identity-container.jsx | 12 +++++++++ .../proof-of-identity-submission-for-mt5.jsx | 11 ++++++-- .../proof-of-identity-submission.jsx | 2 ++ 9 files changed, 70 insertions(+), 14 deletions(-) diff --git a/packages/account/src/Components/poi/status/unsupported/detail-component.tsx b/packages/account/src/Components/poi/status/unsupported/detail-component.tsx index d62531d487d2..15d02741ddb9 100644 --- a/packages/account/src/Components/poi/status/unsupported/detail-component.tsx +++ b/packages/account/src/Components/poi/status/unsupported/detail-component.tsx @@ -159,6 +159,8 @@ const DetailComponent = ({ documents_supported={[document.onfido_name]} height={height ?? null} handleComplete={is_mt5 ? handlePOIforMT5Complete : handleComplete} + is_default_enabled + handleViewComplete={is_mt5 ? handlePOIforMT5Complete : handleComplete} {...props} /> diff --git a/packages/account/src/Components/poi/status/unsupported/documents.tsx b/packages/account/src/Components/poi/status/unsupported/documents.tsx index 80c1510810e6..df6d8628477d 100644 --- a/packages/account/src/Components/poi/status/unsupported/documents.tsx +++ b/packages/account/src/Components/poi/status/unsupported/documents.tsx @@ -8,14 +8,17 @@ type TDocument = { documents: object[]; }; -export const Documents = ({ toggleDetail, documents }: TDocument) => - documents.map((item: FormikValues, index: number) => ( - toggleDetail(index)} {...item.card} />} - /> - )); +export const Documents = ({ toggleDetail, documents }: TDocument) => ( + + {documents.map((item: FormikValues, index: number) => ( + toggleDetail(index)} {...item.card} />} + /> + ))} + +); diff --git a/packages/account/src/Components/poi/status/unsupported/unsupported.scss b/packages/account/src/Components/poi/status/unsupported/unsupported.scss index 22ce91ade4c4..bbe7b2add6db 100644 --- a/packages/account/src/Components/poi/status/unsupported/unsupported.scss +++ b/packages/account/src/Components/poi/status/unsupported/unsupported.scss @@ -21,6 +21,9 @@ margin: -4px 0 2.4rem; } } + .dc-card__wrapper { + justify-content: center; + } .dc-card__wrapper:last-of-type { margin-bottom: 4rem !important; } diff --git a/packages/account/src/Components/poi/status/unsupported/unsupported.tsx b/packages/account/src/Components/poi/status/unsupported/unsupported.tsx index ea0863d9230a..91dae3b9ed92 100644 --- a/packages/account/src/Components/poi/status/unsupported/unsupported.tsx +++ b/packages/account/src/Components/poi/status/unsupported/unsupported.tsx @@ -32,7 +32,11 @@ type TUnsupported = { redirect_button: React.ReactElement; needs_poa: boolean; handleRequireSubmission: () => void; + handleViewComplete: () => void; allow_poi_resubmission: boolean; + onfido: { + submissions_left: number; + }; }; const Unsupported = ({ @@ -43,6 +47,8 @@ const Unsupported = ({ needs_poa, handleRequireSubmission, allow_poi_resubmission, + handleViewComplete, + onfido, ...props }: Partial) => { const [detail, setDetail] = React.useState(null); @@ -65,14 +71,20 @@ const Unsupported = ({ } if (detail !== null) { + const is_onfido_supported = + country_code === 'ng' && + !checkNimcStep(documents[detail ?? 0].details.documents) && + onfido && + onfido.submissions_left > 0; return ( setDetail(null)} handlePOIforMT5Complete={handlePOIforMT5Complete} + handleComplete={handleViewComplete} {...props} /> ); diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/onfido-sdk-view-container.tsx b/packages/account/src/Sections/Verification/ProofOfIdentity/onfido-sdk-view-container.tsx index 8cd8a3d03f06..4efe217507a3 100644 --- a/packages/account/src/Sections/Verification/ProofOfIdentity/onfido-sdk-view-container.tsx +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/onfido-sdk-view-container.tsx @@ -33,6 +33,7 @@ type TOnfidoSdkViewContainer = { getChangeableFields: () => string[]; handleViewComplete: () => void; height?: number | string; + is_default_enabled?: boolean; }; const OnfidoSdkViewContainer = ({ @@ -42,6 +43,7 @@ const OnfidoSdkViewContainer = ({ getChangeableFields, handleViewComplete, height, + is_default_enabled, }: TOnfidoSdkViewContainer) => { const [api_error, setAPIError] = React.useState(); const [missing_personal_details, setMissingPersonalDetails] = React.useState(''); @@ -68,6 +70,14 @@ const OnfidoSdkViewContainer = ({ const onfido_init = React.useRef(); + // pass is_default_enabled to enable onfido immediately if personal detail component is not required + // so no user prompt will be there so submit the details in i.e. in case of flow for nigerian clients ATM + React.useEffect(() => { + if (is_default_enabled) { + setIsOnfidoDisabled(false); + } + }, [is_default_enabled]); + const onComplete = React.useCallback( (data: Omit & { data?: { id?: string } }) => { onfido_init?.current?.tearDown(); diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/onfido.jsx b/packages/account/src/Sections/Verification/ProofOfIdentity/onfido.jsx index 5c359e0cdefc..95a1477d72c7 100644 --- a/packages/account/src/Sections/Verification/ProofOfIdentity/onfido.jsx +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/onfido.jsx @@ -14,6 +14,8 @@ const Onfido = ({ redirect_button, manual, setIsCfdPoiCompleted, + country_code, + handleViewComplete, }) => { const { status, submissions_left, last_rejected: rejected_reasons } = onfido; @@ -34,6 +36,9 @@ const Onfido = ({ manual={manual} is_from_external={is_from_external} setIsCfdPoiCompleted={setIsCfdPoiCompleted} + country_code={country_code} + handleViewComplete={handleViewComplete} + onfido={onfido} /> ); } diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-container.jsx b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-container.jsx index c3029ced831d..a77b3ea5d4d9 100644 --- a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-container.jsx +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-container.jsx @@ -48,6 +48,13 @@ const ProofOfIdentityContainer = ({ const routeBackTo = redirect_route => routeBackInApp(history, [redirect_route]); const handleRequireSubmission = () => setHasRequireSubmission(true); + const country_code = account_settings?.citizen || account_settings?.country_code; + + const handleManualSubmit = () => { + WS.authorized.getAccountStatus().then(() => { + refreshNotifications(); + }); + }; React.useEffect(() => { // only re-mount logic when switching is done @@ -206,17 +213,22 @@ const ProofOfIdentityContainer = ({ manual={manual} setIsCfdPoiCompleted={setIsCfdPoiCompleted} redirect_button={redirect_button} + country_code={country_code} + handleViewComplete={handleManualSubmit} /> ); case service_code.manual: return ( ); default: diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission-for-mt5.jsx b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission-for-mt5.jsx index 5b1a7e58ade6..821e6b2094e3 100644 --- a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission-for-mt5.jsx +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission-for-mt5.jsx @@ -35,7 +35,7 @@ const POISubmissionForMT5 = ({ jurisdiction_selected_shortcode !== Jurisdiction.VANUATU ) { setSubmissionService(service_code.idv); - } else if (onfido_submissions_left && is_onfido_supported) { + } else if (onfido_submissions_left > 0 && is_onfido_supported) { setSubmissionService(service_code.onfido); } else { setSubmissionService(service_code.manual); @@ -131,7 +131,14 @@ const POISubmissionForMT5 = ({ ); } case service_code.manual: - return ; + return ( + + ); default: return null; } diff --git a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission.jsx b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission.jsx index 47cbba9ea1c1..81e2c69d245f 100644 --- a/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission.jsx +++ b/packages/account/src/Sections/Verification/ProofOfIdentity/proof-of-identity-submission.jsx @@ -159,6 +159,8 @@ const POISubmission = ({ is_from_external={is_from_external} setIsCfdPoiCompleted={setIsCfdPoiCompleted} allow_poi_resubmission={allow_poi_resubmission} + handleViewComplete={handleViewComplete} + onfido={onfido} /> ); default: From fa5353770ac9aaa21460bf98fd5514830883d21f Mon Sep 17 00:00:00 2001 From: Maryia <103177211+maryia-deriv@users.noreply.github.com> Date: Fri, 21 Jul 2023 12:00:48 +0300 Subject: [PATCH 05/52] maryia/DTRA-297/fix: Crypto profit text & Hide barriers in case of trade params errors (#9347) * chore: remove animation correction * feat: clear barriers upon errors * fix: profit text & hide it for crypto with more than 2 decimals * test: AccumulatorsProfitLossText * Revert "chore: remove animation correction" This reverts commit f9bb5ecbef7e0a8ad6fa56734fcf6d2b3de8b8b6. * fix: not hide barriers for ongoing contract in case of trade params error --------- Co-authored-by: Ali(Ako) Hosseini --- packages/core/src/Stores/contract-trade-store.js | 2 +- .../__tests__/accumulators-profit-loss-text.spec.js | 4 ++-- .../Markers/accumulators-profit-loss-text.jsx | 10 ++++++---- .../Markers/accumulators-profit-loss-tooltip.jsx | 11 ++++------- .../trader/src/Modules/Trading/Containers/trade.jsx | 12 ++++++++---- .../trader/src/Stores/Modules/Trading/trade-store.js | 2 ++ 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/packages/core/src/Stores/contract-trade-store.js b/packages/core/src/Stores/contract-trade-store.js index a01da87f82b4..81b6ffe8512f 100644 --- a/packages/core/src/Stores/contract-trade-store.js +++ b/packages/core/src/Stores/contract-trade-store.js @@ -103,7 +103,7 @@ export default class ContractTradeStore extends BaseStore { clearAccumulatorBarriersData(should_clear_contract_data_only, should_clear_timeout = true) { if (this.accu_barriers_timeout_id && should_clear_timeout) clearTimeout(this.accu_barriers_timeout_id); - this.accumulator_contract_barriers_data = {}; + if (!isAccumulatorContractOpen(this.last_contract.contract_info)) this.accumulator_contract_barriers_data = {}; if (!should_clear_contract_data_only) { this.accumulator_barriers_data = {}; } diff --git a/packages/trader/src/Modules/SmartChart/Components/Markers/__tests__/accumulators-profit-loss-text.spec.js b/packages/trader/src/Modules/SmartChart/Components/Markers/__tests__/accumulators-profit-loss-text.spec.js index 1c4f33daa1a5..e574c88367a8 100644 --- a/packages/trader/src/Modules/SmartChart/Components/Markers/__tests__/accumulators-profit-loss-text.spec.js +++ b/packages/trader/src/Modules/SmartChart/Components/Markers/__tests__/accumulators-profit-loss-text.spec.js @@ -10,7 +10,7 @@ jest.mock('Modules/SmartChart', () => ({ describe('AccumulatorsProfitLossText', () => { const props = { className: 'profit-loss-text', - currency: 'USD test', + currency: 'USD', profit: +0.35, }; @@ -19,6 +19,6 @@ describe('AccumulatorsProfitLossText', () => { const text_el = screen.getByTestId('dt_accumulator_profit_text'); expect(text_el).toHaveClass('profit-loss-text__profit'); expect(screen.getByText('3')).toHaveClass('profit-loss-text__sliding-tenth'); - expect(screen.getByText('USD test')).toHaveClass('profit-loss-text__currency'); + expect(screen.getByText('USD')).toHaveClass('profit-loss-text__currency'); }); }); diff --git a/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-text.jsx b/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-text.jsx index 08f848afb58c..4a2ad85431f1 100644 --- a/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-text.jsx +++ b/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-text.jsx @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import { Text } from '@deriv/components'; +import { formatMoney, getCurrencyDisplayCode } from '@deriv/shared'; import { FastMarker } from 'Modules/SmartChart'; import classNames from 'classnames'; @@ -19,14 +20,15 @@ const AccumulatorsProfitLossText = ({ }) => { const [is_fading_in, setIsFadingIn] = React.useState(false); const [is_sliding, setIsSliding] = React.useState(false); - const prev_profit = React.useRef(profit); - const prev_profit_tenth = +prev_profit.current?.toFixed(2).split('.')[1][0]; + const formatted_profit = formatMoney(currency, profit, true, 0, 0); + const prev_profit = React.useRef(formatted_profit); + const prev_profit_tenth = +prev_profit.current?.split('.')[1][0]; const [current_profit_tenth, setCurrentProfitTenth] = React.useState(prev_profit_tenth); const profit_tenth_ref = React.useRef(); const interval_id_ref = React.useRef(null); const fading_in_timeout_id = React.useRef(); const sliding_timeout_id = React.useRef(); - const profit_portions_array = profit.toFixed(2).split('.'); + const profit_portions_array = formatted_profit.split('.'); const profit_whole_number = +profit_portions_array[0]; const profit_tenth = +profit_portions_array[1][0]; const profit_hundredths = +profit_portions_array[1].slice(1); @@ -113,7 +115,7 @@ const AccumulatorsProfitLossText = ({ {`${profit_hundredths}`} - {currency} + {getCurrencyDisplayCode(currency)} ); diff --git a/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-tooltip.jsx b/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-tooltip.jsx index a42523530e11..afac1504921d 100644 --- a/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-tooltip.jsx +++ b/packages/trader/src/Modules/SmartChart/Components/Markers/accumulators-profit-loss-tooltip.jsx @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import classNames from 'classnames'; import { CSSTransition } from 'react-transition-group'; -import { Text } from '@deriv/components'; +import { Money, Text } from '@deriv/components'; import { localize } from '@deriv/translations'; import { FastMarker } from 'Modules/SmartChart'; import AccumulatorsProfitLossText from './accumulators-profit-loss-text'; @@ -22,7 +22,6 @@ const AccumulatorsProfitLossTooltip = ({ }) => { const [is_tooltip_open, setIsTooltipOpen] = React.useState(false); const won = profit >= 0; - const sign = profit > 0 ? '+' : ''; const tooltip_timeout = React.useRef(null); React.useEffect(() => { @@ -100,11 +99,9 @@ const AccumulatorsProfitLossTooltip = ({ {localize('Total profit/loss:')} - {`${sign}${profit} ${currency}`} + + +
diff --git a/packages/trader/src/Modules/Trading/Containers/trade.jsx b/packages/trader/src/Modules/Trading/Containers/trade.jsx index d75f69679883..5a18ce1abc37 100644 --- a/packages/trader/src/Modules/Trading/Containers/trade.jsx +++ b/packages/trader/src/Modules/Trading/Containers/trade.jsx @@ -1,7 +1,7 @@ import React from 'react'; import classNames from 'classnames'; import { DesktopWrapper, Div100vhContainer, MobileWrapper, SwipeableWrapper } from '@deriv/components'; -import { isDesktop, isMobile } from '@deriv/shared'; +import { getDecimalPlaces, isDesktop, isMobile } from '@deriv/shared'; import ChartLoader from 'App/Components/Elements/chart-loader.jsx'; import PositionsDrawer from 'App/Components/Elements/PositionsDrawer'; import MarketIsClosedOverlay from 'App/Components/Elements/market-is-closed-overlay.jsx'; @@ -267,6 +267,7 @@ const ChartTrade = observer(props => { const { client, ui, common, contract_trade, portfolio } = useStore(); const { accumulator_barriers_data, + accumulator_contract_barriers_data, chart_type, granularity, has_crossed_accu_barriers, @@ -276,7 +277,7 @@ const ChartTrade = observer(props => { const { all_positions } = portfolio; const { is_chart_layout_default, is_chart_countdown_visible, is_dark_mode_on } = ui; const { is_socket_opened, current_language } = common; - const { should_show_eu_content } = client; + const { currency, should_show_eu_content } = client; const { chartStateChange, is_trade_enabled, @@ -305,7 +306,7 @@ const ChartTrade = observer(props => { theme: is_dark_mode_on ? 'dark' : 'light', }; - const { accumulators_high_barrier, current_spot, current_spot_time } = accumulator_barriers_data || {}; + const { current_spot, current_spot_time } = accumulator_barriers_data || {}; const bottomWidgets = React.useCallback( ({ digits, tick }) => ( @@ -396,7 +397,10 @@ const ChartTrade = observer(props => { current_spot={current_spot} current_spot_time={current_spot_time} has_crossed_accu_barriers={has_crossed_accu_barriers} - should_show_profit_text={!!accumulators_high_barrier} + should_show_profit_text={ + !!accumulator_contract_barriers_data.accumulators_high_barrier && + getDecimalPlaces(currency) <= 2 + } symbol={symbol} /> )} diff --git a/packages/trader/src/Stores/Modules/Trading/trade-store.js b/packages/trader/src/Stores/Modules/Trading/trade-store.js index dcf2b73dd2b0..a402a1662617 100644 --- a/packages/trader/src/Stores/Modules/Trading/trade-store.js +++ b/packages/trader/src/Stores/Modules/Trading/trade-store.js @@ -1082,6 +1082,7 @@ export default class TradeStore extends BaseStore { this.proposal_info = {}; this.purchase_info = {}; this.forgetAllProposal(); + if (this.is_accumulator) this.resetAccumulatorData(); return; } @@ -1204,6 +1205,7 @@ export default class TradeStore extends BaseStore { this.commission = commission_match[1]; } } + if (this.is_accumulator) this.resetAccumulatorData(); // Sometimes the initial barrier doesn't match with current barrier choices received from API. // When this happens we want to populate the list of barrier choices to choose from since the value cannot be specified manually From 0ee0f439725c88ae1a2b9f17a335a4f1fed4f032 Mon Sep 17 00:00:00 2001 From: kate-deriv <121025168+kate-deriv@users.noreply.github.com> Date: Fri, 21 Jul 2023 12:03:34 +0300 Subject: [PATCH 06/52] Kate / DTRA-175 / Enable 'Only ups/downs' in reports and contract details page (#8883) * refactor: move trade type from un to supported * feat: ad contract type check func and add to contract details * feat: add chart markers settings for contract type * chore: add style for mobile * chore: remove gradient * chore: empty commit * chore: add gradient for contract details card for desktop * feat: add chart markers setings and update style * refactor: apply suggestions * chore: empty commit --------- Co-authored-by: Ali(Ako) Hosseini --- .../contract-card-header.tsx | 12 +++++-- .../contract-type-cell.tsx | 9 +++-- .../contract-card/contract-card.scss | 10 ++++++ .../positions-drawer-card.tsx | 4 +-- .../stories/contract-card/statics/contract.js | 16 ++++----- packages/core/src/Constants/contract.js | 16 ++++----- .../Stores/Helpers/chart-marker-helpers.js | 4 ++- .../core/src/Stores/Helpers/chart-markers.js | 20 +++++++++-- .../src/sass/app/modules/smart-chart.scss | 3 +- .../shared/src/utils/constants/contract.tsx | 16 ++++----- .../shared/src/utils/contract/contract.ts | 10 +++--- .../Elements/ContractAudit/contract-audit.jsx | 2 ++ .../ContractAudit/contract-details.jsx | 35 ++++++++++--------- .../ContractDrawer/contract-drawer-card.jsx | 4 +-- .../ContractDrawer/contract-drawer.jsx | 8 +++-- .../PositionsDrawer/positions-modal-card.jsx | 4 +-- packages/trader/src/Constants/contract.js | 16 ++++----- .../Contract/Containers/contract-replay.jsx | 3 ++ .../src/sass/app/modules/smart-chart.scss | 3 +- 19 files changed, 126 insertions(+), 69 deletions(-) diff --git a/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx b/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx index fcea1f82e34a..80295e90933f 100644 --- a/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx +++ b/packages/components/src/components/contract-card/contract-card-items/contract-card-header.tsx @@ -7,6 +7,7 @@ import { getGrowthRatePercentage, isBot, isAccumulatorContract, + isOnlyUpsDownsContract, isMobile, } from '@deriv/shared'; import ContractTypeCell from './contract-type-cell'; @@ -62,7 +63,8 @@ const ContractCardHeader = ({ } = contract_info; const { is_pathname_bot } = isBot(); const is_sold = !!contract_info.is_sold || is_contract_sold; - const is_accumulator = isAccumulatorContract(contract_type || ''); + const is_accumulator = isAccumulatorContract(contract_type); + const is_only_ups_downs = isOnlyUpsDownsContract(contract_type); const is_mobile = isMobile(); const contract_type_list_info = [ { @@ -99,7 +101,13 @@ const ContractCardHeader = ({ width={is_accumulator ? 46 : 40} size={32} /> - + {display_name || contract_info.display_name} diff --git a/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.tsx b/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.tsx index e38dd8c8a00e..e87f1b6868d2 100644 --- a/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.tsx +++ b/packages/components/src/components/contract-card/contract-card-items/contract-type-cell.tsx @@ -1,7 +1,8 @@ import React from 'react'; +import classNames from 'classnames'; import { TGetContractTypeDisplay } from '../../types'; import IconTradeTypes from '../../icon-trade-types'; -import { isVanillaContract } from '@deriv/shared'; +import { isVanillaContract, isOnlyUpsDownsContract } from '@deriv/shared'; export type TContractTypeCellProps = { getContractTypeDisplay: TGetContractTypeDisplay; @@ -25,7 +26,11 @@ const ContractTypeCell = ({ size={24} /> -
+
{getContractTypeDisplay(type, is_high_low) || ''}
{displayed_trade_param && (
{displayed_trade_param}
diff --git a/packages/components/src/components/contract-card/contract-card.scss b/packages/components/src/components/contract-card/contract-card.scss index e4f823fa739b..cd0835ccdeca 100644 --- a/packages/components/src/components/contract-card/contract-card.scss +++ b/packages/components/src/components/contract-card/contract-card.scss @@ -228,6 +228,12 @@ } &__symbol { margin-left: 0.4rem; + &--ups-downs { + width: 7rem; + @include mobile { + width: initial; + } + } } &__header { display: flex; @@ -570,6 +576,10 @@ line-height: 1.5; text-align: left; + &--ups-downs { + width: 7rem; + } + &-trade-param { font-size: 1rem; line-height: 1rem; diff --git a/packages/components/src/components/positions-drawer-card/positions-drawer-card.tsx b/packages/components/src/components/positions-drawer-card/positions-drawer-card.tsx index 0a5d122c999c..c68fd8834018 100644 --- a/packages/components/src/components/positions-drawer-card/positions-drawer-card.tsx +++ b/packages/components/src/components/positions-drawer-card/positions-drawer-card.tsx @@ -93,8 +93,8 @@ const PositionsDrawerCard = ({ const has_ended = !!getEndTime(contract_info); const is_mobile = isMobile(); const contract_card_classname = classNames('dc-contract-card', { - 'dc-contract-card--green': !is_accumulator && !is_multiplier && profit_loss > 0 && !result, - 'dc-contract-card--red': !is_accumulator && !is_multiplier && profit_loss < 0 && !result, + 'dc-contract-card--green': profit_loss > 0 && !result, + 'dc-contract-card--red': profit_loss < 0 && !result, }); const loader_el = ( diff --git a/packages/components/stories/contract-card/statics/contract.js b/packages/components/stories/contract-card/statics/contract.js index f30a52cf9415..cdd2501ea056 100644 --- a/packages/components/stories/contract-card/statics/contract.js +++ b/packages/components/stories/contract-card/statics/contract.js @@ -171,14 +171,6 @@ export const getUnsupportedContracts = () => ({ name: 'Spread Down', position: 'bottom', }, - RUNHIGH: { - name: 'Only Ups', - position: 'top', - }, - RUNLOW: { - name: 'Only Downs', - position: 'bottom', - }, }); export const getSupportedContracts = is_high_low => ({ @@ -243,6 +235,14 @@ export const getSupportedContracts = is_high_low => ({ name: 'Down', position: 'bottom', }, + RUNHIGH: { + name: 'Only Ups', + position: 'top', + }, + RUNLOW: { + name: 'Only Downs', + position: 'bottom', + }, }); export const getContractConfig = is_high_low => ({ diff --git a/packages/core/src/Constants/contract.js b/packages/core/src/Constants/contract.js index 578efc82df9e..f5873f7c3a9d 100644 --- a/packages/core/src/Constants/contract.js +++ b/packages/core/src/Constants/contract.js @@ -158,14 +158,6 @@ export const getUnsupportedContracts = () => ({ name: localize('Put Spread'), position: 'bottom', }, - RUNHIGH: { - name: localize('Only Ups'), - position: 'top', - }, - RUNLOW: { - name: localize('Only Downs'), - position: 'bottom', - }, }); export const getSupportedContracts = is_high_low => ({ @@ -222,6 +214,14 @@ export const getSupportedContracts = is_high_low => ({ name: localize('No Touch'), position: 'bottom', }, + RUNHIGH: { + name: localize('Only Ups'), + position: 'top', + }, + RUNLOW: { + name: localize('Only Downs'), + position: 'bottom', + }, }); export const getContractConfig = is_high_low => ({ diff --git a/packages/core/src/Stores/Helpers/chart-marker-helpers.js b/packages/core/src/Stores/Helpers/chart-marker-helpers.js index 86f17feeb097..3b3ce5483645 100644 --- a/packages/core/src/Stores/Helpers/chart-marker-helpers.js +++ b/packages/core/src/Stores/Helpers/chart-marker-helpers.js @@ -3,6 +3,7 @@ import { formatMoney, getEndTime, isAccumulatorContract, + isOnlyUpsDownsContract, isDesktop, isDigitContract, isMobile, @@ -24,7 +25,8 @@ const createMarkerConfig = (marker_type, x, y, content_config) => export const getSpotCount = (contract_info, spot_count) => { if (isDigitContract(contract_info.contract_type)) return spot_count + 1; - if (isAccumulatorContract(contract_info.contract_type)) return null; + if (isAccumulatorContract(contract_info.contract_type) || isOnlyUpsDownsContract(contract_info.contract_type)) + return null; return spot_count; }; diff --git a/packages/core/src/Stores/Helpers/chart-markers.js b/packages/core/src/Stores/Helpers/chart-markers.js index 128d2799271d..5f42bfaa3f5e 100644 --- a/packages/core/src/Stores/Helpers/chart-markers.js +++ b/packages/core/src/Stores/Helpers/chart-markers.js @@ -7,7 +7,14 @@ import { createMarkerSpotMiddle, getSpotCount, } from './chart-marker-helpers'; -import { getEndTime, isAccumulatorContract, isAccumulatorContractOpen, isOpen, unique } from '@deriv/shared'; +import { + getEndTime, + isAccumulatorContract, + isAccumulatorContractOpen, + isOnlyUpsDownsContract, + isOpen, + unique, +} from '@deriv/shared'; import { MARKER_TYPES_CONFIG } from '../Constants/markers'; import { getChartType } from './logic'; @@ -67,6 +74,7 @@ const addLabelAlignment = (tick, idx, arr) => { export const createTickMarkers = (contract_info, is_delayed_markers_update) => { const is_accumulator = isAccumulatorContract(contract_info.contract_type); + const is_only_ups_downs = isOnlyUpsDownsContract(contract_info.contract_type); const is_accu_contract_closed = is_accumulator && !isOpen(contract_info); const available_ticks = (is_accumulator && contract_info.audit_details?.all_ticks) || contract_info.tick_stream; const tick_stream = unique(available_ticks, 'epoch').map(addLabelAlignment); @@ -93,8 +101,9 @@ export const createTickMarkers = (contract_info, is_delayed_markers_update) => { +_tick.epoch === +contract_info.exit_tick_time || getSpotCount(contract_info, _idx) === contract_info.tick_count; const is_exit_spot = isExitSpot(tick, idx); + const is_current_last_spot = idx === tick_stream.length - 1; const exit_spot_index = tick_stream.findIndex(isExitSpot); - const is_accu_current_last_spot = is_accumulator && !is_exit_spot && idx === tick_stream.length - 1; + const is_accu_current_last_spot = is_accumulator && !is_exit_spot && is_current_last_spot; const is_accu_preexit_spot = is_accumulator && (is_accu_contract_closed ? idx === exit_spot_index - 1 : idx === tick_stream.length - 2); @@ -107,6 +116,13 @@ export const createTickMarkers = (contract_info, is_delayed_markers_update) => { tick.align_label = 'top'; // force exit spot label to be 'top' to avoid overlapping marker_config = createMarkerSpotExit(contract_info, tick, idx); } + if (is_only_ups_downs && is_middle_spot) { + const spot_className = marker_config.content_config.spot_className; + marker_config.content_config.spot_className = `${spot_className} ${spot_className}--only-ups-downs-middle`; + if (!is_current_last_spot) { + marker_config.content_config.is_value_hidden = true; + } + } if (is_accumulator) { if ((is_accu_current_last_spot || is_exit_spot) && !is_accu_contract_closed) return; if (marker_config && (is_middle_spot || is_exit_spot)) { diff --git a/packages/reports/src/sass/app/modules/smart-chart.scss b/packages/reports/src/sass/app/modules/smart-chart.scss index f31c236932e1..fcc182c30979 100644 --- a/packages/reports/src/sass/app/modules/smart-chart.scss +++ b/packages/reports/src/sass/app/modules/smart-chart.scss @@ -56,7 +56,8 @@ width: 16px; height: 16px; } - &--accumulator { + &--accumulator, + &--only-ups-downs { &-middle, &-middle--preexit { width: 6px; diff --git a/packages/shared/src/utils/constants/contract.tsx b/packages/shared/src/utils/constants/contract.tsx index f8bd4a8b309b..1ad120d30033 100644 --- a/packages/shared/src/utils/constants/contract.tsx +++ b/packages/shared/src/utils/constants/contract.tsx @@ -379,14 +379,6 @@ export const getUnsupportedContracts = () => ({ name: localize('Spread Down'), position: 'bottom', }, - RUNHIGH: { - name: localize('Only Ups'), - position: 'top', - }, - RUNLOW: { - name: localize('Only Downs'), - position: 'bottom', - }, }); export const getSupportedContracts = (is_high_low?: boolean) => ({ @@ -459,6 +451,14 @@ export const getSupportedContracts = (is_high_low?: boolean) => ({ name: , position: 'bottom', }, + RUNHIGH: { + name: localize('Only Ups'), + position: 'top', + }, + RUNLOW: { + name: localize('Only Downs'), + position: 'bottom', + }, }); export const getContractConfig = (is_high_low?: boolean) => ({ diff --git a/packages/shared/src/utils/contract/contract.ts b/packages/shared/src/utils/contract/contract.ts index 9d4298f7b778..9617f4b02466 100644 --- a/packages/shared/src/utils/contract/contract.ts +++ b/packages/shared/src/utils/contract/contract.ts @@ -57,11 +57,13 @@ export const isAccumulatorContractOpen = (contract_info: TContractInfo = {}) => return isAccumulatorContract(contract_info.contract_type) && getContractStatus(contract_info) === 'open'; }; -export const isMultiplierContract = (contract_type: string) => /MULT/i.test(contract_type); +export const isMultiplierContract = (contract_type = '') => /MULT/i.test(contract_type); -export const isVanillaContract = (contract_type: string) => /VANILLA/i.test(contract_type); +export const isVanillaContract = (contract_type = '') => /VANILLA/i.test(contract_type); -export const isCryptoContract = (underlying: string) => /^cry/.test(underlying); +export const isOnlyUpsDownsContract = (contract_type = '') => /RUN/i.test(contract_type); + +export const isCryptoContract = (underlying = '') => underlying.startsWith('cry'); export const getAccuBarriersDefaultTimeout = (symbol: string) => { return symbols_2s.includes(symbol) ? DELAY_TIME_1S_SYMBOL * 2 : DELAY_TIME_1S_SYMBOL; @@ -192,6 +194,6 @@ export const getContractUpdateConfig = ({ contract_update, limit_order }: TContr }; }; -export const shouldShowExpiration = (symbol: string) => /^cry/.test(symbol); +export const shouldShowExpiration = (symbol = '') => symbol.startsWith('cry'); export const shouldShowCancellation = (symbol = '') => !/^(cry|CRASH|BOOM|stpRNG|WLD|JD)/.test(symbol); diff --git a/packages/trader/src/App/Components/Elements/ContractAudit/contract-audit.jsx b/packages/trader/src/App/Components/Elements/ContractAudit/contract-audit.jsx index 8d0698f60150..42c4dd8538d8 100644 --- a/packages/trader/src/App/Components/Elements/ContractAudit/contract-audit.jsx +++ b/packages/trader/src/App/Components/Elements/ContractAudit/contract-audit.jsx @@ -11,6 +11,7 @@ const ContractAudit = ({ has_result, is_accumulator, is_multiplier, + is_only_ups_downs, toggleHistoryTab, ...props }) => { @@ -62,6 +63,7 @@ ContractAudit.propTypes = { has_result: PropTypes.bool, is_accumulator: PropTypes.bool, is_multiplier: PropTypes.bool, + is_only_ups_downs: PropTypes.bool, toggleHistoryTab: PropTypes.func, }; diff --git a/packages/trader/src/App/Components/Elements/ContractAudit/contract-details.jsx b/packages/trader/src/App/Components/Elements/ContractAudit/contract-details.jsx index d13461c7c3e4..23a98fb901b7 100644 --- a/packages/trader/src/App/Components/Elements/ContractAudit/contract-details.jsx +++ b/packages/trader/src/App/Components/Elements/ContractAudit/contract-details.jsx @@ -4,15 +4,16 @@ import { Money, Icon, ThemedScrollbars } from '@deriv/components'; import { localize } from '@deriv/translations'; import { epochToMoment, - toGMTFormat, getCancellationPrice, - isAccumulatorContract, getCurrencyDisplayCode, + isAccumulatorContract, isMobile, isMultiplierContract, + isOnlyUpsDownsContract, isUserSold, isEndedBeforeCancellationExpired, isUserCancelled, + toGMTFormat, } from '@deriv/shared'; import { addCommaToNumber, @@ -107,20 +108,22 @@ const ContractDetails = ({ contract_end_time, contract_info, duration, duration_ /> )} - {!isAccumulatorContract(contract_type) && !is_vanilla && ( - - ) : ( - - ) - } - label={getBarrierLabel(contract_info)} - value={getBarrierValue(contract_info) || ' - '} - /> - )} + {!isAccumulatorContract(contract_type) && + !is_vanilla && + !isOnlyUpsDownsContract(contract_type) && ( + + ) : ( + + ) + } + label={getBarrierLabel(contract_info)} + value={getBarrierValue(contract_info) || ' - '} + /> + )} )}
0 && !result, - 'dc-contract-card--red': is_mobile && !is_multiplier && profit < 0 && !result, + 'dc-contract-card--green': profit > 0 && !result, + 'dc-contract-card--red': profit < 0 && !result, 'contract-card__market-closed--disabled': is_market_closed && should_hide_closed_overlay, })} ref={hover_ref} diff --git a/packages/trader/src/App/Components/Elements/ContractDrawer/contract-drawer.jsx b/packages/trader/src/App/Components/Elements/ContractDrawer/contract-drawer.jsx index daaad6f0f55e..f618d3f48677 100644 --- a/packages/trader/src/App/Components/Elements/ContractDrawer/contract-drawer.jsx +++ b/packages/trader/src/App/Components/Elements/ContractDrawer/contract-drawer.jsx @@ -29,6 +29,7 @@ const ContractDrawer = observer( is_market_closed, is_multiplier, is_vanilla, + is_only_ups_downs, onClickCancel, onClickSell, status, @@ -54,11 +55,12 @@ const ContractDrawer = observer( is_accumulator={is_accumulator} is_dark_theme={is_dark_theme} is_multiplier={is_multiplier} + is_only_ups_downs={is_only_ups_downs} is_open duration={getDurationTime(contract_info)} duration_unit={getDurationUnitText(getDurationPeriod(contract_info))} exit_spot={exit_spot} - has_result={!!is_sold || is_multiplier || is_vanilla || is_accumulator} + has_result={!!is_sold || is_multiplier || is_vanilla || is_accumulator || is_only_ups_downs} toggleHistoryTab={toggleHistoryTab} is_vanilla={is_vanilla} /> @@ -106,11 +108,12 @@ const ContractDrawer = observer( is_accumulator={is_accumulator} is_dark_theme={is_dark_theme} is_multiplier={is_multiplier} + is_only_ups_downs={is_only_ups_downs} is_open duration={getDurationTime(contract_info)} duration_unit={getDurationUnitText(getDurationPeriod(contract_info))} exit_spot={exit_spot} - has_result={!!is_sold || is_multiplier || is_vanilla || is_accumulator} + has_result={!!is_sold || is_multiplier || is_vanilla || is_accumulator || is_only_ups_downs} toggleHistoryTab={toggleHistoryTab} is_vanilla={is_vanilla} /> @@ -183,6 +186,7 @@ ContractDrawer.propTypes = { is_accumulator: PropTypes.bool, is_multiplier: PropTypes.bool, is_vanilla: PropTypes.bool, + is_only_ups_downs: PropTypes.bool, toggleHistoryTab: PropTypes.func, }; diff --git a/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.jsx b/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.jsx index 29e1edb72785..5fefa49c8de1 100644 --- a/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.jsx +++ b/packages/trader/src/App/Components/Elements/PositionsDrawer/positions-modal-card.jsx @@ -219,8 +219,8 @@ const PositionsModalCard = observer( 0 && !result, - 'dc-contract-card--red': !is_multiplier && profit_loss < 0 && !result, + 'dc-contract-card--green': profit_loss > 0 && !result, + 'dc-contract-card--red': profit_loss < 0 && !result, })} to={{ pathname: `/contract/${contract_info.contract_id}`, diff --git a/packages/trader/src/Constants/contract.js b/packages/trader/src/Constants/contract.js index 64debe49ba5e..1bffd31f4f48 100644 --- a/packages/trader/src/Constants/contract.js +++ b/packages/trader/src/Constants/contract.js @@ -197,14 +197,6 @@ export const getUnsupportedContracts = () => ({ name: , position: 'bottom', }, - RUNHIGH: { - name: , - position: 'top', - }, - RUNLOW: { - name: , - position: 'bottom', - }, }); // Config to display trade button and their position @@ -278,6 +270,14 @@ export const getSupportedContracts = is_high_low => ({ name: , position: 'bottom', }, + RUNHIGH: { + name: , + position: 'top', + }, + RUNLOW: { + name: , + position: 'bottom', + }, }); export const getContractConfig = is_high_low => ({ diff --git a/packages/trader/src/Modules/Contract/Containers/contract-replay.jsx b/packages/trader/src/Modules/Contract/Containers/contract-replay.jsx index e16951054df5..3f7dbca23bf1 100644 --- a/packages/trader/src/Modules/Contract/Containers/contract-replay.jsx +++ b/packages/trader/src/Modules/Contract/Containers/contract-replay.jsx @@ -21,6 +21,7 @@ import { isMobile, isMultiplierContract, isVanillaContract, + isOnlyUpsDownsContract, urlFor, } from '@deriv/shared'; import { localize } from '@deriv/translations'; @@ -80,6 +81,7 @@ const ContractReplay = observer(({ contract_id }) => { const is_accumulator = isAccumulatorContract(contract_info.contract_type); const is_multiplier = isMultiplierContract(contract_info.contract_type); const is_vanilla = isVanillaContract(contract_info.contract_type); + const is_only_ups_downs = isOnlyUpsDownsContract(contract_info.contract_type); const contract_drawer_el = ( { is_sell_requested={is_sell_requested} is_valid_to_cancel={is_valid_to_cancel} is_vanilla={is_vanilla} + is_only_ups_downs={is_only_ups_downs} onClickCancel={onClickCancel} onClickSell={onClickSell} status={indicative_status} diff --git a/packages/trader/src/sass/app/modules/smart-chart.scss b/packages/trader/src/sass/app/modules/smart-chart.scss index f31c236932e1..fcc182c30979 100644 --- a/packages/trader/src/sass/app/modules/smart-chart.scss +++ b/packages/trader/src/sass/app/modules/smart-chart.scss @@ -56,7 +56,8 @@ width: 16px; height: 16px; } - &--accumulator { + &--accumulator, + &--only-ups-downs { &-middle, &-middle--preexit { width: 6px; From 36f15104d50ab1eda5b94ccc6b4965dcb3a88630 Mon Sep 17 00:00:00 2001 From: Sui Sin <103026762+suisin-deriv@users.noreply.github.com> Date: Fri, 21 Jul 2023 17:07:44 +0800 Subject: [PATCH 07/52] fix: token leakage to third party api (#9000) Co-authored-by: Ali(Ako) Hosseini --- .../core/src/App/Components/Elements/LiveChat/use-livechat.ts | 1 + packages/core/src/index.html | 1 + types/global.d.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/core/src/App/Components/Elements/LiveChat/use-livechat.ts b/packages/core/src/App/Components/Elements/LiveChat/use-livechat.ts index 7e5c9bf7e796..d42f3db7488a 100644 --- a/packages/core/src/App/Components/Elements/LiveChat/use-livechat.ts +++ b/packages/core/src/App/Components/Elements/LiveChat/use-livechat.ts @@ -39,6 +39,7 @@ const useLiveChat = (has_cookie_account = false, active_loginid?: string) => { }, []); const liveChatSetup = (is_logged_in: boolean) => { + window.LiveChatWidget.init(); window.LiveChatWidget?.on('ready', () => { let client_first_name = ''; let client_last_name = ''; diff --git a/packages/core/src/index.html b/packages/core/src/index.html index 33b8b2d72958..99cbc7010d2d 100644 --- a/packages/core/src/index.html +++ b/packages/core/src/index.html @@ -296,6 +296,7 @@