From 27c4eec746daaefc716c3bc3fc397d20d55a584c Mon Sep 17 00:00:00 2001 From: Navin Karkera Date: Wed, 19 Mar 2025 17:49:22 +0000 Subject: [PATCH] refactor: open review tab in course libraries if out of sync (#1743) --- src/course-libraries/CourseLibraries.test.tsx | 18 ++++++++++++++---- src/course-libraries/CourseLibraries.tsx | 17 +++++++++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/course-libraries/CourseLibraries.test.tsx b/src/course-libraries/CourseLibraries.test.tsx index 286e48a79..418bbcc91 100644 --- a/src/course-libraries/CourseLibraries.test.tsx +++ b/src/course-libraries/CourseLibraries.test.tsx @@ -76,11 +76,16 @@ describe('', () => { it('shows alert when out of sync components are present', async () => { await renderCourseLibrariesPage(mockGetEntityLinks.courseKey); + const allTab = await screen.findByRole('tab', { name: 'Libraries' }); + const reviewTab = await screen.findByRole('tab', { name: 'Review Content Updates 5' }); + // review tab should be open by default as outOfSyncCount is greater than 0 + expect(reviewTab).toHaveAttribute('aria-selected', 'true'); + + userEvent.click(allTab); const alert = await screen.findByRole('alert'); expect(await within(alert).findByText( '5 library components are out of sync. Review updates to accept or ignore changes', )).toBeInTheDocument(); - const allTab = await screen.findByRole('tab', { name: 'Libraries' }); expect(allTab).toHaveAttribute('aria-selected', 'true'); const reviewBtn = await screen.findByRole('button', { name: 'Review' }); @@ -104,16 +109,21 @@ describe('', () => { it('hide alert on dismiss', async () => { await renderCourseLibrariesPage(mockGetEntityLinks.courseKey); + const reviewTab = await screen.findByRole('tab', { name: 'Review Content Updates 5' }); + // review tab should be open by default as outOfSyncCount is greater than 0 + expect(reviewTab).toHaveAttribute('aria-selected', 'true'); + const allTab = await screen.findByRole('tab', { name: 'Libraries' }); + userEvent.click(allTab); + expect(allTab).toHaveAttribute('aria-selected', 'true'); + const alert = await screen.findByRole('alert'); expect(await within(alert).findByText( '5 library components are out of sync. Review updates to accept or ignore changes', )).toBeInTheDocument(); const dismissBtn = await screen.findByRole('button', { name: 'Dismiss' }); userEvent.click(dismissBtn); - const allTab = await screen.findByRole('tab', { name: 'Libraries' }); expect(allTab).toHaveAttribute('aria-selected', 'true'); - - expect(alert).not.toBeInTheDocument(); + waitFor(() => expect(alert).not.toBeInTheDocument()); }); }); diff --git a/src/course-libraries/CourseLibraries.tsx b/src/course-libraries/CourseLibraries.tsx index d449f6942..fcdea5c98 100644 --- a/src/course-libraries/CourseLibraries.tsx +++ b/src/course-libraries/CourseLibraries.tsx @@ -1,5 +1,5 @@ import React, { - useCallback, useMemo, useState, + useCallback, useEffect, useMemo, useState, } from 'react'; import { Helmet } from 'react-helmet'; import { getConfig } from '@edx/frontend-platform'; @@ -105,7 +105,7 @@ export const CourseLibraries: React.FC = ({ courseId }) => { const courseDetails = useModel('courseDetails', courseId); const [searchParams] = useSearchParams(); const [tabKey, setTabKey] = useState( - () => searchParams.get('tab') as CourseLibraryTabs || CourseLibraryTabs.all, + () => searchParams.get('tab') as CourseLibraryTabs, ); const [showReviewAlert, setShowReviewAlert] = useState(false); const { data: libraries, isLoading } = useEntityLinksSummaryByDownstreamContext(courseId); @@ -124,6 +124,19 @@ export const CourseLibraries: React.FC = ({ courseId }) => { setTabKey(selectedTab); }, []); + useEffect(() => { + setTabKey((prev) => { + if (outOfSyncCount > 0) { + return CourseLibraryTabs.review; + } + if (prev) { + return prev; + } + /* istanbul ignore next */ + return CourseLibraryTabs.all; + }); + }, [outOfSyncCount]); + const renderLibrariesTabContent = useCallback(() => { if (isLoading) { return ;