refactor: only use dasherized superBlock (#41067)
This commit is contained in:
committed by
GitHub
parent
73f8377d68
commit
97fcaa693f
@ -20,9 +20,7 @@ exports.onCreateNode = function onCreateNode({ node, actions, getNode }) {
|
||||
const { createNodeField } = actions;
|
||||
if (node.internal.type === 'ChallengeNode') {
|
||||
const { tests = [], block, dashedName, superBlock } = node;
|
||||
const slug = `/learn/${dasherize(superBlock)}/${dasherize(
|
||||
block
|
||||
)}/${dashedName}`;
|
||||
const slug = `/learn/${superBlock}/${dasherize(block)}/${dashedName}`;
|
||||
createNodeField({ node, name: 'slug', value: slug });
|
||||
createNodeField({ node, name: 'blockName', value: blockNameify(block) });
|
||||
createNodeField({ node, name: 'tests', value: tests });
|
||||
@ -131,7 +129,7 @@ exports.createPages = function createPages({ graphql, actions, reporter }) {
|
||||
result.data.allChallengeNode.edges.map(
|
||||
({ node: { superBlock } }) => superBlock
|
||||
)
|
||||
).map(superBlock => blockNameify(superBlock));
|
||||
);
|
||||
|
||||
// Create intro pages
|
||||
result.data.allMarkdownRemark.edges.forEach(edge => {
|
||||
|
@ -8,7 +8,7 @@ export default [
|
||||
block: 'block-a',
|
||||
title: 'Challenge One',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block One',
|
||||
superBlock: 'super-block-one',
|
||||
dashedName: 'challenge-one'
|
||||
},
|
||||
{
|
||||
@ -20,7 +20,7 @@ export default [
|
||||
block: 'block-a',
|
||||
title: 'Challenge Two',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block One',
|
||||
superBlock: 'super-block-one',
|
||||
dashedName: 'challenge-two'
|
||||
},
|
||||
{
|
||||
@ -32,7 +32,7 @@ export default [
|
||||
block: 'block-b',
|
||||
title: 'Challenge One',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block One',
|
||||
superBlock: 'super-block-one',
|
||||
dashedName: 'challenge-one'
|
||||
},
|
||||
{
|
||||
@ -45,7 +45,7 @@ export default [
|
||||
block: 'block-b',
|
||||
title: 'Challenge Two',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block One',
|
||||
superBlock: 'super-block-one',
|
||||
dashedName: 'challenge-two'
|
||||
},
|
||||
{
|
||||
@ -57,7 +57,7 @@ export default [
|
||||
block: 'block-c',
|
||||
title: 'Challenge One',
|
||||
isPrivate: true,
|
||||
superBlock: 'Super Block One',
|
||||
superBlock: 'super-block-one',
|
||||
dashedName: 'challenge-one'
|
||||
},
|
||||
{
|
||||
@ -69,7 +69,7 @@ export default [
|
||||
block: 'block-a',
|
||||
title: 'Challenge One',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block Two',
|
||||
superBlock: 'super-block-two',
|
||||
dashedName: 'challenge-one'
|
||||
},
|
||||
{
|
||||
@ -81,7 +81,7 @@ export default [
|
||||
block: 'block-a',
|
||||
title: 'Challenge Two',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block Two',
|
||||
superBlock: 'super-block-two',
|
||||
dashedName: 'challenge-two'
|
||||
},
|
||||
{
|
||||
@ -93,7 +93,7 @@ export default [
|
||||
block: 'block-b',
|
||||
title: 'Challenge One',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block Two',
|
||||
superBlock: 'super-block-two',
|
||||
dashedName: 'challenge-one'
|
||||
},
|
||||
{
|
||||
@ -105,7 +105,7 @@ export default [
|
||||
block: 'block-b',
|
||||
title: 'Challenge Two',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block Two',
|
||||
superBlock: 'super-block-two',
|
||||
dashedName: 'challenge-two'
|
||||
},
|
||||
{
|
||||
@ -117,7 +117,7 @@ export default [
|
||||
block: 'block-a',
|
||||
title: 'Challenge One',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block Three',
|
||||
superBlock: 'super-block-three',
|
||||
dashedName: 'challenge-one'
|
||||
},
|
||||
{
|
||||
@ -129,7 +129,7 @@ export default [
|
||||
block: 'block-c',
|
||||
title: 'Challenge Two',
|
||||
isPrivate: false,
|
||||
superBlock: 'Super Block Three',
|
||||
superBlock: 'super-block-three',
|
||||
dashedName: 'challenge-two'
|
||||
}
|
||||
];
|
||||
|
@ -13,17 +13,17 @@ import Algorithm from './Algorithm';
|
||||
|
||||
const generateIconComponent = (superBlock, className) => {
|
||||
const iconMap = {
|
||||
'Responsive Web Design': ResponsiveDesign,
|
||||
'JavaScript Algorithms and Data Structures': JavaScriptIcon,
|
||||
'Front End Libraries': ReactIcon,
|
||||
'Data Visualization': D3Icon,
|
||||
'APIs and Microservices': APIIcon,
|
||||
'Quality Assurance': Clipboard,
|
||||
'Scientific Computing with Python': PythonIcon,
|
||||
'Data Analysis with Python': Analytics,
|
||||
'Information Security': Shield,
|
||||
'Machine Learning with Python': TensorflowIcon,
|
||||
'Coding Interview Prep': Algorithm
|
||||
'responsive-web-design': ResponsiveDesign,
|
||||
'javascript-algorithms-and-data-structures': JavaScriptIcon,
|
||||
'front-end-libraries': ReactIcon,
|
||||
'data-visualization': D3Icon,
|
||||
'apis-and-microservices': APIIcon,
|
||||
'quality-assurance': Clipboard,
|
||||
'scientific-computing-with-python': PythonIcon,
|
||||
'data-analysis-with-python': Analytics,
|
||||
'information-security': Shield,
|
||||
'machine-learning-with-python': TensorflowIcon,
|
||||
'coding-interview-prep': Algorithm
|
||||
};
|
||||
// fallback in case super block doesn't exist and for tests
|
||||
const Icon = iconMap[superBlock] ? iconMap[superBlock] : ResponsiveDesign;
|
||||
|
@ -6,7 +6,6 @@ import { generateIconComponent } from '../../assets/icons';
|
||||
|
||||
import { Link, Spacer } from '../helpers';
|
||||
import LinkButton from '../../assets/icons/LinkButton';
|
||||
import { dasherize } from '../../../../utils/slugs';
|
||||
import './map.css';
|
||||
import { isAuditedCert } from '../../../../utils/is-audited';
|
||||
import { curriculumLocale } from '../../../../config/env.json';
|
||||
@ -16,11 +15,9 @@ const propTypes = {
|
||||
forLanding: PropTypes.bool
|
||||
};
|
||||
|
||||
const codingPrepRE = new RegExp('Interview Prep');
|
||||
|
||||
function createSuperBlockTitle(str) {
|
||||
const superBlockTitle = i18next.t(`intro:${dasherize(str)}.title`);
|
||||
return codingPrepRE.test(str)
|
||||
function createSuperBlockTitle(superBlock) {
|
||||
const superBlockTitle = i18next.t(`intro:${superBlock}.title`);
|
||||
return superBlock === 'coding-interview-prep'
|
||||
? i18next.t('learn.cert-map-estimates.coding-prep', {
|
||||
title: superBlockTitle
|
||||
})
|
||||
@ -34,18 +31,18 @@ const linkSpacingStyle = {
|
||||
};
|
||||
|
||||
function renderLandingMap(nodes) {
|
||||
nodes = nodes.filter(node => node.superBlock !== 'Coding Interview Prep');
|
||||
nodes = nodes.filter(node => node.superBlock !== 'coding-interview-prep');
|
||||
return (
|
||||
<ul data-test-label='certifications'>
|
||||
{nodes.map((node, i) => (
|
||||
<li key={i}>
|
||||
<Link
|
||||
className='btn link-btn btn-lg'
|
||||
to={`/learn/${dasherize(node.superBlock)}/`}
|
||||
to={`/learn/${node.superBlock}/`}
|
||||
>
|
||||
<div style={linkSpacingStyle}>
|
||||
{generateIconComponent(node.superBlock, 'map-icon')}
|
||||
{i18next.t(`intro:${dasherize(node.superBlock)}.title`)}
|
||||
{i18next.t(`intro:${node.superBlock}.title`)}
|
||||
</div>
|
||||
<LinkButton />
|
||||
</Link>
|
||||
@ -63,7 +60,7 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
|
||||
<li key={i}>
|
||||
<Link
|
||||
className='btn link-btn btn-lg'
|
||||
to={`/learn/${dasherize(node.superBlock)}/`}
|
||||
to={`/learn/${node.superBlock}/`}
|
||||
>
|
||||
<div style={linkSpacingStyle}>
|
||||
{generateIconComponent(node.superBlock, 'map-icon')}
|
||||
@ -76,14 +73,12 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
|
||||
) : (
|
||||
<ul data-test-label='learn-curriculum-map'>
|
||||
{nodes
|
||||
.filter(node =>
|
||||
isAuditedCert(curriculumLocale, dasherize(node.superBlock))
|
||||
)
|
||||
.filter(node => isAuditedCert(curriculumLocale, node.superBlock))
|
||||
.map((node, i) => (
|
||||
<li key={i}>
|
||||
<Link
|
||||
className='btn link-btn btn-lg'
|
||||
to={`/learn/${dasherize(node.superBlock)}/`}
|
||||
to={`/learn/${node.superBlock}/`}
|
||||
>
|
||||
<div style={linkSpacingStyle}>
|
||||
{generateIconComponent(node.superBlock, 'map-icon')}
|
||||
@ -105,14 +100,12 @@ function renderLearnMap(nodes, currentSuperBlock = '') {
|
||||
<Spacer />
|
||||
</div>
|
||||
{nodes
|
||||
.filter(
|
||||
node => !isAuditedCert(curriculumLocale, dasherize(node.superBlock))
|
||||
)
|
||||
.filter(node => !isAuditedCert(curriculumLocale, node.superBlock))
|
||||
.map((node, i) => (
|
||||
<li key={i}>
|
||||
<Link
|
||||
className='btn link-btn btn-lg'
|
||||
to={`/learn/${dasherize(node.superBlock)}/`}
|
||||
to={`/learn/${node.superBlock}/`}
|
||||
>
|
||||
<div style={linkSpacingStyle}>
|
||||
{generateIconComponent(node.superBlock, 'map-icon')}
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: APIs and Microservices
|
||||
superBlock: APIs and Microservices
|
||||
superBlock: apis-and-microservices
|
||||
---
|
||||
## Introduction to APIs and Microservices
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Coding Interview Prep
|
||||
superBlock: Coding Interview Prep
|
||||
superBlock: coding-interview-prep
|
||||
---
|
||||
|
||||
## Introduction to Coding Interview Prep
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Data Analysis with Python
|
||||
superBlock: Data Analysis with Python
|
||||
superBlock: data-analysis-with-python
|
||||
---
|
||||
## Introduction to Data Analysis with Python
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Data Visualization
|
||||
superBlock: Data Visualization
|
||||
superBlock: data-visualization
|
||||
---
|
||||
## Introduction to Data Visualization
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Front End Libraries
|
||||
superBlock: Front End Libraries
|
||||
superBlock: front-end-libraries
|
||||
---
|
||||
## Introduction to Front End Libraries
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Information Security
|
||||
superBlock: Information Security
|
||||
superBlock: information-security
|
||||
---
|
||||
## Introduction to Information Security
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
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
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Machine Learning with Python
|
||||
superBlock: Machine Learning with Python
|
||||
superBlock: machine-learning-with-python
|
||||
---
|
||||
## Introduction to Machine Learning with Python
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Quality Assurance
|
||||
superBlock: Quality Assurance
|
||||
superBlock: quality-assurance
|
||||
---
|
||||
## Introduction to Quality Assurance
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Responsive Web Design
|
||||
superBlock: Responsive Web Design
|
||||
superBlock: responsive-web-design
|
||||
---
|
||||
## Introduction to Responsive Web Design
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Scientific Computing with Python
|
||||
superBlock: Scientific Computing with Python
|
||||
superBlock: scientific-computing-with-python
|
||||
---
|
||||
## Introduction to Scientific Computing with Python
|
||||
|
||||
|
@ -36,21 +36,19 @@ function ChallengeTitle({
|
||||
<Link
|
||||
className='breadcrumb-left'
|
||||
state={{ breadcrumbBlockClick: block }}
|
||||
to={`/learn/${dasherize(superBlock)}`}
|
||||
to={`/learn/${superBlock}`}
|
||||
>
|
||||
<span className='ellipsis'>
|
||||
{i18next.t(`intro:${dasherize(superBlock)}.title`)}
|
||||
{i18next.t(`intro:${superBlock}.title`)}
|
||||
</span>
|
||||
</Link>
|
||||
<div className='breadcrumb-center' />
|
||||
<Link
|
||||
className='breadcrumb-right'
|
||||
state={{ breadcrumbBlockClick: block }}
|
||||
to={`/learn/${dasherize(superBlock)}/#${dasherize(block)}`}
|
||||
to={`/learn/${superBlock}/#${dasherize(block)}`}
|
||||
>
|
||||
{i18next.t(
|
||||
`intro:${dasherize(superBlock)}.blocks.${dasherize(block)}.title`
|
||||
)}
|
||||
{i18next.t(`intro:${superBlock}.blocks.${dasherize(block)}.title`)}
|
||||
</Link>
|
||||
</div>
|
||||
<div className='challenge-title'>
|
||||
|
@ -9,7 +9,7 @@ const baseProps = {
|
||||
block: 'fake block',
|
||||
children: 'title text',
|
||||
isCompleted: true,
|
||||
superBlock: 'fake superblock'
|
||||
superBlock: 'fake-superblock'
|
||||
};
|
||||
|
||||
describe('<ChallengeTitle/>', () => {
|
||||
|
@ -141,12 +141,10 @@ export class SuperBlockIntroductionPage extends Component {
|
||||
t
|
||||
} = this.props;
|
||||
|
||||
const superBlockDashedName = dasherize(superBlock);
|
||||
|
||||
const nodesForSuperBlock = edges.map(({ node }) => node);
|
||||
const blockDashedNames = uniq(nodesForSuperBlock.map(({ block }) => block));
|
||||
|
||||
const i18nSuperBlock = t(`intro:${superBlockDashedName}.title`);
|
||||
const i18nSuperBlock = t(`intro:${superBlock}.title`);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -171,12 +169,12 @@ export class SuperBlockIntroductionPage extends Component {
|
||||
challenges={nodesForSuperBlock.filter(
|
||||
node => node.block === blockDashedName
|
||||
)}
|
||||
superBlockDashedName={superBlockDashedName}
|
||||
superBlockDashedName={superBlock}
|
||||
/>
|
||||
{blockDashedName !== 'project-euler' ? <Spacer /> : null}
|
||||
</Fragment>
|
||||
))}
|
||||
{superBlock !== 'Coding Interview Prep' && (
|
||||
{superBlock !== 'coding-interview-prep' && (
|
||||
<div>
|
||||
<CertChallenge superBlock={superBlock} />
|
||||
</div>
|
||||
|
@ -8,7 +8,6 @@ import { withTranslation } from 'react-i18next';
|
||||
import CertificationIcon from '../../../assets/icons/CertificationIcon';
|
||||
import GreenPass from '../../../assets/icons/GreenPass';
|
||||
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
|
||||
import { dasherize } from '../../../../../utils/slugs';
|
||||
import { userSelector } from '../../../redux';
|
||||
import { User } from '../../../redux/propTypes';
|
||||
|
||||
@ -48,23 +47,22 @@ export class CertChallenge extends Component {
|
||||
} = this.props;
|
||||
|
||||
const userCertificates = {
|
||||
'Responsive Web Design': isRespWebDesignCert,
|
||||
'JavaScript Algorithms and Data Structures': isJsAlgoDataStructCert,
|
||||
'Front End Libraries': isFrontEndLibsCert,
|
||||
'Data Visualization': is2018DataVisCert,
|
||||
'APIs and Microservices': isApisMicroservicesCert,
|
||||
'Quality Assurance': isQaCertV7,
|
||||
'Information Security': isInfosecCertV7,
|
||||
'Scientific Computing with Python': isSciCompPyCertV7,
|
||||
'Data Analysis with Python': isDataAnalysisPyCertV7,
|
||||
'Machine Learning with Python': isMachineLearningPyCertV7
|
||||
'responsive-web-design': isRespWebDesignCert,
|
||||
'javascript-algorithms-and-data-structures': isJsAlgoDataStructCert,
|
||||
'front-end-libraries': isFrontEndLibsCert,
|
||||
'data-visualization': is2018DataVisCert,
|
||||
'apis-and-microservices': isApisMicroservicesCert,
|
||||
'quality-assurance': isQaCertV7,
|
||||
'information-security': isInfosecCertV7,
|
||||
'scientific-computing-with-python': isSciCompPyCertV7,
|
||||
'data-analysis-with-python': isDataAnalysisPyCertV7,
|
||||
'machine-learning-with-python': isMachineLearningPyCertV7
|
||||
};
|
||||
|
||||
const isCertified = userCertificates[superBlock];
|
||||
const superBlockDashedName = dasherize(superBlock);
|
||||
const certLocation = `/certification/${username}/${superBlockDashedName}`;
|
||||
const certLocation = `/certification/${username}/${superBlock}`;
|
||||
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`, {
|
||||
cert: i18nSuperBlock
|
||||
});
|
||||
|
@ -2,7 +2,6 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { dasherize } from '../../../../../utils/slugs';
|
||||
import { Spacer } from '../../../components/helpers';
|
||||
import { generateIconComponent } from '../../../assets/icons';
|
||||
|
||||
@ -13,9 +12,8 @@ const propTypes = {
|
||||
function SuperBlockIntro(props) {
|
||||
const { t } = useTranslation();
|
||||
const { superBlock } = props;
|
||||
const superBlockDashedName = dasherize(superBlock);
|
||||
|
||||
const superBlockIntroObj = t(`intro:${superBlockDashedName}`);
|
||||
const superBlockIntroObj = t(`intro:${superBlock}`);
|
||||
const {
|
||||
title: i18nSuperBlock,
|
||||
intro: superBlockIntroText
|
||||
|
@ -106,7 +106,7 @@ exports.createSuperBlockIntroPages = createPage => edge => {
|
||||
path: slug,
|
||||
component: superBlockIntro,
|
||||
context: {
|
||||
superBlock: superBlock,
|
||||
superBlock,
|
||||
slug
|
||||
}
|
||||
});
|
||||
|
@ -14,7 +14,6 @@ const {
|
||||
const { isAuditedCert } = require('../utils/is-audited');
|
||||
const { dasherize } = require('../utils/slugs');
|
||||
const { createPoly } = require('../utils/polyvinyl');
|
||||
const { blockNameify } = require('../utils/block-nameify');
|
||||
const { helpCategoryMap } = require('../client/utils/challengeTypes');
|
||||
const {
|
||||
curriculum: curriculumLangs
|
||||
@ -346,7 +345,6 @@ function prepareChallenge(challenge) {
|
||||
challenge.solutionFiles = filesToObject(challenge.solutionFiles);
|
||||
}
|
||||
challenge.block = dasherize(challenge.block);
|
||||
challenge.superBlock = blockNameify(challenge.superBlock);
|
||||
return challenge;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user