feat: unify curriculum layout (#53336)

This commit is contained in:
Sem Bauke
2024-01-27 12:40:18 +01:00
committed by GitHub
parent 714bd347a9
commit f66e4dcf96
7 changed files with 59 additions and 70 deletions

View File

@@ -34,10 +34,7 @@ import {
} from '../../../redux/prop-types';
import { editorToneOptions } from '../../../utils/tone/editor-config';
import { editorNotes } from '../../../utils/tone/editor-notes';
import {
challengeTypes,
isFinalProject
} from '../../../../../shared/config/challenge-types';
import { challengeTypes } from '../../../../../shared/config/challenge-types';
import {
executeChallenge,
saveEditorContent,
@@ -66,8 +63,8 @@ import {
setScrollbarArrowStyles
} from '../utils/index';
import { getScrollbarWidth } from '../../../utils/scrollbar-width';
import { isProjectBased } from '../../../utils/curriculum-layout';
import LowerJaw from './lower-jaw';
import './editor.css';
const MonacoEditor = Loadable(() => import('react-monaco-editor'));
@@ -511,7 +508,7 @@ const Editor = (props: EditorProps): JSX.Element => {
monaco.KeyMod.WinCtrl | monaco.KeyCode.Enter
],
run: () => {
if (props.usesMultifileEditor && !isFinalProject(props.challengeType)) {
if (props.usesMultifileEditor && !isProjectBased(props.challengeType)) {
if (challengeIsComplete()) {
tryToSubmitChallenge();
} else {

View File

@@ -23,7 +23,7 @@ import {
challengeTestsSelector
} from '../redux/selectors';
import './hotkeys.css';
import { isFinalProject } from '../../../../../shared/config/challenge-types';
import { isProjectBased } from '../../../utils/curriculum-layout';
import type { EditorProps } from '../classic/editor';
const mapStateToProps = createSelector(
@@ -121,7 +121,7 @@ function Hotkeys({
if (
usesMultifileEditor &&
typeof challengeType == 'number' &&
!isFinalProject(challengeType)
!isProjectBased(challengeType)
) {
if (testsArePassing) {
submitChallenge();

View File

@@ -19,15 +19,7 @@ import { completedChallengesSelector } from '../../../redux/selectors';
import { ChallengeNode, CompletedChallenge } from '../../../redux/prop-types';
import { playTone } from '../../../utils/tone';
import { makeExpandedBlockSelector, toggleBlock } from '../redux';
import {
isNewJsCert,
isSciCompPyCert,
isNewRespCert
} from '../../../utils/is-a-cert';
import {
isCodeAllyPractice,
isFinalProject
} from '../../../../../shared/config/challenge-types';
import { isGridBased, isProjectBased } from '../../../utils/curriculum-layout';
import Challenges from './challenges';
import '../intro.css';
@@ -118,21 +110,12 @@ class Block extends Component<BlockProps> {
});
const isProjectBlock = challenges.some(({ challenge }) => {
const isTakeHomeProject = blockDashedName === 'take-home-projects';
const projectCondition = [
isFinalProject(challenge.challengeType),
isCodeAllyPractice(challenge.challengeType)
].some(Boolean);
return projectCondition && !isTakeHomeProject;
return isProjectBased(challenge.challengeType, blockDashedName);
});
const isGridBlock = [
isNewRespCert(superBlock),
isNewJsCert(superBlock),
isSciCompPyCert(superBlock) && !isProjectBlock
].some(Boolean);
const isGridBlock = challenges.some(({ challenge }) => {
return isGridBased(superBlock, challenge.challengeType);
});
const isAudited = isAuditedSuperBlock(curriculumLocale, superBlock, {
showNewCurriculum,

View File

@@ -0,0 +1,47 @@
import { challengeTypes } from '../../../shared/config/challenge-types';
import { SuperBlocks } from '../../../shared/config/superblocks';
// Show a grid layout on the superblock level
const gridBasedSuperBlocks = [
SuperBlocks.RespWebDesignNew,
SuperBlocks.JsAlgoDataStructNew,
SuperBlocks.SciCompPy
];
export const isGridBased = (
superBlock: SuperBlocks,
challengeType: unknown = null
) => {
// Python projects should not be displayed as a grid, but should be displayed
// as a list of projects. Otherwise, if we do not do this the project will be
// shown as a single certificaton project, which is not what we want.
if (challengeType === 10) return false;
return gridBasedSuperBlocks.includes(superBlock);
};
// Show a single project in a certification layout
const projectBasedChallengeTypes = [
challengeTypes.frontEndProject,
challengeTypes.backEndProject,
challengeTypes.jsProject,
challengeTypes.pythonProject,
challengeTypes.codeAllyCert,
challengeTypes.multifileCertProject,
challengeTypes.exam,
challengeTypes.codeAllyPractice
];
export const isProjectBased = (
challengeType: number,
blockDashedName: unknown = null
) => {
// Is project based but should be collapsable, this differs from the
// other projects which are not collapsable.
if (blockDashedName === 'take-home-projects') return false;
return projectBasedChallengeTypes.includes(challengeType);
};

View File

@@ -1,5 +1,5 @@
import { AllChallengesInfo } from '../redux/prop-types';
import { isFinalProject } from '../../../shared/config/challenge-types';
import { isProjectBased } from './curriculum-layout';
export function getCompletedPercentage(
completedChallengesIds: string[] = [],
@@ -48,7 +48,7 @@ export const getCurrentBlockIds = (
.filter(edge => edge.node.challenge.block === block)
.map(edge => edge.node.challenge.id);
return isFinalProject(challengeType)
return isProjectBased(challengeType)
? currentCertificateIds
: currentBlockIds;
};

View File

@@ -1,25 +1,9 @@
import { SuperBlocks } from '../../../shared/config/superblocks';
export function isNewRespCert(superBlock: string): boolean {
return superBlock === String(SuperBlocks.RespWebDesignNew);
}
export function isOldRespCert(superBlock: string): boolean {
return superBlock === String(SuperBlocks.RespWebDesign);
}
export function isNewJsCert(superBlock: string): boolean {
return superBlock === String(SuperBlocks.JsAlgoDataStructNew);
}
export function isRelationalDbCert(superBlock: string): boolean {
return superBlock === String(SuperBlocks.RelationalDb);
}
export function isCollegeAlgebraPyCert(superBlock: string): boolean {
return superBlock === String(SuperBlocks.CollegeAlgebraPy);
}
export function isSciCompPyCert(superBlock: string): boolean {
return superBlock === String(SuperBlocks.SciCompPy);
}

View File

@@ -50,28 +50,6 @@ export const challengeTypes = {
fillInTheBlank
};
export const isFinalProject = (challengeType: number) => {
// TODO: remove the type check once everything is converted to TS
if (typeof challengeType !== 'number')
throw Error('challengeType must be a number');
return (
challengeType === frontEndProject ||
challengeType === backEndProject ||
challengeType === jsProject ||
challengeType === pythonProject ||
challengeType === codeAllyCert ||
challengeType === multifileCertProject ||
challengeType === exam
);
};
export const isCodeAllyPractice = (challengeType: number) => {
// TODO: remove the type check once everything is converted to TS
if (typeof challengeType !== 'number')
throw Error('challengeType must be a number');
return challengeType === codeAllyPractice;
};
export const hasNoTests = (challengeType: number): boolean =>
challengeType === multipleChoice ||
challengeType === theOdinProject ||