Persist collapsed nodes
This commit is contained in:
@ -10,7 +10,8 @@ module.exports = React.createClass({
|
||||
propTypes: {
|
||||
tree: React.PropTypes.object.isRequired,
|
||||
paddingLeft: React.PropTypes.number,
|
||||
renderNode: React.PropTypes.func.isRequired
|
||||
renderNode: React.PropTypes.func.isRequired,
|
||||
onCollapse: React.PropTypes.func,
|
||||
},
|
||||
|
||||
getDefaultProps() {
|
||||
@ -230,8 +231,7 @@ module.exports = React.createClass({
|
||||
tree: tree
|
||||
});
|
||||
|
||||
// Don't push updates as collapsing is separated from store state
|
||||
// this.change(tree);
|
||||
if(this.props.onCollapse) this.props.onCollapse(node.id, node.collapsed);
|
||||
},
|
||||
|
||||
// buildTreeNumbering(tree) {
|
||||
|
@ -3,7 +3,9 @@ import { toJS } from 'mobx';
|
||||
import { Link, browserHistory } from 'react-router';
|
||||
import { observer } from 'mobx-react';
|
||||
|
||||
import DocumentSceneStore from './DocumentSceneStore';
|
||||
import DocumentSceneStore, {
|
||||
DOCUMENT_PREFERENCES
|
||||
} from './DocumentSceneStore';
|
||||
|
||||
import Layout, { HeaderAction } from 'components/Layout';
|
||||
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
|
||||
@ -29,7 +31,7 @@ class DocumentScene extends React.Component {
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.store = new DocumentSceneStore();
|
||||
this.store = new DocumentSceneStore(JSON.parse(localStorage[DOCUMENT_PREFERENCES]));
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
@ -77,10 +79,6 @@ class DocumentScene extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
handleChange = (tree) => {
|
||||
this.store.updateNavigationTree(tree);
|
||||
}
|
||||
|
||||
render() {
|
||||
const doc = this.store.document;
|
||||
const allowDelete = doc && doc.atlas.type === 'atlas' &&
|
||||
@ -128,8 +126,9 @@ class DocumentScene extends React.Component {
|
||||
<div className={ styles.sidebar }>
|
||||
<Tree
|
||||
paddingLeft={ 10 }
|
||||
tree={ toJS(doc.atlas.navigationTree) }
|
||||
onChange={this.handleChange}
|
||||
tree={ toJS(this.store.atlasTree) }
|
||||
onChange={ this.store.updateNavigationTree }
|
||||
onCollapse={ this.store.onNodeCollapse }
|
||||
isNodeCollapsed={ this.isNodeCollapsed }
|
||||
renderNode={ this.renderNode }
|
||||
/>
|
||||
|
@ -1,10 +1,15 @@
|
||||
import _isEqual from 'lodash/isEqual';
|
||||
import { observable, action, computed, runInAction, toJS } from 'mobx';
|
||||
import _indexOf from 'lodash/indexOf';
|
||||
import _without from 'lodash/without';
|
||||
import { observable, action, computed, runInAction, toJS, autorun } from 'mobx';
|
||||
import { client } from 'utils/ApiClient';
|
||||
import { browserHistory } from 'react-router';
|
||||
|
||||
const DOCUMENT_PREFERENCES = 'DOCUMENT_PREFERENCES';
|
||||
|
||||
class DocumentSceneStore {
|
||||
@observable document;
|
||||
@observable collapsedNodes = [];
|
||||
|
||||
@observable isFetching = true;
|
||||
@observable updatingContent = false;
|
||||
@ -18,6 +23,24 @@ class DocumentSceneStore {
|
||||
this.document.atlas.type === 'atlas';
|
||||
}
|
||||
|
||||
@computed get atlasTree() {
|
||||
if (this.document.atlas.type !== 'atlas') return;
|
||||
let tree = this.document.atlas.navigationTree;
|
||||
|
||||
const collapseNodes = (node) => {
|
||||
if (this.collapsedNodes.includes(node.id)) {
|
||||
node.collapsed = true;
|
||||
}
|
||||
node.children = node.children.map(childNode => {
|
||||
return collapseNodes(childNode);
|
||||
})
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
return collapseNodes(toJS(tree));
|
||||
}
|
||||
|
||||
/* Actions */
|
||||
|
||||
@action fetchDocument = async (id, softLoad) => {
|
||||
@ -71,6 +94,36 @@ class DocumentSceneStore {
|
||||
}
|
||||
this.updatingStructure = false;
|
||||
}
|
||||
|
||||
@action onNodeCollapse = (nodeId, collapsed) => {
|
||||
if (_indexOf(this.collapsedNodes, nodeId) >= 0) {
|
||||
this.collapsedNodes = _without(this.collapsedNodes, nodeId);
|
||||
} else {
|
||||
this.collapsedNodes.push(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
// General
|
||||
|
||||
persistSettings = () => {
|
||||
localStorage[DOCUMENT_PREFERENCES] = JSON.stringify({
|
||||
collapsedNodes: toJS(this.collapsedNodes),
|
||||
});
|
||||
}
|
||||
|
||||
constructor(settings) {
|
||||
// Rehydrate settings
|
||||
this.collapsedNodes = settings.collapsedNodes;
|
||||
|
||||
// Persist settings to localStorage
|
||||
// TODO: This could be done more selectively
|
||||
autorun(() => {
|
||||
this.persistSettings();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default DocumentSceneStore;
|
||||
export {
|
||||
DOCUMENT_PREFERENCES,
|
||||
};
|
||||
|
Reference in New Issue
Block a user