From dcf0389b770b06a04a45b4aedd62bf455d7848e7 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 21 Feb 2021 19:40:38 -0500
Subject: fixed compile warnings.

---
 src/client/views/collections/TreeView.tsx | 1 -
 1 file changed, 1 deletion(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index c0d3be96c..0f69602fa 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -32,7 +32,6 @@ import { CollectionTreeView } from './CollectionTreeView';
 import { CollectionView, CollectionViewType } from './CollectionView';
 import "./TreeView.scss";
 import React = require("react");
-import { ContextMenu } from '../ContextMenu';
 
 export interface TreeViewProps {
     document: Doc;
-- 
cgit v1.2.3-70-g09d2


From 628abc9e0498505f4c05261404d37bd830ef8797 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Feb 2021 11:15:48 -0500
Subject: tweak.

---
 src/client/views/collections/TreeView.tsx | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 0f69602fa..25bdbaa81 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -118,9 +118,6 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed get childDocs() { TraceMobx(); return this.childDocList(this.fieldKey); }
     @computed get childLinks() { return this.childDocList("links"); }
     @computed get childAnnos() { return this.childDocList(this.fieldKey + "-annotations"); }
-    @computed get isCollectionDoc() {
-        return !StrCast(this.props.document.type).includes(DocumentType.COL) || !DocListCast(this.props.document[this.fieldKey]).length ? false : true;
-    }
 
     @undoBatch openRight = () => this.props.addDocTab(this.doc, "add:right");
     @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
@@ -165,8 +162,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         if (e.buttons === 1 && SnappingManager.GetIsDragging()) {
             this._header!.current!.className = "treeView-header";
             document.removeEventListener("pointermove", this.onDragMove, true);
-            document.addEventListener("pointermove", this.onDragMove, true);
             document.removeEventListener("pointerup", this.onDragUp, true);
+            document.addEventListener("pointermove", this.onDragMove, true);
             document.addEventListener("pointerup", this.onDragUp, true);
         }
     }
-- 
cgit v1.2.3-70-g09d2


From 36cd323ff859cb8367d38c84852d09370e899518 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Feb 2021 13:44:10 -0500
Subject: fixing editing of treeView titles to not write to document.

---
 src/client/views/collections/TreeView.tsx | 71 +++++++++++++++++++------------
 src/client/views/nodes/DocumentView.tsx   |  2 +-
 2 files changed, 45 insertions(+), 28 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 25bdbaa81..882696987 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -1,5 +1,5 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable } from "mobx";
+import { action, computed, observable, runInAction, trace, reaction, IReactionDisposer } from "mobx";
 import { observer } from "mobx-react";
 import { DataSym, Doc, DocListCast, DocListCastOrNull, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
@@ -78,16 +78,16 @@ const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("p
  * treeViewExpandedView : name of field whose contents are being displayed as the document's subtree
  */
 export class TreeView extends React.Component<TreeViewProps> {
+    static _editTitleOnLoad: Opt<string>;
     private _editTitleScript: (() => ScriptField) | undefined;
     private _openScript: (() => ScriptField) | undefined;
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
     private _treedropDisposer?: DragManager.DragDropDisposer;
     private _tref = React.createRef<HTMLDivElement>();
-    private _docRef = React.createRef<DocumentView>();
-    private _uniqueId = Utils.GenerateGuid();
+    private _docRef: Opt<DocumentView>;
     private _editMaxWidth: number | string = 0;
 
-
+    @observable _editTitle: boolean = false;
     @observable _dref: DocumentView | undefined | null;
     @computed get doc() { TraceMobx(); return this.props.document; }
     get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); }
@@ -132,15 +132,26 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
     @undoBatch @action removeDoc = (doc: Doc | Doc[]) => this.remove(doc, Doc.LayoutFieldKey(this.doc));
 
-    selected = () => SelectionManager.Views().length && SelectionManager.Views()[0].props.Document === this.props.document;
+
+    @action setEditTitle = (docView?: DocumentView) => {
+        if (!docView) {
+            this._editTitle = false;
+            this._selReaction?.();
+            this._selReaction = undefined;
+        }
+        else if (docView.isSelected()) {
+            this._editTitle = true;
+        } else {
+            docView.select(false);
+        }
+    }
     constructor(props: any) {
         super(props);
-        const titleScript = ScriptField.MakeScript(`{scriptContext.selected() && setInPlace(self, 'editTitle', '${this._uniqueId}'); documentView.select();} `, { scriptContext: "any", documentView: "any" });
+        const titleScript = ScriptField.MakeScript("scriptContext.setEditTitle(documentView)", { scriptContext: "any", documentView: "any" });
         const openScript = ScriptField.MakeScript(`self.isFolder? (scriptContext.treeViewOpen = !scriptContext.treeViewOpen) : openOnRight(self) && documentView.select()`, { scriptContext: "any", documentView: "any" });
         const treeOpenScript = ScriptField.MakeScript(`scriptContext.treeViewOpen = !scriptContext.treeViewOpen`, { scriptContext: "any" });
         this._editTitleScript = !Doc.IsSystem(this.props.document) || props.document.isFolder ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript);
         this._openScript = !Doc.IsSystem(this.props.document) || props.document.isFolder ? openScript && (() => openScript) : undefined;
-        if (Doc.GetT(this.props.document, "editTitle", "string", true) === "*") Doc.SetInPlace(this.props.document, "editTitle", this._uniqueId, false);
     }
 
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
@@ -149,6 +160,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
 
     componentWillUnmount() {
+        this._selReaction?.();
         document.removeEventListener("pointermove", this.onDragMove, true);
         document.removeEventListener("pointermove", this.onDragUp, true);
     }
@@ -197,13 +209,12 @@ export class TreeView extends React.Component<TreeViewProps> {
         });
         Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text');
         Doc.GetProto(bullet).data = new List<Doc>([]);
-        Doc.SetInPlace(bullet, "editTitle", "*", false);
+        TreeView._editTitleOnLoad = bullet[Id];
         FormattedTextBox.SelectOnLoad = bullet[Id];
         return bullet;
     }
 
     makeTextCollection = () => {
-        Doc.SetInPlace(this.doc, "editTitle", undefined, false);
         const bullet = TreeView.makeTextBullet();
         const added = this.props.addDocument(bullet);
         bullet.context = this.props.treeView.Document;
@@ -211,10 +222,10 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
 
     makeFolder = () => {
-        Doc.SetInPlace(this.doc, "editTitle", undefined, false);
         const folder = Docs.Create.TreeDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true, system: true });
         const added = this.props.addDocument(folder);
         folder.context = this.props.treeView.Document;
