diff --git a/src/course-unit/CourseUnit.test.tsx b/src/course-unit/CourseUnit.test.tsx
index 953980eb86..a72ed30e3b 100644
--- a/src/course-unit/CourseUnit.test.tsx
+++ b/src/course-unit/CourseUnit.test.tsx
@@ -149,6 +149,7 @@ const RootWrapper = () => (
describe('
', () => {
beforeEach(async () => {
const mocks = initializeMocks();
+
window.scrollTo = jest.fn();
global.localStorage.clear();
store = mocks.reduxStore;
@@ -180,6 +181,10 @@ describe('
', () => {
});
it('render CourseUnit component correctly', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
const currentSectionName = courseSectionVerticalMock.xblock_info.ancestor_info.ancestors[1].display_name;
const currentSubSectionName = courseSectionVerticalMock.xblock_info.ancestor_info.ancestors[1].display_name;
@@ -271,6 +276,10 @@ describe('
', () => {
});
it('closes legacy edit modal and updates course unit sidebar after saveEditedXBlockData message', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
const xblocksIframe = await screen.findByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
@@ -308,6 +317,10 @@ describe('
', () => {
});
it('updates course unit sidebar after receiving refreshPositions message', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
const xblocksIframe = await screen.findByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
@@ -341,6 +354,10 @@ describe('
', () => {
it('checks whether xblock is removed when the corresponding delete button is clicked and the sidebar is the updated', async () => {
const user = userEvent.setup();
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
const iframe = await screen.findByTitle(xblockContainerIframeMessages.xblockIframeTitle.defaultMessage);
@@ -513,6 +530,10 @@ describe('
', () => {
});
it('checks if xblock is a duplicate when the corresponding duplicate button is clicked and if the sidebar status is updated', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
axiosMock
.onGet(getCourseSectionVerticalApiUrl(blockId))
.reply(200, {
@@ -1130,6 +1151,10 @@ describe('
', () => {
});
it('renders course unit details for a draft with unpublished changes', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
await waitFor(() => {
@@ -1206,6 +1231,10 @@ describe('
', () => {
it('should toggle visibility from sidebar and update course unit state accordingly', async () => {
const user = userEvent.setup();
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
const courseUnitSidebar = await screen.findByTestId('course-unit-sidebar');
@@ -1298,6 +1327,10 @@ describe('
', () => {
it('should publish course unit after click on the "Publish" button', async () => {
const user = userEvent.setup();
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
let courseUnitSidebar;
let publishBtn;
@@ -1350,6 +1383,10 @@ describe('
', () => {
it('should discard changes after click on the Discard changes button', async () => {
const user = userEvent.setup();
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
render(
);
let courseUnitSidebar;
let discardChangesBtn;
@@ -1425,6 +1462,10 @@ describe('
', () => {
});
it('should toggle visibility from header configure modal and update course unit state accordingly', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
const user = userEvent.setup();
render(
);
expect(
@@ -1524,6 +1565,13 @@ describe('
', () => {
});
describe('Copy paste functionality', () => {
+ beforeEach(() => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
+ });
+
it('should copy a unit, paste it as a new unit, and update the course section vertical data', async () => {
const user = userEvent.setup();
render(
);
@@ -2320,17 +2368,31 @@ describe('
', () => {
});
});
- it('should display visibility modal correctly', async () => (
- checkRenderVisibilityModal('libraryContentAccess')
- ));
+ it('should display visibility modal correctly', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
+ await checkRenderVisibilityModal('libraryContentAccess');
+ });
- it('opens legacy edit modal on edit button click', checkLegacyEditModalOnEditMessage);
+ it('opens legacy edit modal on edit button click', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
+ await checkLegacyEditModalOnEditMessage();
+ });
});
describe('Split Test Content page', () => {
const newUnitId = '12345';
beforeEach(async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
axiosMock
.onGet(getCourseSectionVerticalApiUrl(blockId))
.reply(200, {
@@ -2524,6 +2586,7 @@ describe('
', () => {
setConfig({
...getConfig(),
ENABLE_TAGGING_TAXONOMY_PAGES: 'true',
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
});
render(
);
diff --git a/src/course-unit/CourseUnit.tsx b/src/course-unit/CourseUnit.tsx
index 5e4c879dd0..3e4e7bcfc0 100644
--- a/src/course-unit/CourseUnit.tsx
+++ b/src/course-unit/CourseUnit.tsx
@@ -333,7 +333,7 @@ const CourseUnit = () => {
showPasteUnit={showPasteUnit}
/>
)}
-
+
{currentlyVisibleToStudents && (
', () => {
});
it('click Add button should open add sidebar', async () => {
- setConfig({
- ...getConfig(),
- ENABLE_UNIT_PAGE_NEW_DESIGN: 'true',
- });
-
const user = userEvent.setup();
renderComponent({ unitCategory: COURSE_BLOCK_NAMES.vertical.id });
diff --git a/src/course-unit/header-title/HeaderTitle.test.tsx b/src/course-unit/header-title/HeaderTitle.test.tsx
index 36281e5c8e..ef7511e3bf 100644
--- a/src/course-unit/header-title/HeaderTitle.test.tsx
+++ b/src/course-unit/header-title/HeaderTitle.test.tsx
@@ -1,5 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
+import { getConfig, setConfig } from '@edx/frontend-platform';
import { initializeMocks, render, screen } from '@src/testUtils';
import userEvent from '@testing-library/user-event';
import { executeThunk } from '@src/utils';
@@ -47,6 +48,10 @@ describe('
', () => {
});
it('render HeaderTitle component correctly', () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
renderComponent();
expect(screen.getByText(unitTitle)).toBeInTheDocument();
@@ -55,6 +60,10 @@ describe('
', () => {
});
it('render HeaderTitle with open edit form', () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
renderComponent({
isTitleEditFormOpen: true,
});
@@ -66,6 +75,10 @@ describe('
', () => {
});
it('Units sourced from upstream show a enabled edit button', async () => {
+ setConfig({
+ ...getConfig(),
+ ENABLE_UNIT_PAGE_NEW_DESIGN: false,
+ });
// Override mock unit with one sourced from an upstream library
axiosMock = new MockAdapter(getAuthenticatedHttpClient());
axiosMock
diff --git a/src/course-unit/unit-sidebar/UnitSidebarContext.tsx b/src/course-unit/unit-sidebar/UnitSidebarContext.tsx
index e8e76c4b7f..34517a0327 100644
--- a/src/course-unit/unit-sidebar/UnitSidebarContext.tsx
+++ b/src/course-unit/unit-sidebar/UnitSidebarContext.tsx
@@ -29,9 +29,10 @@ interface UnitSidebarContextData {
readOnly: boolean;
/*
* There are other blocks that use the same unit screen and sidebars.
- * For example: Conditional block.
+ * For example: Conditional block, Content Experiments block.
*/
isVertical: boolean;
+ currentItemCategory?: string;
}
const UnitSidebarContext = createContext
(undefined);
@@ -55,7 +56,8 @@ export const UnitSidebarProvider = ({
const [isOpen, open, , toggle] = useToggle(true);
const currentItemData = useSelector(getCourseUnitData);
- const isVertical = currentItemData?.category === 'vertical';
+ const currentItemCategory = currentItemData?.category;
+ const isVertical = currentItemCategory === 'vertical';
const setCurrentPageKey = useCallback(/* istanbul ignore next */ (
pageKey?: UnitSidebarPageKeys,
@@ -92,6 +94,7 @@ export const UnitSidebarProvider = ({
toggle,
readOnly,
isVertical,
+ currentItemCategory,
}),
[
currentPageKey,
@@ -105,6 +108,7 @@ export const UnitSidebarProvider = ({
toggle,
readOnly,
isVertical,
+ currentItemCategory,
],
);
diff --git a/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx b/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx
index 3054f622c0..18b821a841 100644
--- a/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx
+++ b/src/course-unit/unit-sidebar/UnitSidebarPagesContext.tsx
@@ -16,7 +16,7 @@ export type UnitSidebarPages = {
align?: SidebarPage;
};
-const getUnitSidebarPages = (readOnly: boolean, hasComponentSelected: boolean) => {
+const getUnitSidebarPages = (readOnly: boolean, disableAdd: boolean) => {
const showAlignSidebar = getConfig().ENABLE_TAGGING_TAXONOMY_PAGES === 'true';
return {
@@ -30,8 +30,8 @@ const getUnitSidebarPages = (readOnly: boolean, hasComponentSelected: boolean) =
component: AddSidebar,
icon: Plus,
title: messages.sidebarButtonAdd,
- disabled: hasComponentSelected,
- tooltip: hasComponentSelected ? messages.sidebarDisabledAddTooltip : undefined,
+ disabled: disableAdd,
+ tooltip: disableAdd ? messages.sidebarDisabledAddTooltip : undefined,
},
}),
...(showAlignSidebar && {
@@ -81,13 +81,19 @@ type UnitSidebarPagesProviderProps = {
};
export const UnitSidebarPagesProvider = ({ children }: UnitSidebarPagesProviderProps) => {
- const { readOnly, selectedComponentId } = useUnitSidebarContext();
+ const {
+ readOnly,
+ selectedComponentId,
+ currentItemCategory,
+ } = useUnitSidebarContext();
const hasComponentSelected = selectedComponentId !== undefined;
+ const isSplitTest = currentItemCategory === 'split_test';
+ const disableAdd = hasComponentSelected || isSplitTest;
const sidebarPages = useMemo(
- () => getUnitSidebarPages(readOnly, hasComponentSelected),
- [readOnly, hasComponentSelected],
+ () => getUnitSidebarPages(readOnly, disableAdd),
+ [readOnly, disableAdd],
);
return (
diff --git a/src/course-unit/utils.ts b/src/course-unit/utils.ts
index 973f053686..cb15e6a87f 100644
--- a/src/course-unit/utils.ts
+++ b/src/course-unit/utils.ts
@@ -47,5 +47,5 @@ export const subsectionFirstUnitEditUrl = (
};
export const isUnitPageNewDesignEnabled = () => (
- getConfig().ENABLE_UNIT_PAGE_NEW_DESIGN?.toString().toLowerCase() === 'true'
+ (getConfig().ENABLE_UNIT_PAGE_NEW_DESIGN?.toString().toLowerCase() ?? 'true') === 'true'
);
diff --git a/src/generic/resizable/Resizable.tsx b/src/generic/resizable/Resizable.tsx
index adfe1606bb..d484a1bea9 100644
--- a/src/generic/resizable/Resizable.tsx
+++ b/src/generic/resizable/Resizable.tsx
@@ -62,13 +62,13 @@ export const ResizableBox = ({
return (
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex, jsx-a11y/no-static-element-interactions */}
-
diff --git a/src/generic/sidebar/Sidebar.tsx b/src/generic/sidebar/Sidebar.tsx
index ae3c0e3cc7..35a83739a1 100644
--- a/src/generic/sidebar/Sidebar.tsx
+++ b/src/generic/sidebar/Sidebar.tsx
@@ -96,7 +96,7 @@ export function Sidebar
({
const activeKey = isOpen ? currentPageKey : undefined;
return (
-
+
{(isOpen && !!currentPageKey) ?
(
diff --git a/src/generic/sidebar/index.scss b/src/generic/sidebar/index.scss
index 88b6dd101f..9b09753138 100644
--- a/src/generic/sidebar/index.scss
+++ b/src/generic/sidebar/index.scss
@@ -2,14 +2,16 @@
position: sticky;
top: 0;
align-self: flex-start;
+ height: 100vh;
max-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ margin-left: 1rem;
.sidebar-content {
flex: 0 1 auto;
min-width: 440px;
- overflow-y: auto;
- height: 100vh;
- max-height: 100vh;
+ overflow: hidden auto;
/*
* Change the styles for tabs in all sidebars.
diff --git a/src/index.jsx b/src/index.jsx
index b62a9e58cf..4d4d6d2c73 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -184,8 +184,7 @@ initialize({
process.env.ENABLE_VIDEO_UPLOAD_PAGE_LINK_IN_CONTENT_DROPDOWN || 'false',
ENABLE_CERTIFICATE_PAGE: process.env.ENABLE_CERTIFICATE_PAGE || 'false',
ENABLE_COURSE_IMPORT_IN_LIBRARY: process.env.ENABLE_COURSE_IMPORT_IN_LIBRARY || 'false',
- ENABLE_UNIT_PAGE_NEW_DESIGN: process.env.ENABLE_UNIT_PAGE_NEW_DESIGN || 'false',
- ENABLE_COURSE_OUTLINE_NEW_DESIGN: process.env.ENABLE_COURSE_OUTLINE_NEW_DESIGN || 'false',
+ ENABLE_UNIT_PAGE_NEW_DESIGN: process.env.ENABLE_UNIT_PAGE_NEW_DESIGN || 'true',
ENABLE_TAGGING_TAXONOMY_PAGES: process.env.ENABLE_TAGGING_TAXONOMY_PAGES || 'false',
ENABLE_CHECKLIST_QUALITY: process.env.ENABLE_CHECKLIST_QUALITY || 'true',
ENABLE_GRADING_METHOD_IN_PROBLEMS: process.env.ENABLE_GRADING_METHOD_IN_PROBLEMS === 'true',
diff --git a/src/plugin-slots/CourseAuthoringOutlineSidebarSlot/index.tsx b/src/plugin-slots/CourseAuthoringOutlineSidebarSlot/index.tsx
index da5c54e1cc..9f7d947bfd 100644
--- a/src/plugin-slots/CourseAuthoringOutlineSidebarSlot/index.tsx
+++ b/src/plugin-slots/CourseAuthoringOutlineSidebarSlot/index.tsx
@@ -7,17 +7,19 @@ export const CourseAuthoringOutlineSidebarSlot = ({
courseName,
sections,
}: CourseAuthoringOutlineSidebarSlotProps) => (
-
+
+
+
);
type Section = {
diff --git a/src/plugin-slots/CourseAuthoringUnitSidebarSlot/index.tsx b/src/plugin-slots/CourseAuthoringUnitSidebarSlot/index.tsx
index 67575020ca..2a37c0a993 100644
--- a/src/plugin-slots/CourseAuthoringUnitSidebarSlot/index.tsx
+++ b/src/plugin-slots/CourseAuthoringUnitSidebarSlot/index.tsx
@@ -1,5 +1,8 @@
import { PluginSlot } from '@openedx/frontend-plugin-framework/dist';
+import classNames from 'classnames';
+
import { UnitSidebar } from '@src/course-unit/unit-sidebar/UnitSidebar';
+import { isUnitPageNewDesignEnabled } from '@src/course-unit/utils';
export const CourseAuthoringUnitSidebarSlot = (
{
@@ -12,28 +15,32 @@ export const CourseAuthoringUnitSidebarSlot = (
isSplitTestType,
}: CourseAuthoringUnitSidebarSlotProps,
) => (
-
+ >
+
+
+
);
type XBlock = {