feat(client): move FSD superblock into Next superblock stage (#57349)

This commit is contained in:
Oliver Eyton-Williams
2024-12-10 12:21:30 +01:00
committed by GitHub
parent 02c3c7913a
commit 383cf7f978
5 changed files with 47 additions and 13 deletions
@@ -166,6 +166,7 @@
"professional-certs-heading": "Earn free professional certifications:",
"interview-prep-heading": "Prepare for the developer interview job search:",
"legacy-curriculum-heading": "Explore our Legacy Curriculum:",
"next-heading": "Try our beta curriculum:",
"upcoming-heading": "Upcoming curriculum:",
"faq": "Frequently asked questions:",
"faqs": [
+9 -1
View File
@@ -3,6 +3,8 @@ import { useTranslation } from 'react-i18next';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { Spacer } from '@freecodecamp/ui';
import { useFeature } from '@growthbook/growthbook-react';
import {
type SuperBlocks,
SuperBlockStage,
@@ -60,6 +62,7 @@ const superBlockHeadings: { [key in SuperBlockStage]: string } = {
[SuperBlockStage.Extra]: 'landing.interview-prep-heading',
[SuperBlockStage.Legacy]: 'landing.legacy-curriculum-heading',
[SuperBlockStage.New]: '', // TODO: add translation
[SuperBlockStage.Next]: 'landing.next-heading',
[SuperBlockStage.Upcoming]: 'landing.upcoming-heading'
};
@@ -135,6 +138,7 @@ function Map({
allChallenges
}: MapProps): React.ReactElement {
const { t } = useTranslation();
const showNextCurriculum = useFeature('fcc-10').on;
const allSuperblockChallengesCompleted = (superblock: SuperBlocks) => {
// array of all challenge ID's in the superblock
@@ -161,7 +165,11 @@ function Map({
return (
<div className='map-ui' data-test-label='curriculum-map'>
{getStageOrder({ showNewCurriculum, showUpcomingChanges }).map(stage => (
{getStageOrder({
showNewCurriculum,
showUpcomingChanges,
showNextCurriculum
}).map(stage => (
<Fragment key={stage}>
<h2 className={forLanding ? 'big-heading' : ''}>
{t(superBlockHeadings[stage])}
+2 -1
View File
@@ -44,7 +44,8 @@ function createSuperOrder(superBlocks) {
const flatSuperBlockMap = generateSuperBlockList({
showNewCurriculum: process.env.SHOW_NEW_CURRICULUM === 'true',
showUpcomingChanges: process.env.SHOW_UPCOMING_CHANGES === 'true'
showUpcomingChanges: process.env.SHOW_UPCOMING_CHANGES === 'true',
showNextCurriculum: true
});
const superOrder = createSuperOrder(flatSuperBlockMap);
+18 -3
View File
@@ -20,10 +20,11 @@ describe('superBlockOrder', () => {
});
describe('generateSuperBlockList', () => {
it('should return an array of SuperBlocks object with New and Upcoming when { showNewCurriculum: true, showUpcomingChanges: true }', () => {
it('should return an array of SuperBlocks object with all elements when if all configs are true', () => {
const result = generateSuperBlockList({
showNewCurriculum: true,
showUpcomingChanges: true
showUpcomingChanges: true,
showNextCurriculum: true
});
expect(result).toHaveLength(Object.values(superBlockStages).flat().length);
});
@@ -31,13 +32,27 @@ describe('generateSuperBlockList', () => {
it('should return an array of SuperBlocks without New and Upcoming when { showNewCurriculum: false, showUpcomingChanges: false }', () => {
const result = generateSuperBlockList({
showNewCurriculum: false,
showUpcomingChanges: false
showUpcomingChanges: false,
showNextCurriculum: true
});
const tempSuperBlockMap = { ...superBlockStages };
tempSuperBlockMap[SuperBlockStage.New] = [];
tempSuperBlockMap[SuperBlockStage.Upcoming] = [];
expect(result).toHaveLength(Object.values(tempSuperBlockMap).flat().length);
});
it('should exclude the Next SuperBlocks when { showNextCurriculum: false }', () => {
const result = generateSuperBlockList({
showNewCurriculum: false,
showUpcomingChanges: false,
showNextCurriculum: false
});
const tempSuperBlockMap = { ...superBlockStages };
tempSuperBlockMap[SuperBlockStage.New] = [];
tempSuperBlockMap[SuperBlockStage.Upcoming] = [];
tempSuperBlockMap[SuperBlockStage.Next] = [];
expect(result).toHaveLength(Object.values(tempSuperBlockMap).flat().length);
});
});
describe('Immutability of superBlockOrder, notAuditedSuperBlocks, and flatSuperBlockMap', () => {
+17 -8
View File
@@ -35,6 +35,10 @@ export enum SuperBlocks {
*
* SuperBlockStages.Upcoming = SHOW_UPCOMING_CHANGES === 'true'
* 'Upcoming' is for development -> not shown on stag or prod anywhere
*
* SuperBlockStages.Next = deployed, but only shown if the Growthbook feature
* is enabled.
*
*/
export enum SuperBlockStage {
Core,
@@ -43,11 +47,13 @@ export enum SuperBlockStage {
Extra,
Legacy,
New,
Upcoming
Upcoming,
Next
}
const defaultStageOrder = [
SuperBlockStage.Core,
SuperBlockStage.Next,
SuperBlockStage.English,
SuperBlockStage.Professional,
SuperBlockStage.Extra,
@@ -56,9 +62,12 @@ const defaultStageOrder = [
export function getStageOrder({
showNewCurriculum,
showUpcomingChanges
showUpcomingChanges,
showNextCurriculum
}: Config): SuperBlockStage[] {
const stageOrder = [...defaultStageOrder];
const stageOrder = showNextCurriculum
? [...defaultStageOrder]
: [...defaultStageOrder.filter(stage => stage !== SuperBlockStage.Next)];
if (showNewCurriculum) stageOrder.push(SuperBlockStage.New);
if (showUpcomingChanges) stageOrder.push(SuperBlockStage.Upcoming);
@@ -85,6 +94,7 @@ export const superBlockStages: StageMap = {
SuperBlocks.MachineLearningPy,
SuperBlocks.CollegeAlgebraPy
],
[SuperBlockStage.Next]: [SuperBlocks.FullStackDeveloper],
[SuperBlockStage.English]: [SuperBlocks.A2English],
[SuperBlockStage.Professional]: [SuperBlocks.FoundationalCSharp],
[SuperBlockStage.Extra]: [
@@ -99,10 +109,7 @@ export const superBlockStages: StageMap = {
SuperBlocks.PythonForEverybody
],
[SuperBlockStage.New]: [],
[SuperBlockStage.Upcoming]: [
SuperBlocks.B1English,
SuperBlocks.FullStackDeveloper
]
[SuperBlockStage.Upcoming]: [SuperBlocks.B1English]
};
Object.freeze(superBlockStages);
@@ -246,6 +253,7 @@ Object.freeze(notAuditedSuperBlocks);
type Config = {
showNewCurriculum: boolean;
showUpcomingChanges: boolean;
showNextCurriculum: boolean;
};
export function generateSuperBlockList(config: Config): SuperBlocks[] {
@@ -266,7 +274,8 @@ export function getAuditedSuperBlocks({
// To find the audited superblocks, we need to start with all superblocks.
const flatSuperBlockMap = generateSuperBlockList({
showNewCurriculum: true,
showUpcomingChanges: true
showUpcomingChanges: true,
showNextCurriculum: true
});
const auditedSuperBlocks = flatSuperBlockMap.filter(
superBlock =>