diff --git a/src/course-outline/CourseOutline.jsx b/src/course-outline/CourseOutline.jsx
index 678b721093..6811e3244b 100644
--- a/src/course-outline/CourseOutline.jsx
+++ b/src/course-outline/CourseOutline.jsx
@@ -1,6 +1,4 @@
-import {
- React, useState, useEffect,
-} from 'react';
+import { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
@@ -40,7 +38,9 @@ import EmptyPlaceholder from './empty-placeholder/EmptyPlaceholder';
import PublishModal from './publish-modal/PublishModal';
import ConfigureModal from './configure-modal/ConfigureModal';
import DeleteModal from './delete-modal/DeleteModal';
-import { useCourseOutline } from './hooks';
+import {
+ useCourseOutline, useScrollToLocatorElement,
+} from './hooks';
import messages from './messages';
const CourseOutline = ({ courseId }) => {
@@ -88,6 +88,8 @@ const CourseOutline = ({ courseId }) => {
handleDragNDrop,
} = useCourseOutline({ courseId });
+ useScrollToLocatorElement({ isLoading });
+
const [sections, setSections] = useState(sectionsList);
const initialSections = [...sectionsList];
diff --git a/src/course-outline/CourseOutline.test.jsx b/src/course-outline/CourseOutline.test.jsx
index 0f4ee33e17..77d81fc9ce 100644
--- a/src/course-outline/CourseOutline.test.jsx
+++ b/src/course-outline/CourseOutline.test.jsx
@@ -1,4 +1,3 @@
-import React from 'react';
import {
act, render, waitFor, cleanup, fireEvent, within,
} from '@testing-library/react';
@@ -46,6 +45,8 @@ let axiosMock;
let store;
const mockPathname = '/foo-bar';
const courseId = '123';
+const locatorSectionName = 'Demo Course Overview';
+const locatorSectionId = 'block-v1:edX+DemoX+Demo_Course+type@sequential+block@edx_introduction';
window.HTMLElement.prototype.scrollIntoView = jest.fn();
@@ -54,6 +55,7 @@ jest.mock('react-router-dom', () => ({
useLocation: () => ({
pathname: mockPathname,
}),
+ useSearchParams: () => [new URLSearchParams({ show: locatorSectionId })],
}));
jest.mock('../help-urls/hooks', () => ({
@@ -380,6 +382,18 @@ describe('', () => {
expect(await findAllByTestId('section-card')).toHaveLength(5);
});
+ it('check correct scrolling to the locator section when URL has a "show" param', async () => {
+ const scrollIntoViewFn = jest.fn();
+ window.HTMLElement.prototype.scrollIntoView = scrollIntoViewFn;
+ const { getByText } = render();
+
+ await waitFor(() => {
+ expect(getByText(locatorSectionName)).toBeInTheDocument();
+ expect(scrollIntoViewFn).toHaveBeenCalled();
+ expect(scrollIntoViewFn).toHaveBeenCalledWith({'behavior': 'smooth'});
+ });
+ });
+
it('check whether subsection is duplicated successfully', async () => {
const { findAllByTestId } = render();
const section = courseOutlineIndexMock.courseStructure.childInfo.children[0];
diff --git a/src/course-outline/card-header/CardHeader.jsx b/src/course-outline/card-header/CardHeader.jsx
index 2c06e02220..76a2c22a02 100644
--- a/src/course-outline/card-header/CardHeader.jsx
+++ b/src/course-outline/card-header/CardHeader.jsx
@@ -27,6 +27,7 @@ import messages from './messages';
const CardHeader = ({
title,
status,
+ sectionId,
hasChanges,
isExpanded,
onClickPublish,
@@ -58,7 +59,11 @@ const CardHeader = ({
});
return (
-
+
{isFormOpen ? (
{
};
};
-// eslint-disable-next-line import/prefer-default-export
-export { useCourseOutline };
+const useScrollToLocatorElement = ({ isLoading }) => {
+ const [searchParams] = useSearchParams();
+
+ useEffect(() => {
+ const locator = searchParams.get('show');
+ const locatorToShow = document.querySelector(`[data-locator="${locator}"]`);
+
+ if (locator && locatorToShow) {
+ locatorToShow.scrollIntoView({ behavior: 'smooth' });
+ }
+ }, [isLoading]);
+};
+
+export {
+ useCourseOutline,
+ useScrollToLocatorElement,
+};
diff --git a/src/course-outline/section-card/SectionCard.jsx b/src/course-outline/section-card/SectionCard.jsx
index 8b6730d37b..11d0315eac 100644
--- a/src/course-outline/section-card/SectionCard.jsx
+++ b/src/course-outline/section-card/SectionCard.jsx
@@ -122,7 +122,10 @@ const SectionCard = ({
onClickDuplicate={onDuplicateSubmit}
namePrefix="section"
/>
-
+