From 6187a9698f52cfe6a614ee33120fffdc4a2ba8eb Mon Sep 17 00:00:00 2001 From: Peter Kulko Date: Mon, 7 Oct 2024 16:58:42 +0300 Subject: [PATCH] chore: improved SPA routes --- .../ChecklistSection/ChecklistItemBody.jsx | 98 ++++++++++++------- .../ChecklistSection/ChecklistSection.jsx | 4 +- src/course-checklist/CourseChecklist.jsx | 1 + src/course-outline/hooks.jsx | 6 +- src/course-outline/status-bar/StatusBar.jsx | 21 ++-- src/course-unit/breadcrumbs/Breadcrumbs.jsx | 18 +++- src/generic/help-sidebar/HelpSidebar.jsx | 24 +++-- src/generic/help-sidebar/HelpSidebarLink.jsx | 19 +++- .../index.jsx | 4 +- src/group-configurations/index.jsx | 1 + src/header/Header.tsx | 20 ++-- src/header/hooks.js | 36 ++++--- src/hooks.ts | 6 +- src/pages-and-resources/PagesAndResources.jsx | 2 +- src/pages-and-resources/pages/PageCard.jsx | 5 +- src/pages-and-resources/pages/PageGrid.jsx | 6 +- .../pages/PageSettingButton.jsx | 44 +++++++-- src/studio-home/card-item/index.tsx | 10 +- src/studio-home/data/api.js | 27 ++++- src/studio-home/data/selectors.js | 2 +- src/utils.js | 2 +- 21 files changed, 255 insertions(+), 101 deletions(-) diff --git a/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx b/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx index f48bdc69b3..1d523416e4 100644 --- a/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx +++ b/src/course-checklist/ChecklistSection/ChecklistItemBody.jsx @@ -1,5 +1,5 @@ -import React from 'react'; import PropTypes from 'prop-types'; +import { useNavigate } from 'react-router'; import { injectIntl, intlShape, FormattedMessage } from '@edx/frontend-platform/i18n'; import { ActionRow, @@ -7,59 +7,83 @@ import { Hyperlink, Icon, } from '@openedx/paragon'; +import { useSelector } from 'react-redux'; import { CheckCircle, RadioButtonUnchecked } from '@openedx/paragon/icons'; + +import { getStudioHomeData } from '../../studio-home/data/selectors'; import messages from './messages'; const ChecklistItemBody = ({ + courseId, checkId, isCompleted, updateLink, // injected intl, -}) => ( - -
- {isCompleted ? ( - - ) : ( - - )} -
-
-
- +}) => { + const { waffleFlags } = useSelector(getStudioHomeData); + const navigate = useNavigate(); + + const handleClick = (e, url) => { + e.preventDefault(); + + if (waffleFlags?.ENABLE_NEW_COURSE_UPDATES_PAGE) { + navigate(`/course/${courseId}/course_info`); + } else { + window.location.href = url; + } + }; + + return ( + +
+ {isCompleted ? ( + + ) : ( + + )}
-
- +
+
+ +
+
+ +
-
- - {updateLink && ( - - - - )} -
-); + + {updateLink && ( + handleClick(e, updateLink)} + > + + + )} + + ); +}; ChecklistItemBody.defaultProps = { updateLink: null, }; ChecklistItemBody.propTypes = { + courseId: PropTypes.string.isRequired, checkId: PropTypes.string.isRequired, isCompleted: PropTypes.bool.isRequired, updateLink: PropTypes.string, diff --git a/src/course-checklist/ChecklistSection/ChecklistSection.jsx b/src/course-checklist/ChecklistSection/ChecklistSection.jsx index 46fe71889c..0af5611a17 100644 --- a/src/course-checklist/ChecklistSection/ChecklistSection.jsx +++ b/src/course-checklist/ChecklistSection/ChecklistSection.jsx @@ -10,6 +10,7 @@ import ChecklistItemComment from './ChecklistItemComment'; import { checklistItems } from './utils/courseChecklistData'; const ChecklistSection = ({ + courseId, dataHeading, data, idPrefix, @@ -46,7 +47,7 @@ const ChecklistSection = ({ data-testid={`checklist-item-${checkId}`} key={checkId} > - +
@@ -66,6 +67,7 @@ ChecklistSection.defaultProps = { }; ChecklistSection.propTypes = { + courseId: PropTypes.string.isRequired, dataHeading: PropTypes.string.isRequired, data: PropTypes.oneOfType([ PropTypes.shape({ diff --git a/src/course-checklist/CourseChecklist.jsx b/src/course-checklist/CourseChecklist.jsx index 5766bfe45e..2e0d5bcd8a 100644 --- a/src/course-checklist/CourseChecklist.jsx +++ b/src/course-checklist/CourseChecklist.jsx @@ -66,6 +66,7 @@ const CourseChecklist = ({ /> { const dispatch = useDispatch(); const navigate = useNavigate(); + const { waffleFlags } = useSelector(getStudioHomeData); const { reindexLink, @@ -112,7 +114,7 @@ const useCourseOutline = ({ courseId }) => { }; const getUnitUrl = (locator) => { - if (getConfig().ENABLE_UNIT_PAGE === 'true') { + if (getConfig().ENABLE_UNIT_PAGE === 'true' || waffleFlags?.ENABLE_NEW_UNIT_PAGE) { return `/course/${courseId}/container/${locator}`; } return `${getConfig().STUDIO_BASE_URL}/container/${locator}`; @@ -120,7 +122,7 @@ const useCourseOutline = ({ courseId }) => { const openUnitPage = (locator) => { const url = getUnitUrl(locator); - if (getConfig().ENABLE_UNIT_PAGE === 'true') { + if (getConfig().ENABLE_UNIT_PAGE === 'true' || waffleFlags?.ENABLE_NEW_UNIT_PAGE) { navigate(url); } else { window.location.assign(url); diff --git a/src/course-outline/status-bar/StatusBar.jsx b/src/course-outline/status-bar/StatusBar.jsx index ed8fa28309..cfae93734e 100644 --- a/src/course-outline/status-bar/StatusBar.jsx +++ b/src/course-outline/status-bar/StatusBar.jsx @@ -1,4 +1,4 @@ -import React, { useContext } from 'react'; +import { useContext } from 'react'; import moment from 'moment/moment'; import PropTypes from 'prop-types'; import { FormattedDate, useIntl } from '@edx/frontend-platform/i18n'; @@ -6,7 +6,10 @@ import { getConfig } from '@edx/frontend-platform/config'; import { Button, Hyperlink, Form, Stack, useToggle, } from '@openedx/paragon'; +import { Link } from 'react-router-dom'; import { AppContext } from '@edx/frontend-platform/react'; +import { useSelector } from 'react-redux'; +import { getStudioHomeData } from '../../studio-home/data/selectors'; import { ContentTagsDrawerSheet } from '../../content-tags-drawer'; import TagCount from '../../generic/tag-count'; @@ -43,6 +46,7 @@ const StatusBar = ({ }) => { const intl = useIntl(); const { config } = useContext(AppContext); + const { waffleFlags } = useSelector(getStudioHomeData); const { courseReleaseDate, @@ -62,7 +66,6 @@ const StatusBar = ({ const courseReleaseDateObj = moment.utc(courseReleaseDate, 'MMM DD, YYYY at HH:mm UTC', true); const checkListTitle = `${completedCourseLaunchChecks + completedCourseBestPracticesChecks}/${totalCourseLaunchChecks + totalCourseBestPracticesChecks}`; - const checklistDestination = () => new URL(`checklists/${courseId}`, config.STUDIO_BASE_URL).href; const scheduleDestination = () => new URL(`settings/details/${courseId}#schedule`, config.STUDIO_BASE_URL).href; const { @@ -82,10 +85,9 @@ const StatusBar = ({ <> - {courseReleaseDateObj.isValid() ? ( ) : courseReleaseDate} - + @@ -107,13 +109,12 @@ const StatusBar = ({ - {checkListTitle} {intl.formatMessage(messages.checklistCompleted)} - +
diff --git a/src/course-unit/breadcrumbs/Breadcrumbs.jsx b/src/course-unit/breadcrumbs/Breadcrumbs.jsx index 8dd34cfc52..bde230ff08 100644 --- a/src/course-unit/breadcrumbs/Breadcrumbs.jsx +++ b/src/course-unit/breadcrumbs/Breadcrumbs.jsx @@ -1,19 +1,33 @@ import { useSelector } from 'react-redux'; import { useIntl } from '@edx/frontend-platform/i18n'; import { Dropdown, Icon } from '@openedx/paragon'; +import { useNavigate } from 'react-router-dom'; import { ArrowDropDown as ArrowDropDownIcon, ChevronRight as ChevronRightIcon, } from '@openedx/paragon/icons'; +import { getConfig } from '@edx/frontend-platform'; import { createCorrectInternalRoute } from '../../utils'; import { getCourseSectionVertical } from '../data/selectors'; +import { getStudioHomeData } from '../../studio-home/data/selectors'; import messages from './messages'; const Breadcrumbs = () => { const intl = useIntl(); const { ancestorXblocks } = useSelector(getCourseSectionVertical); const [section, subsection] = ancestorXblocks ?? []; + const navigate = useNavigate(); + const { waffleFlags } = useSelector(getStudioHomeData); + + const handleClick = (e, url) => { + e.preventDefault(); + if (waffleFlags?.ENABLE_NEW_COURSE_OUTLINE_PAGE) { + navigate(url); + } else { + window.location.href = `${getConfig().STUDIO_BASE_URL}/${url}`; + } + }; return (