Sidebar editing toggle and only scroll atlas content

This commit is contained in:
Jori Lallo
2016-08-11 13:32:56 +02:00
parent 41505039b2
commit eb156e3069
15 changed files with 167 additions and 85 deletions

View File

@ -22,7 +22,6 @@ class Layout extends React.Component {
actions: React.PropTypes.node,
title: React.PropTypes.node,
titleText: React.PropTypes.node,
fixed: React.PropTypes.bool,
loading: React.PropTypes.bool,
user: React.PropTypes.object.isRequired,
search: React.PropTypes.bool,
@ -59,7 +58,7 @@ class Layout extends React.Component {
<LoadingIndicator />
) : null }
<div className={ cx(styles.header, { fixed: this.props.fixed }) }>
<div className={ cx(styles.header) }>
<div className={ styles.headerLeft }>
<Link to="/" className={ styles.team }>{ user.team.name }</Link>
<span className={ styles.title }>
@ -93,7 +92,9 @@ class Layout extends React.Component {
</Flex>
</div>
<div className={ cx(styles.content, { fixed: this.props.fixed }) }>
<div
className={ cx(styles.content) }
>
{ this.props.children }
</div>
</div>

View File

@ -6,6 +6,7 @@
flex-direction: column;
width: 100%;
height: 100%;
}
.header {
@ -20,15 +21,6 @@
font-size: 14px;
line-height: 1;
&.fixed {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 900;
background: #fff;
}
}
.headerLeft {
@ -73,8 +65,6 @@
display: flex;
flex: 1;
justify-content: center;
&.fixed {
padding-top: $headerHeight;
}
height: 100%;
overflow: scroll;
}

View File

