diff --git a/src/CourseAuthoringRoutes.tsx b/src/CourseAuthoringRoutes.tsx index 8f11ca3a2e..9bdcbeb75f 100644 --- a/src/CourseAuthoringRoutes.tsx +++ b/src/CourseAuthoringRoutes.tsx @@ -11,7 +11,7 @@ import VideoSelectorContainer from './selectors/VideoSelectorContainer'; import CustomPages from './custom-pages'; import { FilesPage, VideosPage } from './files-and-videos'; import { AdvancedSettings } from './advanced-settings'; -import { CourseOutline } from './course-outline'; +import { CourseOutline, OutlineSidebarPagesProvider } from './course-outline'; import ScheduleAndDetails from './schedule-and-details'; import { GradingSettings } from './grading-settings'; import CourseTeam from './course-team/CourseTeam'; @@ -58,7 +58,13 @@ const CourseAuthoringRoutes = () => { } + element={( + + + + + + )} /> new Promise((resolve) => setTimeout(resolve, ms)); const renderComponent = () => render( - + + + , ); diff --git a/src/course-outline/index.ts b/src/course-outline/index.ts index 0e3d68a3ce..113a93daaa 100644 --- a/src/course-outline/index.ts +++ b/src/course-outline/index.ts @@ -1 +1,2 @@ export { default as CourseOutline } from './CourseOutline'; +export { OutlineSidebarPagesProvider } from './outline-sidebar/OutlineSidebarPagesContext'; diff --git a/src/course-outline/outline-sidebar/OutlineHelpSidebar.tsx b/src/course-outline/outline-sidebar/OutlineHelpSidebar.tsx index 663b8b7ce6..aef1bcdd24 100644 --- a/src/course-outline/outline-sidebar/OutlineHelpSidebar.tsx +++ b/src/course-outline/outline-sidebar/OutlineHelpSidebar.tsx @@ -1,10 +1,12 @@ import { Hyperlink } from '@openedx/paragon'; import { useIntl } from '@edx/frontend-platform/i18n'; +import { SchoolOutline } from '@openedx/paragon/icons'; -import { HelpSidebar } from '@src/generic/help-sidebar'; +import { SidebarContent, SidebarSection, SidebarTitle } from '@src/generic/sidebar'; import { useHelpUrls } from '@src/help-urls/hooks'; import { useCourseAuthoringContext } from '@src/CourseAuthoringContext'; +import { useCourseDetails } from '../data/apiHooks'; import { getFormattedSidebarMessages } from './utils'; const OutlineHelpSideBar = () => { @@ -15,6 +17,7 @@ const OutlineHelpSideBar = () => { outline: learnMoreOutlineUrl, } = useHelpUrls(['visibility', 'grading', 'outline']); const { courseId } = useCourseAuthoringContext(); + const { data: courseDetails } = useCourseDetails(courseId); const sidebarMessages = getFormattedSidebarMessages( { @@ -26,24 +29,23 @@ const OutlineHelpSideBar = () => { ); return ( - - {sidebarMessages.map(({ title, descriptions, link }, index) => { - const isLastSection = index === sidebarMessages.length - 1; - - return ( -
-

{title}

+ <> + + + {sidebarMessages.map(({ title, descriptions, link }) => ( + {descriptions.map((description) => ( -

{description}

+

{description}

))} {!!link?.href && ( { {link.text} )} - {!isLastSection &&
} -
- ); - })} -
+ + ))} + + ); }; diff --git a/src/course-outline/outline-sidebar/OutlineSidebar.test.tsx b/src/course-outline/outline-sidebar/OutlineSidebar.test.tsx index eb80c02ce6..8ab935f9c9 100644 --- a/src/course-outline/outline-sidebar/OutlineSidebar.test.tsx +++ b/src/course-outline/outline-sidebar/OutlineSidebar.test.tsx @@ -7,6 +7,7 @@ import { import { CourseAuthoringProvider } from '@src/CourseAuthoringContext'; import { OutlineSidebarProvider } from './OutlineSidebarContext'; +import { OutlineSidebarPagesProvider } from './OutlineSidebarPagesContext'; import OutlineSidebar from './OutlineSidebar'; // Mock the useCourseDetails hook @@ -19,9 +20,11 @@ const courseId = '123'; const extraWrapper = ({ children }) => ( - - {children} - + + + {children} + + ); diff --git a/src/course-outline/outline-sidebar/OutlineSidebarPagesContext.tsx b/src/course-outline/outline-sidebar/OutlineSidebarPagesContext.tsx index 93acf1fbba..8aaf0412ab 100644 --- a/src/course-outline/outline-sidebar/OutlineSidebarPagesContext.tsx +++ b/src/course-outline/outline-sidebar/OutlineSidebarPagesContext.tsx @@ -1,4 +1,4 @@ -import { createContext, useContext } from 'react'; +import { createContext, useContext, useMemo } from 'react'; import { getConfig } from '@edx/frontend-platform'; import { HelpOutline, Info, Plus, Tag, @@ -19,15 +19,18 @@ export type OutlineSidebarPages = { align?: SidebarPage; }; -const showAlignSidebar = getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true'; - -const OUTLINE_SIDEBAR_PAGES: OutlineSidebarPages = { +const getOutlineSidebarPages = () => ({ info: { component: OutlineInfoSidebar, icon: Info, title: messages.sidebarButtonInfo, }, - ...(showAlignSidebar && { + add: { + component: AddSidebar, + icon: Plus, + title: messages.sidebarButtonAdd, + }, + ...(getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true' && { align: { component: OutlineAlignSidebar, icon: Tag, @@ -39,12 +42,7 @@ const OUTLINE_SIDEBAR_PAGES: OutlineSidebarPages = { icon: HelpOutline, title: messages.sidebarButtonHelp, }, - add: { - component: AddSidebar, - icon: Plus, - title: messages.sidebarButtonAdd, - }, -}; +}); /** * Context for the Outline Sidebar Pages. @@ -77,6 +75,24 @@ const OUTLINE_SIDEBAR_PAGES: OutlineSidebarPages = { * ); *} */ -export const OutlineSidebarPagesContext = createContext(OUTLINE_SIDEBAR_PAGES); +export const OutlineSidebarPagesContext = createContext(undefined); + +type OutlineSidebarPagesProviderProps = { + children: React.ReactNode; +}; -export const useOutlineSidebarPagesContext = (): OutlineSidebarPages => useContext(OutlineSidebarPagesContext); +export const OutlineSidebarPagesProvider = ({ children }: OutlineSidebarPagesProviderProps) => { + const sidebarPages = useMemo(getOutlineSidebarPages, []); + + return ( + + {children} + + ); +}; + +export const useOutlineSidebarPagesContext = (): OutlineSidebarPages => { + const ctx = useContext(OutlineSidebarPagesContext); + if (ctx === undefined) { throw new Error('useOutlineSidebarPages must be used within an OutlineSidebarPagesProvider'); } + return ctx; +}; diff --git a/src/course-outline/outline-sidebar/sidebarPages.ts b/src/course-outline/outline-sidebar/sidebarPages.ts deleted file mode 100644 index 18f83b9151..0000000000 --- a/src/course-outline/outline-sidebar/sidebarPages.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { getConfig } from '@edx/frontend-platform'; -import { - HelpOutline, Info, Plus, Tag, -} from '@openedx/paragon/icons'; -import type { SidebarPage } from '@src/generic/sidebar'; -import OutlineHelpSidebar from './OutlineHelpSidebar'; -import { OutlineInfoSidebar } from './OutlineInfoSidebar'; -import messages from './messages'; -import { AddSidebar } from './AddSidebar'; -import { OutlineAlignSidebar } from './OutlineAlignSidebar'; - -export type OutlineSidebarPages = { - info: SidebarPage; - help: SidebarPage; - add: SidebarPage; - align?: SidebarPage; -}; - -export const getOutlineSidebarPages = (): OutlineSidebarPages => { - const showAlignSidebar = getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true'; - return { - info: { - component: OutlineInfoSidebar, - icon: Info, - title: messages.sidebarButtonInfo, - }, - ...(showAlignSidebar && { - align: { - component: OutlineAlignSidebar, - icon: Tag, - title: messages.sidebarButtonAlign, - }, - }), - help: { - component: OutlineHelpSidebar, - icon: HelpOutline, - title: messages.sidebarButtonHelp, - }, - add: { - component: AddSidebar, - icon: Plus, - title: messages.sidebarButtonAdd, - }, - } satisfies OutlineSidebarPages; -}; diff --git a/src/course-unit/CourseUnit.test.jsx b/src/course-unit/CourseUnit.test.jsx index 2d58f1d8b6..5e1edd70f8 100644 --- a/src/course-unit/CourseUnit.test.jsx +++ b/src/course-unit/CourseUnit.test.jsx @@ -581,17 +581,16 @@ describe('', () => { published_preview_link: publishedPreviewLink, } = courseSectionVerticalMock; - await waitFor(async () => { - const viewLiveButton = screen.getByRole('button', { name: headerNavigationsMessages.viewLiveButton.defaultMessage }); - await user.click(viewLiveButton); - expect(window.open).toHaveBeenCalled(); - expect(window.open).toHaveBeenCalledWith(publishedPreviewLink, '_blank'); + const viewLiveButton = await screen.findByRole('button', { name: headerNavigationsMessages.viewLiveButton.defaultMessage }); - const previewButton = screen.getByRole('button', { name: headerNavigationsMessages.previewButton.defaultMessage }); - await user.click(previewButton); - expect(window.open).toHaveBeenCalled(); - expect(window.open).toHaveBeenCalledWith(draftPreviewLink, '_blank'); - }); + await user.click(viewLiveButton); + expect(window.open).toHaveBeenCalled(); + expect(window.open).toHaveBeenCalledWith(publishedPreviewLink, '_blank'); + + const previewButton = screen.getByRole('button', { name: headerNavigationsMessages.previewButton.defaultMessage }); + await user.click(previewButton); + expect(window.open).toHaveBeenCalled(); + expect(window.open).toHaveBeenCalledWith(draftPreviewLink, '_blank'); window.open = open; }); @@ -870,9 +869,8 @@ describe('', () => { .reply(200, courseCreateXblockMock); render(); - await waitFor(async () => { - await user.click(screen.getByRole('button', { name: legacySidebarMessages.actionButtonPublishTitle.defaultMessage })); - }); + const publishButton = await screen.findByRole('button', { name: legacySidebarMessages.actionButtonPublishTitle.defaultMessage }); + await user.click(publishButton); axiosMock .onPost(getXBlockBaseApiUrl(blockId), {