diff --git a/src/library-authoring/LibraryAuthoringPage.test.tsx b/src/library-authoring/LibraryAuthoringPage.test.tsx
index 84e50c70f..f6d55792a 100644
--- a/src/library-authoring/LibraryAuthoringPage.test.tsx
+++ b/src/library-authoring/LibraryAuthoringPage.test.tsx
@@ -18,6 +18,8 @@ import {
mockXBlockFields,
} from './data/api.mocks';
import { mockContentSearchConfig } from '../search-manager/data/api.mock';
+import { studioHomeMock } from '../studio-home/__mocks__';
+import { getStudioHomeApiUrl } from '../studio-home/data/api';
import { mockBroadcastChannel } from '../generic/data/api.mock';
import { LibraryLayout } from '.';
import { getLibraryCollectionsApiUrl } from './data/api';
@@ -79,7 +81,8 @@ const libraryTitle = mockContentLibrary.libraryData.title;
describe('', () => {
beforeEach(() => {
- initializeMocks();
+ const { axiosMock } = initializeMocks();
+ axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
// The Meilisearch client-side API uses fetch, not Axios.
fetchMock.mockReset();
@@ -787,4 +790,16 @@ describe('', () => {
});
});
});
+
+ it('Shows an error if libraries V2 is disabled', async () => {
+ const { axiosMock } = initializeMocks();
+ axiosMock.onGet(getStudioHomeApiUrl()).reply(200, {
+ ...studioHomeMock,
+ libraries_v2_enabled: false,
+ });
+
+ render(, { path, params: { libraryId: mockContentLibrary.libraryId } });
+ await waitFor(() => { expect(axiosMock.history.get.length).toBe(1); });
+ expect(screen.getByRole('alert')).toHaveTextContent('This page cannot be shown: Libraries v2 are disabled.');
+ });
});
diff --git a/src/library-authoring/LibraryAuthoringPage.tsx b/src/library-authoring/LibraryAuthoringPage.tsx
index 57ca633ab..ebb0b0308 100644
--- a/src/library-authoring/LibraryAuthoringPage.tsx
+++ b/src/library-authoring/LibraryAuthoringPage.tsx
@@ -4,6 +4,7 @@ import classNames from 'classnames';
import { StudioFooter } from '@edx/frontend-component-footer';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
+ Alert,
Badge,
Breadcrumb,
Button,
@@ -25,6 +26,7 @@ import Loading from '../generic/Loading';
import SubHeader from '../generic/sub-header/SubHeader';
import Header from '../header';
import NotFoundAlert from '../generic/NotFoundAlert';
+import { useStudioHome } from '../studio-home/hooks';
import {
ClearFiltersButton,
FilterByBlockType,
@@ -143,6 +145,12 @@ const LibraryAuthoringPage = ({ returnToLibrarySelection }: LibraryAuthoringPage
const location = useLocation();
const navigate = useNavigate();
+ const {
+ isLoadingPage: isLoadingStudioHome,
+ isFailedLoadingPage: isFailedLoadingStudioHome,
+ librariesV2Enabled,
+ } = useStudioHome();
+
const {
libraryId,
libraryData,
@@ -178,6 +186,14 @@ const LibraryAuthoringPage = ({ returnToLibrarySelection }: LibraryAuthoringPage
return ;
}
+ if (!isLoadingStudioHome && (!librariesV2Enabled || isFailedLoadingStudioHome)) {
+ return (
+
+ {intl.formatMessage(messages.librariesV2DisabledError)}
+
+ );
+ }
+
// istanbul ignore if: this should never happen
if (activeKey === undefined) {
return ;
diff --git a/src/library-authoring/add-content/AddContentWorkflow.test.tsx b/src/library-authoring/add-content/AddContentWorkflow.test.tsx
index bd464f39b..915cfc6fe 100644
--- a/src/library-authoring/add-content/AddContentWorkflow.test.tsx
+++ b/src/library-authoring/add-content/AddContentWorkflow.test.tsx
@@ -19,6 +19,8 @@ import {
} from '../data/api.mocks';
import { mockBroadcastChannel, mockClipboardEmpty } from '../../generic/data/api.mock';
import { mockContentSearchConfig, mockSearchResult } from '../../search-manager/data/api.mock';
+import { studioHomeMock } from '../../studio-home/__mocks__';
+import { getStudioHomeApiUrl } from '../../studio-home/data/api';
import LibraryLayout from '../LibraryLayout';
mockContentSearchConfig.applyMock();
@@ -46,8 +48,12 @@ const renderOpts = {
};
describe('AddContentWorkflow test', () => {
+ beforeEach(() => {
+ const { axiosMock } = initializeMocks();
+ axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
+ });
+
it('can create an HTML component', async () => {
- initializeMocks();
render(, renderOpts);
// Click "New [Component]"
@@ -84,7 +90,6 @@ describe('AddContentWorkflow test', () => {
});
it('can create a Problem component', async () => {
- initializeMocks();
render(, renderOpts);
// Click "New [Component]"
@@ -119,7 +124,6 @@ describe('AddContentWorkflow test', () => {
});
it('can create a Video component', async () => {
- initializeMocks();
render(, renderOpts);
// Click "New [Component]"
diff --git a/src/library-authoring/add-content/PickLibraryContentModal.test.tsx b/src/library-authoring/add-content/PickLibraryContentModal.test.tsx
index d59baa569..b7425a7ee 100644
--- a/src/library-authoring/add-content/PickLibraryContentModal.test.tsx
+++ b/src/library-authoring/add-content/PickLibraryContentModal.test.tsx
@@ -6,6 +6,8 @@ import {
screen,
initializeMocks,
} from '../../testUtils';
+import { studioHomeMock } from '../../studio-home/__mocks__';
+import { getStudioHomeApiUrl } from '../../studio-home/data/api';
import mockResult from '../__mocks__/library-search.json';
import { LibraryProvider } from '../common/context';
import { ComponentPickerModal } from '../component-picker';
@@ -16,7 +18,6 @@ import {
} from '../data/api.mocks';
import { PickLibraryContentModal } from './PickLibraryContentModal';
-initializeMocks();
mockContentSearchConfig.applyMock();
mockContentLibrary.applyMock();
mockGetCollectionMetadata.applyMock();
@@ -45,6 +46,7 @@ describe('', () => {
beforeEach(() => {
const mocks = initializeMocks();
mockShowToast = mocks.mockShowToast;
+ mocks.axiosMock.onGet(getStudioHomeApiUrl()).reply(200, studioHomeMock);
});
it('can pick components from the modal', async () => {
diff --git a/src/library-authoring/component-picker/ComponentPicker.test.tsx b/src/library-authoring/component-picker/ComponentPicker.test.tsx
index 4c06a9846..083d9a635 100644
--- a/src/library-authoring/component-picker/ComponentPicker.test.tsx
+++ b/src/library-authoring/component-picker/ComponentPicker.test.tsx
@@ -27,6 +27,13 @@ jest.mock('react-router-dom', () => ({
},
}),
}));
+jest.mock('../../studio-home/hooks', () => ({
+ useStudioHome: () => ({
+ isLoadingPage: false,
+ isFailedLoadingPage: false,
+ librariesV2Enabled: true,
+ }),
+}));
mockContentLibrary.applyMock();
mockContentSearchConfig.applyMock();
mockGetCollectionMetadata.applyMock();
diff --git a/src/library-authoring/messages.ts b/src/library-authoring/messages.ts
index 7ae8c2b21..f0ac2cc1d 100644
--- a/src/library-authoring/messages.ts
+++ b/src/library-authoring/messages.ts
@@ -111,6 +111,11 @@ const messages = defineMessages({
defaultMessage: 'Change Library',
description: 'Breadcrumbs link to return to library selection',
},
+ librariesV2DisabledError: {
+ id: 'authoring.alert.error.libraries.v2.disabled',
+ defaultMessage: 'This page cannot be shown: Libraries v2 are disabled.',
+ description: 'Error message shown to users when trying to load a libraries V2 page while libraries v2 are disabled.',
+ },
});
export default messages;
diff --git a/src/studio-home/StudioHome.tsx b/src/studio-home/StudioHome.tsx
index 56e6b00cf..aff75fc6b 100644
--- a/src/studio-home/StudioHome.tsx
+++ b/src/studio-home/StudioHome.tsx
@@ -47,7 +47,7 @@ const StudioHome = () => {
setShowNewCourseContainer,
librariesV1Enabled,
librariesV2Enabled,
- } = useStudioHome(isPaginationCoursesEnabled);
+ } = useStudioHome();
const v1LibraryTab = librariesV1Enabled && location?.pathname.split('/').pop() === 'libraries-v1';
const showV2LibraryURL = librariesV2Enabled && !v1LibraryTab;
diff --git a/src/studio-home/hooks.jsx b/src/studio-home/hooks.jsx
index 584d69d84..81762eb1c 100644
--- a/src/studio-home/hooks.jsx
+++ b/src/studio-home/hooks.jsx
@@ -1,6 +1,7 @@
import { useEffect, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
+import { getConfig } from '@edx/frontend-platform';
import { RequestStatus } from '../data/constants';
import { COURSE_CREATOR_STATES } from '../constants';
@@ -14,9 +15,10 @@ import {
} from './data/selectors';
import { updateSavingStatuses } from './data/slice';
-const useStudioHome = (isPaginated = false) => {
+const useStudioHome = () => {
const location = useLocation();
const dispatch = useDispatch();
+ const isPaginated = getConfig().ENABLE_HOME_PAGE_COURSE_API_V2;
const studioHomeData = useSelector(getStudioHomeData);
const studioHomeCoursesParams = useSelector(getStudioHomeCoursesParams);
const { isFiltered } = studioHomeCoursesParams;