diff --git a/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js b/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js index c6fa15f9..3247bd49 100644 --- a/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js +++ b/frontend/components/Layout/components/SidebarCollection/SidebarCollection.js @@ -7,6 +7,7 @@ import styled from 'styled-components'; import SidebarLink from '../SidebarLink'; import Collection from 'models/Collection'; +import Document from 'models/Document'; type Props = { collection: ?Collection, @@ -17,14 +18,18 @@ class SidebarCollection extends React.Component { props: Props; renderDocuments(documentList) { - return documentList.map(document => ( - - - {document.title} + const { document } = this.props; + + return documentList.map(doc => ( + + + {doc.title} - - {document.children && this.renderDocuments(document.children)} - + {} + {(document.pathToDocument.includes(doc.id) || document.id === doc.id) && + + {doc.children && this.renderDocuments(doc.children)} + } )); } diff --git a/frontend/models/Document.js b/frontend/models/Document.js new file mode 100644 index 00000000..6f98addd --- /dev/null +++ b/frontend/models/Document.js @@ -0,0 +1,81 @@ +// @flow +import { extendObservable, action, runInAction, computed } from 'mobx'; +import invariant from 'invariant'; + +import ApiClient, { client } from 'utils/ApiClient'; +import stores from 'stores'; +import ErrorsStore from 'stores/ErrorsStore'; + +import type { User } from 'types'; +import Collection from './Collection'; + +class Document { + collaborators: Array; + collection: Collection; + createdAt: string; + createdBy: User; + html: string; + id: string; + private: boolean; + team: string; + text: string; + title: string; + updatedAt: string; + updatedBy: User; + url: string; + + client: ApiClient; + errors: ErrorsStore; + + /* Computed */ + + @computed get pathToDocument(): Array { + let path; + const traveler = (nodes, previousPath) => { + nodes.forEach(childNode => { + const newPath = [...previousPath, childNode.id]; + if (childNode.id === this.id) { + path = newPath; + return; + } else { + return traveler(childNode.children, newPath); + } + }); + }; + + if (this.collection.documents) { + traveler(this.collection.documents, []); + invariant(path, 'Path is not available for collection, abort'); + return path; + } + + return []; + } + + /* Actions */ + + @action update = async () => { + try { + const res = await this.client.post('/documents.info', { id: this.id }); + invariant(res && res.data, 'Document API response should be available'); + const { data } = res; + runInAction('Document#update', () => { + this.updateData(data); + }); + } catch (e) { + this.errors.add('Document failed loading'); + } + }; + + updateData(data: Document) { + extendObservable(this, data); + } + + constructor(document: Document) { + this.updateData(document); + this.client = client; + this.errors = stores.errors; + } +} + +export default Document; diff --git a/frontend/scenes/Document/DocumentStore.js b/frontend/scenes/Document/DocumentStore.js index 7088e27c..bcc59500 100644 --- a/frontend/scenes/Document/DocumentStore.js +++ b/frontend/scenes/Document/DocumentStore.js @@ -4,7 +4,7 @@ import get from 'lodash/get'; import invariant from 'invariant'; import { client } from 'utils/ApiClient'; import emojify from 'utils/emojify'; -import type { Document, NavigationNode } from 'types'; +import Document from 'models/Document'; import UiStore from 'stores/UiStore'; type SaveProps = { redirect?: boolean }; @@ -29,10 +29,10 @@ type Options = { }; class DocumentStore { + document: Document; @observable collapsedNodes: string[] = []; @observable documentId = null; @observable collectionId = null; - @observable document: Document; @observable parentDocument: Document; @observable hasPendingChanges = false; @observable newDocument: ?boolean; @@ -52,29 +52,6 @@ class DocumentStore { return !!this.document && this.document.collection.type === 'atlas'; } - @computed get pathToDocument(): Array { - let path; - const traveler = (nodes, previousPath) => { - nodes.forEach(childNode => { - const newPath = [...previousPath, childNode]; - if (childNode.id === this.document.id) { - path = previousPath; - return; - } else { - return traveler(childNode.chilren, newPath); - } - }); - }; - - if (this.document && this.document.collection.documents) { - traveler(this.document.collection.documents, []); - invariant(path, 'Path is not available for collection, abort'); - return path.splice(1); - } - - return []; - } - /* Actions */ @action starDocument = async () => { @@ -118,8 +95,8 @@ class DocumentStore { if (this.newChildDocument) { this.parentDocument = res.data; } else { - this.document = res.data; - this.ui.setActiveDocument(res.data); + this.document = new Document(res.data); + this.ui.setActiveDocument(this.document); } } catch (e) { console.error('Something went wrong');