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

[DTRA] henry/dtra-1237/fix: dtrader-v2 setup #14991

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
5baf11b
fix: initial setup
henry-deriv May 6, 2024
8632910
fix: partially finished setup
henry-deriv May 9, 2024
f450178
fix: ensure new header only appears for mobile
henry-deriv May 9, 2024
a509a82
fix: quill-ui version bump
henry-deriv May 10, 2024
1593a82
fix: change classnames
henry-deriv May 10, 2024
8db429d
fix: change to kebab case file names
henry-deriv May 13, 2024
776d53a
fix: resolve comments
henry-deriv May 13, 2024
61c1088
fix: add color to text
henry-deriv May 13, 2024
7b25581
fix: add tests
henry-deriv May 13, 2024
8b8fd1e
fix: sonarcloud
henry-deriv May 13, 2024
b6746b6
fix: sonarcloud issues
henry-deriv May 13, 2024
ac0ec49
fix: parse JSON with try catch in case FeatureFlagsStore returns empty
henry-deriv May 13, 2024
b64ff30
fix: change to quill icons
henry-deriv May 13, 2024
01214a6
fix: add missing css
henry-deriv May 13, 2024
07af4f6
Merge branch 'master' of github.com:binary-com/deriv-app into henry/d…
henry-deriv May 14, 2024
8ecea00
fix: change hamburger menu icon to standalone
henry-deriv May 14, 2024
7bd0965
fix: move quill-ui to core and wrap application with themeprovider
henry-deriv May 14, 2024
ddec755
fix: import themeprovider from quill/ui
henry-deriv May 14, 2024
fc3d244
fix: wrong import
henry-deriv May 14, 2024
5bf1def
Merge branch 'master' of github.com:binary-com/deriv-app into henry/d…
henry-deriv May 14, 2024
86401fe
fix: remove unused css and make header bold
henry-deriv May 14, 2024
3cc68db
fix: make labels red when active
henry-deriv May 15, 2024
db600a9
fix: change text to correct component
henry-deriv May 15, 2024
7501931
fix: move themeprovider to appcontent to react to changes in store
henry-deriv May 15, 2024
fe98975
Merge branch 'master' of github.com:binary-com/deriv-app into henry/d…
henry-deriv May 15, 2024
e706195
chore: reset package lock
henry-deriv May 15, 2024
9fbaa8b
fix: update package-lock and add quill-ui to traders package
henry-deriv May 15, 2024
2e9e896
fix: jest config error
henry-deriv May 15, 2024
9f16083
fix: ignore errors from quill-ui
henry-deriv May 15, 2024
6dc46c3
fix: jest config and add babel config
henry-deriv May 15, 2024
80b13f6
fix: remove a plugin
henry-deriv May 15, 2024
93b528c
fix: lets try this
henry-deriv May 15, 2024
9b72174
fix: remove irrelevant files
henry-deriv May 16, 2024
41f986f
fix: resolve conflicts
henry-deriv May 16, 2024
78d8e6c
fix: test
henry-deriv May 16, 2024
8efb948
fix: change
henry-deriv May 16, 2024
2367b75
fix: asdf
henry-deriv May 16, 2024
bf975ac
fix: errors
henry-deriv May 16, 2024
ec8b9b2
fix: give contract details page a new header
henry-deriv May 17, 2024
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
36 changes: 31 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
"@babel/polyfill": "^7.4.4",
"@datadog/browser-rum": "^5.11.0",
"@deriv-com/analytics": "1.4.13",
"@deriv-com/quill-ui": "^1.9.17",
"@deriv-com/utils": "^0.0.20",
"@deriv/account": "^1.0.0",
"@deriv/account-v2": "^1.0.0",
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/App/AppContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import AppModals from './Containers/Modals';
import Routes from './Containers/Routes/routes.jsx';
import Devtools from './Devtools';
import initDatadog from '../Utils/Datadog';
import { ThemeProvider } from '@deriv-com/quill-ui';

