feat(client): refactor desktop-layout to ts (#42651)

Co-authored-by: moT01 <20648924+moT01@users.noreply.github.com>
This commit is contained in:
Shaun Hamilton
2021-10-19 15:51:38 +01:00
committed by GitHub
parent 187ef03ed3
commit 2bddbbff42
4 changed files with 168 additions and 178 deletions

View File

@ -1,170 +0,0 @@
import { first } from 'lodash-es';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex';
import envData from '../../../../../config/env.json';
import { sortChallengeFiles } from '../../../../../utils/sort-challengefiles';
import EditorTabs from './EditorTabs';
import ActionRow from './action-row.tsx';
const { showUpcomingChanges } = envData;
const paneType = {
flex: PropTypes.number
};
const propTypes = {
block: PropTypes.string,
challengeFiles: PropTypes.array,
editor: PropTypes.element,
hasEditableBoundries: PropTypes.bool,
hasPreview: PropTypes.bool,
instructions: PropTypes.element,
layoutState: PropTypes.shape({
codePane: paneType,
editorPane: paneType,
instructionPane: paneType,
previewPane: paneType,
testsPane: paneType
}),
preview: PropTypes.element,
resizeProps: PropTypes.shape({
onStopResize: PropTypes.func,
onResize: PropTypes.func
}),
superBlock: PropTypes.string,
testOutput: PropTypes.element
};
const reflexProps = {
propagateDimensions: true
};
class DesktopLayout extends Component {
constructor(props) {
super(props);
this.state = { showNotes: false, showPreview: true, showConsole: false };
this.switchDisplayTab = this.switchDisplayTab.bind(this);
}
switchDisplayTab(displayTab) {
this.setState(state => {
return {
[displayTab]: !state[displayTab]
};
});
}
getChallengeFile() {
const { challengeFiles } = this.props;
return first(sortChallengeFiles(challengeFiles));
}
render() {
const {
resizeProps,
instructions,
editor,
testOutput,
hasPreview,
layoutState,
preview,
hasEditableBoundries,
superBlock,
block
} = this.props;
const { showPreview, showConsole } = this.state;
const challengeFile = this.getChallengeFile();
const projectBasedChallenge = showUpcomingChanges && hasEditableBoundries;
const isPreviewDisplayable = projectBasedChallenge
? showPreview && hasPreview
: hasPreview;
const isConsoleDisplayable = projectBasedChallenge ? showConsole : true;
const { codePane, editorPane, instructionPane, previewPane, testsPane } =
layoutState;
return (
<div className='desktop-layout'>
{projectBasedChallenge && (
<ActionRow
block={block}
switchDisplayTab={this.switchDisplayTab}
{...this.state}
superBlock={superBlock}
/>
)}
<ReflexContainer orientation='vertical'>
{!projectBasedChallenge && (
<ReflexElement
flex={instructionPane.flex}
name='instructionPane'
{...resizeProps}
>
{instructions}
</ReflexElement>
)}
{!projectBasedChallenge && (
<ReflexSplitter propagate={true} {...resizeProps} />
)}
<ReflexElement
flex={editorPane.flex}
name='editorPane'
{...resizeProps}
>
{challengeFile && showUpcomingChanges && !hasEditableBoundries && (
<EditorTabs />
)}
{challengeFile && (
<ReflexContainer
key={challengeFile.fileKey}
orientation='horizontal'
>
<ReflexElement
flex={codePane.flex}
name='codePane'
{...reflexProps}
{...resizeProps}
>
{editor}
</ReflexElement>
{isConsoleDisplayable && (
<ReflexSplitter propagate={true} {...resizeProps} />
)}
{isConsoleDisplayable && (
<ReflexElement
flex={testsPane.flex}
name='testsPane'
{...reflexProps}
{...resizeProps}
>
{testOutput}
</ReflexElement>
)}
</ReflexContainer>
)}
</ReflexElement>
{isPreviewDisplayable && (
<ReflexSplitter propagate={true} {...resizeProps} />
)}
{isPreviewDisplayable && (
<ReflexElement
flex={previewPane.flex}
name='previewPane'
{...resizeProps}
>
{preview}
</ReflexElement>
)}
</ReflexContainer>
</div>
);
}
}
DesktopLayout.displayName = 'DesktopLayout';
DesktopLayout.propTypes = propTypes;
export default DesktopLayout;

View File

@ -7,7 +7,7 @@ import EditorTabs from './EditorTabs';
interface ActionRowProps {
block: string;
showConsole: boolean;
showNotes: boolean;
showNotes?: boolean;
showPreview: boolean;
superBlock: string;
switchDisplayTab: (displayTab: string) => void;

View File

@ -0,0 +1,160 @@
import { first } from 'lodash-es';
import React, { useState, ReactElement } from 'react';
import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex';
import envData from '../../../../../config/env.json';
import { sortChallengeFiles } from '../../../../../utils/sort-challengefiles';
import {
ChallengeFile,
ChallengeFiles,
ResizePropsType
} from '../../../redux/prop-types';
import EditorTabs from './EditorTabs';
import ActionRow from './action-row';
const { showUpcomingChanges } = envData;
type Pane = { flex: number };
interface DesktopLayoutProps {
block: string;
challengeFiles: ChallengeFiles;
editor: ReactElement | null;
hasEditableBoundaries: boolean;
hasPreview: boolean;
instructions: ReactElement;
layoutState: {
codePane: Pane;
editorPane: Pane;
instructionPane: Pane;
previewPane: Pane;
testsPane: Pane;
};
preview: ReactElement;
resizeProps: ResizePropsType;
superBlock: string;
testOutput: ReactElement;
}
const reflexProps = {
propagateDimensions: true
};
const DesktopLayout = (props: DesktopLayoutProps): JSX.Element => {
const [showNotes, setShowNotes] = useState(false);
const [showPreview, setShowPreview] = useState(true);
const [showConsole, setShowConsole] = useState(false);
const switchDisplayTab = (displayTab: string): void => {
switch (displayTab) {
case 'showPreview':
setShowPreview(!showPreview);
break;
case 'showConsole':
setShowConsole(!showConsole);
break;
case 'showNotes':
setShowNotes(!showNotes);
break;
default:
setShowConsole(false);
setShowPreview(false);
setShowNotes(false);
}
};
const getChallengeFile = () => {
const { challengeFiles } = props;
return first(sortChallengeFiles(challengeFiles)) as ChallengeFile | null;
};
const {
block,
resizeProps,
instructions,
editor,
testOutput,
hasPreview,
layoutState,
preview,
hasEditableBoundaries,
superBlock
} = props;
const challengeFile = getChallengeFile();
const projectBasedChallenge = showUpcomingChanges && hasEditableBoundaries;
const isPreviewDisplayable = projectBasedChallenge
? showPreview && hasPreview
: hasPreview;
const isConsoleDisplayable = projectBasedChallenge ? showConsole : true;
const { codePane, editorPane, instructionPane, previewPane, testsPane } =
layoutState;
return (
<div className='desktop-layout'>
{projectBasedChallenge && (
<ActionRow
block={block}
showConsole={showConsole}
showNotes={showNotes}
showPreview={showPreview}
superBlock={superBlock}
switchDisplayTab={switchDisplayTab}
/>
)}
<ReflexContainer orientation='vertical'>
{!projectBasedChallenge && (
<ReflexElement flex={instructionPane.flex} {...resizeProps}>
{instructions}
</ReflexElement>
)}
{!projectBasedChallenge && (
<ReflexSplitter propagate={true} {...resizeProps} />
)}
<ReflexElement flex={editorPane.flex} {...resizeProps}>
{challengeFile && showUpcomingChanges && !hasEditableBoundaries && (
<EditorTabs />
)}
{challengeFile && (
<ReflexContainer
key={challengeFile.fileKey}
orientation='horizontal'
>
<ReflexElement
flex={codePane.flex}
{...reflexProps}
{...resizeProps}
>
{editor}
</ReflexElement>
{isConsoleDisplayable && (
<ReflexSplitter propagate={true} {...resizeProps} />
)}
{isConsoleDisplayable && (
<ReflexElement
flex={testsPane.flex}
{...reflexProps}
{...resizeProps}
>
{testOutput}
</ReflexElement>
)}
</ReflexContainer>
)}
</ReflexElement>
{isPreviewDisplayable && (
<ReflexSplitter propagate={true} {...resizeProps} />
)}
{isPreviewDisplayable && (
<ReflexElement flex={previewPane.flex} {...resizeProps}>
{preview}
</ReflexElement>
)}
</ReflexContainer>
</div>
);
};
DesktopLayout.displayName = 'DesktopLayout';
export default DesktopLayout;

View File

@ -44,9 +44,9 @@ import {
updateChallengeMeta
} from '../redux';
import { getGuideUrl } from '../utils';
import DesktopLayout from './DesktopLayout';
import MobileLayout from './MobileLayout';
import MultifileEditor from './MultifileEditor';
import DesktopLayout from './desktop-layout';
import './classic.css';
import '../components/test-frame.css';
@ -94,7 +94,7 @@ interface ShowClassicProps {
}
interface ShowClassicState {
layout: ReflexLayout | string;
layout: ReflexLayout;
resizing: boolean;
}
@ -143,9 +143,9 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
this.instructionsPanelRef = React.createRef();
}
getLayoutState(): ReflexLayout | string {
getLayoutState(): ReflexLayout {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const reflexLayout: ReflexLayout | string = store.get(REFLEX_LAYOUT);
const reflexLayout: ReflexLayout = store.get(REFLEX_LAYOUT);
// Validate if user has not done any resize of the panes
if (!reflexLayout) return BASE_LAYOUT;
@ -333,7 +333,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
containerRef={this.containerRef}
description={description}
editorRef={this.editorRef}
hasEditableBoundries={this.hasEditableBoundries()}
hasEditableBoundaries={this.hasEditableBoundaries()}
initialTests={tests}
resizeProps={this.resizeProps}
title={title}
@ -363,7 +363,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
);
}
hasEditableBoundries() {
hasEditableBoundaries() {
const { challengeFiles } = this.props;
return (
challengeFiles?.some(
@ -424,7 +424,7 @@ class ShowClassic extends Component<ShowClassicProps, ShowClassicState> {
block={block}
challengeFiles={challengeFiles}
editor={this.renderEditor()}
hasEditableBoundries={this.hasEditableBoundries()}
hasEditableBoundaries={this.hasEditableBoundaries()}
hasPreview={this.hasPreview()}
instructions={this.renderInstructionsPanel({
showToolPanel: true