+        TreeView._editTitleOnLoad = folder[Id];
         return added;
     }
 
@@ -228,19 +239,11 @@ export class TreeView extends React.Component<TreeViewProps> {
         fontStyle={style}
         fontSize={12}
         GetValue={() => StrCast(this.doc[key])}
-        OnFillDown={(value) => {
-            if (this.fileSysMode) {
-                this.makeFolder();
-            }
-        }}
+        OnFillDown={(value) => this.fileSysMode && this.makeFolder()}
         SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
             Doc.SetInPlace(this.doc, key, value, false);
             if (this.outlineMode && enterKey) {
                 this.makeTextCollection();
-            } else if (this.fileSysMode && enterKey) {
-                // add folder
-            } else {
-                Doc.SetInPlace(this.doc, "editTitle", undefined, false);
             }
         })}
         onClick={() => {
@@ -249,8 +252,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         }}
         OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))}
         OnTab={undoBatch((shift?: boolean) => {
+            TreeView._editTitleOnLoad = this.props.document[Id];
             shift ? this.props.outdentDocument?.() : this.props.indentDocument?.();
-            setTimeout(() => Doc.SetInPlace(this.doc, "editTitle", `${this.props.treeView._uniqueId}`, false), 0);
         })}
     />)
 
@@ -374,6 +377,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         return rows;
     }
 
+    selected = () => SelectionManager.Views().length && SelectionManager.Views()[0].props.Document === this.props.document;
     rtfWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.props.panelWidth() - treeBulletWidth());
     rtfHeight = () => this.rtfWidth() <= this.layoutDoc?.[WidthSym]() ? Math.min(this.layoutDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
     rtfOutlineHeight = () => Math.max(this.layoutDoc?.[HeightSym](), treeBulletWidth());
@@ -484,9 +488,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         </div>;
     }
 
-    @computed get showTitleEditorControl() { return ["*", this._uniqueId, this.props.treeView._uniqueId].includes(Doc.GetT(this.doc, "editTitle", "string", true) || ""); }
     @computed get headerElements() {
-        return (Doc.IsSystem(this.doc) && Doc.UserDoc().noviceMode) || this.props.treeViewHideHeaderFields() ? (null) :
+        return (Doc.IsSystem(this.doc) && Doc.UserDoc().noviceMode && !this.doc.isFolder) || this.props.treeViewHideHeaderFields() ? (null) :
             <>
                 <FontAwesomeIcon key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />
                 <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
@@ -508,7 +511,7 @@ export class TreeView extends React.Component<TreeViewProps> {
             </>;
     }
 
-    showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef.current?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
+    showContextMenu = (e: React.MouseEvent) => simulateMouseClick(this._docRef?.ContentDiv, e.clientX, e.clientY + 30, e.screenX, e.screenY + 30);
     contextMenuItems = () => this.doc.isFolder ? [{ script: ScriptField.MakeFunction(`scriptContext.makeFolder()`, { scriptContext: "any" })!, label: "New Folder" }] : Doc.IsSystem(this.doc) ? [] : [{ script: ScriptField.MakeFunction(`openOnRight(self)`)!, label: "Open" }, { script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }];
     truncateTitleWidth = () => NumCast(this.props.treeView.props.Document.treeViewTruncateTitleWidth, this.props.panelWidth());
     onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
@@ -554,15 +557,29 @@ export class TreeView extends React.Component<TreeViewProps> {
         }
     }
 
