Skip to content
This repository was archived by the owner on May 13, 2024. It is now read-only.

Commit 2651ce5

Browse files
Merge branch 'master' into utkarsha/display-popup-upon-token-creation
2 parents ef1adf8 + b340722 commit 2651ce5

File tree

11 files changed

+127
-42
lines changed

11 files changed

+127
-42
lines changed

src/components/UserNavbarItem/UserNavbarItem.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
border: 2px solid var(--colors-coral500);
1111
border-radius: rem(1.6);
1212
padding: rem(1) rem(1.6);
13-
height: rem(4);
13+
height: rem(1.5);
1414
}
1515
}
1616

src/components/UserNavbarItem/__tests__/item.desktop.test.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ describe('User Navbar Desktop Item', () => {
4242
});
4343

4444
it('Should render login link navbar item', async () => {
45-
const login_nav_button = screen.getByRole<HTMLAnchorElement>('link', { name: /log in/i });
46-
expect(login_nav_button).toHaveAttribute('href', 'https://www.example.com');
45+
const login_nav_button = screen.getByRole('button', { name: /log in/i });
46+
expect(login_nav_button).toBeVisible();
47+
48+
await userEvent.click(login_nav_button);
49+
50+
expect(location.href).toBe('https://www.example.com/');
4751
});
4852
});
4953
describe('Given user is logged in', () => {

src/components/UserNavbarItem/item.desktop.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import SearchButton from '../SearchButton';
99
const UserNavbarDesktopItem = ({ authUrl, is_logged_in }: IUserNavbarItemProps) => {
1010
const [toggle_search, setToggleSearch] = useState<boolean>(false);
1111

12+
const handleClick = () => {
13+
location.assign(authUrl);
14+
};
15+
1216
const logInButtonClasses = clsx(
1317
'navbar__item navbar__link',
1418
styles.UserNavbarItem,
@@ -24,10 +28,10 @@ const UserNavbarDesktopItem = ({ authUrl, is_logged_in }: IUserNavbarItemProps)
2428
<AccountSwitcher />
2529
) : (
2630
<nav className={`right-navigation ${toggle_search ? 'search-open' : 'search-closed'}`}>
27-
<Link to={authUrl} className={logInButtonClasses}>
31+
<button onClick={handleClick} className={logInButtonClasses}>
2832
Log in
29-
</Link>
30-
<Link to={'https://deriv.com/signup/'} className={signUpButtonClasses} target='_blank'>
33+
</button>
34+
<Link to={'https://deriv.com/signup/'} className={signUpButtonClasses}>
3135
Sign up
3236
</Link>
3337
<SearchButton setToggleSearch={setToggleSearch} toggle_search={toggle_search} />

src/features/Apiexplorer/SubscribeRenderer/__tests__/SubscribeRenderer.test.tsx

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import React from 'react';
22
import userEvent from '@testing-library/user-event';
3-
import { cleanup, render, screen } from '@testing-library/react';
3+
import { cleanup, render, screen, waitFor } from '@testing-library/react';
44
import SubscribeRenderer from '..';
55
import useAuthContext from '@site/src/hooks/useAuthContext';
66
import useSubscription from '@site/src/hooks/useSubscription';
77
import useDynamicImportJSON from '@site/src/hooks/useDynamicImportJSON';
88
import { IAuthContext } from '@site/src/contexts/auth/auth.context';
9+
import LoginDialog from '../../LoginDialog';
910

1011
jest.mock('@site/src/hooks/useAuthContext');
1112

@@ -78,39 +79,82 @@ describe('SubscribeRenderer', () => {
7879
expect(button).toBeVisible();
7980
});
8081

82+
it('should throw an error if incorrect json is being parsed', async () => {
83+
const consoleOutput = [];
84+
const mockedError = (output) => consoleOutput.push(output);
85+
console.error = mockedError;
86+
87+
render(<SubscribeRenderer name='ticks' auth={1} reqData={'asdawefaewf3232'} />);
88+
const button = await screen.findByRole('button', { name: /Send Request/i });
89+
await userEvent.click(button);
90+
91+
expect(consoleOutput[0]).toEqual(
92+
'Could not parse the JSON data while trying to send the request: ',
93+
);
94+
});
95+
8196
it('should call subscribe and unsubscribe when pressing the send request button', async () => {
97+
jest.spyOn(React, 'useRef').mockReturnValue({
98+
current: {
99+
unsubscribe: mockUnsubscribe,
100+
},
101+
});
82102
render(<SubscribeRenderer name='ticks' auth={1} reqData={request_data} />);
83103
const button = await screen.findByRole('button', { name: /Send Request/i });
84104
expect(button).toBeVisible();
85105

86106
await userEvent.click(button);
87-
88107
expect(mockUnsubscribe).toBeCalledTimes(1);
89108
expect(mockSubscribe).toBeCalledTimes(1);
90109
expect(mockSubscribe).toBeCalledWith({ ticks: 'R_50', subscribe: 1 });
91110
});
92111

93112
it('should call unsubscribe when pressing the clear button', async () => {
113+
jest.spyOn(React, 'useRef').mockReturnValue({
114+
current: {
115+
unsubscribe: mockUnsubscribe,
116+
},
117+
});
94118
render(<SubscribeRenderer name='ticks' auth={1} reqData={request_data} />);
95119
const button = await screen.findByRole('button', { name: 'Clear' });
96120
expect(button).toBeVisible();
97121

98122
await userEvent.click(button);
99-
100123
expect(mockUnsubscribe).toBeCalledTimes(1);
101124
});
102125

103-
it('should throw an error if incorrect json is being parsed', async () => {
104-
const consoleOutput = [];
105-
const mockedError = (output) => consoleOutput.push(output);
106-
console.error = mockedError;
126+
it('should call unsubscribe when unmounting the component', async () => {
127+
jest.spyOn(React, 'useRef').mockReturnValue({
128+
current: {
129+
unsubscribe: mockUnsubscribe,
130+
},
131+
});
132+
const { unmount } = render(<SubscribeRenderer name='ticks' auth={1} reqData={request_data} />);
133+
unmount();
134+
expect(mockUnsubscribe).toBeCalledTimes(1);
135+
});
136+
it('should call login dialog when the error code is not authourized', async () => {
137+
const setToggleModal = jest.fn();
138+
jest.spyOn(React, 'useState').mockReturnValue([false, setToggleModal]);
139+
mockUseAuthContext.mockImplementation(() => ({
140+
is_logged_in: false,
141+
is_authorized: false,
142+
}));
143+
mockUseSubscription.mockImplementation(() => ({
144+
subscribe: mockSubscribe,
145+
unsubscribe: mockUnsubscribe,
146+
error: { code: 'AuthorizationRequired' },
147+
full_response: {
148+
tick: 1,
149+
echo_req: { tick: 1 },
150+
},
151+
}));
107152

108-
render(<SubscribeRenderer name='ticks' auth={1} reqData={'asdawefaewf3232'} />);
153+
render(<SubscribeRenderer name='ticks' auth={1} reqData={request_data} />);
109154
const button = await screen.findByRole('button', { name: /Send Request/i });
110155
await userEvent.click(button);
111-
112-
expect(consoleOutput[0]).toEqual(
113-
'Could not parse the JSON data while trying to send the request: ',
114-
);
156+
await waitFor(() => {
157+
expect(setToggleModal).toHaveBeenCalled();
158+
});
115159
});
116160
});

src/features/Apiexplorer/SubscribeRenderer/index.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useCallback, useEffect } from 'react';
1+
import React, { useState, useCallback, useEffect, useRef } from 'react';
22
import {
33
TSocketSubscribableEndpointNames,
44
TSocketRequestProps,
@@ -25,18 +25,24 @@ function SubscribeRenderer<T extends TSocketSubscribableEndpointNames>({
2525
}: IResponseRendererProps<T>) {
2626
const { is_logged_in } = useAuthContext();
2727
const { disableSendRequest } = useDisableSendRequest();
28-
const { full_response, is_loading, subscribe, unsubscribe, error } = useSubscription<T>(name);
28+
const { full_response, is_loading, subscribe, error } = useSubscription<T>(name);
2929
const [response_state, setResponseState] = useState(false);
3030
const [toggle_modal, setToggleModal] = useState(false);
3131
const [is_not_valid, setIsNotValid] = useState(false);
3232

33+
const subscribe_ref: React.MutableRefObject<{ unsubscribe: () => void }> = useRef();
34+
3335
useEffect(() => {
3436
if (error && error.code === 'AuthorizationRequired') {
3537
setToggleModal(true);
3638
}
39+
40+
return () => {
41+
if (subscribe_ref.current) subscribe_ref.current.unsubscribe();
42+
};
3743
}, [error]);
3844

39-
const parseRequestJSON = () => {
45+
const parseRequestJSON = useCallback(() => {
4046
let request_data: TSocketRequestProps<T> extends never ? undefined : TSocketRequestProps<T>;
4147

4248
try {
@@ -48,16 +54,16 @@ function SubscribeRenderer<T extends TSocketSubscribableEndpointNames>({
4854
}
4955

5056
return request_data;
51-
};
57+
}, [reqData]);
5258

5359
const handleClick = useCallback(() => {
54-
unsubscribe();
55-
subscribe(parseRequestJSON());
60+
if (subscribe_ref.current) subscribe_ref.current.unsubscribe();
61+
subscribe_ref.current = subscribe(parseRequestJSON());
5662
setResponseState(true);
57-
}, [reqData, subscribe, unsubscribe]);
63+
}, [parseRequestJSON, subscribe]);
5864

5965
const handleClear = () => {
60-
unsubscribe();
66+
subscribe_ref.current.unsubscribe();
6167
setResponseState(false);
6268
};
6369

@@ -88,4 +94,4 @@ function SubscribeRenderer<T extends TSocketSubscribableEndpointNames>({
8894
);
8995
}
9096

91-
export default SubscribeRenderer;
97+
export default React.memo(SubscribeRenderer);

src/features/dashboard/components/ApiTokenTable/api-table.module.scss

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
.api_table_container {
44
position: relative;
5-
.api_table {
6-
height: rem(30);
7-
min-height: 10rem;
8-
table {
9-
position: absolute;
10-
}
5+
overflow-y: hidden;
6+
overflow-x: auto;
7+
.api_table table {
8+
position: absolute;
119
}
1210
}

src/features/dashboard/components/ApiTokenTable/index.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { HTMLAttributes } from 'react';
1+
import React, { HTMLAttributes, useEffect, useState } from 'react';
22
import { Circles } from 'react-loader-spinner';
33
import styles from './api-table.module.scss';
44
import useApiToken from '@site/src/hooks/useApiToken';
@@ -38,10 +38,21 @@ const tableColumns: TTokenColumn[] = [
3838
];
3939

4040
const ApiTokenTable = (props: HTMLAttributes<HTMLDivElement>) => {
41+
const ROW_HEIGHT = 125;
4142
const { tokens, isLoadingTokens } = useApiToken();
43+
const [table_height, setTableHeight] = useState(0);
44+
45+
useEffect(() => {
46+
if (tokens.length > 0) {
47+
setTableHeight(ROW_HEIGHT * tokens.length);
48+
}
49+
}, [tokens]);
4250

4351
return (
44-
<div className={styles.api_table_container}>
52+
<div
53+
style={{ height: `calc(${table_height}px + ${ROW_HEIGHT}px + 50px)` }}
54+
className={styles.api_table_container}
55+
>
4556
<div className={styles.api_table} {...props}>
4657
<Circles
4758
height='100'
@@ -55,6 +66,7 @@ const ApiTokenTable = (props: HTMLAttributes<HTMLDivElement>) => {
5566
columns={tableColumns}
5667
data={tokens}
5768
initialState={{ hiddenColumns: ['valid_for_ip'] }}
69+
row_height={ROW_HEIGHT}
5870
/>
5971
</div>
6072
</div>

src/features/dashboard/components/NoApps/no-apps.module.scss

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
position: relative;
1111
display: flex;
1212
flex-direction: column;
13-
justify-content: var(center);
13+
justify-content: center;
1414
align-items: center;
1515
width: calc(rem(32) - rem(3.2));
1616
position: relative;
@@ -28,13 +28,13 @@
2828
height: rem(10);
2929
}
3030

31-
.noAppsText {
31+
.noAppsText p {
3232
text-align: center;
33+
margin-bottom: rem(2);
3334
}
3435

3536
[data-state*="responsive.desktop"] {
3637
.noAppsWrapper {
37-
width: calc(100% - rem(12.5));
3838
position: relative;
3939
}
4040
.noApps {

src/features/dashboard/components/Table/index.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { HTMLAttributes } from 'react';
1+
import React, { HTMLAttributes, LegacyRef, ReactNode } from 'react';
22
import { Cell, Column, TableState, useTable } from 'react-table';
33
import './table.scss';
44

@@ -8,6 +8,7 @@ interface ITableProps<T extends object> extends HTMLAttributes<HTMLTableElement>
88
data: T[];
99
columns: Column<T>[];
1010
initialState?: TableState<T>;
11+
row_height?: number;
1112
getCustomCellProps?: (cell: Cell<T, unknown>) => object;
1213
}
1314

@@ -16,6 +17,7 @@ const Table = <T extends object>({
1617
columns,
1718
initialState,
1819
getCustomCellProps = defaultPropGetter,
20+
row_height,
1921
...rest
2022
}: ITableProps<T>) => {
2123
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable<T>({
@@ -41,7 +43,11 @@ const Table = <T extends object>({
4143
{rows.map((row) => {
4244
prepareRow(row);
4345
return (
44-
<tr key={row.getRowProps().key} {...row.getRowProps()}>
46+
<tr
47+
style={{ height: `${row_height}px` }}
48+
key={row.getRowProps().key}
49+
{...row.getRowProps()}
50+
>
4551
{row.cells.map((cell) => {
4652
return (
4753
<td key={cell.getCellProps().key} {...cell.getCellProps()}>

src/features/dashboard/components/Tabs/tabs.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@
5151
justify-content: space-around;
5252
align-items: center;
5353
padding: rem(2);
54+
overflow-y: auto;
5455
}

0 commit comments

Comments
 (0)