feat(client): place tool panel at the bottom

This commit is contained in:
Valeriy S
2019-02-14 17:13:35 +03:00
parent 5e137d2022
commit e6d2a9df93
5 changed files with 83 additions and 52 deletions

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React, { Component, Fragment } from 'react';
import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex'; import { ReflexContainer, ReflexSplitter, ReflexElement } from 'react-reflex';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
@ -14,7 +14,8 @@ const propTypes = {
onStopResize: PropTypes.func, onStopResize: PropTypes.func,
onResize: PropTypes.func onResize: PropTypes.func
}), }),
testOutput: PropTypes.element testOutput: PropTypes.element,
toolPanel: PropTypes.element
}; };
class DesktopLayout extends Component { class DesktopLayout extends Component {
@ -26,9 +27,11 @@ class DesktopLayout extends Component {
editor, editor,
testOutput, testOutput,
hasPreview, hasPreview,
preview preview,
toolPanel
} = this.props; } = this.props;
return ( return (
<Fragment>
<ReflexContainer className='desktop-layout' orientation='vertical'> <ReflexContainer className='desktop-layout' orientation='vertical'>
<ReflexElement flex={1} {...resizeProps}> <ReflexElement flex={1} {...resizeProps}>
{instructions} {instructions}
@ -66,6 +69,8 @@ class DesktopLayout extends Component {
</ReflexElement> </ReflexElement>
)} )}
</ReflexContainer> </ReflexContainer>
{toolPanel}
</Fragment>
); );
} }
} }

View File

@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
import { TabPane, Tabs } from '@freecodecamp/react-bootstrap'; import { TabPane, Tabs } from '@freecodecamp/react-bootstrap';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import ToolPanel from '../components/Tool-Panel';
import { createStructuredSelector } from 'reselect'; import { createStructuredSelector } from 'reselect';
import { currentTabSelector, moveToTab } from '../redux'; import { currentTabSelector, moveToTab } from '../redux';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -23,13 +22,12 @@ const mapDispatchToProps = dispatch =>
const propTypes = { const propTypes = {
currentTab: PropTypes.number, currentTab: PropTypes.number,
editor: PropTypes.element, editor: PropTypes.element,
guideUrl: PropTypes.string,
hasPreview: PropTypes.bool, hasPreview: PropTypes.bool,
instructions: PropTypes.element, instructions: PropTypes.element,
moveToTab: PropTypes.func, moveToTab: PropTypes.func,
preview: PropTypes.element, preview: PropTypes.element,
testOutput: PropTypes.element, testOutput: PropTypes.element,
videoUrl: PropTypes.string toolPanel: PropTypes.element
}; };
class MobileLayout extends Component { class MobileLayout extends Component {
@ -42,8 +40,7 @@ class MobileLayout extends Component {
testOutput, testOutput,
hasPreview, hasPreview,
preview, preview,
guideUrl, toolPanel
videoUrl
} = this.props; } = this.props;
const editorTabPaneProps = { const editorTabPaneProps = {
@ -74,7 +71,7 @@ class MobileLayout extends Component {
</TabPane> </TabPane>
)} )}
</Tabs> </Tabs>
<ToolPanel guideUrl={guideUrl} isMobile={true} videoUrl={videoUrl} /> {toolPanel}
</Fragment> </Fragment>
); );
} }

View File

