From 92c3a98a3dd22d166a40365e0efa2f533e668b32 Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Thu, 7 Aug 2025 01:11:05 +0530 Subject: [PATCH] fix: show/hide add unit button based on childAddable flag of parent in unit page (#2351) Course unit page shows Add Unit option without checking whether the parent subsection allows adding children. This fixes it. --- src/course-unit/CourseUnit.test.jsx | 22 +++++++++++++++++++ .../SequenceNavigationTabs.jsx | 6 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/course-unit/CourseUnit.test.jsx b/src/course-unit/CourseUnit.test.jsx index 8f000d041..60305c385 100644 --- a/src/course-unit/CourseUnit.test.jsx +++ b/src/course-unit/CourseUnit.test.jsx @@ -792,6 +792,28 @@ describe('', () => { .toHaveBeenCalledWith(`/course/${courseId}/container/${blockId}/${updatedAncestorsChild.id}`, { replace: true }); }); + it('Show or hide new unit button based on parent sequence childAddable action', async () => { + render(); + // The new unit button should be visible when childAddable is true + await screen.findByRole('button', { name: courseSequenceMessages.newUnitBtnText.defaultMessage }); + + const updatedCourseSectionVerticalData = cloneDeep(courseSectionVerticalMock); + // Set childAddable to false for sequence i.e. current units parent. + set(updatedCourseSectionVerticalData, 'xblock_info.ancestor_info.ancestors[0].actions.childAddable', false); + axiosMock + .onGet(getCourseSectionVerticalApiUrl(blockId)) + .reply(200, { + ...updatedCourseSectionVerticalData, + }); + render(); + // to wait for loading + screen.findByTestId('unit-header-title'); + // The new unit button should not be visible when childAddable is false + expect( + screen.queryByRole('button', { name: courseSequenceMessages.newUnitBtnText.defaultMessage }), + ).not.toBeInTheDocument(); + }); + it('the sequence unit is updated after changing the unit header', async () => { const user = userEvent.setup(); render(); diff --git a/src/course-unit/course-sequence/sequence-navigation/SequenceNavigationTabs.jsx b/src/course-unit/course-sequence/sequence-navigation/SequenceNavigationTabs.jsx index 77372988f..0307c2f55 100644 --- a/src/course-unit/course-sequence/sequence-navigation/SequenceNavigationTabs.jsx +++ b/src/course-unit/course-sequence/sequence-navigation/SequenceNavigationTabs.jsx @@ -6,7 +6,7 @@ import { Plus as PlusIcon, ContentPasteGo as ContentPasteGoIcon } from '@openedx import { useIntl } from '@edx/frontend-platform/i18n'; import { changeEditTitleFormOpen, updateQueryPendingStatus } from '../../data/slice'; -import { getCourseId, getSequenceId } from '../../data/selectors'; +import { getCourseUnitData, getCourseId, getSequenceId } from '../../data/selectors'; import messages from '../messages'; import { useIndexOfLastVisibleChild } from '../hooks'; import SequenceNavigationDropdown from './SequenceNavigationDropdown'; @@ -20,6 +20,8 @@ const SequenceNavigationTabs = ({ const navigate = useNavigate(); const sequenceId = useSelector(getSequenceId); const courseId = useSelector(getCourseId); + const courseUnit = useSelector(getCourseUnitData); + const sequenceChildAddable = courseUnit?.ancestorInfo?.ancestors?.[0]?.actions?.childAddable; const [ indexOfLastVisibleChild, @@ -58,6 +60,7 @@ const SequenceNavigationTabs = ({ isActive={unitId === buttonUnitId} /> ))} + {sequenceChildAddable && ( + )} {showPasteUnit && (