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

refactor--dbot-tours #9990

Merged
merged 49 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
a24fd99
fix: refactored the function to reduce cognitive complexity
farabi-deriv Aug 30, 2023
46f7e64
chore: fix cognitive code complexity
rupato-deriv Aug 30, 2023
40cf354
fix: refactored tours
rupato-deriv Sep 1, 2023
3c472ab
fix: removed tour interdependency
rupato-deriv Sep 1, 2023
ab7029b
fix: added observer to missing files
rupato-deriv Sep 1, 2023
8019fd0
chore: updated test cases
rupato-deriv Sep 4, 2023
a2b3804
fix: addded common test cases
rupato-deriv Sep 4, 2023
b0bad6a
fix: addded common test cases
rupato-deriv Sep 4, 2023
bdfd943
fix: added else check for toggleTourLoadModal
rupato-deriv Sep 5, 2023
e635034
fix: tour test cases
rupato-deriv Sep 6, 2023
56480e9
fix: review comments
rupato-deriv Sep 6, 2023
550fdd7
fix: review comments
rupato-deriv Sep 6, 2023
5f8ee6a
Merge remote-tracking branch 'upstream/master' into farabi/bot-565/cr…
farabi-deriv Sep 6, 2023
27c9a2b
fix: review comments
rupato-deriv Sep 6, 2023
1e0a650
chore: removed redundant tour type key
farabi-deriv Sep 6, 2023
10428ac
fix: resolved merge conflict
rupato-deriv Sep 7, 2023
2db7ecc
fix: reverted icon changes
rupato-deriv Sep 7, 2023
095d2c1
fix: reverted icon changes
rupato-deriv Sep 7, 2023
7c5484e
fix: reverted icon changes
rupato-deriv Sep 7, 2023
8c0449e
fix: reverted icon changes
rupato-deriv Sep 7, 2023
1b69dca
chore: create refactor branch
rupato-deriv Sep 7, 2023
4f9c51f
Merge pull request #19 from rupato-deriv/Rupato/BOT-566/Fix--cognitiv…
rupato-deriv Sep 7, 2023
b308c4a
Merge remote-tracking branch 'rupato/refactor--dbot-tours' into farab…
farabi-deriv Sep 7, 2023
0fad9f3
refactor: refactored dbot tours
farabi-deriv Sep 8, 2023
ac17947
refactor: refactored tour trigger dialog
farabi-deriv Sep 8, 2023
db44e15
fix: removed redundant css
farabi-deriv Sep 8, 2023
e262903
Merge pull request #20 from farabi-deriv/farabi/bot-565/critical-code…
farabi-deriv Sep 8, 2023
39fa1ef
chore: resolved merge conflict
rupato-deriv Sep 11, 2023
bff6890
fix: removed previous button on step 1 and 2
rupato-deriv Sep 11, 2023
e0583f1
fix: cognitive complexity
rupato-deriv Sep 11, 2023
7a55938
fix: test cases
rupato-deriv Sep 11, 2023
e70dc83
fix: test cases
rupato-deriv Sep 11, 2023
c63a3e8
fix: cognitive complexity
rupato-deriv Sep 11, 2023
2339462
fix: cognitive complexity
rupato-deriv Sep 11, 2023
a503c02
Merge remote-tracking branch 'upstream/master' into refactor--dbot-tours
rupato-deriv Sep 11, 2023
0cdbdb2
fix: for onboarding mobile
rupato-deriv Sep 12, 2023
1837e8e
fix: added eslint disable
rupato-deriv Sep 12, 2023
e3c0331
fix: added eslint disable
rupato-deriv Sep 12, 2023
b63ade2
fix: added eslint disable
rupato-deriv Sep 12, 2023
30a50e6
fix: added eslint disable
rupato-deriv Sep 12, 2023
6dbb978
fix: added eslint disable
rupato-deriv Sep 12, 2023
9de18c2
fix: added eslint disable
rupato-deriv Sep 12, 2023
70dbd07
fix: added eslint disable
rupato-deriv Sep 12, 2023
c319a11
fix: added eslint disable
rupato-deriv Sep 12, 2023
cfeb3ef
fix: added eslint disable
rupato-deriv Sep 12, 2023
4a197a0
fix: added eslint disable
rupato-deriv Sep 12, 2023
72a6a6c
fix: reverted lint changes
rupato-deriv Sep 12, 2023
955d3aa
Merge remote-tracking branch 'upstream/master' into refactor--dbot-tours
rupato-deriv Sep 13, 2023
bfc1dc6
fix: added data test id
rupato-deriv Sep 13, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@ import { observer } from '@deriv/stores';
import { useDBotStore } from '../../../stores/useDBotStore';
import LoadModal from '../../load-modal';
import SaveModal from '../dashboard-component/load-bot-preview/save-modal';
import { BOT_BUILDER_TOUR } from '../joyride-config';
import DesktopTours from '../dbot-tours/desktop-tours/desktop-tours';
import MobileTours from '../dbot-tours/mobile-tours/mobile-tours';
import QuickStrategy from '../quick-strategy';
import ReactJoyrideWrapper from '../react-joyride-wrapper';
import TourSlider from '../tour-slider';
import WorkspaceWrapper from './workspace-wrapper';