@ -19,6 +19,7 @@ import VideoModal from '../components/VideoModal';
import ResetModal from '../components/ResetModal'; import ResetModal from '../components/ResetModal';
import MobileLayout from './MobileLayout'; import MobileLayout from './MobileLayout';
import DesktopLayout from './DesktopLayout'; import DesktopLayout from './DesktopLayout';
import ToolPanel from '../components/Tool-Panel';
import { randomCompliment } from '../utils/get-words'; import { randomCompliment } from '../utils/get-words';
import { createGuideUrl } from '../utils'; import { createGuideUrl } from '../utils';
@ -246,6 +247,17 @@ class ShowClassic extends Component {
); );
} }
renderToolPanel(isMobile) {
return (
<ToolPanel
className='classic-tool-panel'
guideUrl={this.getGuideUrl()}
isMobile={isMobile}
videoUrl={this.getVideoUrl()}
/>
);
}
render() { render() {
return ( return (
<LearnLayout> <LearnLayout>
@ -257,14 +269,13 @@ class ShowClassic extends Component {
matches ? ( matches ? (
<MobileLayout <MobileLayout
editor={this.renderEditor()} editor={this.renderEditor()}
guideUrl={this.getGuideUrl()}
hasPreview={this.hasPreview()} hasPreview={this.hasPreview()}
instructions={this.renderInstructionsPanel({ instructions={this.renderInstructionsPanel({
showToolPanel: false showToolPanel: false
})} })}
preview={this.renderPreview()} preview={this.renderPreview()}
testOutput={this.renderTestOutput()} testOutput={this.renderTestOutput()}
videoUrl={this.getVideoUrl()} toolPanel={this.renderToolPanel(true)}
/> />
) : ( ) : (
<DesktopLayout <DesktopLayout
@ -272,11 +283,12 @@ class ShowClassic extends Component {
editor={this.renderEditor()} editor={this.renderEditor()}
hasPreview={this.hasPreview()} hasPreview={this.hasPreview()}
instructions={this.renderInstructionsPanel({ instructions={this.renderInstructionsPanel({
showToolPanel: true showToolPanel: false
})} })}
preview={this.renderPreview()} preview={this.renderPreview()}
resizeProps={this.resizeProps} resizeProps={this.resizeProps}
testOutput={this.renderTestOutput()} testOutput={this.renderTestOutput()}
toolPanel={this.renderToolPanel(false)}
/> />
) )
} }

View File

@ -3,7 +3,7 @@
} }
.desktop-layout { .desktop-layout {
height: calc(100vh - var(--header-height)); height: calc(100vh - var(--header-height) - 42px);
} }
.monaco-menu .action-label { .monaco-menu .action-label {
@ -34,3 +34,13 @@
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
} }
.classic-tool-panel.tool-panel-group {
display: flex;
flex-direction: row-reverse;
padding: 0 2px;
}
.classic-tool-panel.tool-panel-group .btn-block + .btn-block {
margin: 0 2px 0 0;
}

View File

@ -21,6 +21,7 @@ const mapDispatchToProps = dispatch =>
); );
const propTypes = { const propTypes = {
className: PropTypes.string,
executeChallenge: PropTypes.func.isRequired, executeChallenge: PropTypes.func.isRequired,
guideUrl: PropTypes.string, guideUrl: PropTypes.string,
isMobile: PropTypes.bool, isMobile: PropTypes.bool,
@ -31,6 +32,7 @@ const propTypes = {
}; };
function ToolPanel({ function ToolPanel({
className,
executeChallenge, executeChallenge,
isMobile, isMobile,
openHelpModal, openHelpModal,
@ -41,9 +43,11 @@ function ToolPanel({
}) { }) {
return ( return (
<Fragment> <Fragment>
<div className={`tool-panel-group ${ <div
className={`tool-panel-group ${
isMobile ? 'tool-panel-group-mobile' : '' isMobile ? 'tool-panel-group-mobile' : ''
}`}> } ${className}`}
>
<Button block={true} bsStyle='primary' onClick={executeChallenge}> <Button block={true} bsStyle='primary' onClick={executeChallenge}>
{isMobile ? 'Run' : 'Run the Tests'} {isMobile ? 'Run' : 'Run the Tests'}
</Button> </Button>
@ -92,7 +96,10 @@ function ToolPanel({
ToolPanel.displayName = 'ToolPanel'; ToolPanel.displayName = 'ToolPanel';
ToolPanel.propTypes = propTypes; ToolPanel.propTypes = propTypes;
export default connect(mapStateToProps, mapDispatchToProps)(ToolPanel); export default connect(
mapStateToProps,
mapDispatchToProps
)(ToolPanel);
/* /*
<Button <Button