From b8da23556e49bebf4e81f422efcab42e8f3e9f7c Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Thu, 7 Jul 2016 00:27:11 -0700 Subject: [PATCH] Persist collapsed nodes --- src/components/Tree/UiTree.js | 6 +- src/scenes/DocumentScene/DocumentScene.js | 21 ++++--- .../DocumentScene/DocumentSceneStore.js | 55 ++++++++++++++++++- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/components/Tree/UiTree.js b/src/components/Tree/UiTree.js index b309e9c4..9fdc21e2 100644 --- a/src/components/Tree/UiTree.js +++ b/src/components/Tree/UiTree.js @@ -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) { diff --git a/src/scenes/DocumentScene/DocumentScene.js b/src/scenes/DocumentScene/DocumentScene.js index 4606f1ad..04dbcc8d 100644 --- a/src/scenes/DocumentScene/DocumentScene.js +++ b/src/scenes/DocumentScene/DocumentScene.js @@ -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' && @@ -127,11 +125,12 @@ class DocumentScene extends React.Component { { this.store.isAtlas ? (
) : null } diff --git a/src/scenes/DocumentScene/DocumentSceneStore.js b/src/scenes/DocumentScene/DocumentSceneStore.js index 3a269e17..dbd41716 100644 --- a/src/scenes/DocumentScene/DocumentSceneStore.js +++ b/src/scenes/DocumentScene/DocumentSceneStore.js @@ -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, +};