diff --git a/src/courseware/course/SequenceContainer.jsx b/src/courseware/course/SequenceContainer.jsx index 98d81867..6ab03dee 100644 --- a/src/courseware/course/SequenceContainer.jsx +++ b/src/courseware/course/SequenceContainer.jsx @@ -10,6 +10,7 @@ import PageLoading from '../../PageLoading'; import Sequence from '../sequence/Sequence'; import AlertList from '../../user-messages/AlertList'; import { fetchSequenceMetadata, checkBlockCompletion, saveSequencePosition } from '../../data/course-blocks'; +import { createSequenceIdList } from '../utils'; function SequenceContainer(props) { const { @@ -30,10 +31,12 @@ function SequenceContainer(props) { position, items, lmsWebUrl, + models, } = props; const loaded = fetchState === 'loaded'; const unitIds = useMemo(() => items.map(({ id }) => id), [items]); + const sequenceIds = useMemo(() => createSequenceIdList(models, courseId), [models, courseId]); useEffect(() => { props.fetchSequenceMetadata(sequenceId); @@ -68,7 +71,9 @@ function SequenceContainer(props) { }, [isTimeLimited]); const isLoading = !loaded || !unitId || isTimeLimited; - + const isFirstUnit = sequenceIds.indexOf(sequenceId) === 0 && unitIds.indexOf(unitId) === 0; + const isLastUnit = sequenceIds.indexOf(sequenceId) === sequenceIds.length - 1 + && unitIds.indexOf(unitId) === unitIds.length - 1; return ( <> @@ -79,24 +84,22 @@ function SequenceContainer(props) { /> ) : ( )} @@ -121,6 +124,12 @@ SequenceContainer.propTypes = { gatedSectionName: PropTypes.string, prereqId: PropTypes.string, }), + models: PropTypes.objectOf(PropTypes.shape({ + id: PropTypes.string.isRequired, + displayName: PropTypes.string.isRequired, + children: PropTypes.arrayOf(PropTypes.string), + parentId: PropTypes.string, + })).isRequired, checkBlockCompletion: PropTypes.func.isRequired, fetchSequenceMetadata: PropTypes.func.isRequired, saveSequencePosition: PropTypes.func.isRequired, diff --git a/src/courseware/sequence/Sequence.jsx b/src/courseware/sequence/Sequence.jsx index 44d397a0..394775cb 100644 --- a/src/courseware/sequence/Sequence.jsx +++ b/src/courseware/sequence/Sequence.jsx @@ -18,18 +18,20 @@ import UserMessagesContext from '../../user-messages/UserMessagesContext'; const ContentLock = React.lazy(() => import('./content-lock')); function Sequence({ - courseUsageKey, - unitIds, - displayName, - showCompletion, - onNext, - onPrevious, - onNavigateUnit, - isGated, - prerequisite, activeUnitId, bannerText, + courseUsageKey, + displayName, intl, + isFirstUnit, + isGated, + isLastUnit, + onNavigateUnit, + onNext, + onPrevious, + prerequisite, + showCompletion, + unitIds, }) { const handleNext = () => { const nextIndex = unitIds.indexOf(activeUnitId) + 1; @@ -102,7 +104,11 @@ function Sequence({ return ( <> { logEvent('edx.ui.lms.sequence.next_selected', 'top'); handleNext(); @@ -115,10 +121,8 @@ function Sequence({ logEvent('edx.ui.lms.sequence.previous_selected', 'top'); handlePrevious(); }} - unitIds={unitIds} - activeUnitId={activeUnitId} - isLocked={isGated} showCompletion={showCompletion} + unitIds={unitIds} />
{isGated && ( @@ -149,6 +153,7 @@ function Sequence({
- + {isLastUnit ? ( +
+ {/* This is a hugging face emoji */} + {' '} + {intl.formatMessage(messages['learn.end.of.course'])} +
+ ) : ( + + )}
) : null} @@ -183,10 +197,13 @@ function Sequence({ Sequence.propTypes = { activeUnitId: PropTypes.string.isRequired, + bannerText: PropTypes.string, courseUsageKey: PropTypes.string.isRequired, displayName: PropTypes.string.isRequired, intl: intlShape.isRequired, + isFirstUnit: PropTypes.bool.isRequired, isGated: PropTypes.bool.isRequired, + isLastUnit: PropTypes.bool.isRequired, onNavigateUnit: PropTypes.func, onNext: PropTypes.func.isRequired, onPrevious: PropTypes.func.isRequired, @@ -196,7 +213,6 @@ Sequence.propTypes = { id: PropTypes.string, }).isRequired, unitIds: PropTypes.arrayOf(PropTypes.string).isRequired, - bannerText: PropTypes.string, }; Sequence.defaultProps = { diff --git a/src/courseware/sequence/SequenceNavigation.jsx b/src/courseware/sequence/SequenceNavigation.jsx index e0414664..19cb280f 100644 --- a/src/courseware/sequence/SequenceNavigation.jsx +++ b/src/courseware/sequence/SequenceNavigation.jsx @@ -9,14 +9,16 @@ import { FormattedMessage } from '@edx/frontend-platform/i18n'; import UnitButton from './UnitButton'; export default function SequenceNavigation({ - onNext, - onPrevious, - onNavigate, - unitIds, - isLocked, - showCompletion, activeUnitId, className, + isFirstUnit, + isLastUnit, + isLocked, + onNavigate, + onNext, + onPrevious, + showCompletion, + unitIds, }) { const unitButtons = unitIds.map(unitId => ( -