diff --git a/src/library-authoring/component-info/ComponentInfo.tsx b/src/library-authoring/component-info/ComponentInfo.tsx
index 38906d2d5c..e6ea4d74c2 100644
--- a/src/library-authoring/component-info/ComponentInfo.tsx
+++ b/src/library-authoring/component-info/ComponentInfo.tsx
@@ -5,21 +5,18 @@ import {
Tabs,
Stack,
} from '@openedx/paragon';
-import { useContext } from 'react';
-import { ToastContext } from '../../generic/toast-context';
import { useLibraryContext } from '../common/context';
import { ComponentMenu } from '../components';
import { canEditComponent } from '../components/ComponentEditorModal';
-import { useAddComponentToCourse } from '../data/apiHooks';
import ComponentDetails from './ComponentDetails';
import ComponentManagement from './ComponentManagement';
import ComponentPreview from './ComponentPreview';
import messages from './messages';
+import { getBlockType } from '../../generic/key-utils';
const ComponentInfo = () => {
const intl = useIntl();
- const { showToast } = useContext(ToastContext);
const {
sidebarComponentUsageKey: usageKey,
@@ -34,22 +31,15 @@ const ComponentInfo = () => {
throw new Error('usageKey is required');
}
- const {
- mutateAsync: addComponentToCourse,
- reset,
- } = useAddComponentToCourse(parentLocator, usageKey);
-
const canEdit = canEditComponent(usageKey);
const handleAddComponentToCourse = () => {
- addComponentToCourse()
- .then(() => {
- window.parent.postMessage('closeComponentPicker', '*');
- })
- .catch(() => {
- showToast(intl.formatMessage(messages.addComponentToCourseError));
- reset();
- });
+ window.parent.postMessage({
+ parentLocator,
+ usageKey,
+ type: 'pickerComponentSelected',
+ category: getBlockType(usageKey),
+ }, '*');
};
return (
diff --git a/src/library-authoring/component-picker/ComponentPicker.test.tsx b/src/library-authoring/component-picker/ComponentPicker.test.tsx
index f173c7b704..030dd4662e 100644
--- a/src/library-authoring/component-picker/ComponentPicker.test.tsx
+++ b/src/library-authoring/component-picker/ComponentPicker.test.tsx
@@ -1,12 +1,9 @@
-import type MockAdapter from 'axios-mock-adapter';
-
import { mockContentSearchConfig, mockSearchResult } from '../../search-manager/data/api.mock';
import {
initializeMocks,
fireEvent,
render,
screen,
- waitFor,
within,
} from '../../testUtils';
import mockResult from '../__mocks__/library-search.json';
@@ -17,7 +14,6 @@ import {
mockGetContentLibraryV2List,
mockLibraryBlockMetadata,
} from '../data/api.mocks';
-import { getXBlockBaseApiUrl } from '../data/api';
import { ComponentPicker } from './ComponentPicker';
@@ -27,8 +23,7 @@ mockGetCollectionMetadata.applyMock();
mockGetContentLibraryV2List.applyMock();
mockLibraryBlockMetadata.applyMock();
-let axiosMock: MockAdapter;
-let mockShowToast: (message: string) => void;
+let postMessageSpy: jest.SpyInstance;
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
@@ -44,10 +39,8 @@ jest.mock('react-router-dom', () => ({
describe('', () => {
beforeEach(() => {
- const mocks = initializeMocks();
- axiosMock = mocks.axiosMock;
- mockShowToast = mocks.mockShowToast;
- axiosMock.onPost(getXBlockBaseApiUrl()).reply(200, {});
+ initializeMocks();
+ postMessageSpy = jest.spyOn(window.parent, 'postMessage');
mockSearchResult(mockResult);
});
@@ -67,41 +60,12 @@ describe('', () => {
// Click the add component from the component card
fireEvent.click(screen.queryAllByRole('button', { name: 'Add' })[0]);
- await waitFor(() => {
- expect(axiosMock.history.post.length).toBe(1);
- expect(axiosMock.history.post[0].url).toBe(getXBlockBaseApiUrl());
- expect(axiosMock.history.post[0].data).toBe(JSON.stringify({
- parent_locator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
- library_content_key: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
- }));
- });
- });
-
- it('should show toast if error on api call from the component card button', async () => {
- axiosMock.onPost(getXBlockBaseApiUrl()).reply(500, {});
- render();
-
- expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
- fireEvent.click(screen.getByDisplayValue(/lib:sampletaxonomyorg1:tl1/i));
-
- fireEvent.click(screen.getByText('Next'));
-
- // Wait for the content library to load
- await screen.findByText(/Change Library/i);
- expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
-
- // Click the add component from the component card
- fireEvent.click(screen.queryAllByRole('button', { name: 'Add' })[0]);
-
- await waitFor(() => {
- expect(axiosMock.history.post.length).toBe(1);
- expect(axiosMock.history.post[0].url).toBe(getXBlockBaseApiUrl());
- expect(axiosMock.history.post[0].data).toBe(JSON.stringify({
- parent_locator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
- library_content_key: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
- }));
- expect(mockShowToast).toHaveBeenCalledWith('Failed to add component to course');
- });
+ expect(postMessageSpy).toHaveBeenCalledWith({
+ parentLocator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
+ usageKey: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
+ type: 'pickerComponentSelected',
+ category: 'html',
+ }, '*');
});
it('should pick component using the component sidebar', async () => {
@@ -124,46 +88,12 @@ describe('', () => {
// Click the add component from the component sidebar
fireEvent.click(within(sidebar).getByRole('button', { name: 'Add to Course' }));
- await waitFor(() => {
- expect(axiosMock.history.post.length).toBe(1);
- expect(axiosMock.history.post[0].url).toBe(getXBlockBaseApiUrl());
- expect(axiosMock.history.post[0].data).toBe(JSON.stringify({
- parent_locator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
- library_content_key: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
- }));
- });
- });
-
- it('should show toast if error on api call from the component sidebar button', async () => {
- axiosMock.onPost(getXBlockBaseApiUrl()).reply(500, {});
- render();
-
- expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
- fireEvent.click(screen.getByDisplayValue(/lib:sampletaxonomyorg1:tl1/i));
-
- fireEvent.click(screen.getByText('Next'));
-
- // Wait for the content library to load
- await screen.findByText(/Change Library/i);
- expect(await screen.findByText('Test Library 1')).toBeInTheDocument();
-
- // Click on the component card to open the sidebar
- fireEvent.click(screen.queryAllByText('Introduction to Testing')[0]);
-
- const sidebar = await screen.findByTestId('library-sidebar');
-
- // Click the add component from the component sidebar
- fireEvent.click(within(sidebar).getByRole('button', { name: 'Add to Course' }));
-
- await waitFor(() => {
- expect(axiosMock.history.post.length).toBe(1);
- expect(axiosMock.history.post[0].url).toBe(getXBlockBaseApiUrl());
- expect(axiosMock.history.post[0].data).toBe(JSON.stringify({
- parent_locator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
- library_content_key: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
- }));
- expect(mockShowToast).toHaveBeenCalledWith('Failed to add component to course');
- });
+ expect(postMessageSpy).toHaveBeenCalledWith({
+ parentLocator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
+ usageKey: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
+ type: 'pickerComponentSelected',
+ category: 'html',
+ }, '*');
});
it('should pick component inside a collection using the card', async () => {
@@ -196,14 +126,12 @@ describe('', () => {
// Click the add component from the component card
fireEvent.click(screen.queryAllByRole('button', { name: 'Add' })[0]);
- await waitFor(() => {
- expect(axiosMock.history.post.length).toBe(1);
- expect(axiosMock.history.post[0].url).toBe(getXBlockBaseApiUrl());
- expect(axiosMock.history.post[0].data).toBe(JSON.stringify({
- parent_locator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
- library_content_key: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
- }));
- });
+ expect(postMessageSpy).toHaveBeenCalledWith({
+ parentLocator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
+ usageKey: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
+ type: 'pickerComponentSelected',
+ category: 'html',
+ }, '*');
});
it('should pick component inside a collection using the sidebar', async () => {
@@ -241,14 +169,12 @@ describe('', () => {
// Click the add component from the collection sidebar
fireEvent.click(within(collectionSidebar).getByRole('button', { name: 'Add to Course' }));
- await waitFor(() => {
- expect(axiosMock.history.post.length).toBe(1);
- expect(axiosMock.history.post[0].url).toBe(getXBlockBaseApiUrl());
- expect(axiosMock.history.post[0].data).toBe(JSON.stringify({
- parent_locator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
- library_content_key: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
- }));
- });
+ expect(postMessageSpy).toHaveBeenCalledWith({
+ parentLocator: 'block-v1:edX+DemoX+Demo_Course+type@vertical+block@vertical1',
+ usageKey: 'lb:Axim:TEST:html:571fe018-f3ce-45c9-8f53-5dafcb422fdd',
+ type: 'pickerComponentSelected',
+ category: 'html',
+ }, '*');
});
it('should return to library selection', async () => {
diff --git a/src/library-authoring/components/ComponentCard.tsx b/src/library-authoring/components/ComponentCard.tsx
index 3e0b4e2d33..c8df6c202b 100644
--- a/src/library-authoring/components/ComponentCard.tsx
+++ b/src/library-authoring/components/ComponentCard.tsx
@@ -14,7 +14,7 @@ import { updateClipboard } from '../../generic/data/api';
import { ToastContext } from '../../generic/toast-context';
import { type ContentHit } from '../../search-manager';
import { useLibraryContext } from '../common/context';
-import { useAddComponentToCourse, useRemoveComponentsFromCollection } from '../data/apiHooks';
+import { useRemoveComponentsFromCollection } from '../data/apiHooks';
import BaseComponentCard from './BaseComponentCard';
import { canEditComponent } from './ComponentEditorModal';
import messages from './messages';
@@ -90,14 +90,11 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
};
const ComponentCard = ({ contentHit }: ComponentCardProps) => {
- const intl = useIntl();
-
const {
openComponentInfoSidebar,
componentPickerMode,
parentLocator,
} = useLibraryContext();
- const { showToast } = useContext(ToastContext);
const {
blockType,
@@ -112,20 +109,13 @@ const ComponentCard = ({ contentHit }: ComponentCardProps) => {
) ?? '';/* eslint-enable */
const displayName = formatted?.displayName ?? '';
- const {
- mutateAsync: addComponentToCourse,
- reset,
- } = useAddComponentToCourse(parentLocator, contentHit.usageKey);
-
const handleAddComponentToCourse = () => {
- addComponentToCourse()
- .then(() => {
- window.parent.postMessage('closeComponentPicker', '*');
- })
- .catch(() => {
- showToast(intl.formatMessage(messages.addComponentToCourseError));
- reset();
- });
+ window.parent.postMessage({
+ parentLocator,
+ usageKey,
+ type: 'pickerComponentSelected',
+ category: blockType,
+ }, '*');
};
return (
diff --git a/src/library-authoring/data/api.ts b/src/library-authoring/data/api.ts
index 578c06b336..d8f22c741d 100644
--- a/src/library-authoring/data/api.ts
+++ b/src/library-authoring/data/api.ts
@@ -483,15 +483,3 @@ export async function updateComponentCollections(usageKey: string, collectionKey
collection_keys: collectionKeys,
});
}
-
-/**
- * Add a component to a course.
- */
-// istanbul ignore next
-export async function addComponentToCourse(parentLocator: string, componentUsageKey: string) {
- const client = getAuthenticatedHttpClient();
- await client.post(getXBlockBaseApiUrl(), {
- parent_locator: parentLocator,
- library_content_key: componentUsageKey,
- });
-}
diff --git a/src/library-authoring/data/apiHooks.ts b/src/library-authoring/data/apiHooks.ts
index 6cfb0f333f..de43624855 100644
--- a/src/library-authoring/data/apiHooks.ts
+++ b/src/library-authoring/data/apiHooks.ts
@@ -40,7 +40,6 @@ import {
getXBlockAssets,
updateComponentCollections,
removeComponentsFromCollection,
- addComponentToCourse,
} from './api';
export const libraryQueryPredicate = (query: Query, libraryId: string): boolean => {
@@ -474,18 +473,3 @@ export const useUpdateComponentCollections = (libraryId: string, usageKey: strin
},
});
};
-
-/**
- * Use this mutation to add a component to a course
- */
-export const useAddComponentToCourse = (parentLocator: string | undefined, componentUsageKey: string) => (
- useMutation({
- mutationFn: () => {
- // istanbul ignore if: this should never happen
- if (!parentLocator) {
- throw new Error('parentLocator is required');
- }
- return addComponentToCourse(parentLocator, componentUsageKey);
- },
- })
-);