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

george / rm65047 / convert routes, cashier, error-component components to TS #6361

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 9 additions & 13 deletions packages/cashier/src/components/error-dialog/error-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ import { Dialog } from '@deriv/components';
import { localize, Localize } from '@deriv/translations';
import { routes } from '@deriv/shared';
import { connect } from 'Stores/connect';
import { RootStore, TReactElement } from 'Types';
import { RootStore, TError, TReactElement } from 'Types';

type TErrorDialogProps = {
disableApp: () => void;
enableApp: () => void;
error: {
message?: string;
code?: string;
setErrorMessage?: (message: string) => void;
};
error: TError | Record<string, never>;
};

type TSetDetails = {
Expand All @@ -36,6 +32,13 @@ const ErrorDialog = ({ disableApp, enableApp, error = {} }: TErrorDialogProps) =
message: '',
});

const dismissError = React.useCallback(() => {
if (error.setErrorMessage) {
error.setErrorMessage('', null, false);
}
setErrorVisibility(false);
}, [error]);

const mapErrorToDetails = React.useCallback(
(error_code?: string, error_message?: string) => {
if (
Expand Down Expand Up @@ -118,13 +121,6 @@ const ErrorDialog = ({ disableApp, enableApp, error = {} }: TErrorDialogProps) =
setIsVisible(is_error_visible);
};

const dismissError = React.useCallback(() => {
if (error.setErrorMessage) {
error.setErrorMessage('');
}
setErrorVisibility(false);
}, [error]);

return (
<Dialog
title={details.title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { routes, moduleLoader } from '@deriv/shared';
import { localize } from '@deriv/translations';
import { Cashier } from '../containers';
import { AccountTransfer, Deposit, OnRamp, P2PCashier, PaymentAgent, PaymentAgentTransfer, Withdrawal } from '../pages';
import { TRouteConfig, TRoute } from 'Types';

// Error Routes
const Page404 = React.lazy(() => moduleLoader(() => import(/* webpackChunkName: "404" */ 'Components/page-404')));
export type TPage404 = typeof Page404;

// Order matters
const initRoutesConfig = () => [
const initRoutesConfig = (): TRouteConfig[] => [
{
path: routes.cashier,
component: Cashier,
Expand Down Expand Up @@ -72,14 +74,14 @@ const initRoutesConfig = () => [
},
];

let routesConfig;
let routesConfig: undefined | TRouteConfig[];

// For default page route if page/path is not found, must be kept at the end of routes_config array
const route_default = { component: Page404, getTitle: () => localize('Error 404') };
const route_default: TRoute = { component: Page404, getTitle: () => localize('Error 404') };

const getRoutesConfig = ({ is_appstore }) => {
const getRoutesConfig = (): TRouteConfig[] => {
heorhi-deriv marked this conversation as resolved.
Show resolved Hide resolved
if (!routesConfig) {
routesConfig = initRoutesConfig({ is_appstore });
heorhi-deriv marked this conversation as resolved.
Show resolved Hide resolved
routesConfig = initRoutesConfig();
routesConfig.push(route_default);
}
return routesConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createBrowserHistory } from 'history';
import { Router } from 'react-router';
import { isMobile } from '@deriv/shared';
import getRoutesConfig from 'Constants/routes-config';
import Cashier from '../cashier.jsx';
import Cashier from '../cashier';

jest.mock('Stores/connect', () => ({
__esModule: true,
Expand Down Expand Up @@ -58,7 +58,7 @@ describe('<Cashier />', () => {
is_p2p_enabled: true,
is_onramp_tab_visible: true,
is_visible: true,
routes: getRoutesConfig({})[0].routes,
routes: getRoutesConfig()[0].routes,
routeBackInApp: jest.fn(),
onMount: jest.fn(),
setAccountSwitchListener: jest.fn(),
Expand Down Expand Up @@ -121,7 +121,7 @@ describe('<Cashier />', () => {
});

it('should show the selected route page on mobile', () => {
isMobile.mockReturnValue(true);
(isMobile as jest.Mock).mockReturnValue(true);

renderWithRouter(<Cashier {...props} />);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import PropTypes from 'prop-types';
import { RouteComponentProps } from 'react-router';
import { withRouter } from 'react-router-dom';
import {
Button,
Expand All @@ -11,13 +11,50 @@ import {
VerticalTab,
Loading,
} from '@deriv/components';
import { localize } from '@deriv/translations';
import { getSelectedRoute, getStaticUrl, isMobile, routes, WS } from '@deriv/shared';
import { connect } from 'Stores/connect';
import { localize } from '@deriv/translations';
import AccountPromptDialog from 'Components/account-prompt-dialog';
import ErrorDialog from 'Components/error-dialog';
import { connect } from 'Stores/connect';
import { TClientStore, TCommonStore, TError, TRootStore, TRoute, TUiStore } from 'Types';
import './cashier.scss';

type TCashierProps = RouteComponentProps & {
error: TError;
is_account_transfer_visible: boolean;
is_account_setting_loaded: TClientStore['is_account_setting_loaded'];
is_cashier_onboarding: boolean;
is_crypto: boolean;
is_crypto_transactions_visible: boolean;
is_loading: boolean;
is_logged_in: TClientStore['is_logged_in'];
is_logging_in: TClientStore['is_logging_in'];
is_from_derivgo: TCommonStore['is_from_derivgo'];
is_onramp_tab_visible: boolean;
is_p2p_enabled: boolean;
is_payment_agent_transfer_visible: boolean;
is_payment_agent_visible: boolean;
is_visible: TUiStore['is_cashier_visible'];
p2p_notification_count: number;
routes: TRoute[];
tab_index: number;
onMount: (should_remount?: boolean) => void;
setAccountSwitchListener: () => void;
setTabIndex: (index: number) => void;
routeBackInApp: TCommonStore['routeBackInApp'];
toggleCashier: TUiStore['toggleCashier'];
};

type TCashierOptions = {
count?: number;
default?: boolean;
has_side_note: boolean;
icon?: string;
label: string;
path?: string;
value: TRoute['component'];
};

const Cashier = ({
error,
history,
Expand Down Expand Up @@ -45,7 +82,7 @@ const Cashier = ({
setTabIndex,
tab_index,
toggleCashier,
}) => {
}: TCashierProps) => {
React.useEffect(() => {
toggleCashier();
// we still need to populate the tabs shown on cashier
Expand All @@ -65,7 +102,7 @@ const Cashier = ({

const onClickClose = () => routeBackInApp(history);
const getMenuOptions = () => {
const options = [];
const options: TCashierOptions[] = [];
routes_config.forEach(route => {
if (
!route.is_invisible &&
Expand Down Expand Up @@ -179,36 +216,7 @@ const Cashier = ({
);
};

Cashier.propTypes = {
error: PropTypes.object,
history: PropTypes.object,
is_account_transfer_visible: PropTypes.bool,
is_account_setting_loaded: PropTypes.bool,
is_cashier_onboarding: PropTypes.bool,
is_crypto: PropTypes.bool,
is_crypto_transactions_visible: PropTypes.bool,
is_loading: PropTypes.bool,
is_logged_in: PropTypes.bool,
is_logging_in: PropTypes.bool,
is_from_derivgo: PropTypes.bool,
is_onramp_tab_visible: PropTypes.bool,
is_p2p_enabled: PropTypes.bool,
is_payment_agent_transfer_visible: PropTypes.bool,
is_payment_agent_visible: PropTypes.bool,
is_virtual: PropTypes.bool,
is_visible: PropTypes.bool,
location: PropTypes.object,
onMount: PropTypes.func,
p2p_notification_count: PropTypes.number,
routeBackInApp: PropTypes.func,
routes: PropTypes.arrayOf(PropTypes.object),
setAccountSwitchListener: PropTypes.func,
setTabIndex: PropTypes.func,
tab_index: PropTypes.number,
toggleCashier: PropTypes.func,
};

export default connect(({ client, common, modules, ui }) => ({
export default connect(({ client, common, modules, ui }: TRootStore) => ({
error: modules.cashier.withdraw.error,
is_cashier_onboarding: modules.cashier.general_store.is_cashier_onboarding,
is_account_transfer_visible: modules.cashier.account_transfer.is_account_transfer_visible,
Expand Down
3 changes: 0 additions & 3 deletions packages/cashier/src/containers/cashier/index.js

This file was deleted.

3 changes: 3 additions & 0 deletions packages/cashier/src/containers/cashier/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Cashier from './cashier';

export default Cashier;
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { expect } from 'chai';
import { configure, shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import { RouteWithSubRoutesRender } from '../route-with-sub-routes.jsx';
import { RouteWithSubRoutesRender } from '../route-with-sub-routes';
import { Redirect } from 'react-router-dom';

configure({ adapter: new Adapter() });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jest.mock('Stores/connect.js', () => ({
connect: () => Component => Component,
}));

jest.mock('../binary-routes', () => () => <div>BinaryRoutes</div>);
jest.mock('../binary-routes', () => jest.fn(() => 'BinaryRoutes'));

describe('<Routes />', () => {
it('should show error messages when "has_error = true"', () => {
Expand Down
29 changes: 0 additions & 29 deletions packages/cashier/src/containers/routes/binary-routes.jsx

This file was deleted.

32 changes: 32 additions & 0 deletions packages/cashier/src/containers/routes/binary-routes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { Switch } from 'react-router-dom';
import { Localize } from '@deriv/shared';
import getRoutesConfig from 'Constants/routes-config';
import RouteWithSubRoutes from './route-with-sub-routes';

type TBinaryRoutesProps = {
is_logged_in: boolean;
is_logging_in: boolean;
};

const Loading = () => {
return (
<div>
<Localize i18n_default_text='Loading...' />
</div>
);
};

const BinaryRoutes = (props: TBinaryRoutesProps) => {
return (
<React.Suspense fallback={<Loading />}>
<Switch>
{getRoutesConfig().map((route, idx: number) => (
<RouteWithSubRoutes key={idx} {...route} {...props} />
))}
</Switch>
</React.Suspense>
);
};

export default BinaryRoutes;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { screen, render, fireEvent } from '@testing-library/react';
import ErrorComponent from '../error-component.jsx';
import ErrorComponent from '../error-component';
import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

Expand All @@ -11,7 +11,7 @@ describe('<ErrorComponent/>', () => {
return render(<Router history={history}>{component}</Router>);
};
const reloadFn = () => {
window.location.reload(true);
window.location.reload();
};
beforeAll(() => {
Object.defineProperty(window, 'location', {
Expand Down Expand Up @@ -40,7 +40,7 @@ describe('<ErrorComponent/>', () => {
it('do not show refresh message when should_show_refresh is false', () => {
const refreshRequestText = screen.queryByText('Please refresh this page to continue.');
renderWithRouter(<ErrorComponent {...props} should_show_refresh={false} />);
expect(refreshRequestText).toBeNull();
expect(refreshRequestText).not.toBeInTheDocument();
});
it('should show default message when header message is not passed', () => {
const header = '';
Expand All @@ -66,13 +66,9 @@ describe('<ErrorComponent/>', () => {
});
it('should trigger the history.listen and call the setError function when redirect button get clicked', () => {
const redirectOnClick = jest.fn();
const history = createBrowserHistory();
const setError = jest.fn();
render(
<Router history={history}>
<ErrorComponent {...props} buttonOnClick={redirectOnClick} setError={setError} />
</Router>
);
renderWithRouter(<ErrorComponent {...props} buttonOnClick={redirectOnClick} setError={setError} />);

fireEvent.click(screen.getByText('testlabel'));
if (typeof setError === 'function') {
expect(setError).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import PropTypes from 'prop-types';
import React from 'react';
import { useHistory } from 'react-router-dom';
import { PageError } from '@deriv/components';
import { routes } from '@deriv/shared';
import { Localize } from '@deriv/translations';
import { TCommonStore } from 'Types';

const ErrorComponent = ({
header,
Expand All @@ -14,7 +14,7 @@ const ErrorComponent = ({
setError,
redirect_to = routes.trade,
should_show_refresh = true,
}) => {
}: TCommonStore['error']) => {
const history = useHistory();

React.useEffect(() => {
Expand Down Expand Up @@ -55,16 +55,4 @@ const ErrorComponent = ({
);
};

ErrorComponent.propTypes = {
header: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
message: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]),
redirect_label: PropTypes.string,
redirect_to: PropTypes.string,
redirectOnClick: PropTypes.func,
setError: PropTypes.func,
should_clear_error_on_click: PropTypes.bool,
should_show_refresh: PropTypes.bool,
type: PropTypes.string,
};

export default ErrorComponent;

This file was deleted.

Loading