+    _selReaction: Opt<IReactionDisposer>;
+
     /**
      * Renders the EditableView title element for placement into the tree.
      */
     @computed
     get renderTitle() {
+        trace();
         TraceMobx();
-        const view = this.showTitleEditorControl ? this.editableView("title") :
+        const view = this._editTitle ? this.editableView("title") :
             <DocumentView key="title"
-                ref={this._docRef}
+                ref={r => {
+                    this._docRef = r ? r : undefined;
+                    if (r) {
+                        if (r && TreeView._editTitleOnLoad === this.props.document[Id]) {
+                            r.select(false);
+                            this.setEditTitle(r);
+                            TreeView._editTitleOnLoad = undefined;
+                        }
+                        this._selReaction?.();
+                        this._selReaction = reaction(() => this._docRef?.isSelected(), sel => !sel && this.setEditTitle(undefined));
+                    }
+                }}
                 Document={this.doc}
                 DataDoc={undefined}
                 scriptContext={this}
@@ -696,12 +713,12 @@ export class TreeView extends React.Component<TreeViewProps> {
     render() {
         TraceMobx();
         if (this.props.renderedIds.indexOf(this.doc[Id]) !== -1) return "<" + this.doc.title + ">";
-        if (this.showTitleEditorControl) { // find containing CollectionTreeView and set our maximum width so the containing tree view won't have to scroll
+        if (this._editTitle) { // find containing CollectionTreeView and set our maximum width so the containing tree view won't have to scroll
             let par: any = this._header?.current;
             while (par && par.className !== "collectionTreeView-dropTarget") par = par.parentNode;
             if (par) {
                 const par_rect = (par as HTMLElement).getBoundingClientRect();
-                const my_recct = this._docRef.current?.ContentDiv?.getBoundingClientRect();
+                const my_recct = this._docRef?.ContentDiv?.getBoundingClientRect();
                 this._editMaxWidth = Math.max(100, par_rect.right - (my_recct?.left || 0));
             }
         }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index de4e99948..97dc922db 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -729,7 +729,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             }
         }
 
-        if (this.props.removeDocument && !this.props.Document._stayInCollection && CurrentUserUtils.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
+        if (this.props.removeDocument && (!this.props.Document._stayInCollection || this.props.Document.isFolder) && CurrentUserUtils.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
             moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
         }
 
-- 
cgit v1.2.3-70-g09d2


From 1ef89b4f56ce8567da3b632e95ea31e1c3c4386a Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Feb 2021 14:55:22 -0500
Subject: cleaned up indent/outdent in treeview to work with aliases.

---
 .../views/collections/CollectionTreeView.tsx       |  2 +-
 src/client/views/collections/TreeView.tsx          | 95 ++++++++++------------
 2 files changed, 43 insertions(+), 54 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 7beb76fdc..a12de0320 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -208,7 +208,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
             moveDoc, dropAction, this.props.addDocTab, this.props.pinToPres, this.props.styleProvider, this.props.ScreenToLocalTransform,
             this.outerXf, this.active, this.panelWidth, this.props.renderDepth, () => this.props.treeViewHideHeaderFields || BoolCast(this.doc.treeViewHideHeaderFields),
             BoolCast(this.doc.treeViewPreventOpen), [], this.props.onCheckedClick,
-            this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.dontRegisterChildViews, "boolean", null));
+            this.onChildClick, this.props.treeViewSkipFields, true, this.whenActiveChanged, this.props.dontRegisterView || Cast(this.props.Document.dontRegisterChildViews, "boolean", null), this);
     }
     @computed get titleBar() {
         const hideTitle = this.props.treeViewHideTitle || this.doc.treeViewHideTitle;
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 882696987..5caddc56d 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -47,8 +47,8 @@ export interface TreeViewProps {
     panelWidth: () => number;
     panelHeight: () => number;
     addDocument: (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => boolean;
-    indentDocument?: () => void;
-    outdentDocument?: () => void;
+    indentDocument?: (editTitle: boolean) => void;
+    outdentDocument?: (editTitle: boolean) => void;
     ScreenToLocalTransform: () => Transform;
     dontRegisterView?: boolean;
     styleProvider?: StyleProviderFunc | undefined;
@@ -64,6 +64,7 @@ export interface TreeViewProps {
     skipFields?: string[];
     firstLevel: boolean;
     whenActiveChanged: (isActive: boolean) => void;
+    parentTreeView: TreeView | CollectionTreeView | undefined;
 }
 
 const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("px", "")); };
@@ -78,7 +79,7 @@ const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("p
  * treeViewExpandedView : name of field whose contents are being displayed as the document's subtree
  */
 export class TreeView extends React.Component<TreeViewProps> {
-    static _editTitleOnLoad: Opt<string>;
+    static _editTitleOnLoad: Opt<{ id: string, parent: TreeView | CollectionTreeView | undefined }>;
     private _editTitleScript: (() => ScriptField) | undefined;
     private _openScript: (() => ScriptField) | undefined;
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
@@ -86,20 +87,21 @@ export class TreeView extends React.Component<TreeViewProps> {
     private _tref = React.createRef<HTMLDivElement>();
     private _docRef: Opt<DocumentView>;
     private _editMaxWidth: number | string = 0;
+    private _selReaction: Opt<IReactionDisposer>;
 
+    set treeViewOpen(c: boolean) {
+        if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c;
+        else this.doc.treeViewOpen = this._overrideTreeViewOpen = c;
+    }
+    @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
     @observable _editTitle: boolean = false;
     @observable _dref: DocumentView | undefined | null;
-    @computed get doc() { TraceMobx(); return this.props.document; }
-    get noviceMode() { return BoolCast(Doc.UserDoc().noviceMode, false); }
     get displayName() { return "TreeView(" + this.props.document.title + ")"; }  // this makes mobx trace() statements more descriptive
     get treeViewLockExpandedView() { return this.doc.treeViewLockExpandedView; }
-    get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.fileSysMode ? "data" : this.noviceMode || this.outlineMode ? "layout" : "fields"); }
+    get defaultExpandedView() { return StrCast(this.doc.treeViewDefaultExpandedView, this.fileSysMode ? "data" : Doc.UserDoc().noviceMode || this.outlineMode ? "layout" : "fields"); }
     get treeViewDefaultExpandedView() { return this.treeViewLockExpandedView ? this.defaultExpandedView : (this.childDocs && !this.fileSysMode ? this.fieldKey : this.defaultExpandedView); }
-    @observable _overrideTreeViewOpen = false; // override of the treeViewOpen field allowing the display state to be independent of the document's state
-    set treeViewOpen(c: boolean) {
-        if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c;
-        else this.doc.treeViewOpen = this._overrideTreeViewOpen = c;
-    }
+
+    @computed get doc() { TraceMobx(); return this.props.document; }
     @computed get outlineMode() { return this.props.treeView.doc.treeViewType === "outline"; }
     @computed get fileSysMode() { return this.props.treeView.doc.treeViewType === "fileSystem"; }
     @computed get treeViewOpen() { return (!this.props.treeViewPreventOpen && !this.doc.treeViewPreventOpen && BoolCast(this.doc.treeViewOpen)) || this._overrideTreeViewOpen; }
@@ -108,6 +110,10 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed get dataDoc() { return this.doc[DataSym]; }
     @computed get layoutDoc() { return Doc.Layout(this.doc); }
     @computed get fieldKey() { TraceMobx(); const splits = StrCast(Doc.LayoutField(this.doc)).split("fieldKey={\'"); return splits.length > 1 ? splits[1].split("\'")[0] : "data"; }
+    @computed get childDocs() { TraceMobx(); return this.childDocList(this.fieldKey); }
+    @computed get childLinks() { return this.childDocList("links"); }
+    @computed get childAnnos() { return this.childDocList(this.fieldKey + "-annotations"); }
+
     childDocList(field: string) {
         if (this.fileSysMode && !this.doc.isFolder) return [] as Doc[];
         const layout = Doc.LayoutField(this.doc) instanceof Doc ? Doc.LayoutField(this.doc) as Doc : undefined;
@@ -115,10 +121,6 @@ export class TreeView extends React.Component<TreeViewProps> {
             (layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields
             DocListCastOrNull(this.doc[field])); // otherwise use the document's data field
     }
-    @computed get childDocs() { TraceMobx(); return this.childDocList(this.fieldKey); }
-    @computed get childLinks() { return this.childDocList("links"); }
-    @computed get childAnnos() { return this.childDocList(this.fieldKey + "-annotations"); }
-
     @undoBatch openRight = () => this.props.addDocTab(this.doc, "add:right");
     @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
         return this.doc !== target && this.props.removeDoc?.(doc) === true && addDoc(doc);
@@ -130,8 +132,6 @@ export class TreeView extends React.Component<TreeViewProps> {
         res && ind > 0 && DocumentManager.Instance.getDocumentView(this.dataDoc[key][ind - 1], this.props.treeView.props.CollectionView)?.select(false);
         return res;
     }
-    @undoBatch @action removeDoc = (doc: Doc | Doc[]) => this.remove(doc, Doc.LayoutFieldKey(this.doc));
-
 
     @action setEditTitle = (docView?: DocumentView) => {
         if (!docView) {
@@ -209,7 +209,6 @@ export class TreeView extends React.Component<TreeViewProps> {
         });
         Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text');
         Doc.GetProto(bullet).data = new List<Doc>([]);
-        TreeView._editTitleOnLoad = bullet[Id];
         FormattedTextBox.SelectOnLoad = bullet[Id];
         return bullet;
     }
@@ -217,6 +216,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     makeTextCollection = () => {
         const bullet = TreeView.makeTextBullet();
         const added = this.props.addDocument(bullet);
+        TreeView._editTitleOnLoad = { id: bullet[Id], parent: this };
         bullet.context = this.props.treeView.Document;
         return added;
     }
@@ -225,7 +225,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         const folder = Docs.Create.TreeDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true, system: true });
         const added = this.props.addDocument(folder);
         folder.context = this.props.treeView.Document;
-        TreeView._editTitleOnLoad = folder[Id];
+        TreeView._editTitleOnLoad = { id: folder[Id], parent: this.props.parentTreeView };
         return added;
     }
 
