Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Send message after update tags on content [FC-0036] #800

Closed
Closed
11 changes: 11 additions & 0 deletions src/content-tags-drawer/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<Object>}
*/
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)
Expand Down
13 changes: 13 additions & 0 deletions src/content-tags-drawer/data/api.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ import {
import {
getTaxonomyTagsApiUrl,
getContentTaxonomyTagsApiUrl,
getContentTaxonomyTagsCountApiUrl,
getXBlockContentDataApiURL,
getLibraryContentDataApiUrl,
getTaxonomyTagsData,
getContentTaxonomyTagsData,
getContentTaxonomyTagsCountData,
getContentData,
updateContentTaxonomyTags,
} from './api';
Expand Down Expand Up @@ -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);
Expand Down
35 changes: 35 additions & 0 deletions src/content-tags-drawer/data/apiHooks.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-check
import { useMemo } from 'react';
import { getConfig } from '@edx/frontend-platform';
import {
useQuery,
useQueries,
Expand All @@ -9,6 +10,7 @@ import {
import {
getTaxonomyTagsData,
getContentTaxonomyTagsData,
getContentTaxonomyTagsCountData,
getContentData,
updateContentTaxonomyTags,
} from './api';
Expand Down Expand Up @@ -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) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be simpler to just send a message that the count has changed, with only the contentId and to let the parent frame call the API to retrieve the updated count if it wants to. That will keep the code here simpler. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have also thought the same thing, but I feel that it is simpler to make and handle the API calls here and just send the data to be displayed in the template. Also I don't think there is much problem with the code here since it is temporary

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I just don't want people to copy this pattern when they move it into the MFE. If we just use React-Query in the MFE it will update without any special code, as long as we do the "query invalidation" correctly.

const contentData = {
contentId,
count: data,
};
window.top?.postMessage(
{ type: 'authoring.events.tags.count.updated', data: contentData },
getConfig().STUDIO_BASE_URL,
);
});
}
},
});
};
Loading