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

chore: edit application functionality #31

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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { render, screen } from '@site/src/test-utils';
import React from 'react';
import ApiTokenNavbarItem from '..';
import { TTokensArrayType } from '@site/src/types';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

jest.mock('@site/src/hooks/useApiToken');
const mockUseApiToken = useApiToken as jest.MockedFunction<
Expand Down Expand Up @@ -162,7 +163,7 @@ describe('Api Token Navbar Item', () => {
await userEvent.click(create_token);

expect(mockUpdateCurrentTab).toHaveBeenCalledTimes(1);
expect(mockUpdateCurrentTab).toHaveBeenCalledWith('MANAGE_TOKENS');
expect(mockUpdateCurrentTab).toHaveBeenCalledWith(TDashboardTab.MANAGE_TOKENS);
});

it('Should render token in drop down', async () => {
Expand Down
9 changes: 6 additions & 3 deletions src/components/ApiTokenNavbarItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import useOnClickOutside from '@site/src/hooks/useOnClickOutside';
import useAppManager from '@site/src/hooks/useAppManager';
import styles from './api_token_switcher.module.scss';
import RenderOfficialContents from '../RenderOfficialContents';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

const ApiTokenNavbarItem = () => {
const { is_logged_in, is_authorized } = useAuthContext();
Expand All @@ -15,7 +16,9 @@ const ApiTokenNavbarItem = () => {
const { updateCurrentTab, currentTab, is_dashboard } = useAppManager();
const toggle_dropdown = is_toggle_dropdown ? styles.active : '';
const has_one_token =
tokens.length <= 1 && is_dashboard && currentTab === 'MANAGE_TOKENS' ? styles.oneToken : '';
tokens.length <= 1 && is_dashboard && currentTab === TDashboardTab.MANAGE_TOKENS
? styles.oneToken
: '';

const dropdownRef = useRef(null);

Expand All @@ -26,13 +29,13 @@ const ApiTokenNavbarItem = () => {
}

const CreateToken = () => {
const is_not_on_manage_tab = is_dashboard && !(currentTab === 'MANAGE_TOKENS');
const is_not_on_manage_tab = is_dashboard && !(currentTab === TDashboardTab.MANAGE_TOKENS);
return (
<React.Fragment>
{(is_not_on_manage_tab || !is_dashboard) && (
<div className={styles.tokenContainer}>
<Link
onClick={() => updateCurrentTab('MANAGE_TOKENS')}
onClick={() => updateCurrentTab(TDashboardTab.MANAGE_TOKENS)}
className={styles.createToken}
to='/dashboard'
>
Expand Down
7 changes: 6 additions & 1 deletion src/contexts/app-manager/app-manager.context.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { ApplicationObject } from '@deriv/api-types';
import { createContext, Dispatch, SetStateAction } from 'react';

export type TDashboardTab = 'MANAGE_TOKENS' | 'REGISTER_APP' | 'MANAGE_APPS';
export enum TDashboardTab {
MANAGE_TOKENS,
REGISTER_APP,
MANAGE_APPS,
UPDATE_APP,
}

export type TAppManagerContext = {
apps: ApplicationObject[];
Expand Down
2 changes: 1 addition & 1 deletion src/contexts/app-manager/app-manager.provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type TAppManagerContextProps = {

const AppManagerContextProvider = ({ children }: TAppManagerContextProps) => {
const [apps, setApps] = useState<ApplicationObject[]>([]);
const [currentTab, setCurrentTab] = useState<TDashboardTab>('MANAGE_APPS');
const [currentTab, setCurrentTab] = useState<TDashboardTab>(TDashboardTab.MANAGE_APPS);
const [is_dashboard, setIsDashboard] = useState(false);
const [app_register_modal_open, setAppRegisterModalOpen] = useState(false);
const { getAllApps, apps: updatedApps } = useGetApps();
Expand Down
14 changes: 9 additions & 5 deletions src/features/dashboard/components/AppsTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Table from '../Table';
import UpdateAppDialog from '../Dialogs/UpdateAppDialog';
import clsx from 'clsx';
import './apps-table.scss';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

export type TAppColumn = Column<ApplicationObject>;

Expand Down Expand Up @@ -56,9 +57,10 @@ interface AppsTableProps extends HTMLAttributes<HTMLTableElement> {
apps: ApplicationObject[];
}

const AppsTableHeader: React.FC<{ is_desktop: boolean }> = ({ is_desktop }) => {
const { updateCurrentTab } = useAppManager();

const AppsTableHeader: React.FC<{
is_desktop: boolean;
updateCurrentTab: (tab: TDashboardTab) => void;
}> = ({ is_desktop, updateCurrentTab }) => {
return (
<div
className={clsx('apps_table__header', {
Expand All @@ -81,7 +83,7 @@ const AppsTableHeader: React.FC<{ is_desktop: boolean }> = ({ is_desktop }) => {
icon={LabelPairedCirclePlusMdRegularIcon}
className='apps_table__header__button'
onClick={() => {
updateCurrentTab('REGISTER_APP');
updateCurrentTab(TDashboardTab.REGISTER_APP);
}}
>
Register new application
Expand All @@ -94,6 +96,7 @@ const AppsTable = ({ apps }: AppsTableProps) => {
const [isDeleteOpen, setIsDeleteOpen] = useState(false);
const [isEditOpen, setIsEditOpen] = useState(false);
const [actionRow, setActionRow] = useState<ApplicationObject>();
const { updateCurrentTab } = useAppManager();
const { deviceType } = useDeviceType();
const is_desktop = deviceType === 'desktop';

Expand All @@ -107,6 +110,7 @@ const AppsTable = ({ apps }: AppsTableProps) => {
openEditDialog: () => {
setActionRow(item);
// setIsEditOpen(true);
updateCurrentTab(TDashboardTab.UPDATE_APP);
},
};
}, []);
Expand Down Expand Up @@ -157,7 +161,7 @@ const AppsTable = ({ apps }: AppsTableProps) => {
{isDeleteOpen && <DeleteAppDialog appId={actionRow.app_id} onClose={onCloseDelete} />}
{isEditOpen && <UpdateAppDialog app={actionRow} onClose={onCloseEdit} />}
<div>
<AppsTableHeader is_desktop={is_desktop} />
<AppsTableHeader is_desktop={is_desktop} updateCurrentTab={updateCurrentTab} />
{apps?.length ? renderTable() : null}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { render, screen, cleanup } from '@site/src/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { RegisterAppDialogSuccess } from '..';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

jest.mock('@site/src/hooks/useAppManager');

Expand All @@ -13,7 +14,7 @@ const mockUseAppManager = useAppManager as jest.MockedFunction<
>;

mockUseAppManager.mockImplementation(() => ({
updateCurrentTab: mockUpdateCurrentTab,
updateCurrentTab: mockUpdateCurrentTab as jest.MockedFunction<(tab: TDashboardTab) => void>,
}));

describe('App Dialog Register Success', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import { Button, Modal } from '@deriv/ui';
import useAppManager from '@site/src/hooks/useAppManager';
import styles from './register-app-dialog-success.module.scss';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

interface IRegisterAppDialogSuccessProps {
onClose: () => void;
Expand All @@ -11,7 +12,7 @@ export const RegisterAppDialogSuccess = ({ onClose }: IRegisterAppDialogSuccessP
const { updateCurrentTab } = useAppManager();

const onSuccessfulClick = () => {
updateCurrentTab('MANAGE_APPS');
updateCurrentTab(TDashboardTab.MANAGE_APPS);
window.open('https://t.me/+g6FV5tFY1u9lZGE1', '_blank');
onClose();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { render, cleanup, screen } from '@site/src/test-utils';
import userEvent from '@testing-library/user-event';
import React from 'react';
import NoApps from '..';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

jest.mock('@site/src/hooks/useAppManager');

Expand Down Expand Up @@ -39,6 +40,6 @@ describe('No Apps', () => {
await userEvent.click(registerNowButton);

expect(mockUpdateCurrentTab).toHaveBeenCalledTimes(1);
expect(mockUpdateCurrentTab).toHaveBeenCalledWith('REGISTER_APP');
expect(mockUpdateCurrentTab).toHaveBeenCalledWith(TDashboardTab.REGISTER_APP);
});
});
3 changes: 2 additions & 1 deletion src/features/dashboard/components/NoApps/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import React, { useCallback } from 'react';
import styles from './no-apps.module.scss';
import { Button, Text } from '@deriv/ui';
import useAppManager from '@site/src/hooks/useAppManager';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

const NoApps = () => {
const { updateCurrentTab } = useAppManager();

const onRegisterClick = useCallback(() => {
updateCurrentTab('REGISTER_APP');
updateCurrentTab(TDashboardTab.REGISTER_APP);
}, [updateCurrentTab]);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const mockUseAppManager = useAppManager as jest.MockedFunction<
() => Partial<ReturnType<typeof useAppManager>>
>;

let mockCurrentTab: TDashboardTab = 'MANAGE_TOKENS';
let mockCurrentTab: TDashboardTab = TDashboardTab.MANAGE_TOKENS;

const mockUpdateCurrentTab = jest.fn().mockImplementation((newTab: TDashboardTab) => {
mockCurrentTab = newTab;
Expand All @@ -29,7 +29,7 @@ describe('Dashboard Tabs', () => {

afterEach(() => {
cleanup();
mockCurrentTab = 'MANAGE_TOKENS';
mockCurrentTab = TDashboardTab.MANAGE_TOKENS;
jest.clearAllMocks();
});

Expand Down Expand Up @@ -64,6 +64,6 @@ describe('Dashboard Tabs', () => {
await userEvent.click(registerApplicationTab);

expect(mockUpdateCurrentTab).toBeCalled();
expect(mockUpdateCurrentTab).toBeCalledWith('REGISTER_APP');
expect(mockUpdateCurrentTab).toBeCalledWith(TDashboardTab.REGISTER_APP.toString());
});
});
22 changes: 16 additions & 6 deletions src/features/dashboard/components/Tabs/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ type TTab = {
const tabs: TTab[] = [
{
id: 0,
value: 'MANAGE_TOKENS',
value: TDashboardTab.MANAGE_TOKENS,
label: 'Manage tokens',
content: ApiToken,
},
{
id: 1,
value: 'REGISTER_APP',
value: TDashboardTab.REGISTER_APP,
label: 'Register application',
content: AppRegistration,
},
{
id: 2,
value: 'MANAGE_APPS',
value: TDashboardTab.MANAGE_APPS,
label: 'Manage applications',
content: AppManagement,
},
Expand All @@ -49,10 +49,20 @@ const DashboardTabs = () => {
Register your app, get an app ID, and start using the Deriv API
</Text>
</div>
<Tabs.Root className={styles.tabs_root} value={currentTab} onValueChange={updateCurrentTab}>
<Tabs.Root
className={styles.tabs_root}
value={currentTab.toString()}
onValueChange={(tab) => {
updateCurrentTab(tab as unknown as TDashboardTab);
}}
>
<Tabs.List className={styles.tabs_list}>
{tabs.map((item) => (
<Tabs.Trigger className={styles.tabs_trigger} key={item.id} value={item.value}>
<Tabs.Trigger
className={styles.tabs_trigger}
key={item.id}
value={item.value?.toString()}
>
<Text as={'h3'} type={'paragraph-1'}>
{item.label}
</Text>
Expand All @@ -61,7 +71,7 @@ const DashboardTabs = () => {
</Tabs.List>
<>
{tabs.map(({ id, value, content: Content }) => (
<Tabs.Content key={id} value={value}>
<Tabs.Content key={id} value={value?.toString()}>
<div className={styles.tab_content}>
<Content />
</div>
Expand Down
13 changes: 9 additions & 4 deletions src/features/dashboard/manage-dashboard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { RegisterAppDialogError } from '../components/Dialogs/RegisterAppDialogE
import { AppRegisterSuccessModal } from '../components/Modals/AppRegisterSuccessModal';
import AppManagement from '../manage-apps';
import './manage-dashboard.scss';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

const ManageDashboard = () => {
const { apps, getApps, setAppRegisterModalOpen, currentTab, updateCurrentTab } = useAppManager();
Expand All @@ -36,9 +37,9 @@ const ManageDashboard = () => {

useEffect(() => {
if (!apps?.length && !tokens?.length) {
updateCurrentTab('REGISTER_APP');
updateCurrentTab(TDashboardTab.REGISTER_APP);
} else {
updateCurrentTab('MANAGE_APPS');
updateCurrentTab(TDashboardTab.MANAGE_APPS);
}
}, [tokens, apps, updateCurrentTab]);

Expand All @@ -62,10 +63,14 @@ const ManageDashboard = () => {

const renderScreen = () => {
switch (currentTab) {
case 'REGISTER_APP':
case TDashboardTab.REGISTER_APP:
return <AppRegister submit={submit} />;
case 'MANAGE_APPS':
case TDashboardTab.MANAGE_APPS:
return <AppManagement />;
case TDashboardTab.UPDATE_APP:
return (
<div className='app_dashboard_container_top'>Update app will be developed later</div>
);
default:
return <AppRegister submit={submit} />;
}
Expand Down
7 changes: 4 additions & 3 deletions src/hooks/useAppManager/__tests__/useAppManager.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import useAuthContext from '../../useAuthContext';
import AppManagerContextProvider from '@site/src/contexts/app-manager/app-manager.provider';
import makeMockSocket from '@site/src/__mocks__/socket.mock';
import { cleanup } from '@testing-library/react';
import { TDashboardTab } from '@site/src/contexts/app-manager/app-manager.context';

const connection = makeMockSocket();

Expand Down Expand Up @@ -52,15 +53,15 @@ describe('use App Manager', () => {

it('Should have MANAGE_APPS as initial value for currentTab', () => {
const { result } = renderHook(() => useAppManager(), { wrapper });
expect(result.current.currentTab).toBe('MANAGE_APPS');
expect(result.current.currentTab).toBe(TDashboardTab.MANAGE_APPS);
});

it('Should update currentTab value', () => {
const { result } = renderHook(() => useAppManager(), { wrapper });
act(() => {
result.current.updateCurrentTab('REGISTER_APP');
result.current.updateCurrentTab(TDashboardTab.REGISTER_APP);
});
expect(result.current.currentTab).toBe('REGISTER_APP');
expect(result.current.currentTab).toBe(TDashboardTab.REGISTER_APP);
});

it('Should set is_dashboard to truthy when user visits dashboard tab', () => {
Expand Down