diff --git a/src/content-tags-drawer/data/api.js b/src/content-tags-drawer/data/api.js index 28bd7a36c8..4ad0275e4f 100644 --- a/src/content-tags-drawer/data/api.js +++ b/src/content-tags-drawer/data/api.js @@ -29,6 +29,7 @@ export const getTaxonomyTagsApiUrl = (taxonomyId, options = {}) => { return url.href; }; export const getContentTaxonomyTagsApiUrl = (contentId) => new URL(`api/content_tagging/v1/object_tags/${contentId}/`, getApiBaseUrl()).href; +export const getContentTaxonomyTagsCountApiUrl = (contentId) => new URL(`api/content_tagging/v1/object_tag_counts/${contentId}/?count_implicit`, getApiBaseUrl()).href; export const getXBlockContentDataApiURL = (contentId) => new URL(`/xblock/outline/${contentId}`, getApiBaseUrl()).href; export const getLibraryContentDataApiUrl = (contentId) => new URL(`/api/libraries/v2/blocks/${contentId}/`, getApiBaseUrl()).href; @@ -54,6 +55,16 @@ export async function getContentTaxonomyTagsData(contentId) { return camelCaseObject(data[contentId]); } +/** + * Get the count of the tags that are applied to the content object + * @param {string} contentId The id of the content object to fetch the applied tags for + * @returns {Promise} + */ +export async function getContentTaxonomyTagsCountData(contentId) { + const { data } = await getAuthenticatedHttpClient().get(getContentTaxonomyTagsCountApiUrl(contentId)); + return camelCaseObject(data[contentId]); +} + /** * Fetch meta data (eg: display_name) about the content object (unit/compoenent) * @param {string} contentId The id of the content object (unit/component) diff --git a/src/content-tags-drawer/data/api.test.js b/src/content-tags-drawer/data/api.test.js index 9fa88dcb79..1863c8d833 100644 --- a/src/content-tags-drawer/data/api.test.js +++ b/src/content-tags-drawer/data/api.test.js @@ -13,10 +13,12 @@ import { import { getTaxonomyTagsApiUrl, getContentTaxonomyTagsApiUrl, + getContentTaxonomyTagsCountApiUrl, getXBlockContentDataApiURL, getLibraryContentDataApiUrl, getTaxonomyTagsData, getContentTaxonomyTagsData, + getContentTaxonomyTagsCountData, getContentData, updateContentTaxonomyTags, } from './api'; @@ -88,6 +90,17 @@ describe('content tags drawer api calls', () => { expect(result).toEqual(contentTaxonomyTagsMock[contentId]); }); + it('should get content taxonomy tags count', async () => { + const contentId = 'block-v1:SampleTaxonomyOrg1+STC1+2023_1+type@vertical+block@aaf8b8eb86b54281aeeab12499d2cb0b'; + const dataMock = {}; + dataMock[contentId] = 1000; + axiosMock.onGet(getContentTaxonomyTagsCountApiUrl(contentId)).reply(200, dataMock); + const result = await getContentTaxonomyTagsCountData(contentId); + + expect(axiosMock.history.get[0].url).toEqual(getContentTaxonomyTagsCountApiUrl(contentId)); + expect(result).toEqual(1000); + }); + it('should get content data for course component', async () => { const contentId = 'block-v1:SampleTaxonomyOrg1+STC1+2023_1+type@vertical+block@aaf8b8eb86b54281aeeab12499d2cb0b'; axiosMock.onGet(getXBlockContentDataApiURL(contentId)).reply(200, contentDataMock); diff --git a/src/content-tags-drawer/data/apiHooks.jsx b/src/content-tags-drawer/data/apiHooks.jsx index 1b95f60936..e7afba6d03 100644 --- a/src/content-tags-drawer/data/apiHooks.jsx +++ b/src/content-tags-drawer/data/apiHooks.jsx @@ -1,5 +1,6 @@ // @ts-check import { useMemo } from 'react'; +import { getConfig } from '@edx/frontend-platform'; import { useQuery, useQueries, @@ -9,6 +10,7 @@ import { import { getTaxonomyTagsData, getContentTaxonomyTagsData, + getContentTaxonomyTagsCountData, getContentData, updateContentTaxonomyTags, } from './api'; @@ -138,5 +140,38 @@ export const useContentTaxonomyTagsUpdater = (contentId, taxonomyId) => { onSettled: () => { queryClient.invalidateQueries({ queryKey: ['contentTaxonomyTags', contentId] }); }, + onSuccess: /* istanbul ignore next */ () => { + if (window.top != null) { + // This send messages to the parent page if the drawer is called from a iframe. + // Is used on Studio to update tags data and counts. + // In the future, when the Course Outline Page and Unit Page are integrated into this MFE, + // they should just use React Query to load the tag counts, and React Query will automatically + // refresh those counts when the mutation invalidates them. So this postMessage is just a temporary + // feature to support the legacy Django template courseware page. + + // Sends content tags. + getContentTaxonomyTagsData(contentId).then((data) => { + const contentData = { + contentId, + ...data, + }; + window.top?.postMessage( + { type: 'authoring.events.tags.updated', data: contentData }, + getConfig().STUDIO_BASE_URL, + ); + }); + // Sends tags count. + getContentTaxonomyTagsCountData(contentId).then((data) => { + const contentData = { + contentId, + count: data, + }; + window.top?.postMessage( + { type: 'authoring.events.tags.count.updated', data: contentData }, + getConfig().STUDIO_BASE_URL, + ); + }); + } + }, }); };