@@ -252,8 +252,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         }}
         OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))}
         OnTab={undoBatch((shift?: boolean) => {
-            TreeView._editTitleOnLoad = this.props.document[Id];
-            shift ? this.props.outdentDocument?.() : this.props.indentDocument?.();
+            !shift ? this.props.indentDocument?.(true) : this.props.outdentDocument?.(true);
         })}
     />)
 
@@ -350,7 +349,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                     this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                     this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.titleStyleProvider, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
                     this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen,
-                    [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView);
+                    [...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView, this);
             } else {
                 contentElement = <EditableView key="editableView"
                     contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
@@ -431,7 +430,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                         this.dataDoc, expandKey, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
                         StrCast(this.doc.childDropAction, this.props.dropAction) as dropActionType, this.props.addDocTab, this.props.pinToPres, this.titleStyleProvider, this.props.ScreenToLocalTransform,
                         this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen,
-                        [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView)}
+                        [...this.props.renderedIds, this.doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.skipFields, false, this.props.whenActiveChanged, this.props.dontRegisterView, this)}
             </ul >;
         } else if (this.treeViewExpandedView === "fields") {
             return <ul key={this.doc[Id] + this.doc.title}>
@@ -550,28 +549,25 @@ export class TreeView extends React.Component<TreeViewProps> {
             e.preventDefault();
             switch (e.key) {
                 case "Tab": setTimeout(() => RichTextMenu.Instance.TextView?.EditorView?.focus(), 150);
-                    return UndoManager.RunInBatch(() => e.shiftKey ? this.props.outdentDocument?.() : this.props.indentDocument?.(), "tab");
+                    return UndoManager.RunInBatch(() => e.shiftKey ? this.props.outdentDocument?.(true) : this.props.indentDocument?.(true), "tab");
                 case "Backspace": return !(this.doc.text as RichTextField)?.Text && this.props.removeDoc?.(this.doc);
                 case "Enter": return UndoManager.RunInBatch(this.makeTextCollection, "bullet");
             }
         }
     }
 
