- {isUnitPageNewDesignEnabled() && isUnitVerticalType && (
-
- )}
-
- {isUnitVerticalType && (
-
-
- {currentlyVisibleToStudents && (
-
)}
- {staticFileNotices && (
-
)}
- {blockId && (
-
)}
- {!readOnly && showPasteXBlock && canPasteComponent && isUnitVerticalType && sharedClipboardData
- && /* istanbul ignore next */ (
-
handleCreateNewCourseXBlock({ stagedContent: 'clipboard', parentLocator: blockId })
- }
- text={intl.formatMessage(messages.pasteButtonText)}
+ />
+
+ {isUnitPageNewDesignEnabled() && isUnitVerticalType && (
+
+ )}
+
+ {isUnitVerticalType && (
+
+ )}
+
+
+ {currentlyVisibleToStudents && (
+
)}
- {!readOnly && blockId && (
-
+ )}
+ {blockId && (
+
+ )}
+ {!readOnly && showPasteXBlock && canPasteComponent && isUnitVerticalType && sharedClipboardData
+ && /* istanbul ignore next */ (
+
handleCreateNewCourseXBlock({ stagedContent: 'clipboard', parentLocator: blockId })
+ }
+ text={intl.formatMessage(messages.pasteButtonText)}
+ />
+ )}
+ {!readOnly && blockId && (
+
+ )}
+
+
+
+ {!isUnitLegacyLibraryType && (
+
)}
-
-
- {!isUnitLegacyLibraryType && (
-
- )}
-
-
-
-
+
+
+
+
);
};
diff --git a/src/course-unit/course-sequence/Sequence.jsx b/src/course-unit/course-sequence/Sequence.jsx
index f8a7ea007f..e17db25a72 100644
--- a/src/course-unit/course-sequence/Sequence.jsx
+++ b/src/course-unit/course-sequence/Sequence.jsx
@@ -4,7 +4,8 @@ import classNames from 'classnames';
import { breakpoints, useWindowSize } from '@openedx/paragon';
import { useIntl } from '@edx/frontend-platform/i18n';
-import Loading from '../../generic/Loading';
+import Loading from '@src/generic/Loading';
+
import { RequestStatus } from '../../data/constants';
import SequenceNavigation from './sequence-navigation/SequenceNavigation';
import messages from './messages';
diff --git a/src/course-unit/unit-sidebar/UnitSidebar.tsx b/src/course-unit/unit-sidebar/UnitSidebar.tsx
index f6d3c597a6..0c1593fdc6 100644
--- a/src/course-unit/unit-sidebar/UnitSidebar.tsx
+++ b/src/course-unit/unit-sidebar/UnitSidebar.tsx
@@ -1,8 +1,9 @@
import { Sidebar } from '@src/generic/sidebar';
+
import LegacySidebar, { LegacySidebarProps } from '../legacy-sidebar';
-import { UnitSidebarPageKeys, useUnitSidebarContext } from './UnitSidebarContext';
import { isUnitPageNewDesignEnabled } from '../utils';
-import { useUnitSidebarPages } from './sidebarPages';
+import { UnitSidebarPageKeys, useUnitSidebarContext } from './UnitSidebarContext';
+import { useUnitSidebarPagesContext } from './UnitSidebarPagesContext';
export type UnitSidebarProps = {
legacySidebarProps: LegacySidebarProps,
@@ -22,7 +23,7 @@ export const UnitSidebar = ({
toggle,
} = useUnitSidebarContext();
- const sidebarPages = useUnitSidebarPages();
+ const sidebarPages = useUnitSidebarPagesContext();
if (!isUnitPageNewDesignEnabled()) {
return (
diff --git a/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx b/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx
new file mode 100644
index 0000000000..3054f622c0
--- /dev/null
+++ b/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx
@@ -0,0 +1,104 @@
+import { createContext, useContext, useMemo } from 'react';
+import { getConfig } from '@edx/frontend-platform';
+import { Info, Plus, Tag } from '@openedx/paragon/icons';
+
+import type { SidebarPage } from '@src/generic/sidebar';
+
+import { InfoSidebar } from './unit-info/InfoSidebar';
+import { AddSidebar } from './AddSidebar';
+import { UnitAlignSidebar } from './UnitAlignSidebar';
+import { useUnitSidebarContext } from './UnitSidebarContext';
+import messages from './messages';
+
+export type UnitSidebarPages = {
+ info: SidebarPage;
+ add?: SidebarPage;
+ align?: SidebarPage;
+};
+
+const getUnitSidebarPages = (readOnly: boolean, hasComponentSelected: boolean) => {
+ const showAlignSidebar = getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true';
+
+ return {
+ info: {
+ component: InfoSidebar,
+ icon: Info,
+ title: messages.sidebarButtonInfo,
+ },
+ ...(!readOnly && {
+ add: {
+ component: AddSidebar,
+ icon: Plus,
+ title: messages.sidebarButtonAdd,
+ disabled: hasComponentSelected,
+ tooltip: hasComponentSelected ? messages.sidebarDisabledAddTooltip : undefined,
+ },
+ }),
+ ...(showAlignSidebar && {
+ align: {
+ component: UnitAlignSidebar,
+ icon: Tag,
+ title: messages.sidebarButtonAlign,
+ },
+ }),
+ };
+};
+
+/**
+ * Context for the Unit Sidebar Pages.
+ *
+ * This could be used in plugins to add new pages to the sidebar.
+ *
+ * @example
+ *
+ * ```tsx
+ * export function UnitOutlineSidebarWrapper(
+ * { component, pluginProps }: { component: React.ReactNode, pluginProps: UnitOutlineAspectsPageProps},
+ * ) {
+ * const sidebarPages = useUnitSidebarPagesContext();
+ * const AnalyticsPage = useCallback(() =>
, [pluginProps]);
+ *
+ * const overridedPages = useMemo(() => ({
+ * ...sidebarPages,
+ * analytics: {
+ * component: AnalyticsPage,
+ * icon: AutoGraph,
+ * title: messages.analyticsLabel,
+ * },
+ * }), [sidebarPages, AnalyticsPage]);
+ *
+ * return (
+ *
+ * {component}
+ *
+ * );
+ * }
+ */
+export const UnitSidebarPagesContext = createContext
(undefined);
+
+type UnitSidebarPagesProviderProps = {
+ children: React.ReactNode;
+};
+
+export const UnitSidebarPagesProvider = ({ children }: UnitSidebarPagesProviderProps) => {
+ const { readOnly, selectedComponentId } = useUnitSidebarContext();
+
+ const hasComponentSelected = selectedComponentId !== undefined;
+
+ const sidebarPages = useMemo(
+ () => getUnitSidebarPages(readOnly, hasComponentSelected),
+ [readOnly, hasComponentSelected],
+ );
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useUnitSidebarPagesContext = (): UnitSidebarPages => {
+ const ctx = useContext(UnitSidebarPagesContext);
+ if (ctx === undefined) { throw new Error('useUnitSidebarPages must be used within an UnitSidebarPagesProvider'); }
+ return ctx;
+};
diff --git a/src/course-unit/unit-sidebar/sidebarPages.ts b/src/course-unit/unit-sidebar/sidebarPages.ts
deleted file mode 100644
index f54dd96e25..0000000000
--- a/src/course-unit/unit-sidebar/sidebarPages.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import { getConfig } from '@edx/frontend-platform';
-import { Info, Tag, Plus } from '@openedx/paragon/icons';
-import { SidebarPage } from '@src/generic/sidebar';
-import messages from './messages';
-import { UnitAlignSidebar } from './UnitAlignSidebar';
-import { AddSidebar } from './AddSidebar';
-import { useUnitSidebarContext } from './UnitSidebarContext';
-import { InfoSidebar } from './unit-info/InfoSidebar';
-
-export type UnitSidebarPages = {
- info: SidebarPage;
- align?: SidebarPage;
- add?: SidebarPage;
-};
-
-/**
- * Sidebar pages for the unit sidebar
- *
- * This has been separated from the context to avoid a cyclical import
- * if you want to use the context in the sidebar pages.
- */
-export const useUnitSidebarPages = (): UnitSidebarPages => {
- const showAlignSidebar = getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true';
- const { readOnly, selectedComponentId } = useUnitSidebarContext();
- const hasComponentSelected = selectedComponentId !== undefined;
- return {
- info: {
- component: InfoSidebar,
- icon: Info,
- title: messages.sidebarButtonInfo,
- },
- ...(!readOnly && {
- add: {
- component: AddSidebar,
- icon: Plus,
- title: messages.sidebarButtonAdd,
- disabled: hasComponentSelected,
- tooltip: hasComponentSelected ? messages.sidebarDisabledAddTooltip : undefined,
- },
- }),
- ...(showAlignSidebar && {
- align: {
- component: UnitAlignSidebar,
- icon: Tag,
- title: messages.sidebarButtonAlign,
- },
- }),
- };
-};
diff --git a/src/course-unit/unit-sidebar/unit-info/UnitInfoSidebar.tsx b/src/course-unit/unit-sidebar/unit-info/UnitInfoSidebar.tsx
index 48dc7c76a8..4bcdc29157 100644
--- a/src/course-unit/unit-sidebar/unit-info/UnitInfoSidebar.tsx
+++ b/src/course-unit/unit-sidebar/unit-info/UnitInfoSidebar.tsx
@@ -205,7 +205,7 @@ export const UnitInfoSidebar = () => {
}, []);
return (
-
+ <>
{
-
+ >
);
};
diff --git a/src/generic/sidebar/Sidebar.tsx b/src/generic/sidebar/Sidebar.tsx
index 56f9aa699d..ebfd06aee4 100644
--- a/src/generic/sidebar/Sidebar.tsx
+++ b/src/generic/sidebar/Sidebar.tsx
@@ -144,7 +144,6 @@ export function Sidebar