-
Notifications
You must be signed in to change notification settings - Fork 298
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: show snackbar if strategy changed while running bot (#10393)
* chore: show snackbar if strategy changed while running bot * chore: added test cases * fix: notification icon * fix: remove timer if mouse over * fix: update notification timer on everytime the snackbar opens
- Loading branch information
1 parent
15cdb89
commit 1e73722
Showing
6 changed files
with
242 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,4 +15,5 @@ | |
--zindex-drawer: 5; | ||
--zindex-modal: 6; | ||
--zindex-draggable-modal: 7; | ||
--zindex-snackbar: 8; | ||
} |
103 changes: 103 additions & 0 deletions
103
packages/bot-web-ui/src/components/bot-snackbar/__tests__/bot-snackbar.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import React from 'react'; | ||
import { mockStore, StoreProvider } from '@deriv/stores'; | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
import { act, fireEvent, render, screen } from '@testing-library/react'; | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
import userEvent from '@testing-library/user-event'; | ||
import RootStore from '../../../stores/root-store'; | ||
import { DBotStoreProvider, mockDBotStore } from '../../../stores/useDBotStore'; | ||
import BotSnackbar from '../bot-snackbar'; | ||
|
||
jest.mock('@deriv/shared', () => ({ | ||
...jest.requireActual('@deriv/shared'), | ||
isMobile: jest.fn(() => false), | ||
})); | ||
|
||
jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); | ||
jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ | ||
saveRecentWorkspace: jest.fn(), | ||
unHighlightAllBlocks: jest.fn(), | ||
})); | ||
jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); | ||
jest.mock('@deriv/deriv-charts', () => ({ | ||
setSmartChartsPublicPath: jest.fn(), | ||
})); | ||
|
||
const mock_ws = { | ||
authorized: { | ||
subscribeProposalOpenContract: jest.fn(), | ||
send: jest.fn(), | ||
}, | ||
storage: { | ||
send: jest.fn(), | ||
}, | ||
contractUpdate: jest.fn(), | ||
subscribeTicksHistory: jest.fn(), | ||
forgetStream: jest.fn(), | ||
activeSymbols: jest.fn(), | ||
send: jest.fn(), | ||
}; | ||
|
||
jest.useFakeTimers(); | ||
|
||
describe('BotSnackbar', () => { | ||
let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element, mock_DBot_store: RootStore | undefined; | ||
const mockHandleClose = jest.fn(); | ||
beforeAll(() => { | ||
const mock_store = mockStore({}); | ||
mock_DBot_store = mockDBotStore(mock_store, mock_ws); | ||
|
||
wrapper = ({ children }: { children: JSX.Element }) => ( | ||
<StoreProvider store={mock_store}> | ||
<DBotStoreProvider ws={mock_ws} mock={mock_DBot_store}> | ||
{children} | ||
</DBotStoreProvider> | ||
</StoreProvider> | ||
); | ||
}); | ||
it('should render BotSnackbar with correct message', () => { | ||
const test_message = 'message test'; | ||
render(<BotSnackbar message={test_message} handleClose={mockHandleClose} is_open={true} />, { | ||
wrapper, | ||
}); | ||
expect(screen.getByText(test_message)).toBeInTheDocument(); | ||
}); | ||
|
||
it('should not render BotSnackbar if snack bar is not opened', () => { | ||
const test_message = 'message test'; | ||
render(<BotSnackbar message={test_message} handleClose={mockHandleClose} is_open={false} />, { | ||
wrapper, | ||
}); | ||
expect(screen.queryByText(test_message)).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('should render close button if snackbar is open', () => { | ||
render(<BotSnackbar message='test' handleClose={mockHandleClose} is_open={true} />, { | ||
wrapper, | ||
}); | ||
const cls_btn = screen.getByTestId('bot-snackbar-notification-close'); | ||
expect(cls_btn).toBeInTheDocument(); | ||
}); | ||
|
||
it('should hanlde close function on click close button', async () => { | ||
render(<BotSnackbar message='test' handleClose={mockHandleClose} is_open={true} />, { | ||
wrapper, | ||
}); | ||
const cls_btn = screen.getByTestId('bot-snackbar-notification-close'); | ||
await userEvent.click(cls_btn); | ||
expect(mockHandleClose).toBeCalled(); | ||
}); | ||
|
||
it('should close snackbar after timeout is passed and mouse is not over the snackbar', async () => { | ||
render(<BotSnackbar message='test' handleClose={mockHandleClose} is_open={true} timeout={4000} />, { | ||
wrapper, | ||
}); | ||
const element = screen.getByTestId('bot-snackbar-notification-container'); | ||
act(() => { | ||
fireEvent.mouseLeave(element); | ||
jest.advanceTimersByTime(4100); | ||
}); | ||
const cls_btn = screen.queryByTestId('bot-snackbar-notification-close'); | ||
expect(cls_btn).not.toBeInTheDocument(); | ||
}); | ||
}); |
36 changes: 36 additions & 0 deletions
36
packages/bot-web-ui/src/components/bot-snackbar/bot-snackbar.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
.bot-snackbar { | ||
position: fixed; | ||
z-index: var(--zindex-snackbar); | ||
right: 38rem; | ||
top: 12rem; | ||
|
||
.dc-toast { | ||
width: 100%; | ||
&__message { | ||
background: var(--text-prominent); | ||
color: var(--general-main-1); | ||
padding: 1rem 1.6rem; | ||
} | ||
&__message-content { | ||
display: flex; | ||
|
||
@include mobile { | ||
align-items: center; | ||
} | ||
} | ||
} | ||
|
||
@include mobile { | ||
top: unset; | ||
left: 0; | ||
right: 0; | ||
bottom: 10.5rem; | ||
} | ||
|
||
.notification-close { | ||
cursor: pointer; | ||
filter: invert(1); | ||
margin-left: 1rem; | ||
margin-top: 0.1rem; | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
packages/bot-web-ui/src/components/bot-snackbar/bot-snackbar.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React, { useState } from 'react'; | ||
import { Icon, Toast } from '@deriv/components'; | ||
import { Localize } from '@deriv/translations'; | ||
|
||
type TBotSnackbar = { | ||
className?: string; | ||
is_open: boolean; | ||
onClick?: React.MouseEventHandler<HTMLDivElement>; | ||
handleClose: () => void; | ||
type?: 'error' | 'info' | 'notification'; | ||
timeout?: number; | ||
msg_localize_components?: JSX.Element[]; | ||
message: string; | ||
}; | ||
|
||
const BotSnackbar = ({ | ||
message, | ||
msg_localize_components = [], | ||
timeout = 6000, | ||
is_open, | ||
onClick, | ||
handleClose, | ||
type, | ||
className, | ||
}: TBotSnackbar) => { | ||
const [notification_timer, setNotificationTimer] = useState(timeout); | ||
|
||
React.useEffect(() => { | ||
if (is_open) { | ||
setNotificationTimer(timeout); | ||
} | ||
}, [is_open, timeout]); | ||
|
||
return ( | ||
<div | ||
onMouseOver={() => { | ||
setNotificationTimer(0); | ||
}} | ||
onMouseLeave={() => { | ||
setNotificationTimer(timeout); | ||
}} | ||
className={className ?? 'bot-snackbar'} | ||
data-testid='bot-snackbar-notification-container' | ||
> | ||
<Toast is_open={is_open} type={type} timeout={notification_timer} onClick={onClick} onClose={handleClose}> | ||
<div>{message && <Localize i18n_default_text={message} components={msg_localize_components} />}</div> | ||
<Icon | ||
icon='IcCross' | ||
className={'notification-close'} | ||
data_testid={'bot-snackbar-notification-close'} | ||
onClick={handleClose} | ||
/> | ||
</Toast> | ||
</div> | ||
); | ||
}; | ||
export default BotSnackbar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import BotSnackbar from './bot-snackbar'; | ||
import './bot-snackbar.scss'; | ||
|
||
export default BotSnackbar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1e73722
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
deriv-app – ./
deriv-app.vercel.app
binary.sx
deriv-app.binary.sx
deriv-app-git-master.binary.sx