diff options
author | tschicke-brown <tyler_schicke@brown.edu> | 2019-02-25 18:03:05 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-25 18:03:05 -0500 |
commit | 292ff1a8d75f8b15f9388d2c577e09a13836d5dc (patch) | |
tree | 59dd222b58abdeefa5c648219411411d7c45128e | |
parent | abec712d1e5169704473a7fad2c21b0ab04299ad (diff) | |
parent | 326696caa52a7feadf37f8f9e0f8bbb69d39bf9a (diff) |
Merge pull request #10 from browngraphicslab/treeview
Treeview
-rw-r--r-- | src/client/views/Main.tsx | 1 | ||||
-rw-r--r-- | src/client/views/collections/CollectionFreeFormView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.scss | 28 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 104 | ||||
-rw-r--r-- | src/client/views/collections/CollectionView.tsx | 8 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 1 |
6 files changed, 141 insertions, 2 deletions
diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index 61ad66c72..17dda899d 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -30,6 +30,7 @@ window.addEventListener("dragover", function (e) { e.preventDefault(); }, false) document.addEventListener("pointerdown", action(function (e: PointerEvent) { + console.log(ContextMenu); if (!ContextMenu.Instance.intersects(e.pageX, e.pageY)) { ContextMenu.Instance.clearItems() } diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index b54d9e0cf..12909c151 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -10,6 +10,7 @@ import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; +import { CollectionTreeView } from "../collections/CollectionTreeView"; import { CollectionView } from "../collections/CollectionView"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss new file mode 100644 index 000000000..675fc6c53 --- /dev/null +++ b/src/client/views/collections/CollectionTreeView.scss @@ -0,0 +1,28 @@ +ul { + list-style: none; +} + +li { + margin: 5px 0; +} + +.no-indent { + padding-left: 0; +} + +/* ALL THESE SPACINGS ARE SUPER HACKY RIGHT NOW HANNAH PLS HELP */ + +li:before { + content: '\2014'; + margin-right: 0.7em; +} + +.collapsed:before { + content: '\25b6'; + margin-right: 0.65em; +} + +.uncollapsed:before { + content: '\25bc'; + margin-right: 0.5em; +}
\ No newline at end of file diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx new file mode 100644 index 000000000..52e853bf7 --- /dev/null +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -0,0 +1,104 @@ +import { observer } from "mobx-react"; +import { CollectionViewBase } from "./CollectionViewBase"; +import { Document } from "../../../fields/Document"; +import { KeyStore } from "../../../fields/KeyStore"; +import { ListField } from "../../../fields/ListField"; +import React = require("react") +import { TextField } from "../../../fields/TextField"; +import { observable, action } from "mobx"; +import "./CollectionTreeView.scss"; + +export interface TreeViewProps { + document: Document; +} + +@observer +/** + * Component that takes in a document prop and a boolean whether it's collapsed or not. + */ +class TreeView extends React.Component<TreeViewProps> { + + @observable + collapsed: boolean = false; + + /** + * Renders a single child document. If this child is a collection, it will call renderTreeView again. Otherwise, it will just append a list element. + * @param document The document to render. + */ + renderChild(document: Document) { + var children = document.GetT<ListField<Document>>(KeyStore.Data, ListField); + let title = document.GetT<TextField>(KeyStore.Title, TextField); + + // if the title hasn't loaded, immediately return the div + if (!title || title === "<Waiting>") { + return <div key={document.Id}></div>; + } + + // otherwise, check if it's a collection. + else if (children && children !== "<Waiting>") { + // if it's not collapsed, then render the full TreeView. + if (!this.collapsed) { + return ( + <li className="uncollapsed" key={document.Id} onClick={action(() => this.collapsed = true)} > + {title.Data} + <ul key={document.Id}> + <TreeView + document={document} + /> + </ul> + </li> + ); + } else { + return <li className="collapsed" key={document.Id} onClick={action(() => this.collapsed = false)}>{title.Data}</li> + } + } + + // finally, if it's a normal document, then render it as such. + else { + return <li key={document.Id}>{title.Data}</li>; + } + } + + render() { + var children = this.props.document.GetT<ListField<Document>>(KeyStore.Data, ListField); + + if (children && children !== "<Waiting>") { + return (<div> + {children.Data.map(value => this.renderChild(value))} + </div>) + // let results: JSX.Element[] = []; + + // // append a list item for each child in the collection + // children.Data.forEach((value) => { + // results.push(this.renderChild(value)); + // }) + + // return results; + } else { + return <div></div>; + } + } +} + + +@observer +export class CollectionTreeView extends CollectionViewBase { + + render() { + let titleStr = ""; + let title = this.props.Document.GetT<TextField>(KeyStore.Title, TextField); + if (title && title !== "<Waiting>") { + titleStr = title.Data; + } + return ( + <div> + <h3>{titleStr}</h3> + <ul className="no-indent"> + <TreeView + document={this.props.Document} + /> + </ul> + </div> + ); + } +}
\ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 83886f933..03e1f1fa4 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -11,15 +11,15 @@ import { CollectionFreeFormView } from "./CollectionFreeFormView"; import { CollectionDockingView } from "./CollectionDockingView"; import { CollectionSchemaView } from "./CollectionSchemaView"; import { CollectionViewProps } from "./CollectionViewBase"; +import { CollectionTreeView } from "./CollectionTreeView"; import { Field } from "../../../fields/Field"; - - export enum CollectionViewType { Invalid, Freeform, Schema, Docking, + Tree } export const COLLECTION_BORDER_WIDTH = 2; @@ -102,6 +102,10 @@ export class CollectionView extends React.Component<CollectionViewProps> { return (<CollectionDockingView {...this.props} addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active} CollectionView={this} />) + case CollectionViewType.Tree: + return (<CollectionTreeView {...this.props} + addDocument={this.addDocument} removeDocument={this.removeDocument} active={this.active} + CollectionView={this} />) default: return <div></div> } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 6fe78daee..87f2e205b 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -189,6 +189,7 @@ export class DocumentView extends React.Component<DocumentViewProps> { ContextMenu.Instance.addItem({ description: "Delete", event: this.deleteClicked }) ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) + ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) ContextMenu.Instance.addItem({ description: "Docking", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Docking) }) ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15) SelectionManager.SelectDoc(this, e.ctrlKey); |