@ -1,14 +1,14 @@
var React = require('react');
import React from 'react';
import history from 'utils/History';
import styles from './Tree.scss';
import classNames from 'classnames/bind';
const cx = classNames.bind(styles);
var Node = React.createClass({
displayName: 'UITreeNode',
class Node extends React.Component {
displayName: 'UITreeNode'
renderCollapse() {
renderCollapse = () => {
var index = this.props.index;
if(index.children && index.children.length) {
@ -26,9 +26,9 @@ var Node = React.createClass({
}
return null;
},
}
renderChildren() {
renderChildren = () => {
var index = this.props.index;
var tree = this.props.tree;
var dragging = this.props.dragging;
@ -51,6 +51,7 @@ var Node = React.createClass({
index={childIndex}
key={childIndex.id}
dragging={dragging}
allowUpdates={ this.props.allowUpdates }
paddingLeft={this.props.paddingLeft}
onCollapse={this.props.onCollapse}
onDragStart={this.props.onDragStart}
@ -62,14 +63,25 @@ var Node = React.createClass({
}
return null;
},
}
isModifying = () => {
return this.props.allowUpdates && !this.props.rootNode;
}
onClick = () => {
const index = this.props.index;
const node = index.node;
if (!this.isModifying()) history.push(node.url);
}
render() {
var tree = this.props.tree;
var index = this.props.index;
var dragging = this.props.dragging;
var node = index.node;
var style = {};
const tree = this.props.tree;
const index = this.props.index;
const dragging = this.props.dragging;
const node = index.node;
const style = {};
return (
<div className={cx(styles.node, {
@ -79,12 +91,15 @@ var Node = React.createClass({
<div
className={ styles.inner }
ref="inner"
onMouseDown={this.props.rootNode ? (e) => e.stopPropagation() : this.handleMouseDown}
onMouseDown={this.props.rootNode || !this.props.allowUpdates ? (e) => e.stopPropagation() : this.handleMouseDown}
>
{!this.props.rootNode && this.renderCollapse()}
{ !this.props.rootNode && this.renderCollapse() }
<span
className={ cx(styles.nodeLabel, { rootLabel: this.props.rootNode }) }
onClick={() => { history.push(node.url) }}
className={ cx(styles.nodeLabel, {
rootLabel: this.props.rootNode,
isModifying: this.isModifying(),
}) }
onClick={ this.onClick }
>
{ node.title }
</span>
@ -92,15 +107,15 @@ var Node = React.createClass({
{this.renderChildren()}
</div>
);
},
}
handleCollapse(e) {
handleCollapse = (e) => {
e.stopPropagation();
var nodeId = this.props.index.id;
if(this.props.onCollapse) this.props.onCollapse(nodeId);
},
}
handleMouseDown(e) {
handleMouseDown = (e) => {
var nodeId = this.props.index.id;
var dom = this.refs.inner;
@ -108,6 +123,6 @@ var Node = React.createClass({
this.props.onDragStart(nodeId, dom, e);
}
}
});
};
module.exports = Node;

View File

@ -7,9 +7,14 @@
}
.tree {
position: relative;
overflow: hidden;
@include no-select;
padding: 20px 20px 20px 5px;
overflow: scroll;
position: absolute;
top: 0;
bottom: 40px;
right: 0;
left: 0;
}
.draggable {
@ -71,6 +76,10 @@
white-space: nowrap;
overflow: hidden;
&.isModifying {
cursor: move;
}
&.isActive {
background-color: #31363F;
}

View File

@ -10,8 +10,8 @@ module.exports = React.createClass({
propTypes: {
tree: React.PropTypes.object.isRequired,
paddingLeft: React.PropTypes.number,
renderNode: React.PropTypes.func.isRequired,
onCollapse: React.PropTypes.func,
allowUpdates: React.PropTypes.bool,
},
getDefaultProps() {
@ -32,7 +32,6 @@ module.exports = React.createClass({
init(props) {
var tree = new Tree(props.tree);
tree.isNodeCollapsed = props.isNodeCollapsed;
tree.renderNode = props.renderNode;
tree.changeNodeCollapsed = props.changeNodeCollapsed;
tree.updateNodesPosition();
@ -61,11 +60,12 @@ module.exports = React.createClass({
};
return (
<div className={ styles.draggable } style={draggingStyles}>
<div className={ styles.draggable } style={ draggingStyles }>
<Node
tree={tree}
index={draggingIndex}
paddingLeft={this.props.paddingLeft}
tree={ tree }
index={ draggingIndex }
paddingLeft={ this.props.paddingLeft }
allowUpdates={ this.props.allowUpdates }
/>
</div>
);
@ -81,16 +81,17 @@ module.exports = React.createClass({
return (
<div className={ styles.tree }>
{draggingDom}
{ draggingDom }
<Node
rootNode={ true }
tree={tree}
index={tree.getIndex(1)}
key={1}
paddingLeft={this.props.paddingLeft}
onDragStart={this.dragStart}
onCollapse={this.toggleCollapse}
dragging={dragging && dragging.id}
rootNode
tree={ tree }
index={ tree.getIndex(1) }
key={ 1 }
paddingLeft={ this.props.paddingLeft }
allowUpdates={ this.props.allowUpdates }
onDragStart={ this.dragStart }
onCollapse={ this.toggleCollapse }
dragging={ dragging && dragging.id }
/>
</div>
);

View File

@ -43,7 +43,7 @@ function requireAuth(nextState, replace) {
}
render((
<div style={{ display: 'flex', flex: 1, minHeight: '100%' }}>
<div style={{ display: 'flex', flex: 1, height: '100%' }}>
<Provider { ...stores }>
<Router history={ History }>
<Route path="/" component={ Application }>

View File

@ -1,15 +1,18 @@
import React from "react";
import React from 'react';
import { observer } from 'mobx-react';
import Helmet from "react-helmet";
import Helmet from 'react-helmet';
const Application = observer((props) => {
return (
<div style={{ width: '100%', display: 'flex', flex: 1, }}>
<div style={{ width: '100%', height: '100%', display: 'flex', flex: 1 }}>
<Helmet
title="Atlas"
meta={[
{"name": "viewport", "content": "width=device-width, initial-scale=1.0"},
]}
meta={ [
{
name: 'viewport',
content: 'width=device-width, initial-scale=1.0',
},
] }
/>
{ props.children }
</div>
@ -18,6 +21,6 @@ const Application = observer((props) => {
Application.propTypes = {
children: React.PropTypes.node.isRequired,
}
};
export default Application;

View File

@ -175,7 +175,7 @@ class DocumentScene extends React.Component {
onNodeCollapse={ this.store.onNodeCollapse }
/>
) }
<Flex flex justify="center" className={ styles.content }>
<Flex auto justify="center" className={ styles.content }>
<CenteredContent>
{ this.store.updatingContent ? (
<AtlasPreviewLoading />

View File

@ -5,4 +5,5 @@
.content {
position: relative;
overflow: scroll;
}

View File

@ -8,10 +8,14 @@ import styles from './Sidebar.scss';
import classNames from 'classnames/bind';
const cx = classNames.bind(styles);
import treeStyles from 'components/Tree/Tree.scss';
import SidebarStore from './SidebarStore';
// import treeStyles from 'components/Tree/Tree.scss';
@observer
class Sidebar extends React.Component {
static store;
static propTypes = {
open: PropTypes.bool,
onToggle: PropTypes.func.isRequired,
@ -20,27 +24,39 @@ class Sidebar extends React.Component {
onNodeCollapse: PropTypes.func.isRequired,
}
renderNode = (node) => {
return (
<span className={ treeStyles.nodeLabel } onClick={ this.onClickNode.bind(null, node) }>
{ node.module.name }
</span>
);
constructor(props) {
super(props);
this.store = new SidebarStore();
}
toggleEdit = (e) => {
e.preventDefault();
this.store.toggleEdit();
}
render() {
return (
<Flex>
{ this.props.open && (
<div className={ cx(styles.sidebar) }>
<Flex column className={ cx(styles.sidebar) }>
<Flex auto className={ cx(styles.content) }>
<Tree
paddingLeft={ 10 }
tree={ this.props.navigationTree }
allowUpdates={ this.store.isEditing }
onChange={ this.props.onNavigationUpdate }
onCollapse={ this.props.onNodeCollapse }
renderNode={ this.renderNode }
/>
</div>
</Flex>
<Flex auto className={ styles.actions }>
<a
href
onClick={ this.toggleEdit }
className={ cx(styles.action, { active: this.store.isEditing }) }
>Edit</a>
</Flex>
</Flex>
) }
<div
onClick={ this.props.onToggle }

View File

@ -1,7 +1,8 @@
.sidebar {
width: 250px;
padding: 20px 20px 20px 5px;
@import '~styles/constants.scss';
.sidebar {
position: relative;
width: 250px;
border-right: 1px solid #eee;
}
@ -26,3 +27,30 @@
height: 28px;
opacity: 0.15;
}
.content {
padding: 20px 20px 20px 5px;
}
.tree {
}
.actions {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
padding: 10px 20px;
height: 40px;
font-size: 14px;
}
.action {
color: $darkGray;
&.active {
color: $textColor;
}
}

View File

@ -0,0 +1,13 @@
import { observable, action } from 'mobx';
class SidebarStore {
@observable isEditing = false;
/* Actions */
@action toggleEdit = () => {
this.isEditing = !this.isEditing;
}
}
export default SidebarStore;

View File

@ -3,6 +3,9 @@ $lightGray: #eee;
$textColor: #171B35;
$actionColor: #2da9e1;
$darkGray: #ccc;
$lightGray: #eee;
$headerHeight: 42px;
:export {

View File

@ -6,6 +6,7 @@
<style>
#root {
flex: 1;
height: 100%;
}
.container {
@ -21,7 +22,7 @@
}
</style>
</head>
<body style='display: flex; width: 100%'>
<body style='display: flex; width: 100%; height: 100%;'>
<div id="root">
<div class="container">
<div class="header"></div>

View File

@ -5,6 +5,7 @@
<style>
#root {
flex: 1;
height: 100%;
}
.container {
@ -20,7 +21,7 @@
}
</style>
</head>
<body style='display: flex; width: 100%'>
<body style='display: flex; width: 100%; height: 100%;'>
<div id="root">
<div class="container">
<div class="header"></div>