-    _selReaction: Opt<IReactionDisposer>;
-
     /**
      * Renders the EditableView title element for placement into the tree.
      */
     @computed
     get renderTitle() {
-        trace();
         TraceMobx();
         const view = this._editTitle ? this.editableView("title") :
             <DocumentView key="title"
                 ref={r => {
                     this._docRef = r ? r : undefined;
                     if (r) {
-                        if (r && TreeView._editTitleOnLoad === this.props.document[Id]) {
+                        if (r && TreeView._editTitleOnLoad?.id === this.props.document[Id] && TreeView._editTitleOnLoad.parent == this.props.parentTreeView) {
                             r.select(false);
                             this.setEditTitle(r);
                             TreeView._editTitleOnLoad = undefined;
@@ -793,59 +789,51 @@ export class TreeView extends React.Component<TreeViewProps> {
         skipFields: string[] | undefined,
         firstLevel: boolean,
         whenActiveChanged: (isActive: boolean) => void,
-        dontRegisterView: boolean | undefined) {
+        dontRegisterView: boolean | undefined,
+        parentTreeView: CollectionTreeView | TreeView | undefined
+    ) {
         const viewSpecScript = Cast(containingCollection.viewSpecScript, ScriptField);
         if (viewSpecScript) {
             childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result);
         }
 
         const docs = TreeView.sortDocs(childDocs, StrCast(containingCollection?.[key + "-sortCriteria"]));
-
         const rowWidth = () => panelWidth() - treeBulletWidth();
+        const treeViewRefs: Map<Doc, TreeView | undefined> = new Map();
         return docs.filter(child => child instanceof Doc).map((child, i) => {
             const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child);
             if (!pair.layout || pair.data instanceof Promise) {
                 return (null);
             }
 
-            const indent = i === 0 ? undefined : () => {
-                if (remove && StrCast(docs[i - 1].layout).indexOf('fieldKey') !== -1) {
-                    const fieldKeysub = StrCast(docs[i - 1].layout).split('fieldKey')[1];
-                    const fieldKey = fieldKeysub.split("\'")[1];
-                    if (fieldKey && Cast(docs[i - 1][fieldKey], listSpec(Doc)) !== undefined) {
-                        remove(child);
-                        FormattedTextBox.SelectOnLoad = child[Id];
-                        Doc.AddDocToList(docs[i - 1], fieldKey, child);
-                        docs[i - 1].treeViewOpen = true;
-                        child.context = treeView.Document;
-                    }
-                }
-            };
-            const outdent = !parentCollectionDoc ? undefined : () => {
-                if (parentCollectionDoc._viewType === CollectionViewType.Tree && remove && StrCast(parentCollectionDoc.layout).indexOf('fieldKey') !== -1) {
-                    const fieldKeysub = StrCast(parentCollectionDoc.layout).split('fieldKey')[1];
-                    const fieldKey = fieldKeysub.split("\'")[1];
+            const dentDoc = (editTitle: boolean, newParent: Doc, addAfter: Doc | undefined, parent: TreeView | CollectionTreeView | undefined) => {
+                const fieldKey = Doc.LayoutFieldKey(newParent);
+                if (remove && fieldKey && Cast(newParent[fieldKey], listSpec(Doc)) !== undefined) {
                     remove(child);
                     FormattedTextBox.SelectOnLoad = child[Id];
-                    Doc.AddDocToList(parentCollectionDoc, fieldKey, child, parentPrevSibling, false);
-                    parentCollectionDoc.treeViewOpen = true;
+                    TreeView._editTitleOnLoad = editTitle ? { id: child[Id], parent } : undefined;
+                    Doc.AddDocToList(newParent, fieldKey, child, addAfter, false);
+                    newParent.treeViewOpen = true;
                     child.context = treeView.Document;
                 }
-            };
+            }
+            const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeViewRefs.get(docs[i - 1]));
+            const outdent = parentCollectionDoc?._viewType !== CollectionViewType.Tree ? undefined : ((editTitle: boolean) => dentDoc(editTitle, parentCollectionDoc, parentPrevSibling, parentTreeView instanceof TreeView ? parentTreeView.props.parentTreeView : undefined));
+
             const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => add(doc, relativeTo ?? docs[i], before !== undefined ? before : false);
             const childLayout = Doc.Layout(pair.layout);
             const rowHeight = () => {
                 const aspect = Doc.NativeAspect(childLayout);
                 return aspect ? Math.min(childLayout[WidthSym](), rowWidth()) / aspect : childLayout[HeightSym]();
             };
-            return <TreeView key={child[Id]}
+            return <TreeView key={child[Id]} ref={r => treeViewRefs.set(child, r ? r : undefined)}
                 document={pair.layout}
                 dataDoc={pair.data}
                 containingCollection={containingCollection}
                 prevSibling={docs[i]}
                 treeView={treeView}
                 indentDocument={indent}
-                outdentDocument={!parentCollectionDoc ? undefined : outdent}
+                outdentDocument={outdent}
                 onCheckedClick={onCheckedClick}
                 onChildClick={onChildClick}
                 renderDepth={renderDepth}
@@ -868,7 +856,8 @@ export class TreeView extends React.Component<TreeViewProps> {
                 renderedIds={renderedIds}
                 skipFields={skipFields}
                 firstLevel={firstLevel}
-                whenActiveChanged={whenActiveChanged} />;
+                whenActiveChanged={whenActiveChanged}
+                parentTreeView={parentTreeView} />;
         });
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 4fcb0b69f2b96c5ace46362490d54f1059eb1339 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Feb 2021 16:09:21 -0500
Subject: switched folders so that they're not marked as system anymore.  made
 close menu appear unless something is a system doc.

---
 src/client/util/CurrentUserUtils.ts                            |  2 ++
 src/client/views/collections/TreeView.tsx                      | 10 +++++-----
 .../views/collections/collectionFreeForm/MarqueeView.tsx       |  2 +-
 src/client/views/nodes/DocumentView.tsx                        |  4 ++--
 4 files changed, 10 insertions(+), 8 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 064d4b3b6..288f75592 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -548,6 +548,7 @@ export class CurrentUserUtils {
                     iconShape: "square",
                     _stayInCollection: true,
                     _hideContextMenu: true,
+                    system: true,
                     dontUndo: true,
                     title,
                     target,
@@ -580,6 +581,7 @@ export class CurrentUserUtils {
                     btn.color = "white";
                     btn._backgroundColor = "";
                     btn.dontUndo = true;
+                    btn.system = true;
                     if (btn.title === "Catalog" || btn.title === "My Files") { // migration from Catalog to My Files
                         btn.target = Doc.UserDoc().myFilesystem;
                         btn.title = "My Files";
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 5caddc56d..d67cd9fa3 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -150,8 +150,8 @@ export class TreeView extends React.Component<TreeViewProps> {
         const titleScript = ScriptField.MakeScript("scriptContext.setEditTitle(documentView)", { scriptContext: "any", documentView: "any" });
         const openScript = ScriptField.MakeScript(`self.isFolder? (scriptContext.treeViewOpen = !scriptContext.treeViewOpen) : openOnRight(self) && documentView.select()`, { scriptContext: "any", documentView: "any" });
         const treeOpenScript = ScriptField.MakeScript(`scriptContext.treeViewOpen = !scriptContext.treeViewOpen`, { scriptContext: "any" });
-        this._editTitleScript = !Doc.IsSystem(this.props.document) || props.document.isFolder ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript);
-        this._openScript = !Doc.IsSystem(this.props.document) || props.document.isFolder ? openScript && (() => openScript) : undefined;
+        this._editTitleScript = !Doc.IsSystem(this.props.document) ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript);
+        this._openScript = !Doc.IsSystem(this.props.document) ? openScript && (() => openScript) : undefined;
     }
 
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
@@ -222,7 +222,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
 
     makeFolder = () => {
-        const folder = Docs.Create.TreeDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true, system: true });
+        const folder = Docs.Create.TreeDocument([], { title: "-folder-", _stayInCollection: true, isFolder: true });
         const added = this.props.addDocument(folder);
         folder.context = this.props.treeView.Document;
         TreeView._editTitleOnLoad = { id: folder[Id], parent: this.props.parentTreeView };
@@ -488,7 +488,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
 
     @computed get headerElements() {
-        return (Doc.IsSystem(this.doc) && Doc.UserDoc().noviceMode && !this.doc.isFolder) || this.props.treeViewHideHeaderFields() ? (null) :
+        return (Doc.IsSystem(this.doc) && Doc.UserDoc().noviceMode) || this.props.treeViewHideHeaderFields() ? (null) :
             <>
                 <FontAwesomeIcon key="bars" icon="bars" size="sm" onClick={e => { this.showContextMenu(e); e.stopPropagation(); }} />
                 <span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
@@ -612,7 +612,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 ContainingCollectionDoc={this.props.treeView.props.Document}
             />;
         return <>
-            <div className={`docContainer${Doc.IsSystem(this.props.document) ? "-system" : ""}`} ref={this._tref} title="click to edit title. Double Click or Drag to Open"
+            <div className={`docContainer${Doc.IsSystem(this.props.document) || this.props.document.isFolder ? "-system" : ""}`} ref={this._tref} title="click to edit title. Double Click or Drag to Open"
                 style={{
                     fontWeight: Doc.IsSearchMatch(this.doc) !== undefined ? "bold" : undefined,
                     textDecoration: Doc.GetT(this.doc, "title", "string", true) ? "underline" : undefined,
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index f5a60effe..d7fc2feda 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -134,7 +134,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 e.stopPropagation();
             } else if (e.key === "f" && e.ctrlKey) {
                 e.preventDefault();
-                const root = Docs.Create.FreeformDocument([], { title: "folder", _stayInCollection: true, system: true, isFolder: true });
+                const root = Docs.Create.FreeformDocument([], { title: "folder", _stayInCollection: true, isFolder: true });
                 const folder = Docs.Create.TreeDocument([root], { title: "root", isFolder: true, treeViewType: "fileSystem", treeViewTruncateTitleWidth: 150 });
                 Doc.GetProto(folder).isFolder = true;
                 folder.x = x;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 97dc922db..b79c1d474 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -446,7 +446,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
                         shiftKey: e.shiftKey
                     }, console.log);
                     UndoManager.RunInBatch(() => func().result?.select === true ? this.props.select(false) : "", "on double click");
-                } else if (!Doc.IsSystem(this.props.Document)) {
+                } else if (!Doc.IsSystem(this.rootDoc)) {
                     if (this.props.Document.type !== DocumentType.LABEL) {
                         UndoManager.RunInBatch(() => this.props.addDocTab((this.rootDoc._fullScreenView as Doc) || this.rootDoc, "lightbox"), "double tap");
                         SelectionManager.DeselectAll();
@@ -729,7 +729,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             }
         }
 
-        if (this.props.removeDocument && (!this.props.Document._stayInCollection || this.props.Document.isFolder) && CurrentUserUtils.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
+        if (this.props.removeDocument && !Doc.IsSystem(this.rootDoc) && CurrentUserUtils.ActiveDashboard !== this.props.Document) { // need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
             moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
         }
 
-- 
cgit v1.2.3-70-g09d2


From 6412e426d37bb669fc3ef5deb1f5d6803fe4d6ed Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Feb 2021 16:39:28 -0500
Subject: minor cleanup.  fixed doc decorations input width.

---
 src/client/views/DocumentDecorations.tsx  |  4 ++--
 src/client/views/collections/TreeView.tsx | 23 +++++++----------------
 2 files changed, 9 insertions(+), 18 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c8a5b338a..7f1023a4a 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -580,9 +580,9 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b
             </Tooltip>;
 
         const titleArea = this._edtingTitle ?
-            <input ref={this._keyinput} className="documentDecorations-title" type="text" name="dynbox" autoComplete="on" value={this._accumulatedTitle}
+            <input ref={this._keyinput} className="documentDecorations-title" style={{ width: `calc(100% - ${seldoc?.props.hideResizeHandles ? 0 : 20}px` }} type="text" name="dynbox" autoComplete="on" value={this._accumulatedTitle}
                 onBlur={e => this.titleBlur(true)} onChange={action(e => this._accumulatedTitle = e.target.value)} onKeyPress={this.titleEntered} /> :
-            <div className="documentDecorations-title" style={{ width: `calc(100% - ${seldoc.props.hideResizeHandles ? 0 : 20}px` }} key="title" onPointerDown={this.onTitleDown} >
+            <div className="documentDecorations-title" style={{ width: `calc(100% - ${seldoc?.props.hideResizeHandles ? 0 : 20}px` }} key="title" onPointerDown={this.onTitleDown} >
                 <span className="documentDecorations-titleSpan">{`${this.selectionTitle}`}</span>
             </div>;
 
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index d67cd9fa3..62e56f3a3 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -113,6 +113,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed get childDocs() { TraceMobx(); return this.childDocList(this.fieldKey); }
     @computed get childLinks() { return this.childDocList("links"); }
     @computed get childAnnos() { return this.childDocList(this.fieldKey + "-annotations"); }
+    @computed get selected() { return SelectionManager.Views().length && SelectionManager.Views()[0].props.Document === this.props.document; }
 
     childDocList(field: string) {
         if (this.fileSysMode && !this.doc.isFolder) return [] as Doc[];
@@ -121,7 +122,6 @@ export class TreeView extends React.Component<TreeViewProps> {
             (layout ? DocListCastOrNull(layout[field]) : undefined) || // else if there's a layout doc, display it's fields
             DocListCastOrNull(this.doc[field])); // otherwise use the document's data field
     }
-    @undoBatch openRight = () => this.props.addDocTab(this.doc, "add:right");
     @undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
         return this.doc !== target && this.props.removeDoc?.(doc) === true && addDoc(doc);
     }
@@ -239,20 +239,12 @@ export class TreeView extends React.Component<TreeViewProps> {
         fontStyle={style}
         fontSize={12}
         GetValue={() => StrCast(this.doc[key])}
-        OnFillDown={(value) => this.fileSysMode && this.makeFolder()}
+        OnTab={undoBatch((shift?: boolean) => !shift ? this.props.indentDocument?.(true) : this.props.outdentDocument?.(true))}
+        OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))}
+        OnFillDown={val => this.fileSysMode && this.makeFolder()}
         SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
             Doc.SetInPlace(this.doc, key, value, false);
-            if (this.outlineMode && enterKey) {
-                this.makeTextCollection();
-            }
-        })}
-        onClick={() => {
-            SelectionManager.DeselectAll();
-            return false;
-        }}
-        OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))}
-        OnTab={undoBatch((shift?: boolean) => {
-            !shift ? this.props.indentDocument?.(true) : this.props.outdentDocument?.(true);
+            this.outlineMode && enterKey && this.makeTextCollection();
         })}
     />)
 
