diff --git a/client/src/templates/Introduction/components/block.test.tsx b/client/src/templates/Introduction/components/block.test.tsx index 05381da6ece..737732b2c51 100644 --- a/client/src/templates/Introduction/components/block.test.tsx +++ b/client/src/templates/Introduction/components/block.test.tsx @@ -13,6 +13,7 @@ import { BilibiliIds } from '../../../redux/prop-types'; import { isAuditedSuperBlock } from '../../../../../shared/utils/is-audited'; +import { BlockTypes } from '../../../../../shared/config/blocks'; import Block from './block'; jest.mock('../../../../../shared/utils/is-audited', () => ({ @@ -20,65 +21,64 @@ jest.mock('../../../../../shared/utils/is-audited', () => ({ })); const defaultProps = { - blockDashedName: 'test-block', + block: 'test-block', challenges: [ { - challenge: { - block: 'testblock', - certification: 'mockCertification', - challengeOrder: 1, - challengeType: 0, - dashedName: 'mock-dashed-name', - description: 'mockDescription', - challengeFiles: {} as ChallengeFiles, - fields: {} as Fields, - forumTopicId: 12345, - guideUrl: 'https://mockurl.com', - head: ['mockHead'], - hasEditableBoundaries: false, - helpCategory: 'mockHelpCategory', - id: 'mockId', - instructions: 'mockInstructions', - isComingSoon: false, - internal: { - content: 'mockContent', - contentDigest: 'mockContentDigest', - description: 'mockInternalDescription', - fieldOwners: ['mockOwner'], - ignoreType: null, - mediaType: 'mockMediaType', - owner: 'mockOwner', - type: 'mockType' - }, - notes: 'mockNotes', - prerequisites: [] as PrerequisiteChallenge[], - isLocked: false, - isPrivate: false, - order: 1, - questions: [] as Question[], - assignments: ['mockAssignment'], - required: [], - solutions: { - ['indexhtml']: {} as FileKeyChallenge, - ['scriptjs']: {} as FileKeyChallenge, - ['stylescss']: {} as FileKeyChallenge, - ['indexjsx']: {} as FileKeyChallenge - }, - sourceInstanceName: 'mockSourceInstanceName', - superOrder: 1, - superBlock: SuperBlocks.UpcomingPython, - tail: ['mockTail'], - template: 'mockTemplate', - tests: [] as Test[], - title: 'mockTitle', - translationPending: false, - url: 'https://mockurl.com', - usesMultifileEditor: false, - videoId: 'mockVideoId', - videoLocaleIds: {}, - bilibiliIds: {} as BilibiliIds, - videoUrl: 'https://mockvideourl.com' - } + block: 'testblock', + blockType: BlockTypes.lab, + certification: 'mockCertification', + challengeOrder: 1, + challengeType: 0, + dashedName: 'mock-dashed-name', + description: 'mockDescription', + challengeFiles: {} as ChallengeFiles, + fields: {} as Fields, + forumTopicId: 12345, + guideUrl: 'https://mockurl.com', + head: ['mockHead'], + hasEditableBoundaries: false, + helpCategory: 'mockHelpCategory', + id: 'mockId', + instructions: 'mockInstructions', + isComingSoon: false, + internal: { + content: 'mockContent', + contentDigest: 'mockContentDigest', + description: 'mockInternalDescription', + fieldOwners: ['mockOwner'], + ignoreType: null, + mediaType: 'mockMediaType', + owner: 'mockOwner', + type: 'mockType' + }, + notes: 'mockNotes', + prerequisites: [] as PrerequisiteChallenge[], + isLocked: false, + isPrivate: false, + order: 1, + questions: [] as Question[], + assignments: ['mockAssignment'], + required: [], + solutions: { + ['indexhtml']: {} as FileKeyChallenge, + ['scriptjs']: {} as FileKeyChallenge, + ['stylescss']: {} as FileKeyChallenge, + ['indexjsx']: {} as FileKeyChallenge + }, + sourceInstanceName: 'mockSourceInstanceName', + superOrder: 1, + superBlock: SuperBlocks.UpcomingPython, + tail: ['mockTail'], + template: 'mockTemplate', + tests: [] as Test[], + title: 'mockTitle', + translationPending: false, + url: 'https://mockurl.com', + usesMultifileEditor: false, + videoId: 'mockVideoId', + videoLocaleIds: {}, + bilibiliIds: {} as BilibiliIds, + videoUrl: 'https://mockvideourl.com' } ], completedChallengeIds: ['testchallengeIds'], diff --git a/client/src/templates/Introduction/components/block.tsx b/client/src/templates/Introduction/components/block.tsx index 271675379b1..b98c6a9af9f 100644 --- a/client/src/templates/Introduction/components/block.tsx +++ b/client/src/templates/Introduction/components/block.tsx @@ -26,11 +26,10 @@ import '../intro.css'; const { curriculumLocale, showUpcomingChanges, showNewCurriculum } = envData; -const mapStateToProps = ( - state: unknown, - ownProps: { blockDashedName: string } -) => { - const expandedSelector = makeExpandedBlockSelector(ownProps.blockDashedName); +type Challenge = ChallengeNode['challenge']; + +const mapStateToProps = (state: unknown, ownProps: { block: string }) => { + const expandedSelector = makeExpandedBlockSelector(ownProps.block); return createSelector( expandedSelector, @@ -46,8 +45,8 @@ const mapDispatchToProps = (dispatch: Dispatch) => bindActionCreators({ toggleBlock }, dispatch); interface BlockProps { - blockDashedName: string; - challenges: ChallengeNode[]; + block: string; + challenges: Challenge[]; completedChallengeIds: string[]; isExpanded: boolean; superBlock: SuperBlocks; @@ -82,14 +81,14 @@ class Block extends Component { } handleBlockClick(): void { - const { blockDashedName, toggleBlock } = this.props; + const { block, toggleBlock } = this.props; void playTone('block-toggle'); - toggleBlock(blockDashedName); + toggleBlock(block); } render(): JSX.Element { const { - blockDashedName, + block, completedChallengeIds, challenges, isExpanded, @@ -99,7 +98,7 @@ class Block extends Component { let completedCount = 0; - const challengesWithCompleted = challenges.map(({ challenge }) => { + const challengesWithCompleted = challenges.map(challenge => { const { id } = challenge; const isCompleted = completedChallengeIds.some( (completedChallengeId: string) => completedChallengeId === id @@ -110,11 +109,11 @@ class Block extends Component { return { ...challenge, isCompleted }; }); - const isProjectBlock = challenges.some(({ challenge }) => { - return isProjectBased(challenge.challengeType, blockDashedName); + const isProjectBlock = challenges.some(challenge => { + return isProjectBased(challenge.challengeType, block); }); - const isGridBlock = challenges.some(({ challenge }) => { + const isGridBlock = challenges.some(challenge => { return isGridBased(superBlock, challenge.challengeType); }); @@ -123,12 +122,12 @@ class Block extends Component { showUpcomingChanges }); - const blockTitle = t(`intro:${superBlock}.blocks.${blockDashedName}.title`); + const blockTitle = t(`intro:${superBlock}.blocks.${block}.title`); // the real type of TFunction is the type below, because intro can be an array of strings // type RealTypeOFTFunction = TFunction & ((key: string) => string[]); // But changing the type will require refactoring that isn't worth it for a wrong type. const blockIntroArr = t( - `intro:${superBlock}.blocks.${blockDashedName}.intro` + `intro:${superBlock}.blocks.${block}.intro` ); const expandText = t('intro:misc-text.expand'); const collapseText = t('intro:misc-text.collapse'); @@ -151,7 +150,7 @@ class Block extends Component { const Block = ( <> {' '} - +

{blockTitle}

@@ -207,7 +206,7 @@ class Block extends Component { const ProjectBlock = ( <> - +

{blockTitle}

@@ -245,12 +244,12 @@ class Block extends Component { const GridBlock = ( <> {' '} - +

)} {isExpanded && ( -
+
{ ); const GridProjectBlock = ( - +