aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/collections/CollectionTreeView.tsx
diff options
context:
space:
mode:
authorab <abdullah_ahmed@brown.edu>2019-06-19 10:07:45 -0400
committerab <abdullah_ahmed@brown.edu>2019-06-19 10:07:45 -0400
commit5959f37c89db0fcafdc2aa94a4aba692960edb54 (patch)
tree720b7010d2d107770862353a5a6ac0e327eb1c8b /src/client/views/collections/CollectionTreeView.tsx
parentc2da1676379817fb977a7233fadfb96ab67dc16f (diff)
parent0674331f3611d297028526c888c718a75b012e0a (diff)
merged
Diffstat (limited to 'src/client/views/collections/CollectionTreeView.tsx')
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx129
1 files changed, 97 insertions, 32 deletions
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 8a6764c58..5e690361c 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -21,6 +21,9 @@ import "./CollectionTreeView.scss";
import React = require("react");
import { Transform } from '../../util/Transform';
import { SelectionManager } from '../../util/SelectionManager';
+import { emptyFunction } from '../../../Utils';
+import { List } from '../../../new_fields/List';
+import { Templates } from '../Templates';
export interface TreeViewProps {
@@ -30,6 +33,7 @@ export interface TreeViewProps {
dropAction: "alias" | "copy" | undefined;
addDocTab: (doc: Doc, where: string) => void;
addDocument: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean;
+ indentDocument?: () => void;
ScreenToLocalTransform: () => Transform;
treeViewId: string;
parentKey: string;
@@ -67,8 +71,8 @@ class TreeView extends React.Component<TreeViewProps> {
@undoBatch delete = () => this.props.deleteDoc(this.props.document);
@undoBatch openRight = async () => this.props.addDocTab(this.props.document, "openRight");
- @action onMouseEnter = () => { this._isOver = true; }
- @action onMouseLeave = () => { this._isOver = false; }
+ @action onMouseEnter = () => { this._isOver = true; };
+ @action onMouseLeave = () => { this._isOver = false; };
onPointerEnter = (e: React.PointerEvent): void => {
this.props.active() && (this.props.document.libraryBrush = true);
@@ -89,10 +93,10 @@ class TreeView extends React.Component<TreeViewProps> {
let bounds = this.props.ScreenToLocalTransform().transformPoint(rect.left, rect.top + rect.height / 2);
let before = x[1] < bounds[1];
let inside = x[0] > bounds[0] + 75 || (!before && this._bulletType === BulletType.Collapsible);
- this._header!.current!.className = "treeViewItem-header"
- if (inside && this._bulletType != BulletType.List) this._header!.current!.className = "treeViewItem-header-inside";
- else if (before) this._header!.current!.className = "treeViewItem-header-above";
- else if (!before) this._header!.current!.className = "treeViewItem-header-below";
+ this._header!.current!.className = "treeViewItem-header";
+ if (inside && this._bulletType !== BulletType.List) this._header!.current!.className += " treeViewItem-header-inside";
+ else if (before) this._header!.current!.className += " treeViewItem-header-above";
+ else if (!before) this._header!.current!.className += " treeViewItem-header-below";
e.stopPropagation();
}
onPointerDown = (e: React.PointerEvent) => {
@@ -114,6 +118,12 @@ class TreeView extends React.Component<TreeViewProps> {
}
return true;
}
+ @action
+ indent = () => {
+ this.props.addDocument(this.props.document);
+ this.delete();
+ }
+
renderBullet(type: BulletType) {
let onClicked = action(() => this._collapsed = !this._collapsed);
@@ -124,42 +134,56 @@ class TreeView extends React.Component<TreeViewProps> {
}
return <div className="bullet" onClick={onClicked}>{bullet ? <FontAwesomeIcon icon={bullet} /> : ""} </div>;
}
+ static loadId = "";
+ editableView = (key: string, style?: string) =>
+ (<EditableView
+ oneLine={true}
+ display={"inline"}
+ editing={this.props.document[Id] === TreeView.loadId}
+ contents={StrCast(this.props.document[key])}
+ height={36}
+ fontStyle={style}
+ GetValue={() => StrCast(this.props.document[key])}
+ OnFillDown={(value: string) => {
+ Doc.GetProto(this.props.document)[key] = value;
+ let doc = Docs.FreeformDocument([], { title: "", x: 0, y: 0, width: 100, height: 25 });
+ TreeView.loadId = doc[Id];
+ doc.templates = new List<string>([Templates.Title.Layout]);
+ this.props.addDocument(doc);
+ return true;
+ }}
+ OnTab={() => this.props.indentDocument && this.props.indentDocument()}
+ SetValue={(value: string) => {
+ Doc.GetProto(this.props.document)[key] = value;
+ return true;
+ }}
+ />)
+
/**
* Renders the EditableView title element for placement into the tree.
*/
renderTitle() {
let reference = React.createRef<HTMLDivElement>();
let onItemDown = SetupDrag(reference, () => this.props.document, this.move, this.props.dropAction, this.props.treeViewId, true);
- let editableView = (titleString: string) =>
- (<EditableView
- oneLine={!this._isOver ? true : false}
- display={"inline"}
- contents={titleString}
- height={36}
- GetValue={() => StrCast(this.props.document.title)}
- SetValue={(value: string) => {
- let target = this.props.document.proto ? this.props.document.proto : this.props.document;
- target.title = value;
- return true;
- }}
- />);
+
let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document.data, listSpec(Doc), []) : [];
let openRight = dataDocs && dataDocs.indexOf(this.props.document) !== -1 ? (null) : (
<div className="treeViewItem-openRight" onPointerDown={this.onPointerDown} onClick={this.openRight}>
<FontAwesomeIcon icon="angle-right" size="lg" />
{/* <FontAwesomeIcon icon="angle-right" size="lg" /> */}
</div>);
- return (
+ return <>
<div className="docContainer" id={`docContainer-${this.props.parentKey}`} ref={reference} onPointerDown={onItemDown} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}
style={{
background: BoolCast(this.props.document.protoBrush, false) ? "#06123232" : BoolCast(this.props.document.libraryBrush, false) ? "#06121212" : "0",
pointerEvents: this.props.active() || SelectionManager.GetIsDragging() ? "all" : "none"
}}
>
- {editableView(StrCast(this.props.document.title))}
- {openRight}
+ {this.editableView("title")}
{/* {<div className="delete-button" onClick={this.delete}><FontAwesomeIcon icon="trash-alt" size="xs" /></div>} */}
- </div >);
+ </div >
+ {openRight}
+ </>;
}
onWorkspaceContextMenu = (e: React.MouseEvent): void => {
@@ -191,7 +215,7 @@ class TreeView extends React.Component<TreeViewProps> {
if (inside) {
let docList = Cast(this.props.document.data, listSpec(Doc));
if (docList !== undefined) {
- addDoc = (doc: Doc) => { docList && docList.push(doc); return true; }
+ addDoc = (doc: Doc) => { docList && docList.push(doc); return true; };
}
}
let added = false;
@@ -220,6 +244,7 @@ class TreeView extends React.Component<TreeViewProps> {
return true;
}
+ @observable _chosenKey: string = "data";
_bulletType: BulletType = BulletType.List;
render() {
let bulletType = BulletType.List;
@@ -229,19 +254,37 @@ class TreeView extends React.Component<TreeViewProps> {
keys.push(...Array.from(Object.keys(this.props.document.proto)));
while (keys.indexOf("proto") !== -1) keys.splice(keys.indexOf("proto"), 1);
}
+ if (keys.indexOf("data") !== -1) {
+ keys.splice(keys.indexOf("data"), 1);
+ keys.splice(0, 0, "data");
+ }
+ let keyList: string[] = [];
keys.map(key => {
let docList = Cast(this.props.document[key], listSpec(Doc));
+ let doc = Cast(this.props.document[key], Doc);
+ if (doc instanceof Doc || (docList && (DocListCast(docList).length > 0 || key === "data"))) {
+ keyList.push(key);
+ }
+ });
+ let headerElements = <div style={{ display: "block", marginTop: "7px" }} key={this._chosenKey}>{keyList.map(key =>
+ <span className="collectionTreeView-keyHeader" key={key} onPointerDown={action(() => this._chosenKey = key)}
+ style={{ display: "inline", marginRight: "3px", marginTop: "7px", background: key === this._chosenKey ? "lightgray" : undefined }}>
+ {key}
+ </span>)}
+ </div>;
+ [this._chosenKey].map(key => {
+ let docList = Cast(this.props.document[key], listSpec(Doc));
let remDoc = (doc: Doc) => this.remove(doc, key);
let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.document, key, doc, addBefore, before);
let doc = Cast(this.props.document[key], Doc);
- if (doc instanceof Doc || docList) {
+ if (doc instanceof Doc || (docList && (DocListCast(docList).length > 0 || key === "data"))) {
if (!this._collapsed) {
bulletType = BulletType.Collapsible;
contentElement.push(<ul key={key + "more"}>
- {(key === "data") ? (null) :
- <span className="collectionTreeView-keyHeader" style={{ display: "block", marginTop: "7px" }} key={key}>{key}</span>}
+ {headerElements}
<div style={{ display: "block" }}>
{TreeView.GetChildElements(doc instanceof Doc ? [doc] : DocListCast(docList), this.props.treeViewId, key, addDoc, remDoc, this.move,
+ this.indent,
this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.active)}
</div>
</ul >);
@@ -270,14 +313,36 @@ class TreeView extends React.Component<TreeViewProps> {
add: (doc: Doc, relativeTo?: Doc, before?: boolean) => boolean,
remove: ((doc: Doc) => void),
move: DragManager.MoveFunction,
+ indent: () => void,
dropAction: dropActionType,
addDocTab: (doc: Doc, where: string) => void,
screenToLocalXf: () => Transform,
active: () => boolean
) {
- return docs.filter(child => !child.excludeFromLibrary && (key !== "data" || !child.isMinimized)).map(child =>
- <TreeView document={child} treeViewId={treeViewId} key={child[Id]} deleteDoc={remove} addDocument={add} moveDocument={move}
- dropAction={dropAction} addDocTab={addDocTab} ScreenToLocalTransform={screenToLocalXf} parentKey={key} active={active} />);
+ let docList = docs.filter(child => !child.excludeFromLibrary && (key !== "data" || !child.isMinimized));
+ return docList.map((child, i) => {
+ let indent = i === 0 ? undefined : () => {
+ if (StrCast(docList[i - 1].layout).indexOf("CollectionView") !== -1) {
+ let fieldKeysub = StrCast(docList[i - 1].layout).split("fieldKey")[1];
+ let fieldKey = fieldKeysub.split("\"")[1];
+ TreeView.AddDocToList(docList[i - 1], fieldKey, child);
+ remove(child);
+ }
+ }
+ return <TreeView
+ document={child}
+ treeViewId={treeViewId}
+ key={child[Id]}
+ indentDocument={indent}
+ deleteDoc={remove}
+ addDocument={add}
+ moveDocument={move}
+ dropAction={dropAction}
+ addDocTab={addDocTab}
+ ScreenToLocalTransform={screenToLocalXf}
+ parentKey={key}
+ active={active} />;
+ });
}
}
@@ -310,14 +375,14 @@ export class CollectionTreeView extends CollectionSubView(Document) {
this.onDrop(e, {});
}
render() {
- let dropAction = Cast(this.props.Document.dropAction, "string") as dropActionType;
+ let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
if (!this.childDocs) {
return (null);
}
let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => TreeView.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before);
let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
let childElements = TreeView.GetChildElements(this.childDocs, this.props.Document[Id], this.props.fieldKey, addDoc, this.remove,
- moveDoc, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.active);
+ moveDoc, emptyFunction, dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.active);
return (
<div id="body" className="collectionTreeView-dropTarget"