@@ -376,7 +368,6 @@ export class TreeView extends React.Component<TreeViewProps> {
         return rows;
     }
 
-    selected = () => SelectionManager.Views().length && SelectionManager.Views()[0].props.Document === this.props.document;
     rtfWidth = () => Math.min(this.layoutDoc?.[WidthSym](), this.props.panelWidth() - treeBulletWidth());
     rtfHeight = () => this.rtfWidth() <= this.layoutDoc?.[WidthSym]() ? Math.min(this.layoutDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
     rtfOutlineHeight = () => Math.max(this.layoutDoc?.[HeightSym](), treeBulletWidth());
@@ -528,7 +519,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
         switch (property.split(":")[0]) {
             case StyleProp.Opacity: return this.outlineMode ? undefined : 1;
-            case StyleProp.BackgroundColor: return this.selected() ? "#7089bb" : StrCast(doc._backgroundColor, StrCast(doc.backgroundColor));
+            case StyleProp.BackgroundColor: return this.selected ? "#7089bb" : StrCast(doc._backgroundColor, StrCast(doc.backgroundColor));
             case StyleProp.DocContents: return testDocProps(props) && !props?.treeViewDoc ? (null) :
                 <div className="treeView-label" style={{    // just render a title for a tree view label (identified by treeViewDoc being set in 'props')
                     maxWidth: props?.PanelWidth() || undefined,
@@ -799,7 +790,7 @@ export class TreeView extends React.Component<TreeViewProps> {
 
         const docs = TreeView.sortDocs(childDocs, StrCast(containingCollection?.[key + "-sortCriteria"]));
         const rowWidth = () => panelWidth() - treeBulletWidth();
-        const treeViewRefs: Map<Doc, TreeView | undefined> = new Map();
+        const treeViewRefs = new Map<Doc, TreeView | undefined>();
         return docs.filter(child => child instanceof Doc).map((child, i) => {
             const pair = Doc.GetLayoutDataDocPair(containingCollection, dataDoc, child);
             if (!pair.layout || pair.data instanceof Promise) {
-- 
cgit v1.2.3-70-g09d2


From f22163e9e4118df3faf06afc28045b84615fba0d Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Mon, 22 Feb 2021 20:38:57 -0500
Subject: fixes to tree view folders to fix indent/outdent/retitlte issues
 related to stoppropagating events when active() was not true

---
 src/client/views/collections/TreeView.tsx          | 104 +++++++++++----------
 .../collections/collectionFreeForm/MarqueeView.tsx |   2 +-
 2 files changed, 58 insertions(+), 48 deletions(-)

(limited to 'src/client/views/collections/TreeView.tsx')

diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 62e56f3a3..aed6302ad 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -80,6 +80,8 @@ const treeBulletWidth = function () { return Number(TREE_BULLET_WIDTH.replace("p
  */
 export class TreeView extends React.Component<TreeViewProps> {
     static _editTitleOnLoad: Opt<{ id: string, parent: TreeView | CollectionTreeView | undefined }>;
+    static _openTitleScript: Opt<ScriptField | undefined>;
+    static _openLevelScript: Opt<ScriptField | undefined>;
     private _editTitleScript: (() => ScriptField) | undefined;
     private _openScript: (() => ScriptField) | undefined;
     private _header?: React.RefObject<HTMLDivElement> = React.createRef();
@@ -87,7 +89,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     private _tref = React.createRef<HTMLDivElement>();
     private _docRef: Opt<DocumentView>;
     private _editMaxWidth: number | string = 0;
-    private _selReaction: Opt<IReactionDisposer>;
+    private _selDisposer: Opt<IReactionDisposer>;
 
     set treeViewOpen(c: boolean) {
         if (this.props.treeViewPreventOpen) this._overrideTreeViewOpen = c;
@@ -134,24 +136,34 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
 
     @action setEditTitle = (docView?: DocumentView) => {
+        this._selDisposer?.();
         if (!docView) {
             this._editTitle = false;
-            this._selReaction?.();
-            this._selReaction = undefined;
         }
         else if (docView.isSelected()) {
             this._editTitle = true;
+            this._selDisposer = reaction(() => docView.isSelected(), sel => !sel && this.setEditTitle(undefined));
         } else {
             docView.select(false);
         }
     }
+    @action
+    openLevel = (docView: DocumentView) => {
+        if (this.props.document.isFolder || Doc.IsSystem(this.props.document)) {
+            this.treeViewOpen = !this.treeViewOpen;
+        } else {
+            this.props.addDocTab(this.props.document, "add:right");
+        }
+        docView?.select(false);
+    }
     constructor(props: any) {
         super(props);
-        const titleScript = ScriptField.MakeScript("scriptContext.setEditTitle(documentView)", { scriptContext: "any", documentView: "any" });
-        const openScript = ScriptField.MakeScript(`self.isFolder? (scriptContext.treeViewOpen = !scriptContext.treeViewOpen) : openOnRight(self) && documentView.select()`, { scriptContext: "any", documentView: "any" });
-        const treeOpenScript = ScriptField.MakeScript(`scriptContext.treeViewOpen = !scriptContext.treeViewOpen`, { scriptContext: "any" });
-        this._editTitleScript = !Doc.IsSystem(this.props.document) ? titleScript && (() => titleScript) : treeOpenScript && (() => treeOpenScript);
-        this._openScript = !Doc.IsSystem(this.props.document) ? openScript && (() => openScript) : undefined;
+        if (!TreeView._openLevelScript) {
+            TreeView._openTitleScript = ScriptField.MakeScript("scriptContext.setEditTitle(documentView)", { scriptContext: "any", documentView: "any" });
+            TreeView._openLevelScript = ScriptField.MakeScript(`scriptContext.openLevel(documentView)`, { scriptContext: "any", documentView: "any" });
+        }
+        this._openScript = Doc.IsSystem(this.props.document) ? undefined : () => TreeView._openLevelScript!;
+        this._editTitleScript = Doc.IsSystem(this.props.document) ? () => TreeView._openLevelScript! : () => TreeView._openTitleScript!;
     }
 
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
@@ -160,7 +172,7 @@ export class TreeView extends React.Component<TreeViewProps> {
     }
 
     componentWillUnmount() {
-        this._selReaction?.();
+        this._selDisposer?.();
         document.removeEventListener("pointermove", this.onDragMove, true);
         document.removeEventListener("pointermove", this.onDragUp, true);
     }
@@ -229,25 +241,6 @@ export class TreeView extends React.Component<TreeViewProps> {
         return added;
     }
 
-    editableView = (key: string, style?: string) => (<EditableView
-        oneLine={true}
-        display={"inline-block"}
-        editing={true}
-        contents={StrCast(this.doc[key])}
-        height={12}
-        sizeToContent={true}
-        fontStyle={style}
-        fontSize={12}
-        GetValue={() => StrCast(this.doc[key])}
-        OnTab={undoBatch((shift?: boolean) => !shift ? this.props.indentDocument?.(true) : this.props.outdentDocument?.(true))}
-        OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))}
-        OnFillDown={val => this.fileSysMode && this.makeFolder()}
-        SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
-            Doc.SetInPlace(this.doc, key, value, false);
-            this.outlineMode && enterKey && this.makeTextCollection();
-        })}
-    />)
-
     preTreeDrop = (e: Event, de: DragManager.DropEvent, targetAction: dropActionType) => {
         const dragData = de.complete.docDragData;
         dragData && (dragData.dropAction = this.props.treeView.props.Document === dragData.treeViewDoc ? "same" : dragData.dropAction);
@@ -409,12 +402,14 @@ export class TreeView extends React.Component<TreeViewProps> {
             const docs = expandKey === "links" ? this.childLinks : expandKey === "annotations" ? this.childAnnos : this.childDocs;
             const sortKey = `${this.fieldKey}-sortCriteria`;
             return <ul key={expandKey + "more"} className={this.doc.treeViewHideTitle ? "no-indent" : ""} onClick={(e) => {
-                !this.outlineMode && (this.doc[sortKey] =
-                    (this.doc[sortKey] === "ascending" ? "descending" :
-                        (this.doc[sortKey] === "descending" ? "zorder" :
-                            (this.doc[sortKey] === "zorder" ? undefined :
-                                "ascending"))));
-                e.stopPropagation();
+                if (this.props.active()) {
+                    !this.outlineMode && (this.doc[sortKey] =
+                        (this.doc[sortKey] === "ascending" ? "descending" :
+                            (this.doc[sortKey] === "descending" ? "zorder" :
+                                (this.doc[sortKey] === "zorder" ? undefined :
+                                    "ascending"))));
+                    e.stopPropagation();
+                }
             }}>
                 {!docs ? (null) :
                     TreeView.GetChildElements(docs, this.props.treeView, this.layoutDoc,
@@ -553,20 +548,35 @@ export class TreeView extends React.Component<TreeViewProps> {
     @computed
     get renderTitle() {
         TraceMobx();
-        const view = this._editTitle ? this.editableView("title") :
-            <DocumentView key="title"
-                ref={r => {
+        const view = this._editTitle ? <EditableView key="_editTitle"
+            oneLine={true}
+            display={"inline-block"}
+            editing={true}
+            contents={StrCast(this.doc.title)}
+            height={12}
+            sizeToContent={true}
+            fontSize={12}
+            GetValue={() => StrCast(this.doc.title)}
+            OnTab={undoBatch((shift?: boolean) => {
+                if (!shift) this.props.indentDocument?.(true);
+                else this.props.outdentDocument?.(true);
+            })}
+            OnEmpty={undoBatch(() => this.outlineMode && this.props.removeDoc?.(this.doc))}
+            OnFillDown={val => this.fileSysMode && this.makeFolder()}
+            SetValue={undoBatch((value: string, shiftKey: boolean, enterKey: boolean) => {
+                Doc.SetInPlace(this.doc, "title", value, false);
+                this.outlineMode && enterKey && this.makeTextCollection();
+            })}
+        />
+            : <DocumentView key="title"
+                ref={action((r: any) => {
                     this._docRef = r ? r : undefined;
-                    if (r) {
-                        if (r && TreeView._editTitleOnLoad?.id === this.props.document[Id] && TreeView._editTitleOnLoad.parent == this.props.parentTreeView) {
-                            r.select(false);
-                            this.setEditTitle(r);
-                            TreeView._editTitleOnLoad = undefined;
-                        }
-                        this._selReaction?.();
-                        this._selReaction = reaction(() => this._docRef?.isSelected(), sel => !sel && this.setEditTitle(undefined));
+                    if (this._docRef && TreeView._editTitleOnLoad?.id === this.props.document[Id] && TreeView._editTitleOnLoad.parent == this.props.parentTreeView) {
+                        this._docRef.select(false);
+                        this.setEditTitle(this._docRef);
+                        TreeView._editTitleOnLoad = undefined;
                     }
-                }}
+                })}
                 Document={this.doc}
                 DataDoc={undefined}
                 scriptContext={this}
@@ -602,6 +612,7 @@ export class TreeView extends React.Component<TreeViewProps> {
                 ContainingCollectionView={undefined}
                 ContainingCollectionDoc={this.props.treeView.props.Document}
             />;
+
         return <>
             <div className={`docContainer${Doc.IsSystem(this.props.document) || this.props.document.isFolder ? "-system" : ""}`} ref={this._tref} title="click to edit title. Double Click or Drag to Open"
                 style={{
@@ -810,7 +821,6 @@ export class TreeView extends React.Component<TreeViewProps> {
             }
             const indent = i === 0 ? undefined : (editTitle: boolean) => dentDoc(editTitle, docs[i - 1], undefined, treeViewRefs.get(docs[i - 1]));
             const outdent = parentCollectionDoc?._viewType !== CollectionViewType.Tree ? undefined : ((editTitle: boolean) => dentDoc(editTitle, parentCollectionDoc, parentPrevSibling, parentTreeView instanceof TreeView ? parentTreeView.props.parentTreeView : undefined));
-
             const addDocument = (doc: Doc | Doc[], relativeTo?: Doc, before?: boolean) => add(doc, relativeTo ?? docs[i], before !== undefined ? before : false);
             const childLayout = Doc.Layout(pair.layout);
             const rowHeight = () => {
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index d7fc2feda..36d14056b 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -134,7 +134,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
                 e.stopPropagation();
             } else if (e.key === "f" && e.ctrlKey) {
                 e.preventDefault();
-                const root = Docs.Create.FreeformDocument([], { title: "folder", _stayInCollection: true, isFolder: true });
+                const root = Docs.Create.TreeDocument([], { title: "folder", _stayInCollection: true, isFolder: true });
                 const folder = Docs.Create.TreeDocument([root], { title: "root", isFolder: true, treeViewType: "fileSystem", treeViewTruncateTitleWidth: 150 });
                 Doc.GetProto(folder).isFolder = true;
                 folder.x = x;
-- 
cgit v1.2.3-70-g09d2

