Skip to content

Commit

Permalink
fix: Fixed inconsistent left drawer expansion/collapse behavior (Pali…
Browse files Browse the repository at this point in the history
…sadoesFoundation#1903)

- Adjusted the left drawer component to function properly on screens with a width of 820px or less.
- Ensured smooth expansion and collapse of the left drawer when clicked.
- Ensured the overflow-y of content is handled in smaller screens.
- Modified the changes for organization dashboard screens to match the superadmin screens when the left drawer is collapsed.
- Covered the changes with tests.
- Ensured no other functionality got affected.

Signed-off-by: Akhilender <[email protected]>
  • Loading branch information
akhilender-bongirwar authored Apr 14, 2024
1 parent 2c36281 commit e50da8a
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 67 deletions.
29 changes: 28 additions & 1 deletion src/components/LeftDrawer/LeftDrawer.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import 'jest-localstorage-mock';
import { I18nextProvider } from 'react-i18next';
Expand All @@ -20,6 +20,11 @@ const props = {
setHideDrawer: jest.fn(),
};

const resizeWindow = (width: number): void => {
window.innerWidth = width;
fireEvent(window, new Event('resize'));
};

const propsOrg: InterfaceLeftDrawerProps = {
...props,
};
Expand Down Expand Up @@ -128,6 +133,28 @@ describe('Testing Left Drawer component for SUPERADMIN', () => {
</MockedProvider>,
);
});

test('Testing Drawer when the screen size is less than or equal to 820px', () => {
resizeWindow(800);
render(
<MockedProvider addTypename={false} link={link}>
<BrowserRouter>
<I18nextProvider i18n={i18nForTest}>
<LeftDrawer {...propsOrg} />
</I18nextProvider>
</BrowserRouter>
</MockedProvider>,
);
expect(screen.getByText('My Organizations')).toBeInTheDocument();
expect(screen.getByText('Talawa Admin Portal')).toBeInTheDocument();

const orgsBtn = screen.getByTestId(/orgsBtn/i);

orgsBtn.click();
expect(
orgsBtn.className.includes('text-white btn btn-success'),
).toBeTruthy();
});
});

