Skip to content

feat: close sidebar on mobile after selecting a unit #62

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

Open
wants to merge 1 commit into
base: opencraft-release/redwood.1
Choose a base branch
from
Open
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 { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/ana

import { checkBlockCompletion } from '@src/courseware/data';
import { getCourseOutline } from '@src/courseware/data/selectors';
import { useCourseOutlineSidebar } from '../hooks';
import messages from '../messages';
import UnitIcon, { UNIT_ICON_TYPES } from './UnitIcon';

Expand All @@ -28,6 +29,7 @@ const SidebarUnit = ({
} = unit;
const dispatch = useDispatch();
const { sequences = {} } = useSelector(getCourseOutline);
const { handleToggleCollapse, shouldDisplayFullScreen } = useCourseOutlineSidebar();

const logEvent = (eventName, widgetPlacement) => {
const findSequenceByUnitId = (unitId) => Object.values(sequences).find(seq => seq.unitIds.includes(unitId));
Expand All @@ -53,6 +55,11 @@ const SidebarUnit = ({
const handleClick = () => {
logEvent('edx.ui.lms.sequence.tab_selected', 'left');
dispatch(checkBlockCompletion(courseId, sequenceId, activeUnitId));

// Hide the sidebar after selecting a unit on a mobile device.
if (shouldDisplayFullScreen) {
handleToggleCollapse();
}
};

const iconType = isLocked ? UNIT_ICON_TYPES.lock : icon;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { sendTrackEvent, sendTrackingLogEvent } from '@edx/frontend-platform/ana

import { initializeMockApp, initializeTestStore } from '@src/setupTest';
import SidebarUnit from './SidebarUnit';
import SidebarContext from '../../../SidebarContext';
import { ID } from '../constants';

jest.mock('@edx/frontend-platform/analytics', () => ({
sendTrackEvent: jest.fn(),
Expand All @@ -20,6 +22,13 @@ describe('<SidebarUnit />', () => {
let unit;
let sequenceId;

// A default context for desktop mode.
const defaultSidebarContext = {
toggleSidebar: jest.fn(),
shouldDisplayFullScreen: false,
currentSidebar: ID,
};

const initTestStore = async (options) => {
store = await initializeTestStore(options);
const state = store.getState();
Expand All @@ -28,21 +37,23 @@ describe('<SidebarUnit />', () => {
unit = state.courseware.courseOutline.units[sequence.unitIds[0]];
};

function renderWithProvider(props = {}) {
function renderWithProvider(props = {}, sidebarContext = defaultSidebarContext) {
const { container } = render(
<AppProvider store={store} wrapWithRouter={false}>
<IntlProvider locale="en">
<MemoryRouter>
<SidebarUnit
isFirst
id={unit.id}
courseId="course123"
sequenceId={sequenceId}
unit={{ ...unit, icon: 'video', isLocked: false }}
isActive={false}
activeUnitId={unit.id}
{...props}
/>
<SidebarContext.Provider value={sidebarContext}>
<SidebarUnit
isFirst
id={unit.id}
courseId="course123"
sequenceId={sequenceId}
unit={{ ...unit, icon: 'video', isLocked: false }}
isActive={false}
activeUnitId={unit.id}
{...props}
/>
</SidebarContext.Provider>
</MemoryRouter>
</IntlProvider>
</AppProvider>,
Expand Down Expand Up @@ -87,21 +98,42 @@ describe('<SidebarUnit />', () => {
expect(screen.getByText(unit.title)).toBeInTheDocument();
});

it('sends log event correctly when unit is clicked', async () => {
await initTestStore();
renderWithProvider({ unit: { ...unit } });
const logData = {
id: unit.id,
current_tab: 1,
tab_count: 1,
target_id: unit.id,
target_tab: 1,
widget_placement: 'left',
};

userEvent.click(screen.getByText(unit.title));

expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData);
expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData);
describe('When a unit is clicked', () => {
it('sends log event correctly', async () => {
await initTestStore();
renderWithProvider({ unit: { ...unit } });
const logData = {
id: unit.id,
current_tab: 1,
tab_count: 1,
target_id: unit.id,
target_tab: 1,
widget_placement: 'left',
};

userEvent.click(screen.getByText(unit.title));

expect(sendTrackEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData);
expect(sendTrackingLogEvent).toHaveBeenCalledWith('edx.ui.lms.sequence.tab_selected', logData);
});

it('leaves sidebar open in desktop mode', async () => {
await initTestStore();
renderWithProvider({ unit: { ...unit } });
userEvent.click(screen.getByText(unit.title));

expect(defaultSidebarContext.toggleSidebar).not.toHaveBeenCalled();
expect(window.sessionStorage.getItem('hideCourseOutlineSidebar')).toBeNull();
});

it('closes sidebar on mobile devices', async () => {
await initTestStore();
renderWithProvider({ unit: { ...unit } }, { ...defaultSidebarContext, shouldDisplayFullScreen: true });
userEvent.click(screen.getByText(unit.title));

expect(defaultSidebarContext.toggleSidebar).toHaveBeenCalledTimes(1);
expect(defaultSidebarContext.toggleSidebar).toHaveBeenCalledWith(null);
expect(window.sessionStorage.getItem('hideCourseOutlineSidebar')).toEqual('true');
});
});
});
Loading