const BotBuilder = observer(() => {
const { dashboard, app } = useDBotStore();
const { active_tab, has_started_onboarding_tour, has_started_bot_builder_tour, is_preview_on_popup } = dashboard;

const [is_tour_running] = React.useState<boolean>(true);
const { onMount, onUnmount } = app;
const el_ref = React.useRef<HTMLInputElement | null>(null);

Expand Down Expand Up @@ -49,22 +47,10 @@ const BotBuilder = observer(() => {
{has_started_bot_builder_tour && active_tab === 1 && !has_started_onboarding_tour && (
<>
<MobileWrapper>
<TourSlider />
<MobileTours />
</MobileWrapper>
<DesktopWrapper>
<ReactJoyrideWrapper
steps={BOT_BUILDER_TOUR}
run={is_tour_running}
showProgress
styles={{
options: {
arrowColor: 'transparent',
backgroundColor: 'var(--general-main-2)',
primaryColor: 'var(--brand-red-coral)',
textColor: 'var(--text-general)',
},
}}
/>
<DesktopTours />
</DesktopWrapper>
</>
)}
Expand Down
10 changes: 2 additions & 8 deletions packages/bot-web-ui/src/components/dashboard/dashboard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,12 @@
}
}

&__image {
&__image,
&__media {
background: var(--general-section-1);
text-align: center;
padding: 0.8rem;
width: 100%;
margin-bottom: 0.8rem;
height: 50%;
}

img {
Expand Down Expand Up @@ -544,10 +543,6 @@
}
}

&__content {
color: $color-white;
}

&__status {
height: 5rem;
display: flex;
Expand Down Expand Up @@ -620,7 +615,6 @@
opacity: 0;
color: var(--text-prominent);
padding: 1rem 0;
font-size: 1.2rem;

&--open {
opacity: 1;
Expand Down
31 changes: 12 additions & 19 deletions packages/bot-web-ui/src/components/dashboard/dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,13 @@ import { DBOT_TABS, TAB_IDS } from 'Constants/bot-contents';
import { useDBotStore } from 'Stores/useDBotStore';
import RunPanel from '../run-panel';
import RunStrategy from './dashboard-component/run-strategy';
import TourEndDialog from './dbot-tours/common/tour-end-dialog';
import TourStartDialog from './dbot-tours/common/tour-start-dialog';
import DesktopTours from './dbot-tours/desktop-tours';
import MobileTours from './dbot-tours/mobile-tours';
import { getTourSettings, setTourSettings, setTourType, tour_status_ended, tour_type } from './dbot-tours/utils';
import DashboardComponent from './dashboard-component';
import {
DBOT_ONBOARDING,
getTourSettings,
setTourSettings,
setTourType,
tour_status_ended,
tour_type,
} from './joyride-config';
import ReactJoyrideWrapper from './react-joyride-wrapper';
import StrategyNotification from './strategy-notification';
import TourSlider from './tour-slider';
import TourTriggrerDialog from './tour-trigger-dialog';
import Tutorial from './tutorial-tab';

const Dashboard = observer(() => {
Expand All @@ -39,6 +33,7 @@ const Dashboard = observer(() => {
setHasTourEnded,
has_started_bot_builder_tour,
is_tour_dialog_visible,
has_tour_ended,
setActiveTab,
setBotBuilderTokenCheck,
setOnBoardingTokenCheck,
Expand Down Expand Up @@ -229,15 +224,13 @@ const Dashboard = observer(() => {
'dashboard__container--active': has_tour_started && active_tab === DASHBOARD && is_mobile,
})}
>
{(active_tab === DASHBOARD || active_tab === BOT_BUILDER) && <TourTriggrerDialog />}
{!has_tour_ended && (active_tab === DASHBOARD || active_tab === BOT_BUILDER) ? (
<TourStartDialog />
) : (
<TourEndDialog />
)}

{has_tour_started &&
active_tab === DASHBOARD &&
(is_mobile ? (
<TourSlider />
) : (
<ReactJoyrideWrapper steps={DBOT_ONBOARDING} spotlightClicks hideCloseButton />
))}
{has_tour_started && active_tab === DASHBOARD && (is_mobile ? <MobileTours /> : <DesktopTours />)}
<Tabs
active_index={active_tab}
className='dashboard__tabs'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React from 'react';
import classNames from 'classnames';
import { Dialog, Text } from '@deriv/components';
import { isMobile } from '@deriv/shared';
import { observer } from '@deriv/stores';
import { Localize, localize } from '@deriv/translations';
import { useDBotStore } from '../../../../stores/useDBotStore';
import { setTourSettings, tour_status_ended, tour_type } from '../utils';

const TourEndDialog = observer(() => {
const { dashboard } = useDBotStore();
const { active_tab, has_tour_ended, is_tour_dialog_visible, setTourDialogVisibility, toggleOnConfirm } = dashboard;

const is_mobile = isMobile();

const toggleTour = (value: boolean, type: string) => {
if (tour_type.key === 'bot_builder') {
if (type === 'onConfirm') {
toggleOnConfirm(active_tab, value);
} else {
setTourSettings(new Date().getTime(), `${tour_type.key}_token`);
}
}
setTourDialogVisibility(false);
};

const getTourContent = () => {
return (
<>
<div className='dc-dialog__content__description__text' data-testid='tour-success-message'>
<Localize
key={0}
i18n_default_text={'You have successfully created your bot using a simple strategy.'}
/>
</div>
<div className='dc-dialog__content__description__text'>
<Localize
key={0}
i18n_default_text={'Now, <0>run the bot</0> to test out the strategy.'}
components={[<strong key={0} />]}
/>
</div>
<div className='dc-dialog__content__description__text'>
<Localize
key={0}
i18n_default_text={
'Note: If you wish to learn more about the Bot Builder, you can proceed to the <0>Tutorials</0> tab.'
}
components={[<strong key={0} />]}
/>
</div>
</>
);
};

const onHandleConfirm = React.useCallback(() => {
toggleTour(tour_status_ended.key === 'finished', 'onConfirm');
tour_status_ended.key = '';
return tour_status_ended.key;
}, [has_tour_ended, active_tab]);

return (
<div>
<Dialog
is_visible={is_tour_dialog_visible}
cancel_button_text={localize('Skip')}
onCancel={() => toggleTour(false, 'onCancel')}
confirm_button_text={localize('OK')}
onConfirm={onHandleConfirm}
is_mobile_full_width
className={classNames('dc-dialog tour-dialog', {
'tour-dialog--end': has_tour_ended,
})}
has_close_icon={false}
>
<div className='dc-dialog__content__header'>
<Text weight='bold' color='prominent' size={is_mobile ? 'xs' : 's'}>
{localize('Congratulations')}
</Text>
</div>
<div className='dc-dialog__content__description'>
<Text size={is_mobile ? 'xxs' : 'xs'} color='prominent'>
{getTourContent()}
</Text>
</div>
</Dialog>
</div>
);
});

export default TourEndDialog;
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import classNames from 'classnames';
import { Dialog, Text } from '@deriv/components';
import { isMobile } from '@deriv/shared';
import { observer } from '@deriv/stores';
import { Localize, localize } from '@deriv/translations';
import { DBOT_TABS } from 'Constants/bot-contents';
import { useDBotStore } from '../../../../stores/useDBotStore';
import { bot_builder_tour_header, onboarding_tour_header, tourDialogAction, tourDialogInfo } from '../config';
import { setTourSettings, tour_type } from '../utils';

const TourStartDialog = observer(() => {
const { dashboard } = useDBotStore();
const {
active_tab,
has_tour_ended,
is_tour_dialog_visible,
setTourDialogVisibility,
toggleOnConfirm,
setBotBuilderTourState,
setOnBoardTourRunState,
setTourActive,
} = dashboard;

const is_mobile = isMobile();
const current_tour_type_key = tour_type?.key;
const toggleTour = (value: boolean, type: string) => {
if (type === 'onConfirm') toggleOnConfirm(active_tab, value);
setTourSettings(new Date().getTime(), `${current_tour_type_key}_token`);
setTourDialogVisibility(false);
};

const onboard_tour = active_tab === DBOT_TABS.DASHBOARD;

const getTourContent = () => {
return (
<>
{onboard_tour ? (
<Localize
key={0}
i18n_default_text='Hi! Hit <0>Start</0> for a quick tour.'
components={[<strong key={0} />]}
/>
) : (
<>
<div className='dc-dialog__content__description__text'>{tourDialogInfo}</div>
<div className='dc-dialog__content__description__text'>{tourDialogAction}</div>
<div className='dc-dialog__content__description__text'>
<Localize
key={0}
i18n_default_text={'Note: You can also find this tutorial in the <0>Tutorials</0> tab.'}
components={[<strong key={0} />]}
/>
</div>
</>
)}
</>
);
};

const onHandleConfirm = () => {
setTourActive(true);
if (onboard_tour) setOnBoardTourRunState(true);
else setBotBuilderTourState(true);
setTourDialogVisibility(false);
};
const header_text_size = is_mobile ? 'xs' : 's';
const content_text_size = is_mobile ? 'xxs' : 'xs';

const tour_headers = active_tab === 0 ? onboarding_tour_header : bot_builder_tour_header;

return (
<div>
<Dialog
is_visible={is_tour_dialog_visible}
cancel_button_text={localize('Skip')}
onCancel={() => toggleTour(false, 'onCancel')}
confirm_button_text={localize('Start')}
onConfirm={onHandleConfirm}
is_mobile_full_width
className={classNames('dc-dialog tour-dialog', {
'tour-dialog--end': has_tour_ended,
})}
has_close_icon={false}
>
<div className='dc-dialog__content__header'>
<Text weight='bold' color='prominent' size={header_text_size}>
{tour_headers}
</Text>
</div>
<div className='dc-dialog__content__description'>
<Text size={content_text_size} color='prominent'>
{getTourContent()}
</Text>
</div>
</Dialog>
</div>
);
});

export default TourStartDialog;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { mockStore, StoreProvider } from '@deriv/stores';
import { render, screen } from '@testing-library/react';
import { mock_ws } from 'Utils/mock';
import RootStore from 'Stores/root-store';
import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore';
import BotBuilderTour from '../../mobile-tours/bot-builder-tour';
import OnboardingTour from '../../mobile-tours/onboarding-tour';
import { BOT_BUILDER_MOBILE, DBOT_ONBOARDING_MOBILE } from '../index';

jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn());
jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => jest.fn());
jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn());
jest.mock('@deriv/deriv-charts', () => ({
setSmartChartsPublicPath: jest.fn(),
}));
describe('Tour Config Data', () => {
let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element, mock_DBot_store: RootStore | undefined;

beforeEach(() => {
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('DBOT_ONBOARDING_MOBILE is called', () => {
render(<OnboardingTour />, {
wrapper,
});
const first_step = DBOT_ONBOARDING_MOBILE[0];
expect(screen.getByText(first_step.header)).toBeInTheDocument();
});

it('BOT_BUILDER_MOBILE is called', () => {
render(<BotBuilderTour />, {
wrapper,
});
const first_step = BOT_BUILDER_MOBILE[0];
expect(screen.getByText(first_step.header)).toBeInTheDocument();
});
});
Loading