fix: simplify mobile layout tabs (#44431)
* fix: simplify mobile layout tabs Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@ -80,6 +80,7 @@ exports.createPages = function createPages({ graphql, actions, reporter }) {
|
|||||||
fields {
|
fields {
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
|
hasEditableBoundaries
|
||||||
id
|
id
|
||||||
order
|
order
|
||||||
required {
|
required {
|
||||||
|
@ -139,6 +139,7 @@ export type ChallengeNode = {
|
|||||||
forumTopicId: number;
|
forumTopicId: number;
|
||||||
guideUrl: string;
|
guideUrl: string;
|
||||||
head: string[];
|
head: string[];
|
||||||
|
hasEditableBoundaries: boolean;
|
||||||
helpCategory: string;
|
helpCategory: string;
|
||||||
id: string;
|
id: string;
|
||||||
instructions: string;
|
instructions: string;
|
||||||
|
@ -1,52 +1,55 @@
|
|||||||
import { TabPane, Tabs } from '@freecodecamp/react-bootstrap';
|
import { TabPane, Tabs } from '@freecodecamp/react-bootstrap';
|
||||||
import i18next from 'i18next';
|
import i18next from 'i18next';
|
||||||
import React, { Component, ReactElement } from 'react';
|
import React, { Component, ReactElement } from 'react';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { bindActionCreators, Dispatch } from 'redux';
|
|
||||||
import { createStructuredSelector } from 'reselect';
|
|
||||||
import envData from '../../../../../config/env.json';
|
import envData from '../../../../../config/env.json';
|
||||||
import ToolPanel from '../components/tool-panel';
|
import ToolPanel from '../components/tool-panel';
|
||||||
import { currentTabSelector, moveToTab } from '../redux';
|
|
||||||
import EditorTabs from './editor-tabs';
|
import EditorTabs from './editor-tabs';
|
||||||
|
|
||||||
const { showUpcomingChanges } = envData;
|
const { showUpcomingChanges } = envData;
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
|
||||||
currentTab: currentTabSelector as (state: unknown) => number
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch: Dispatch) =>
|
|
||||||
bindActionCreators(
|
|
||||||
{
|
|
||||||
moveToTab
|
|
||||||
},
|
|
||||||
dispatch
|
|
||||||
);
|
|
||||||
interface MobileLayoutProps {
|
interface MobileLayoutProps {
|
||||||
currentTab: number;
|
|
||||||
editor: JSX.Element | null;
|
editor: JSX.Element | null;
|
||||||
guideUrl: string;
|
guideUrl: string;
|
||||||
hasEditableBoundaries: boolean;
|
hasEditableBoundaries: boolean;
|
||||||
hasNotes: boolean;
|
hasNotes: boolean;
|
||||||
hasPreview: boolean;
|
hasPreview: boolean;
|
||||||
instructions: JSX.Element;
|
instructions: JSX.Element;
|
||||||
moveToTab: typeof moveToTab;
|
|
||||||
notes: ReactElement;
|
notes: ReactElement;
|
||||||
preview: JSX.Element;
|
preview: JSX.Element;
|
||||||
testOutput: JSX.Element;
|
testOutput: JSX.Element;
|
||||||
videoUrl: string;
|
videoUrl: string;
|
||||||
usesMultifileEditor: boolean;
|
usesMultifileEditor: boolean;
|
||||||
}
|
}
|
||||||
class MobileLayout extends Component<MobileLayoutProps> {
|
|
||||||
|
enum Tab {
|
||||||
|
Editor = 'editor',
|
||||||
|
Preview = 'preview',
|
||||||
|
Console = 'console',
|
||||||
|
Notes = 'notes',
|
||||||
|
Instructions = 'instructions'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MobileLayoutState {
|
||||||
|
currentTab: Tab;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MobileLayout extends Component<MobileLayoutProps, MobileLayoutState> {
|
||||||
static displayName: string;
|
static displayName: string;
|
||||||
componentDidMount() {
|
|
||||||
if (this.props.currentTab !== 1) this.props.moveToTab(1);
|
state: MobileLayoutState = {
|
||||||
}
|
currentTab: this.props.hasEditableBoundaries ? Tab.Editor : Tab.Instructions
|
||||||
|
};
|
||||||
|
|
||||||
|
switchTab = (tab: Tab) => {
|
||||||
|
this.setState({
|
||||||
|
currentTab: tab
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { currentTab } = this.state;
|
||||||
const {
|
const {
|
||||||
currentTab,
|
|
||||||
moveToTab,
|
|
||||||
hasEditableBoundaries,
|
hasEditableBoundaries,
|
||||||
instructions,
|
instructions,
|
||||||
editor,
|
editor,
|
||||||
@ -69,26 +72,24 @@ class MobileLayout extends Component<MobileLayoutProps> {
|
|||||||
// but still needs a way to switch between the different tabs.
|
// but still needs a way to switch between the different tabs.
|
||||||
const projectBasedChallenge = showUpcomingChanges && usesMultifileEditor;
|
const projectBasedChallenge = showUpcomingChanges && usesMultifileEditor;
|
||||||
|
|
||||||
const eventKeys = [1, 2, 3, 4, 5];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Tabs
|
<Tabs
|
||||||
activeKey={currentTab}
|
activeKey={currentTab}
|
||||||
defaultActiveKey={1}
|
defaultActiveKey={currentTab}
|
||||||
id='challenge-page-tabs'
|
id='challenge-page-tabs'
|
||||||
onSelect={moveToTab}
|
onSelect={this.switchTab}
|
||||||
>
|
>
|
||||||
{!hasEditableBoundaries && (
|
{!hasEditableBoundaries && (
|
||||||
<TabPane
|
<TabPane
|
||||||
eventKey={eventKeys.shift()}
|
eventKey={Tab.Instructions}
|
||||||
title={i18next.t('learn.editor-tabs.info')}
|
title={i18next.t('learn.editor-tabs.info')}
|
||||||
>
|
>
|
||||||
{instructions}
|
{instructions}
|
||||||
</TabPane>
|
</TabPane>
|
||||||
)}
|
)}
|
||||||
<TabPane
|
<TabPane
|
||||||
eventKey={eventKeys.shift()}
|
eventKey={Tab.Editor}
|
||||||
title={i18next.t('learn.editor-tabs.code')}
|
title={i18next.t('learn.editor-tabs.code')}
|
||||||
{...editorTabPaneProps}
|
{...editorTabPaneProps}
|
||||||
>
|
>
|
||||||
@ -96,7 +97,7 @@ class MobileLayout extends Component<MobileLayoutProps> {
|
|||||||
{editor}
|
{editor}
|
||||||
</TabPane>
|
</TabPane>
|
||||||
<TabPane
|
<TabPane
|
||||||
eventKey={eventKeys.shift()}
|
eventKey={Tab.Console}
|
||||||
title={i18next.t('learn.editor-tabs.tests')}
|
title={i18next.t('learn.editor-tabs.tests')}
|
||||||
{...editorTabPaneProps}
|
{...editorTabPaneProps}
|
||||||
>
|
>
|
||||||
@ -104,7 +105,7 @@ class MobileLayout extends Component<MobileLayoutProps> {
|
|||||||
</TabPane>
|
</TabPane>
|
||||||
{hasNotes && projectBasedChallenge && (
|
{hasNotes && projectBasedChallenge && (
|
||||||
<TabPane
|
<TabPane
|
||||||
eventKey={eventKeys.shift()}
|
eventKey={Tab.Notes}
|
||||||
title={i18next.t('learn.editor-tabs.notes')}
|
title={i18next.t('learn.editor-tabs.notes')}
|
||||||
>
|
>
|
||||||
{notes}
|
{notes}
|
||||||
@ -112,7 +113,7 @@ class MobileLayout extends Component<MobileLayoutProps> {
|
|||||||
)}
|
)}
|
||||||
{hasPreview && (
|
{hasPreview && (
|
||||||
<TabPane
|
<TabPane
|
||||||
eventKey={eventKeys.shift()}
|
eventKey={Tab.Preview}
|
||||||
title={i18next.t('learn.editor-tabs.preview')}
|
title={i18next.t('learn.editor-tabs.preview')}
|
||||||
>
|
>
|
||||||
{preview}
|
{preview}
|
||||||
@ -127,4 +128,4 @@ class MobileLayout extends Component<MobileLayoutProps> {
|
|||||||
|
|
||||||
MobileLayout.displayName = 'MobileLayout';
|
MobileLayout.displayName = 'MobileLayout';
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(MobileLayout);
|
export default MobileLayout;
|
||||||
|
@ -398,20 +398,12 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasEditableBoundaries() {
|
|
||||||
const { challengeFiles } = this.props;
|
|
||||||
return (
|
|
||||||
challengeFiles?.some(
|
|
||||||
challengeFile => challengeFile.editableRegionBoundaries?.length === 2
|
|
||||||
) ?? false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
block,
|
block,
|
||||||
fields: { blockName },
|
fields: { blockName },
|
||||||
forumTopicId,
|
forumTopicId,
|
||||||
|
hasEditableBoundaries,
|
||||||
superBlock,
|
superBlock,
|
||||||
title,
|
title,
|
||||||
usesMultifileEditor,
|
usesMultifileEditor,
|
||||||
@ -443,7 +435,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
<MobileLayout
|
<MobileLayout
|
||||||
editor={this.renderEditor()}
|
editor={this.renderEditor()}
|
||||||
guideUrl={getGuideUrl({ forumTopicId, title })}
|
guideUrl={getGuideUrl({ forumTopicId, title })}
|
||||||
hasEditableBoundaries={this.hasEditableBoundaries()}
|
hasEditableBoundaries={hasEditableBoundaries}
|
||||||
hasNotes={!!notes}
|
hasNotes={!!notes}
|
||||||
hasPreview={this.hasPreview()}
|
hasPreview={this.hasPreview()}
|
||||||
instructions={this.renderInstructionsPanel({
|
instructions={this.renderInstructionsPanel({
|
||||||
@ -461,7 +453,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
|
|||||||
block={block}
|
block={block}
|
||||||
challengeFiles={challengeFiles}
|
challengeFiles={challengeFiles}
|
||||||
editor={this.renderEditor()}
|
editor={this.renderEditor()}
|
||||||
hasEditableBoundaries={this.hasEditableBoundaries()}
|
hasEditableBoundaries={hasEditableBoundaries}
|
||||||
hasNotes={!!notes}
|
hasNotes={!!notes}
|
||||||
hasPreview={this.hasPreview()}
|
hasPreview={this.hasPreview()}
|
||||||
instructions={this.renderInstructionsPanel({
|
instructions={this.renderInstructionsPanel({
|
||||||
@ -504,6 +496,7 @@ export const query = graphql`
|
|||||||
block
|
block
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
|
hasEditableBoundaries
|
||||||
instructions
|
instructions
|
||||||
notes
|
notes
|
||||||
removeComments
|
removeComments
|
||||||
|
@ -40,8 +40,6 @@ export const actionTypes = createTypes(
|
|||||||
'stopResetting',
|
'stopResetting',
|
||||||
'submitChallenge',
|
'submitChallenge',
|
||||||
|
|
||||||
'moveToTab',
|
|
||||||
|
|
||||||
'setEditorFocusability',
|
'setEditorFocusability',
|
||||||
'toggleVisibleEditor'
|
'toggleVisibleEditor'
|
||||||
],
|
],
|
||||||
|
@ -120,8 +120,6 @@ export const resetChallenge = createAction(actionTypes.resetChallenge);
|
|||||||
export const stopResetting = createAction(actionTypes.stopResetting);
|
export const stopResetting = createAction(actionTypes.stopResetting);
|
||||||
export const submitChallenge = createAction(actionTypes.submitChallenge);
|
export const submitChallenge = createAction(actionTypes.submitChallenge);
|
||||||
|
|
||||||
export const moveToTab = createAction(actionTypes.moveToTab);
|
|
||||||
|
|
||||||
export const setEditorFocusability = createAction(
|
export const setEditorFocusability = createAction(
|
||||||
actionTypes.setEditorFocusability
|
actionTypes.setEditorFocusability
|
||||||
);
|
);
|
||||||
@ -344,10 +342,6 @@ export const reducer = handleActions(
|
|||||||
[payload]: true
|
[payload]: true
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
[actionTypes.moveToTab]: (state, { payload }) => ({
|
|
||||||
...state,
|
|
||||||
currentTab: payload
|
|
||||||
}),
|
|
||||||
[actionTypes.executeChallenge]: state => ({
|
[actionTypes.executeChallenge]: state => ({
|
||||||
...state,
|
...state,
|
||||||
currentTab: 3
|
currentTab: 3
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Basic JavaScript RPG Game",
|
"name": "Basic JavaScript RPG Game",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "basic-javascript-rpg-game",
|
"dashedName": "basic-javascript-rpg-game",
|
||||||
"order": 10,
|
"order": 10,
|
||||||
"time": "2 hours",
|
"time": "2 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "D3 Dashboard",
|
"name": "D3 Dashboard",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "d3-dashboard",
|
"dashedName": "d3-dashboard",
|
||||||
"order": 3,
|
"order": 3,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Functional Programming Spreadsheet",
|
"name": "Functional Programming Spreadsheet",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "functional-programming-spreadsheet",
|
"dashedName": "functional-programming-spreadsheet",
|
||||||
"order": 12,
|
"order": 12,
|
||||||
"time": "2 hours",
|
"time": "2 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Intermediate JavaScript Calorie Counter",
|
"name": "Intermediate JavaScript Calorie Counter",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "intermediate-javascript-calorie-counter",
|
"dashedName": "intermediate-javascript-calorie-counter",
|
||||||
"order": 11,
|
"order": 11,
|
||||||
"time": "2 hours",
|
"time": "2 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn Accessibility by Building a Quiz",
|
"name": "Learn Accessibility by Building a Quiz",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-accessibility-by-building-a-quiz",
|
"dashedName": "learn-accessibility-by-building-a-quiz",
|
||||||
"order": 42,
|
"order": 42,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn Basic CSS by Building a Cafe Menu",
|
"name": "Learn Basic CSS by Building a Cafe Menu",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-basic-css-by-building-a-cafe-menu",
|
"dashedName": "learn-basic-css-by-building-a-cafe-menu",
|
||||||
"order": 10,
|
"order": 10,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn CSS Animation by Building a Ferris Wheel",
|
"name": "Learn CSS Animation by Building a Ferris Wheel",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-css-animation-by-building-a-ferris-wheel",
|
"dashedName": "learn-css-animation-by-building-a-ferris-wheel",
|
||||||
"order": 15,
|
"order": 15,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn CSS Flexbox by Building a Photo Gallery",
|
"name": "Learn CSS Flexbox by Building a Photo Gallery",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-css-flexbox-by-building-a-photo-gallery",
|
"dashedName": "learn-css-flexbox-by-building-a-photo-gallery",
|
||||||
"order": 20,
|
"order": 20,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn CSS Grid by Building a Magazine",
|
"name": "Learn CSS Grid by Building a Magazine",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-css-grid-by-building-a-magazine",
|
"dashedName": "learn-css-grid-by-building-a-magazine",
|
||||||
"order": 16,
|
"order": 16,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn CSS Variables by Building a City Skyline",
|
"name": "Learn CSS Variables by Building a City Skyline",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-css-variables-by-building-a-city-skyline",
|
"dashedName": "learn-css-variables-by-building-a-city-skyline",
|
||||||
"order": 8,
|
"order": 8,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn HTML by Building a Cat Photo App",
|
"name": "Learn HTML by Building a Cat Photo App",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-html-by-building-a-cat-photo-app",
|
"dashedName": "learn-html-by-building-a-cat-photo-app",
|
||||||
"order": 9,
|
"order": 9,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn HTML Forms by Building a Registration Form",
|
"name": "Learn HTML Forms by Building a Registration Form",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-html-forms-by-building-a-registration-form",
|
"dashedName": "learn-html-forms-by-building-a-registration-form",
|
||||||
"order": 23,
|
"order": 23,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn Intermediate CSS by Building a Picasso Painting",
|
"name": "Learn Intermediate CSS by Building a Picasso Painting",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-intermediate-css-by-building-a-picasso-painting",
|
"dashedName": "learn-intermediate-css-by-building-a-picasso-painting",
|
||||||
"order": 11,
|
"order": 11,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn Responsive Web Design by Building a Piano",
|
"name": "Learn Responsive Web Design by Building a Piano",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-responsive-web-design-by-building-a-piano",
|
"dashedName": "learn-responsive-web-design-by-building-a-piano",
|
||||||
"order": 13,
|
"order": 13,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn the CSS Box Model by Building a Rothko Painting",
|
"name": "Learn the CSS Box Model by Building a Rothko Painting",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-the-css-box-model-by-building-a-rothko-painting",
|
"dashedName": "learn-the-css-box-model-by-building-a-rothko-painting",
|
||||||
"order": 12,
|
"order": 12,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "Learn Typography by Building a Nutrition Label",
|
"name": "Learn Typography by Building a Nutrition Label",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "learn-typography-by-building-a-nutrition-label",
|
"dashedName": "learn-typography-by-building-a-nutrition-label",
|
||||||
"order": 25,
|
"order": 25,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
@ -296,6 +296,7 @@ ${getFullPath('english')}
|
|||||||
);
|
);
|
||||||
const {
|
const {
|
||||||
name: blockName,
|
name: blockName,
|
||||||
|
hasEditableBoundaries,
|
||||||
order,
|
order,
|
||||||
isPrivate,
|
isPrivate,
|
||||||
required = [],
|
required = [],
|
||||||
@ -304,6 +305,7 @@ ${getFullPath('english')}
|
|||||||
usesMultifileEditor
|
usesMultifileEditor
|
||||||
} = meta;
|
} = meta;
|
||||||
challenge.block = dasherize(blockName);
|
challenge.block = dasherize(blockName);
|
||||||
|
challenge.hasEditableBoundaries = !!hasEditableBoundaries;
|
||||||
challenge.order = order;
|
challenge.order = order;
|
||||||
const superOrder = getSuperOrder(superBlock);
|
const superOrder = getSuperOrder(superBlock);
|
||||||
if (superOrder !== null) challenge.superOrder = superOrder;
|
if (superOrder !== null) challenge.superOrder = superOrder;
|
||||||
|
@ -39,6 +39,7 @@ const schema = Joi.object()
|
|||||||
}),
|
}),
|
||||||
challengeFiles: Joi.array().items(fileJoi),
|
challengeFiles: Joi.array().items(fileJoi),
|
||||||
guideUrl: Joi.string().uri({ scheme: 'https' }),
|
guideUrl: Joi.string().uri({ scheme: 'https' }),
|
||||||
|
hasEditableBoundaries: Joi.boolean(),
|
||||||
helpCategory: Joi.valid(
|
helpCategory: Joi.valid(
|
||||||
'JavaScript',
|
'JavaScript',
|
||||||
'HTML-CSS',
|
'HTML-CSS',
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"name": "",
|
"name": "",
|
||||||
"isUpcomingChange": true,
|
"isUpcomingChange": true,
|
||||||
"usesMultifileEditor": true,
|
"usesMultifileEditor": true,
|
||||||
|
"hasEditableBoundaries": true,
|
||||||
"dashedName": "",
|
"dashedName": "",
|
||||||
"order": 42,
|
"order": 42,
|
||||||
"time": "5 hours",
|
"time": "5 hours",
|
||||||
|
Reference in New Issue
Block a user