diff --git a/src/courseware/course/Course.jsx b/src/courseware/course/Course.jsx
index 459d76bee0..76873b06e3 100644
--- a/src/courseware/course/Course.jsx
+++ b/src/courseware/course/Course.jsx
@@ -17,6 +17,7 @@ import SidebarProvider from './sidebar/SidebarContextProvider';
import SidebarTriggers from './sidebar/SidebarTriggers';
import { useModel } from '../../generic/model-store';
+import { getSessionStorage, setSessionStorage } from '../../data/sessionStorage';
const Course = ({
courseId,
@@ -31,6 +32,7 @@ const Course = ({
const {
celebrations,
isStaff,
+ verifiedMode,
} = useModel('courseHomeMeta', courseId);
const sequence = useModel('sequences', sequenceId);
const section = useModel('sections', sequence ? sequence.sectionId : null);
@@ -53,6 +55,16 @@ const Course = ({
const shouldDisplayTriggers = windowWidth >= breakpoints.small.minWidth;
const daysPerWeek = course?.courseGoals?.selectedGoal?.daysPerWeek;
+ // 1. open the notification tray if the user has not purchased the course and is on a desktop
+ // 2. default to close on the first time access
+ // 3. use the last state if the user has access the course before
+ const shouldDisplayNotificationTrayOpenOnLoad = windowWidth > breakpoints.medium.minWidth && !!verifiedMode;
+ if (shouldDisplayNotificationTrayOpenOnLoad) {
+ setSessionStorage(`notificationTrayStatus.${courseId}`, 'open');
+ } else if (!getSessionStorage(`notificationTrayStatus.${courseId}`)) {
+ setSessionStorage(`notificationTrayStatus.${courseId}`, 'closed');
+ }
+
useEffect(() => {
const celebrateFirstSection = celebrations && celebrations.firstSection;
setFirstSectionCelebrationOpen(shouldCelebrateOnSectionLoad(
diff --git a/src/courseware/course/Course.test.jsx b/src/courseware/course/Course.test.jsx
index 07349601e6..d2c60d8fbe 100644
--- a/src/courseware/course/Course.test.jsx
+++ b/src/courseware/course/Course.test.jsx
@@ -136,9 +136,9 @@ describe('Course', () => {
const notificationTrigger = screen.getByRole('button', { name: /Show notification tray/i });
expect(notificationTrigger).toBeInTheDocument();
- expect(notificationTrigger.parentNode).not.toHaveClass('mt-3', { exact: true });
- fireEvent.click(notificationTrigger);
expect(notificationTrigger.parentNode).toHaveClass('mt-3');
+ fireEvent.click(notificationTrigger);
+ expect(notificationTrigger.parentNode).not.toHaveClass('mt-3', { exact: true });
});
it('handles click to open/close discussions sidebar', async () => {
@@ -146,17 +146,17 @@ describe('Course', () => {
const discussionsTrigger = await screen.getByRole('button', { name: /Show discussions tray/i });
const discussionsSideBar = await waitFor(() => screen.findByTestId('sidebar-DISCUSSIONS'));
- expect(discussionsSideBar).toHaveClass('d-none');
+ expect(discussionsSideBar).not.toHaveClass('d-none');
await act(async () => {
fireEvent.click(discussionsTrigger);
});
- await expect(discussionsSideBar).not.toHaveClass('d-none');
+ await expect(discussionsSideBar).toHaveClass('d-none');
await act(async () => {
fireEvent.click(discussionsTrigger);
});
- await expect(discussionsSideBar).toHaveClass('d-none');
+ await expect(discussionsSideBar).not.toHaveClass('d-none');
});
it('displays discussions sidebar when unit changes', async () => {
@@ -177,9 +177,6 @@ describe('Course', () => {
await waitFor(() => {
expect(screen.getByTestId('sidebar-DISCUSSIONS')).toBeInTheDocument();
- expect(screen.getByTestId('sidebar-DISCUSSIONS')).toHaveClass('d-none');
- const discussionsTrigger = screen.getByRole('button', { name: /Show discussions tray/i });
- fireEvent.click(discussionsTrigger);
expect(screen.getByTestId('sidebar-DISCUSSIONS')).not.toHaveClass('d-none');
});
@@ -189,21 +186,20 @@ describe('Course', () => {
it('handles click to open/close notification tray', async () => {
sessionStorage.clear();
render(, { wrapWithRouter: true });
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe(null);
+ expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"open"');
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
- expect(screen.queryByRole('region', { name: /notification tray/i })).not.toHaveClass('d-none');
- fireEvent.click(notificationShowButton);
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('open');
expect(screen.queryByRole('region', { name: /notification tray/i })).toHaveClass('d-none');
+ fireEvent.click(notificationShowButton);
+ expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"closed"');
+ expect(screen.queryByRole('region', { name: /notification tray/i })).not.toHaveClass('d-none');
});
it('handles reload persisting notification tray status', async () => {
sessionStorage.clear();
render(, { wrapWithRouter: true });
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe(null);
fireEvent.click(notificationShowButton);
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('open');
+ expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"closed"');
// Mock reload window, this doesn't happen in the Course component,
// calling the reload to check if the tray remains closed
@@ -213,7 +209,7 @@ describe('Course', () => {
window.location.reload();
expect(window.location.reload).toHaveBeenCalled();
window.location = location;
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('open');
+ expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"closed"');
expect(screen.queryByTestId('NotificationTray')).not.toBeInTheDocument();
});
@@ -222,18 +218,18 @@ describe('Course', () => {
const courseMetadataSecondCourse = Factory.build('courseMetadata', { id: 'second_course' });
// set sessionStorage for a different course before rendering Course
- sessionStorage.setItem(`notificationTrayStatus.${courseMetadataSecondCourse.id}`, 'open');
+ sessionStorage.setItem(`notificationTrayStatus.${courseMetadataSecondCourse.id}`, '"open"');
render(, { wrapWithRouter: true });
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe(null);
+ expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"open"');
const notificationShowButton = await screen.findByRole('button', { name: /Show notification tray/i });
fireEvent.click(notificationShowButton);
// Verify sessionStorage was updated for the original course
- expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('open');
+ expect(sessionStorage.getItem(`notificationTrayStatus.${mockData.courseId}`)).toBe('"closed"');
// Verify the second course sessionStorage was not changed
- expect(sessionStorage.getItem(`notificationTrayStatus.${courseMetadataSecondCourse.id}`)).toBe('open');
+ expect(sessionStorage.getItem(`notificationTrayStatus.${courseMetadataSecondCourse.id}`)).toBe('"open"');
});
it('renders course breadcrumbs as expected', async () => {
diff --git a/src/courseware/course/sidebar/SidebarContextProvider.jsx b/src/courseware/course/sidebar/SidebarContextProvider.jsx
index 8a4be654fc..b61c577b19 100644
--- a/src/courseware/course/sidebar/SidebarContextProvider.jsx
+++ b/src/courseware/course/sidebar/SidebarContextProvider.jsx
@@ -4,10 +4,7 @@ import React, {
useEffect, useState, useMemo, useCallback,
} from 'react';
-import { useModel } from '../../../generic/model-store';
import { getLocalStorage, setLocalStorage } from '../../../data/localStorage';
-import { getSessionStorage } from '../../../data/sessionStorage';
-
import SidebarContext from './SidebarContext';
import { SIDEBARS } from './sidebars';
@@ -16,8 +13,6 @@ const SidebarProvider = ({
unitId,
children,
}) => {
- const { verifiedMode } = useModel('courseHomeMeta', courseId);
-
const shouldDisplayFullScreen = useWindowSize().width < breakpoints.large.minWidth;
const shouldDisplaySidebarOpen = useWindowSize().width > breakpoints.medium.minWidth;
const query = new URLSearchParams(window.location.search);
@@ -27,11 +22,7 @@ const SidebarProvider = ({
const [upgradeNotificationCurrentState, setUpgradeNotificationCurrentState] = useState(getLocalStorage(`upgradeNotificationCurrentState.${courseId}`));
useEffect(() => {
- // if the user has not purchased the course or previously opened the notification tray, show the notification tray
- const showNotificationsOnLoad = !!verifiedMode || getSessionStorage(`notificationTrayStatus.${courseId}`) !== 'closed';
- if (showNotificationsOnLoad) {
- setCurrentSidebar(SIDEBARS.NOTIFICATIONS.ID);
- }
+ setCurrentSidebar(SIDEBARS.DISCUSSIONS.ID);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [unitId]);
diff --git a/src/data/sessionStorage.js b/src/data/sessionStorage.js
index ef809330d3..fe86b577d0 100644
--- a/src/data/sessionStorage.js
+++ b/src/data/sessionStorage.js
@@ -21,7 +21,7 @@ function getSessionStorage(key) {
function setSessionStorage(key, value) {
try {
if (global.sessionStorage) {
- global.sessionStorage.setItem(key, value);
+ global.sessionStorage.setItem(key, JSON.stringify(value));
}
} catch (e) {
// If this fails, just bail.