From 594ee9af58d684789fccc8b19670aab52e1ff724 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Mon, 18 Nov 2024 22:07:12 +0100 Subject: [PATCH] fix(client): compute step number from challenge order (#57209) --- client/src/redux/prop-types.ts | 3 +- .../Introduction/components/block.tsx | 36 +++++++++++-------- .../Introduction/components/challenges.tsx | 32 ++++++----------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/client/src/redux/prop-types.ts b/client/src/redux/prop-types.ts index 23f5f5a922d..1befe4290d4 100644 --- a/client/src/redux/prop-types.ts +++ b/client/src/redux/prop-types.ts @@ -152,7 +152,7 @@ export interface PrerequisiteChallenge { slug?: string; } -export type ChallengeWithCompletedNode = { +export type ExtendedChallenge = { block: string; challengeType: number; dashedName: string; @@ -163,6 +163,7 @@ export type ChallengeWithCompletedNode = { isCompleted: boolean; order: number; superBlock: SuperBlocks; + stepNumber: number; title: string; }; diff --git a/client/src/templates/Introduction/components/block.tsx b/client/src/templates/Introduction/components/block.tsx index bbb4befd724..2bf2c85e1f0 100644 --- a/client/src/templates/Introduction/components/block.tsx +++ b/client/src/templates/Introduction/components/block.tsx @@ -7,6 +7,7 @@ import { bindActionCreators, Dispatch } from 'redux'; import { createSelector } from 'reselect'; import { Spacer } from '@freecodecamp/ui'; +import { challengeTypes } from '../../../../../shared/config/challenge-types'; import { SuperBlocks } from '../../../../../shared/config/curriculum'; import envData from '../../../../config/env.json'; import { isAuditedSuperBlock } from '../../../../../shared/utils/is-audited'; @@ -83,8 +84,9 @@ class Block extends Component { } = this.props; let completedCount = 0; + let stepNumber = 0; - const challengesWithCompleted = challenges.map(challenge => { + const extendedChallenges = challenges.map(challenge => { const { id } = challenge; const isCompleted = completedChallengeIds.some( (completedChallengeId: string) => completedChallengeId === id @@ -92,7 +94,13 @@ class Block extends Component { if (isCompleted) { completedCount++; } - return { ...challenge, isCompleted }; + // Dialogues are interwoven with other challenges in the curriculum, but + // are not considered to be steps. + if (challenge.challengeType !== challengeTypes.dialogue) { + stepNumber++; + } + + return { ...challenge, isCompleted, stepNumber }; }); const isProjectBlock = challenges.some(challenge => { @@ -118,17 +126,17 @@ class Block extends Component { const expandText = t('intro:misc-text.expand'); const collapseText = t('intro:misc-text.collapse'); - const isBlockCompleted = completedCount === challengesWithCompleted.length; + const isBlockCompleted = completedCount === extendedChallenges.length; const percentageCompleted = Math.floor( - (completedCount / challengesWithCompleted.length) * 100 + (completedCount / extendedChallenges.length) * 100 ); const courseCompletionStatus = () => { if (completedCount === 0) { return t('learn.not-started'); } - if (completedCount === challengesWithCompleted.length) { + if (completedCount === extendedChallenges.length) { return t('learn.completed'); } return `${percentageCompleted}% ${t('learn.completed')}`; @@ -174,19 +182,19 @@ class Block extends Component { + >{`${completedCount}/${extendedChallenges.length}`} ,{' '} {t('learn.challenges-completed', { completedCount, - totalChallenges: challengesWithCompleted.length + totalChallenges: extendedChallenges.length })} {isExpanded && ( )} @@ -218,7 +226,7 @@ class Block extends Component { @@ -258,7 +266,7 @@ class Block extends Component {
{ onClick={() => { this.handleBlockClick(); }} - to={challengesWithCompleted[0].fields.slug} + to={extendedChallenges[0].fields.slug} > {blockTitle}{' '} @@ -351,7 +359,7 @@ class Block extends Component { {isExpanded && (
@@ -386,7 +394,7 @@ class Block extends Component { onClick={() => { this.handleBlockClick(); }} - to={challengesWithCompleted[0].fields.slug} + to={extendedChallenges[0].fields.slug} > {blockType && } @@ -433,7 +441,7 @@ class Block extends Component { {isExpanded && (
{ - // dashedName should be in the format 'step-1' or 'task-1' - const match = dashedName.match(/-(\d+)/); - return match ? match[1] : ''; -}; - interface Challenges { - challengesWithCompleted: ChallengeWithCompletedNode[]; + challenges: ExtendedChallenge[]; isProjectBlock: boolean; isGridMap?: boolean; blockTitle?: string | null; @@ -25,11 +19,7 @@ interface Challenges { const CheckMark = ({ isCompleted }: { isCompleted: boolean }) => isCompleted ? : ; -const Challenge = ({ - challenge -}: { - challenge: ChallengeWithCompletedNode; -}) => ( +const Challenge = ({ challenge }: { challenge: ExtendedChallenge }) => ( @@ -38,7 +28,7 @@ const Challenge = ({ ); -const Project = ({ challenge }: { challenge: ChallengeWithCompletedNode }) => ( +const Project = ({ challenge }: { challenge: ExtendedChallenge }) => ( {challenge.title} @@ -48,18 +38,18 @@ const Project = ({ challenge }: { challenge: ChallengeWithCompletedNode }) => ( ); function Challenges({ - challengesWithCompleted, + challenges, isProjectBlock, isGridMap = false, blockTitle }: Challenges): JSX.Element { const { t } = useTranslation(); - const firstIncompleteChallenge = challengesWithCompleted.find( + const firstIncompleteChallenge = challenges.find( challenge => !challenge.isCompleted ); - const isChallengeStarted = !!challengesWithCompleted.find( + const isChallengeStarted = !!challenges.find( challenge => challenge.isCompleted ); @@ -78,14 +68,14 @@ function Challenges({