refactor: only use dasherized superBlock (#41067)

This commit is contained in:
Oliver Eyton-Williams
2021-02-13 06:06:04 +01:00
committed by GitHub
parent 73f8377d68
commit 97fcaa693f
22 changed files with 68 additions and 87 deletions

View File

@ -20,9 +20,7 @@ exports.onCreateNode = function onCreateNode({ node, actions, getNode }) {
const { createNodeField } = actions; const { createNodeField } = actions;
if (node.internal.type === 'ChallengeNode') { if (node.internal.type === 'ChallengeNode') {
const { tests = [], block, dashedName, superBlock } = node; const { tests = [], block, dashedName, superBlock } = node;
const slug = `/learn/${dasherize(superBlock)}/${dasherize( const slug = `/learn/${superBlock}/${dasherize(block)}/${dashedName}`;
block
)}/${dashedName}`;
createNodeField({ node, name: 'slug', value: slug }); createNodeField({ node, name: 'slug', value: slug });
createNodeField({ node, name: 'blockName', value: blockNameify(block) }); createNodeField({ node, name: 'blockName', value: blockNameify(block) });
createNodeField({ node, name: 'tests', value: tests }); createNodeField({ node, name: 'tests', value: tests });
@ -131,7 +129,7 @@ exports.createPages = function createPages({ graphql, actions, reporter }) {
result.data.allChallengeNode.edges.map( result.data.allChallengeNode.edges.map(
({ node: { superBlock } }) => superBlock ({ node: { superBlock } }) => superBlock
) )
).map(superBlock => blockNameify(superBlock)); );
// Create intro pages // Create intro pages
result.data.allMarkdownRemark.edges.forEach(edge => { result.data.allMarkdownRemark.edges.forEach(edge => {

View File

@ -8,7 +8,7 @@ export default [
block: 'block-a', block: 'block-a',
title: 'Challenge One', title: 'Challenge One',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block One', superBlock: 'super-block-one',
dashedName: 'challenge-one' dashedName: 'challenge-one'
}, },
{ {
@ -20,7 +20,7 @@ export default [
block: 'block-a', block: 'block-a',
title: 'Challenge Two', title: 'Challenge Two',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block One', superBlock: 'super-block-one',
dashedName: 'challenge-two' dashedName: 'challenge-two'
}, },
{ {
@ -32,7 +32,7 @@ export default [
block: 'block-b', block: 'block-b',
title: 'Challenge One', title: 'Challenge One',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block One', superBlock: 'super-block-one',
dashedName: 'challenge-one' dashedName: 'challenge-one'
}, },
{ {
@ -45,7 +45,7 @@ export default [
block: 'block-b', block: 'block-b',
title: 'Challenge Two', title: 'Challenge Two',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block One', superBlock: 'super-block-one',
dashedName: 'challenge-two' dashedName: 'challenge-two'
}, },
{ {
@ -57,7 +57,7 @@ export default [
block: 'block-c', block: 'block-c',
title: 'Challenge One', title: 'Challenge One',
isPrivate: true, isPrivate: true,
superBlock: 'Super Block One', superBlock: 'super-block-one',
dashedName: 'challenge-one' dashedName: 'challenge-one'
}, },
{ {
@ -69,7 +69,7 @@ export default [
block: 'block-a', block: 'block-a',
title: 'Challenge One', title: 'Challenge One',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block Two', superBlock: 'super-block-two',
dashedName: 'challenge-one' dashedName: 'challenge-one'
}, },
{ {
@ -81,7 +81,7 @@ export default [
block: 'block-a', block: 'block-a',
title: 'Challenge Two', title: 'Challenge Two',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block Two', superBlock: 'super-block-two',
dashedName: 'challenge-two' dashedName: 'challenge-two'
}, },
{ {
@ -93,7 +93,7 @@ export default [
block: 'block-b', block: 'block-b',
title: 'Challenge One', title: 'Challenge One',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block Two', superBlock: 'super-block-two',
dashedName: 'challenge-one' dashedName: 'challenge-one'
}, },
{ {
@ -105,7 +105,7 @@ export default [
block: 'block-b', block: 'block-b',
title: 'Challenge Two', title: 'Challenge Two',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block Two', superBlock: 'super-block-two',
dashedName: 'challenge-two' dashedName: 'challenge-two'
}, },
{ {
@ -117,7 +117,7 @@ export default [
block: 'block-a', block: 'block-a',
title: 'Challenge One', title: 'Challenge One',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block Three', superBlock: 'super-block-three',
dashedName: 'challenge-one' dashedName: 'challenge-one'
}, },
{ {
@ -129,7 +129,7 @@ export default [
block: 'block-c', block: 'block-c',
title: 'Challenge Two', title: 'Challenge Two',
isPrivate: false, isPrivate: false,
superBlock: 'Super Block Three', superBlock: 'super-block-three',
dashedName: 'challenge-two' dashedName: 'challenge-two'
} }
]; ];

View File

@ -13,17 +13,17 @@ import Algorithm from './Algorithm';
const generateIconComponent = (superBlock, className) => { const generateIconComponent = (superBlock, className) => {
const iconMap = { const iconMap = {
'Responsive Web Design': ResponsiveDesign, 'responsive-web-design': ResponsiveDesign,
'JavaScript Algorithms and Data Structures': JavaScriptIcon, 'javascript-algorithms-and-data-structures': JavaScriptIcon,
'Front End Libraries': ReactIcon, 'front-end-libraries': ReactIcon,
'Data Visualization': D3Icon, 'data-visualization': D3Icon,
'APIs and Microservices': APIIcon, 'apis-and-microservices': APIIcon,
'Quality Assurance': Clipboard, 'quality-assurance': Clipboard,
'Scientific Computing with Python': PythonIcon, 'scientific-computing-with-python': PythonIcon,
'Data Analysis with Python': Analytics, 'data-analysis-with-python': Analytics,
'Information Security': Shield, 'information-security': Shield,
'Machine Learning with Python': TensorflowIcon, 'machine-learning-with-python': TensorflowIcon,
'Coding Interview Prep': Algorithm 'coding-interview-prep': Algorithm
}; };
// fallback in case super block doesn't exist and for tests // fallback in case super block doesn't exist and for tests
const Icon = iconMap[superBlock] ? iconMap[superBlock] : ResponsiveDesign; const Icon = iconMap[superBlock] ? iconMap[superBlock] : ResponsiveDesign;

View File

@ -6,7 +6,6 @@ import { generateIconComponent } from '../../assets/icons';
import { Link, Spacer } from '../helpers'; import { Link, Spacer } from '../helpers';
import LinkButton from '../../assets/icons/LinkButton'; import LinkButton from '../../assets/icons/LinkButton';
import { dasherize } from '../../../../utils/slugs';
import './map.css'; import './map.css';
import { isAuditedCert } from '../../../../utils/is-audited'; import { isAuditedCert } from '../../../../utils/is-audited';
import { curriculumLocale } from '../../../../config/env.json'; import { curriculumLocale } from '../../../../config/env.json';
@ -16,11 +15,9 @@ const propTypes = {
forLanding: PropTypes.bool forLanding: PropTypes.bool
}; };
const codingPrepRE = new RegExp('Interview Prep'); function createSuperBlockTitle(superBlock) {
const superBlockTitle = i18next.t(`intro:${superBlock}.title`);
function createSuperBlockTitle(str) { return superBlock === 'coding-interview-prep'
const superBlockTitle = i18next.t(`intro:${dasherize(str)}.title`);
return codingPrepRE.test(str)
? i18next.t('learn.cert-map-estimates.coding-prep', { ? i18next.t('learn.cert-map-estimates.coding-prep', {
title: superBlockTitle title: superBlockTitle
}) })
@ -34,18 +31,18 @@ const linkSpacingStyle = {
}; };
function renderLandingMap(nodes) { function renderLandingMap(nodes) {
nodes = nodes.filter(node => node.superBlock !== 'Coding Interview Prep'); nodes = nodes.filter(node => node.superBlock !== 'coding-interview-prep');
return ( return (
<ul data-test-label='certifications'> <ul data-test-label='certifications'>
{nodes.map((node, i) => ( {nodes.map((node, i) => (
<li key={i}> <li key={i}>
<Link <Link
className='btn link-btn btn-lg' className='btn link-btn btn-lg'
to={`/learn/${dasherize(node.superBlock)}/`} to={`/learn/${node.superBlock}/`}
> >
<div style={linkSpacingStyle}> <div style={linkSpacingStyle}>
{generateIconComponent(node.superBlock, 'map-icon')} {generateIconComponent(node.superBlock, 'map-icon')}
{i18next.t(`intro:${dasherize(node.superBlock)}.title`)} {i18next.t(`intro:${node.superBlock}.title`)}
</div> </div>
<LinkButton /> <LinkButton />
</Link> </Link>
@ -63,7 +60,7 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
<li key={i}> <li key={i}>
<Link <Link
className='btn link-btn btn-lg' className='btn link-btn btn-lg'
to={`/learn/${dasherize(node.superBlock)}/`} to={`/learn/${node.superBlock}/`}
> >
<div style={linkSpacingStyle}> <div style={linkSpacingStyle}>
{generateIconComponent(node.superBlock, 'map-icon')} {generateIconComponent(node.superBlock, 'map-icon')}
@ -76,14 +73,12 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
) : ( ) : (
<ul data-test-label='learn-curriculum-map'> <ul data-test-label='learn-curriculum-map'>
{nodes {nodes
.filter(node => .filter(node => isAuditedCert(curriculumLocale, node.superBlock))
isAuditedCert(curriculumLocale, dasherize(node.superBlock))
)
.map((node, i) => ( .map((node, i) => (
<li key={i}> <li key={i}>
<Link <Link
className='btn link-btn btn-lg' className='btn link-btn btn-lg'
to={`/learn/${dasherize(node.superBlock)}/`} to={`/learn/${node.superBlock}/`}
> >
<div style={linkSpacingStyle}> <div style={linkSpacingStyle}>
{generateIconComponent(node.superBlock, 'map-icon')} {generateIconComponent(node.superBlock, 'map-icon')}
@ -105,14 +100,12 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
<Spacer /> <Spacer />
</div> </div>
{nodes {nodes
.filter( .filter(node => !isAuditedCert(curriculumLocale, node.superBlock))
node => !isAuditedCert(curriculumLocale, dasherize(node.superBlock))
)
.map((node, i) => ( .map((node, i) => (
<li key={i}> <li key={i}>
<Link <Link
className='btn link-btn btn-lg' className='btn link-btn btn-lg'
to={`/learn/${dasherize(node.superBlock)}/`} to={`/learn/${node.superBlock}/`}
> >
<div style={linkSpacingStyle}> <div style={linkSpacingStyle}>
{generateIconComponent(node.superBlock, 'map-icon')} {generateIconComponent(node.superBlock, 'map-icon')}

View File

@ -1,6 +1,6 @@
--- ---
title: APIs and Microservices title: APIs and Microservices
superBlock: APIs and Microservices superBlock: apis-and-microservices
--- ---
## Introduction to APIs and Microservices ## Introduction to APIs and Microservices

View File

@ -1,6 +1,6 @@
--- ---
title: Coding Interview Prep title: Coding Interview Prep
superBlock: Coding Interview Prep superBlock: coding-interview-prep
--- ---
## Introduction to Coding Interview Prep ## Introduction to Coding Interview Prep

View File

@ -1,6 +1,6 @@
--- ---
title: Data Analysis with Python title: Data Analysis with Python
superBlock: Data Analysis with Python superBlock: data-analysis-with-python
--- ---
## Introduction to Data Analysis with Python ## Introduction to Data Analysis with Python

View File

@ -1,6 +1,6 @@
--- ---
title: Data Visualization title: Data Visualization
superBlock: Data Visualization superBlock: data-visualization
--- ---
## Introduction to Data Visualization ## Introduction to Data Visualization

View File

@ -1,6 +1,6 @@
--- ---
title: Front End Libraries title: Front End Libraries
superBlock: Front End Libraries superBlock: front-end-libraries
--- ---
## Introduction to Front End Libraries ## Introduction to Front End Libraries

View File

@ -1,6 +1,6 @@
--- ---
title: Information Security title: Information Security
superBlock: Information Security superBlock: information-security
--- ---
## Introduction to Information Security ## Introduction to Information Security

View File

@ -1,6 +1,6 @@
--- ---
title: JavaScript Algorithms and Data Structures title: JavaScript Algorithms and Data Structures
superBlock: JavaScript Algorithms and Data Structures superBlock: javascript-algorithms-and-data-structures
--- ---
## Introduction to JavaScript Algorithms and Data Structures ## Introduction to JavaScript Algorithms and Data Structures

View File

@ -1,6 +1,6 @@
--- ---
title: Machine Learning with Python title: Machine Learning with Python
superBlock: Machine Learning with Python superBlock: machine-learning-with-python
--- ---
## Introduction to Machine Learning with Python ## Introduction to Machine Learning with Python

View File

@ -1,6 +1,6 @@
--- ---
title: Quality Assurance title: Quality Assurance
superBlock: Quality Assurance superBlock: quality-assurance
--- ---
## Introduction to Quality Assurance ## Introduction to Quality Assurance

View File

@ -1,6 +1,6 @@
--- ---
title: Responsive Web Design title: Responsive Web Design
superBlock: Responsive Web Design superBlock: responsive-web-design
--- ---
## Introduction to Responsive Web Design ## Introduction to Responsive Web Design

View File

@ -1,6 +1,6 @@
--- ---
title: Scientific Computing with Python title: Scientific Computing with Python
superBlock: Scientific Computing with Python superBlock: scientific-computing-with-python
--- ---
## Introduction to Scientific Computing with Python ## Introduction to Scientific Computing with Python

View File

@ -36,21 +36,19 @@ function ChallengeTitle({
<Link <Link
className='breadcrumb-left' className='breadcrumb-left'
state={{ breadcrumbBlockClick: block }} state={{ breadcrumbBlockClick: block }}
to={`/learn/${dasherize(superBlock)}`} to={`/learn/${superBlock}`}
> >
<span className='ellipsis'> <span className='ellipsis'>
{i18next.t(`intro:${dasherize(superBlock)}.title`)} {i18next.t(`intro:${superBlock}.title`)}
</span> </span>
</Link> </Link>
<div className='breadcrumb-center' /> <div className='breadcrumb-center' />
<Link <Link
className='breadcrumb-right' className='breadcrumb-right'
state={{ breadcrumbBlockClick: block }} state={{ breadcrumbBlockClick: block }}
to={`/learn/${dasherize(superBlock)}/#${dasherize(block)}`} to={`/learn/${superBlock}/#${dasherize(block)}`}
> >
{i18next.t( {i18next.t(`intro:${superBlock}.blocks.${dasherize(block)}.title`)}
`intro:${dasherize(superBlock)}.blocks.${dasherize(block)}.title`
)}
</Link> </Link>
</div> </div>
<div className='challenge-title'> <div className='challenge-title'>

View File

@ -9,7 +9,7 @@ const baseProps = {
block: 'fake block', block: 'fake block',
children: 'title text', children: 'title text',
isCompleted: true, isCompleted: true,
superBlock: 'fake superblock' superBlock: 'fake-superblock'
}; };
describe('<ChallengeTitle/>', () => { describe('<ChallengeTitle/>', () => {

View File

@ -141,12 +141,10 @@ export class SuperBlockIntroductionPage extends Component {
t t
} = this.props; } = this.props;
const superBlockDashedName = dasherize(superBlock);
const nodesForSuperBlock = edges.map(({ node }) => node); const nodesForSuperBlock = edges.map(({ node }) => node);
const blockDashedNames = uniq(nodesForSuperBlock.map(({ block }) => block)); const blockDashedNames = uniq(nodesForSuperBlock.map(({ block }) => block));
const i18nSuperBlock = t(`intro:${superBlockDashedName}.title`); const i18nSuperBlock = t(`intro:${superBlock}.title`);
return ( return (
<> <>
@ -171,12 +169,12 @@ export class SuperBlockIntroductionPage extends Component {
challenges={nodesForSuperBlock.filter( challenges={nodesForSuperBlock.filter(
node => node.block === blockDashedName node => node.block === blockDashedName
)} )}
superBlockDashedName={superBlockDashedName} superBlockDashedName={superBlock}
/> />
{blockDashedName !== 'project-euler' ? <Spacer /> : null} {blockDashedName !== 'project-euler' ? <Spacer /> : null}
</Fragment> </Fragment>
))} ))}
{superBlock !== 'Coding Interview Prep' && ( {superBlock !== 'coding-interview-prep' && (
<div> <div>
<CertChallenge superBlock={superBlock} /> <CertChallenge superBlock={superBlock} />
</div> </div>

View File

@ -8,7 +8,6 @@ import { withTranslation } from 'react-i18next';
import CertificationIcon from '../../../assets/icons/CertificationIcon'; import CertificationIcon from '../../../assets/icons/CertificationIcon';
import GreenPass from '../../../assets/icons/GreenPass'; import GreenPass from '../../../assets/icons/GreenPass';
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted'; import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
import { dasherize } from '../../../../../utils/slugs';
import { userSelector } from '../../../redux'; import { userSelector } from '../../../redux';
import { User } from '../../../redux/propTypes'; import { User } from '../../../redux/propTypes';
@ -48,23 +47,22 @@ export class CertChallenge extends Component {
} = this.props; } = this.props;
const userCertificates = { const userCertificates = {
'Responsive Web Design': isRespWebDesignCert, 'responsive-web-design': isRespWebDesignCert,
'JavaScript Algorithms and Data Structures': isJsAlgoDataStructCert, 'javascript-algorithms-and-data-structures': isJsAlgoDataStructCert,
'Front End Libraries': isFrontEndLibsCert, 'front-end-libraries': isFrontEndLibsCert,
'Data Visualization': is2018DataVisCert, 'data-visualization': is2018DataVisCert,
'APIs and Microservices': isApisMicroservicesCert, 'apis-and-microservices': isApisMicroservicesCert,
'Quality Assurance': isQaCertV7, 'quality-assurance': isQaCertV7,
'Information Security': isInfosecCertV7, 'information-security': isInfosecCertV7,
'Scientific Computing with Python': isSciCompPyCertV7, 'scientific-computing-with-python': isSciCompPyCertV7,
'Data Analysis with Python': isDataAnalysisPyCertV7, 'data-analysis-with-python': isDataAnalysisPyCertV7,
'Machine Learning with Python': isMachineLearningPyCertV7 'machine-learning-with-python': isMachineLearningPyCertV7
}; };
const isCertified = userCertificates[superBlock]; const isCertified = userCertificates[superBlock];
const superBlockDashedName = dasherize(superBlock); const certLocation = `/certification/${username}/${superBlock}`;
const certLocation = `/certification/${username}/${superBlockDashedName}`;
const certCheckmarkStyle = { height: '40px', width: '40px' }; const certCheckmarkStyle = { height: '40px', width: '40px' };
const i18nSuperBlock = t(`intro:${superBlockDashedName}.title`); const i18nSuperBlock = t(`intro:${superBlock}.title`);
const i18nCertText = t(`intro:misc-text.certification`, { const i18nCertText = t(`intro:misc-text.certification`, {
cert: i18nSuperBlock cert: i18nSuperBlock
}); });

View File

@ -2,7 +2,6 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { dasherize } from '../../../../../utils/slugs';
import { Spacer } from '../../../components/helpers'; import { Spacer } from '../../../components/helpers';
import { generateIconComponent } from '../../../assets/icons'; import { generateIconComponent } from '../../../assets/icons';
@ -13,9 +12,8 @@ const propTypes = {
function SuperBlockIntro(props) { function SuperBlockIntro(props) {
const { t } = useTranslation(); const { t } = useTranslation();
const { superBlock } = props; const { superBlock } = props;
const superBlockDashedName = dasherize(superBlock);
const superBlockIntroObj = t(`intro:${superBlockDashedName}`); const superBlockIntroObj = t(`intro:${superBlock}`);
const { const {
title: i18nSuperBlock, title: i18nSuperBlock,
intro: superBlockIntroText intro: superBlockIntroText

View File

@ -106,7 +106,7 @@ exports.createSuperBlockIntroPages = createPage => edge => {
path: slug, path: slug,
component: superBlockIntro, component: superBlockIntro,
context: { context: {
superBlock: superBlock, superBlock,
slug slug
} }
}); });

View File

@ -14,7 +14,6 @@ const {
const { isAuditedCert } = require('../utils/is-audited'); const { isAuditedCert } = require('../utils/is-audited');
const { dasherize } = require('../utils/slugs'); const { dasherize } = require('../utils/slugs');
const { createPoly } = require('../utils/polyvinyl'); const { createPoly } = require('../utils/polyvinyl');
const { blockNameify } = require('../utils/block-nameify');
const { helpCategoryMap } = require('../client/utils/challengeTypes'); const { helpCategoryMap } = require('../client/utils/challengeTypes');
const { const {
curriculum: curriculumLangs curriculum: curriculumLangs
@ -346,7 +345,6 @@ function prepareChallenge(challenge) {
challenge.solutionFiles = filesToObject(challenge.solutionFiles); challenge.solutionFiles = filesToObject(challenge.solutionFiles);
} }
challenge.block = dasherize(challenge.block); challenge.block = dasherize(challenge.block);
challenge.superBlock = blockNameify(challenge.superBlock);
return challenge; return challenge;
} }