const AppContent: React.FC<{ passthrough: unknown }> = observer(({ passthrough }) => {
const store = useStore();
Expand Down Expand Up @@ -89,7 +90,7 @@ const AppContent: React.FC<{ passthrough: unknown }> = observer(({ passthrough }
}, [has_wallet, store.common, store.ui]);

return (
<>
<ThemeProvider theme={store.ui.is_dark_mode_on ? 'dark' : 'light'}>
<Header />
<ErrorBoundary root_store={store}>
<AppContents>
Expand All @@ -107,7 +108,7 @@ const AppContent: React.FC<{ passthrough: unknown }> = observer(({ passthrough }
<BinaryBotIFrame />
<AppToastMessages />
<Devtools />
</>
</ThemeProvider>
);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Header from '../header';
jest.mock('@deriv/hooks', () => ({
...jest.requireActual('@deriv/hooks'),
useStoreWalletAccountsList: jest.fn(() => ({ data: [], has_wallet: false })),
useFeatureFlags: jest.fn(() => ({})),
}));
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { observer, useStore } from '@deriv/stores';
import { getCurrencyDisplayCode } from '@deriv/shared';
import AccountInfoIcon from 'App/Components/Layout/Header/account-info-icon';
import { CaptionText } from '@deriv-com/quill-ui';

const DTraderV2Header = observer(() => {
const { client } = useStore();
const { balance, currency, is_virtual, loginid } = client;

const currency_lower = currency?.toLowerCase();

return (
<header className='header header-v2'>
<React.Suspense fallback={<div />}>
<div className='header-v2__acc-info'>
<div className='header-v2__acc-info--top'>
<span className='header-v2__acc-info--logo'>
{(is_virtual || currency) && (
<AccountInfoIcon is_virtual={is_virtual} currency={currency_lower} />
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
)}
</span>
<CaptionText size='sm'>{loginid}</CaptionText>
</div>
<div className='header-v2__acc-info--bottom'>
<CaptionText size='sm' bold>{`${balance} ${getCurrencyDisplayCode(currency)}`}</CaptionText>
</div>
</div>
</React.Suspense>
</header>
);
});

export default DTraderV2Header;
31 changes: 25 additions & 6 deletions packages/core/src/App/Containers/Layout/header/header.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React from 'react';
import { useLocation } from 'react-router-dom';
import { useFeatureFlags } from '@deriv/hooks';
import { useReadLocalStorage } from 'usehooks-ts';
import { makeLazyLoader, moduleLoader, routes } from '@deriv/shared';
import { observer, useStore } from '@deriv/stores';
import { useDevice } from '@deriv/components';

const HeaderFallback = () => <div className='header' />;

Expand Down Expand Up @@ -37,10 +39,16 @@ const TradersHubHeaderWallets = makeLazyLoader(
() => <HeaderFallback />
)();

const DTraderV2Header = makeLazyLoader(
() => moduleLoader(() => import(/* webpackChunkName: "dtrader-v2-header" */ './dtrader-v2-header')),
() => <HeaderFallback />
)();

const Header = observer(() => {
const { client } = useStore();
const { accounts, has_wallet, is_logged_in, setAccounts, loginid, switchAccount } = client;
const { pathname } = useLocation();
const { is_mobile } = useDevice();

const is_wallets_cashier_route = pathname.includes(routes.wallets_cashier);

Expand All @@ -59,6 +67,7 @@ const Header = observer(() => {
is_wallets_cashier_route;

const client_accounts = useReadLocalStorage('client.accounts');
const { is_dtrader_v2_enabled } = useFeatureFlags();

React.useEffect(() => {
if (has_wallet && is_logged_in) {
Expand All @@ -74,12 +83,22 @@ const Header = observer(() => {

if (is_logged_in) {
let result;
if (traders_hub_routes) {
result = has_wallet ? <TradersHubHeaderWallets /> : <TradersHubHeader />;
} else if (pathname === routes.onboarding) {
result = null;
} else {
result = has_wallet ? <DTraderHeaderWallets /> : <DTraderHeader />;
switch (true) {
case pathname === routes.onboarding:
result = null;
break;
case is_dtrader_v2_enabled &&
is_mobile &&
(pathname === routes.trade ||
pathname.startsWith('/contract/') === routes.contract.startsWith('/contract/')):
result = <DTraderV2Header />;
break;
case traders_hub_routes:
result = has_wallet ? <TradersHubHeaderWallets /> : <TradersHubHeader />;
break;
default:
result = has_wallet ? <DTraderHeaderWallets /> : <DTraderHeader />;
break;
}
return result;
} else if (pathname === routes.onboarding) {
Expand Down
36 changes: 36 additions & 0 deletions packages/core/src/sass/app/_common/layout/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -382,3 +382,39 @@
}
}
}

.header-v2 {
display: flex;
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
justify-content: center;

&__acc-info {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;

&--top {
display: flex;
align-items: center;
justify-content: center;
gap: var(--semantic-spacing-gap-sm);
}

&--logo {
height: var(--core-size-800);
width: var(--core-size-800);

svg {
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
width: var(--core-size-800);
height: var(--core-size-800);
}
}

&--bottom {
display: flex;
align-items: center;
justify-content: center;
gap: var(--semantic-spacing-gap-sm);
}
}
}
1 change: 1 addition & 0 deletions packages/trader/build/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {
const ALIASES = {
_common: path.resolve(__dirname, '../src/_common'),
App: path.resolve(__dirname, '../src/App'),
AppV2: path.resolve(__dirname, '../src/AppV2'),
Assets: path.resolve(__dirname, '../src/Assets'),
Constants: path.resolve(__dirname, '../src/Constants'),
Fonts: path.resolve(__dirname, '../src/public/fonts'),
Expand Down
3 changes: 3 additions & 0 deletions packages/trader/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ module.exports = {
...baseConfigForPackages,
moduleNameMapper: {
'\\.s(c|a)ss$': '<rootDir>/../../__mocks__/styleMock.js',
'\\.css$': '<rootDir>/../../__mocks__/styleMock.js',
'^.+\\.svg$': '<rootDir>/../../__mocks__/styleMock.js',
'^_common/(.*)$': '<rootDir>/src/_common/$1',
'^App/(.*)$': '<rootDir>/src/App/$1',
'^AppV2/(.*)$': '<rootDir>/src/AppV2/$1',
'^Assets/(.*)$': '<rootDir>/src/Assets/$1',
'^Constants/(.*)$': '<rootDir>/src/Constants/$1',
'^Constants$': '<rootDir>/src/Constants/index.js',
Expand All @@ -16,4 +18,5 @@ module.exports = {
'^Services/(.*)$': '<rootDir>/src/Services/$1',
'^Stores/(.*)$': '<rootDir>/src/Stores/$1',
},
transformIgnorePatterns: ['/node_modules/(?!(@deriv-com/quill-ui|@simplewebauthn/browser)).+\\.js$'],
};
2 changes: 2 additions & 0 deletions packages/trader/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"dependencies": {
"@cloudflare/stream-react": "^1.9.1",
"@deriv-com/analytics": "1.4.13",
"@deriv-com/quill-ui": "^1.9.17",
"@deriv-com/utils": "^0.0.20",
"@deriv/api-types": "^1.0.172",
"@deriv/components": "^1.0.0",
Expand All @@ -99,6 +100,7 @@
"@deriv/shared": "^1.0.0",
"@deriv/stores": "^1.0.0",
"@deriv/translations": "^1.0.0",
"@deriv/quill-icons": "^1.22.4",
"@types/react-loadable": "^5.5.6",
"classnames": "^2.2.6",
"extend": "^3.0.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import BottomNavItem from '../bottom-nav-item';
import userEvent from '@testing-library/user-event';

jest.mock('@deriv-com/quill-ui', () => ({
Text: jest.fn(() => {
return 'MockedText';
}),
}));

describe('BottomNavItem', () => {
const mockProps = {
icon: <div>Icon</div>,
selectedIndex: 0,
label: 'Label',
setSelectedIndex: jest.fn(),
index: 0,
};

it('should render icon and label', () => {
render(<BottomNavItem {...mockProps} />);
expect(screen.getByText('Icon')).toBeInTheDocument();
expect(screen.getByText('MockedText')).toBeInTheDocument();
});
it('should have bottom-nav-item--active class when active', () => {
render(<BottomNavItem {...mockProps} />);
expect(screen.getByText('MockedText')).toHaveClass('bottom-nav-item--active');
});
it('should have not bottomNav-item--active class when not active', () => {
render(<BottomNavItem {...mockProps} selectedIndex={1} />);
expect(screen.getByText('MockedText')).not.toHaveClass('bottom-nav-item--active');
});
it('should call setSelectedIndex with index when clicked', () => {
render(<BottomNavItem {...mockProps} />);
userEvent.click(screen.getByText('MockedText'));
Copy link
Contributor

Choose a reason for hiding this comment

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

just a recommendation for maintainability: since 'MockedText' is used multiple times, we could introduce a reusable variable for it :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd say since it's a test case, there will hardly be any reason to modify/reuse this variable in the future and there's no point or any advantage in doing this)

expect(mockProps.setSelectedIndex).toHaveBeenCalledWith(0);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import BottomNav from '../bottom-nav';
import userEvent from '@testing-library/user-event';

jest.mock('../bottom-nav-item', () => {
return jest.fn(({ index, setSelectedIndex }) => (
<button onClick={() => setSelectedIndex(index)}>MockedBottomNavItem</button>
));
});

jest.mock('@deriv-com/quill-ui', () => ({
Badge: jest.fn(() => {
return 'MockedBadge';
}),
}));
describe('BottomNav', () => {
const mockedTradeContainer = <div>MockedTrade</div>;
const mockedMarketsContainer = <div>MockedMarkets</div>;
const mockedPositionsContainer = <div>MockedPositions</div>;
const renderedBottomNav = (
<BottomNav>
<div>{mockedTradeContainer}</div>
<div>{mockedMarketsContainer}</div>
<div>{mockedPositionsContainer}</div>
</BottomNav>
);
it('should render correctly', () => {
const { container } = render(renderedBottomNav);
expect(container).toBeInTheDocument();
});
it('should render the correct number of BottomNavItem components', () => {
render(renderedBottomNav);
expect(screen.getAllByText(/MockedBottomNavItem/i)).toHaveLength(4);
});
it('should render MockedTrade by default since selected index is 0', () => {
render(renderedBottomNav);
expect(screen.getByText('MockedTrade')).toBeInTheDocument();
});
it('should render MockedPositions if 3rd MockedBottomNavItem is selected', () => {
render(renderedBottomNav);
userEvent.click(screen.getAllByText('MockedBottomNavItem')[2]);
expect(screen.getByText('MockedPositions')).toBeInTheDocument();
});
});
Loading
Loading