describe('Testing Left Drawer component for ADMIN', () => {
Expand Down
17 changes: 13 additions & 4 deletions src/components/LeftDrawer/LeftDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@ export interface InterfaceLeftDrawerProps {
setHideDrawer: React.Dispatch<React.SetStateAction<boolean | null>>;
}

const leftDrawer = ({ hideDrawer }: InterfaceLeftDrawerProps): JSX.Element => {
const leftDrawer = ({
hideDrawer,
setHideDrawer,
}: InterfaceLeftDrawerProps): JSX.Element => {
const { t } = useTranslation('translation', { keyPrefix: 'leftDrawer' });

const { getItem } = useLocalStorage();
const superAdmin = getItem('SuperAdmin');

const handleLinkClick = (): void => {
if (window.innerWidth <= 820) {
setHideDrawer(true);
}
};

return (
<>
<div
Expand All @@ -36,7 +45,7 @@ const leftDrawer = ({ hideDrawer }: InterfaceLeftDrawerProps): JSX.Element => {
<p className={styles.talawaText}>{t('talawaAdminPortal')}</p>
<h5 className={`${styles.titleHeader} text-secondary`}>{t('menu')}</h5>
<div className={styles.optionList}>
<NavLink to={'/orglist'}>
<NavLink to={'/orglist'} onClick={handleLinkClick}>
{({ isActive }) => (
<Button
variant={isActive === true ? 'success' : ''}
Expand All @@ -60,7 +69,7 @@ const leftDrawer = ({ hideDrawer }: InterfaceLeftDrawerProps): JSX.Element => {
</NavLink>
{superAdmin && (
<>
<NavLink to={'/users'}>
<NavLink to={'/users'} onClick={handleLinkClick}>
{({ isActive }) => (
<Button
variant={isActive === true ? 'success' : ''}
Expand All @@ -82,7 +91,7 @@ const leftDrawer = ({ hideDrawer }: InterfaceLeftDrawerProps): JSX.Element => {
</Button>
)}
</NavLink>
<NavLink to={'/communityProfile'}>
<NavLink to={'/communityProfile'} onClick={handleLinkClick}>
{({ isActive }) => (
<Button
variant={isActive === true ? 'success' : ''}
Expand Down
1 change: 1 addition & 0 deletions src/components/LeftDrawerOrg/LeftDrawerOrg.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@

.leftDrawer .optionList {
height: 100%;
overflow-y: auto;
}

.leftDrawer .optionList button {
Expand Down
32 changes: 31 additions & 1 deletion src/components/LeftDrawerOrg/LeftDrawerOrg.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import 'jest-localstorage-mock';
import { I18nextProvider } from 'react-i18next';
Expand Down Expand Up @@ -240,6 +240,12 @@ async function wait(ms = 100): Promise<void> {
});
});
}

const resizeWindow = (width: number): void => {
window.innerWidth = width;
fireEvent(window, new Event('resize'));
};

beforeEach(() => {
setItem('FirstName', 'John');
setItem('LastName', 'Doe');
Expand Down Expand Up @@ -322,6 +328,30 @@ describe('Testing LeftDrawerOrg component for SUPERADMIN', () => {
expect(global.window.location.pathname).toContain('/orgdash/id=123');
});

test('Testing when screen size is less than 820px', async () => {
setItem('SuperAdmin', true);
render(
<MockedProvider addTypename={false} link={link}>
<BrowserRouter>
<Provider store={store}>
<I18nextProvider i18n={i18nForTest}>
<LeftDrawerOrg {...props} />
</I18nextProvider>
</Provider>
</BrowserRouter>
</MockedProvider>,
);
await wait();
resizeWindow(800);
expect(screen.getByText(/Dashboard/i)).toBeInTheDocument();
expect(screen.getByText(/People/i)).toBeInTheDocument();

const peopelBtn = screen.getByTestId(/People/i);
userEvent.click(peopelBtn);
await wait();
expect(window.location.pathname).toContain('/orgpeople/id=123');
});

test('Testing when image is present for Organization', async () => {
setItem('UserImage', '');
setItem('SuperAdmin', true);
Expand Down
9 changes: 8 additions & 1 deletion src/components/LeftDrawerOrg/LeftDrawerOrg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const leftDrawerOrg = ({
targets,
orgId,
hideDrawer,
setHideDrawer,
}: InterfaceLeftDrawerProps): JSX.Element => {
const { t } = useTranslation('translation', { keyPrefix: 'leftDrawerOrg' });
const [showDropdown, setShowDropdown] = React.useState(false);
Expand Down Expand Up @@ -53,6 +54,12 @@ const leftDrawerOrg = ({
};
}, [data]);

const handleLinkClick = (): void => {
if (window.innerWidth <= 820) {
setHideDrawer(true);
}
};

return (
<>
<div
Expand Down Expand Up @@ -122,7 +129,7 @@ const leftDrawerOrg = ({
</h5>
{targets.map(({ name, url }, index) => {
return url ? (
<NavLink to={url} key={name}>
<NavLink to={url} key={name} onClick={handleLinkClick}>
{({ isActive }) => (
<Button
key={name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,14 @@

@media (max-width: 1120px) {
.contract {
padding-left: calc(250px + 2rem + 1.5rem);
padding-left: calc(276px + 2rem + 1.5rem);
}
.collapseSidebarButton {
width: calc(250px + 2rem);
}
}

@media (max-height: 900px) {
.pageContainer {
padding: 1rem 1.5rem 0 calc(300px + 2rem);
}
.collapseSidebarButton {
height: 30px;
width: calc(300px + 1rem);
Expand Down
11 changes: 4 additions & 7 deletions src/components/OrganizationScreen/OrganizationScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import i18nForTest from 'utils/i18nForTest';
import OrganizationScreen from './OrganizationScreen';
import { ORGANIZATIONS_LIST } from 'GraphQl/Queries/Queries';
import { StaticMockLink } from 'utils/StaticMockLink';
import useLocalStorage from 'utils/useLocalstorage';

const { setItem } = useLocalStorage();

let mockID: string | undefined = '123';
jest.mock('react-router-dom', () => ({
Expand Down Expand Up @@ -85,21 +82,21 @@ describe('Testing LeftDrawer in OrganizationScreen', () => {
</BrowserRouter>
</MockedProvider>,
);
const toggleButton = screen.getByTestId('toggleMenuBtn') as HTMLElement;
const toggleButton = screen.getByTestId('closeMenu') as HTMLElement;
const icon = toggleButton.querySelector('i');

// Resize window to a smaller width
resizeWindow(800);
clickToggleMenuBtn(toggleButton);
expect(icon).toHaveClass('fa fa-angle-double-right');
expect(icon).toHaveClass('fa fa-angle-double-left');
// Resize window back to a larger width

resizeWindow(1000);
clickToggleMenuBtn(toggleButton);
expect(icon).toHaveClass('fa fa-angle-double-left');
expect(icon).toHaveClass('fa fa-angle-double-right');

clickToggleMenuBtn(toggleButton);
expect(icon).toHaveClass('fa fa-angle-double-right');
expect(icon).toHaveClass('fa fa-angle-double-left');
});

test('should be redirected to / if orgId is undefined', async () => {
Expand Down
46 changes: 25 additions & 21 deletions src/components/OrganizationScreen/OrganizationScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { RootState } from 'state/reducers';
import type { TargetsType } from 'state/reducers/routesReducer';
import styles from './OrganizationScreen.module.css';
import ProfileDropdown from 'components/ProfileDropdown/ProfileDropdown';
import { Button } from 'react-bootstrap';

const OrganizationScreen = (): JSX.Element => {
const location = useLocation();
Expand All @@ -31,39 +32,42 @@ const OrganizationScreen = (): JSX.Element => {
}, [orgId]); // Added orgId to the dependency array

const handleResize = (): void => {
if (window.innerWidth <= 820 && !hideDrawer) {
setHideDrawer(true);
if (window.innerWidth <= 820) {
setHideDrawer(!hideDrawer);
}
};

const toggleDrawer = (): void => {
setHideDrawer(!hideDrawer);
};

useEffect(() => {
handleResize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, [hideDrawer]);
}, []);

return (
<>
<button
className={
hideDrawer ? styles.opendrawer : styles.collapseSidebarButton
}
onClick={toggleDrawer}
data-testid="toggleMenuBtn"
>
<i
className={
hideDrawer ? 'fa fa-angle-double-right' : 'fa fa-angle-double-left'
}
aria-hidden="true"
></i>
</button>
{hideDrawer ? (
<Button
className={styles.opendrawer}
onClick={(): void => {
setHideDrawer(!hideDrawer);
}}
data-testid="openMenu"
>
<i className="fa fa-angle-double-right" aria-hidden="true"></i>
</Button>
) : (
<Button
className={styles.collapseSidebarButton}
onClick={(): void => {
setHideDrawer(!hideDrawer);
}}
data-testid="closeMenu"
>
<i className="fa fa-angle-double-left" aria-hidden="true"></i>
</Button>
)}
<div className={styles.drawer}>
<LeftDrawerOrg
orgId={orgId}
Expand Down
11 changes: 4 additions & 7 deletions src/components/SuperAdminScreen/SuperAdminScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import { BrowserRouter } from 'react-router-dom';
import { store } from 'state/store';
import i18nForTest from 'utils/i18nForTest';
import SuperAdminScreen from './SuperAdminScreen';
import useLocalStorage from 'utils/useLocalstorage';

const { setItem } = useLocalStorage();

const resizeWindow = (width: number): void => {
window.innerWidth = width;
Expand All @@ -35,20 +32,20 @@ describe('Testing LeftDrawer in SuperAdminScreen', () => {
</MockedProvider>,
);

const toggleButton = screen.getByTestId('toggleMenuBtn') as HTMLElement;
const toggleButton = screen.getByTestId('closeMenu') as HTMLElement;
const icon = toggleButton.querySelector('i');

// Resize window to a smaller width
resizeWindow(800);
clickToggleMenuBtn(toggleButton);
expect(icon).toHaveClass('fa fa-angle-double-right');
expect(icon).toHaveClass('fa fa-angle-double-left');

// Resize window back to a larger width
resizeWindow(1000);
clickToggleMenuBtn(toggleButton);
expect(icon).toHaveClass('fa fa-angle-double-left');
expect(icon).toHaveClass('fa fa-angle-double-right');

clickToggleMenuBtn(toggleButton);
expect(icon).toHaveClass('fa fa-angle-double-right');
expect(icon).toHaveClass('fa fa-angle-double-left');
});
});
Loading

0 comments on commit e50da8a

Please sign in to comment.