Skip to content

Commit

Permalink
feat: tag sections, subsections, and the whole course
Browse files Browse the repository at this point in the history
  • Loading branch information
rpenido committed Mar 12, 2024
1 parent 1fdddfb commit d1bad89
Show file tree
Hide file tree
Showing 16 changed files with 553 additions and 412 deletions.
8 changes: 7 additions & 1 deletion src/content-tags-drawer/data/apiHooks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,13 @@ export const useContentTaxonomyTagsUpdater = (contentId, taxonomyId) => {
onSettled: /* istanbul ignore next */ () => {
queryClient.invalidateQueries({ queryKey: ['contentTaxonomyTags', contentId] });
/// Invalidate query with pattern on course outline
queryClient.invalidateQueries({ queryKey: ['unitTagsCount'] });
let contentPattern;
if (contentId.includes('course-v1')) {
contentPattern = contentId;
} else {
contentPattern = contentId.replace(/\+type@.*$/, '*');
}
queryClient.invalidateQueries({ queryKey: ['contentTagsCount', contentPattern] });
},
});
};
31 changes: 4 additions & 27 deletions src/course-outline/CourseOutline.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState, useEffect, useMemo } from 'react';
// @ts-check
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Expand Down Expand Up @@ -43,7 +44,6 @@ import ConfigureModal from './configure-modal/ConfigureModal';
import PageAlerts from './page-alerts/PageAlerts';
import { useCourseOutline } from './hooks';
import messages from './messages';
import useUnitTagsCount from './data/apiHooks';

const CourseOutline = ({ courseId }) => {
const intl = useIntl();
Expand Down Expand Up @@ -163,35 +163,14 @@ const CourseOutline = ({ courseId }) => {
});
};

const unitsIdPattern = useMemo(() => {
let pattern = '';
sections.forEach((section) => {
section.childInfo.children.forEach((subsection) => {
subsection.childInfo.children.forEach((unit) => {
if (pattern !== '') {
pattern += `,${unit.id}`;
} else {
pattern += unit.id;
}
});
});
});
return pattern;
}, [sections]);

const {
data: unitsTagCounts,
isSuccess: isUnitsTagCountsLoaded,
} = useUnitTagsCount(unitsIdPattern);

/**
* Check if item can be moved by given step.
* Inner function returns false if the new index after moving by given step
* is out of bounds of item length.
* If it is within bounds, returns draggable flag of the item in the new index.
* This helps us avoid moving the item to a position of unmovable item.
* @param {Array} items
* @returns {(id, step) => bool}
* @returns {(id, step) => boolean}
*/
const canMoveItem = (items) => (id, step) => {
const newId = id + step;
Expand Down Expand Up @@ -312,7 +291,6 @@ const CourseOutline = ({ courseId }) => {
) : null}
</TransitionReplace>
<SubHeader
className="mt-5"
title={intl.formatMessage(messages.headingTitle)}
subtitle={intl.formatMessage(messages.headingSubtitle)}
headerActions={(
Expand Down Expand Up @@ -350,7 +328,6 @@ const CourseOutline = ({ courseId }) => {
<DraggableList itemList={sections} setState={setSections} updateOrder={finalizeSectionOrder}>
{sections.map((section, sectionIndex) => (
<SectionCard
id={section.id}
key={section.id}
section={section}
index={sectionIndex}
Expand Down Expand Up @@ -427,7 +404,6 @@ const CourseOutline = ({ courseId }) => {
)}
onCopyToClipboardClick={handleCopyToClipboardClick}
discussionsSettings={discussionsSettings}
tagsCount={isUnitsTagCountsLoaded ? unitsTagCounts[unit.id] : 0}
/>
))}
</DraggableList>
Expand Down Expand Up @@ -510,6 +486,7 @@ const CourseOutline = ({ courseId }) => {
variant="danger"
icon={WarningIcon}
title={intl.formatMessage(messages.alertErrorTitle)}
description=""
aria-hidden="true"
/>
)}
Expand Down
17 changes: 11 additions & 6 deletions src/course-outline/CourseOutline.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { AppProvider } from '@edx/frontend-platform/react';
import { initializeMockApp } from '@edx/frontend-platform';
import MockAdapter from 'axios-mock-adapter';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { cloneDeep } from 'lodash';

import {
Expand Down Expand Up @@ -78,16 +79,20 @@ jest.mock('@edx/frontend-platform/i18n', () => ({
}),
}));

jest.mock('./data/apiHooks', () => () => ({
data: {},
isSuccess: true,
jest.mock('./data/api', () => ({
...jest.requireActual('./data/api'),
getTagsCount: () => jest.fn().mockResolvedValue({}),
}));

const queryClient = new QueryClient();

const RootWrapper = () => (
<AppProvider store={store}>
<IntlProvider locale="en">
<CourseOutline courseId={courseId} />
</IntlProvider>
<QueryClientProvider client={queryClient}>
<IntlProvider locale="en">
<CourseOutline courseId={courseId} />
</IntlProvider>
</QueryClientProvider>
</AppProvider>
);

Expand Down
Loading

0 comments on commit d1bad89

Please sign in to comment.