Skip to content

Commit

Permalink
feat: api call for adding component to collection
Browse files Browse the repository at this point in the history
  • Loading branch information
navinkarkera committed Sep 20, 2024
1 parent 2848746 commit d388335
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 6 deletions.
7 changes: 5 additions & 2 deletions src/library-authoring/add-content/AddContentContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useLocation, useNavigate, useParams } from 'react-router-dom';
import { ToastContext } from '../../generic/toast-context';
import { useCopyToClipboard } from '../../generic/clipboard';
import { getCanEdit } from '../../course-unit/data/selectors';
import { useCreateLibraryBlock, useLibraryPasteClipboard } from '../data/apiHooks';
import { useCreateLibraryBlock, useLibraryPasteClipboard, useUpdateCollectionComponents } from '../data/apiHooks';
import { getEditUrl } from '../components/utils';

import messages from './messages';
Expand Down Expand Up @@ -66,6 +66,7 @@ const AddContentContainer = () => {
const currentPath = location.pathname;
const { libraryId, collectionId } = useParams();
const createBlockMutation = useCreateLibraryBlock();
const updateComponentsMutation = useUpdateCollectionComponents(libraryId, collectionId);
const pasteClipboardMutation = useLibraryPasteClipboard();
const { showToast } = useContext(ToastContext);
const canEdit = useSelector(getCanEdit);
Expand Down Expand Up @@ -149,9 +150,11 @@ const AddContentContainer = () => {
libraryId,
blockType,
definitionId: `${uuid4()}`,
collectionId,
}).then((data) => {
const editUrl = getEditUrl(data.id);
updateComponentsMutation.mutateAsync([data.id]).catch(() => {
showToast(intl.formatMessage(messages.errorAssociateComponentMessage));

Check warning on line 156 in src/library-authoring/add-content/AddContentContainer.tsx

View check run for this annotation

Codecov / codecov/patch

src/library-authoring/add-content/AddContentContainer.tsx#L156

Added line #L156 was not covered by tests
});
if (editUrl) {
// Pass currentPath in state so that we can come back to
// current page on save or cancel
Expand Down
5 changes: 5 additions & 0 deletions src/library-authoring/add-content/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ const messages = defineMessages({
defaultMessage: 'There was an error creating the content.',
description: 'Message when creation of content in library is on error',
},
errorAssociateComponentMessage: {
id: 'course-authoring.library-authoring.associate-collection-content.error.text',
defaultMessage: 'There was an error linking the content to this collection.',
description: 'Message when linking of content to a collection in library fails',
},
addContentTitle: {
id: 'course-authoring.library-authoring.sidebar.title.add-content',
defaultMessage: 'Add Content',
Expand Down
16 changes: 13 additions & 3 deletions src/library-authoring/data/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export const getLibraryCollectionsApiUrl = (libraryId: string) => `${getApiBaseU
* Get the URL for the collection API.
*/
export const getLibraryCollectionApiUrl = (libraryId: string, collectionId: string) => `${getLibraryCollectionsApiUrl(libraryId)}${collectionId}/`;
/**
* Get the URL for the collection API.
*/
export const getLibraryCollectionComponentApiUrl = (libraryId: string, collectionId: string) => `${getLibraryCollectionApiUrl(libraryId, collectionId)}components/`;

export interface ContentLibrary {
id: string;
Expand Down Expand Up @@ -132,7 +136,6 @@ export interface CreateBlockDataRequest {
libraryId: string;
blockType: string;
definitionId: string;
collectionId?: string;
}

export interface LibraryBlockMetadata {
Expand Down Expand Up @@ -196,15 +199,13 @@ export async function createLibraryBlock({
libraryId,
blockType,
definitionId,
collectionId,
}: CreateBlockDataRequest): Promise<LibraryBlockMetadata> {
const client = getAuthenticatedHttpClient();
const { data } = await client.post(
getCreateLibraryBlockUrl(libraryId),
{
block_type: blockType,
definition_id: definitionId,
collection_key: collectionId,
},
);
return camelCaseObject(data);
Expand Down Expand Up @@ -313,3 +314,12 @@ export async function getXBlockOLX(usageKey: string): Promise<string> {
const { data } = await getAuthenticatedHttpClient().get(getXBlockOLXApiUrl(usageKey));
return data.olx;
}

/**
* Update collection components.
*/
export async function updateCollectionComponents(libraryId:string, collectionId: string, usageKeys: string[]) {
await getAuthenticatedHttpClient().patch(getLibraryCollectionComponentApiUrl(libraryId, collectionId), {
usage_keys: usageKeys,
});
}
19 changes: 18 additions & 1 deletion src/library-authoring/data/apiHooks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { renderHook } from '@testing-library/react-hooks';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import MockAdapter from 'axios-mock-adapter';
import { getCommitLibraryChangesUrl, getCreateLibraryBlockUrl, getLibraryCollectionsApiUrl } from './api';
import {
getCommitLibraryChangesUrl,
getCreateLibraryBlockUrl,
getLibraryCollectionComponentApiUrl,
getLibraryCollectionsApiUrl,
} from './api';
import {
useCommitLibraryChanges,
useCreateLibraryBlock,
useCreateLibraryCollection,
useRevertLibraryChanges,
useUpdateCollectionComponents,
} from './apiHooks';

let axiosMock;
Expand Down Expand Up @@ -89,4 +95,15 @@ describe('library api hooks', () => {

expect(axiosMock.history.post[0].url).toEqual(url);
});

it('should add components to collection', async () => {
const libraryId = 'lib:org:1';
const collectionId = 'my-first-collection';
const url = getLibraryCollectionComponentApiUrl(libraryId, collectionId);
axiosMock.onPatch(url).reply(200);
const { result } = renderHook(() => useUpdateCollectionComponents(libraryId, collectionId), { wrapper });
await result.current.mutateAsync(['some-usage-key']);

expect(axiosMock.history.patch[0].url).toEqual(url);
});
});
22 changes: 22 additions & 0 deletions src/library-authoring/data/apiHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
updateXBlockFields,
createCollection,
getXBlockOLX,
updateCollectionComponents,
type CreateLibraryCollectionDataRequest,
} from './api';

Expand Down Expand Up @@ -275,3 +276,24 @@ export const useXBlockOLX = (usageKey: string) => (
enabled: !!usageKey,
})
);

/**
* Use this mutation to add components to a collection in a library
*/
export const useUpdateCollectionComponents = (libraryId?: string, collectionId?: string) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (usage_keys: string[]) => {
if (libraryId !== undefined && collectionId !== undefined) {
return updateCollectionComponents(libraryId, collectionId, usage_keys);
}
return undefined;
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onSettled: (_data, _error, _variables) => {
if (libraryId !== undefined && collectionId !== undefined) {
queryClient.invalidateQueries({ predicate: (query) => libraryQueryPredicate(query, libraryId) });
}
},
});
};

0 comments on commit d388335

Please sign in to comment.