From bdccc7c147dbb985bff5286e318718e48fd7cc62 Mon Sep 17 00:00:00 2001
From: Geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 15 Feb 2022 16:06:18 -0500
Subject: updates

---
 .../views/collections/CollectionStackingView.tsx   | 34 ++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index cdc680a08..ad3f3b217 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -65,6 +65,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
     @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === CollectionViewType.Stacking; }
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
     @computed get showAddAGroup() { return this.pivotField && !this.chromeHidden; }
+    // columnWidth handles the margin on the left and right side of the documents
     @computed get columnWidth() {
         return Math.min(this.props.PanelWidth() - 2 * this.xMargin,
             this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
@@ -88,8 +89,21 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
             const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} style={style} >
+                <div className="hoverButtons">
+                  {/* We'll want to add an onPointerDown that uses DragManager.DocumentDragData
+                   -- we also want to remember to preventDefault (so other drag events are not recognized over this one)
+                   -- Design discussion as to whether we want dragging to be on the document itself or with a drag button
+                   -- Do we want clicking on this button to do anything as well?
+                   -- Design Question: Schema view also has the notion of a drag manager (different from this one), do we want
+                   the same functionality?
+                   -- Problem: This only shows when the outer container is selected...
+                  */}
+                  <div className="buttonWrapper">
+                    <FontAwesomeIcon icon={"grip-vertical"} onPointerDown={e => e.stopPropagation()} />
+                  </div>
+                </div>
                 {this.getDisplayDoc(d, width)}
-            </div>;
+            </div>
         });
     }
     @action
@@ -275,7 +289,13 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
     getDocWidth(d?: Doc) {
         if (!d) return 0;
         const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
-        const maxWidth = this.columnWidth / this.numGroupColumns;
+        // TODO: pj - replace with a better way to calculate the margin
+        let margin = 25;
+        d.margin = 25;
+        if (this.columnWidth < 150){
+          margin = 0;
+        }
+        const maxWidth = (this.columnWidth / this.numGroupColumns) - (margin * 2);
         if (!this.layoutDoc._columnsFill && !(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d))) {
             return Math.min(d[WidthSym](), maxWidth);
         }
@@ -317,9 +337,17 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         </div>;
     }
 
+    @action
+    onPointerOver = (e: React.PointerEvent) => {
+      if (DragManager.docsBeingDragged.length){
+        console.log(DragManager.docsBeingDragged[0].title)
+      }
+    }
+
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+        console.log('drop')
         const where = [de.x, de.y];
         let dropInd = -1;
         let dropAfter = 0;
@@ -371,6 +399,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
     @undoBatch
     @action
     onExternalDrop = async (e: React.DragEvent): Promise<void> => {
+        console.log('external drop')
         const where = [e.clientX, e.clientY];
         let targInd = -1;
         this._docXfs.map((cd, i) => {
@@ -600,6 +629,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                             pointerEvents: this.backgroundEvents ? "all" : undefined
                         }}
                         onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
+                        onPointerOver={this.onPointerOver}
                         onDrop={this.onExternalDrop.bind(this)}
                         onContextMenu={this.onContextMenu}
                         onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
-- 
cgit v1.2.3-70-g09d2


From a0365450297aa96bcc514114413fb983a34226f9 Mon Sep 17 00:00:00 2001
From: Geireann <60007097+geireann@users.noreply.github.com>
Date: Tue, 15 Feb 2022 16:31:35 -0500
Subject: more comments

---
 src/client/views/collections/CollectionStackingView.tsx | 3 +++
 1 file changed, 3 insertions(+)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 70471d0d8..419b9a943 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -80,6 +80,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         }
     }
 
+    // TODO: plj - these are the children
     children = (docs: Doc[]) => {
         TraceMobx();
         this._docXfs.length = 0;
@@ -338,6 +339,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         </div>;
     }
 
+    // TODO: plj
     @action
     onPointerOver = (e: React.PointerEvent) => {
       if (DragManager.docsBeingDragged.length){
@@ -345,6 +347,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
       }
     }
 
+    // TODO: plj - look at this
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
-- 
cgit v1.2.3-70-g09d2


From 2c565fd81daca02cabb9598c699cedb7611c3841 Mon Sep 17 00:00:00 2001
From: ljungster <parkerljung@gmail.com>
Date: Sat, 12 Mar 2022 07:44:01 -0500
Subject: attempting to add note-taking

I think this has something to do with the view not being rendered in novice mode. Assuming this is an issue in CollectionMenu.tsx.

Essentially what I did was add a note-taking view wherever I found a stacking view (via global search)
---
 src/client/documents/Documents.ts                  |   4 +
 src/client/util/CurrentUserUtils.ts                |   3 +-
 src/client/views/DocumentButtonBar.tsx             |   2 +-
 src/client/views/PropertiesButtons.tsx             |   3 +-
 src/client/views/PropertiesView.tsx                |   2 +-
 src/client/views/StyleProvider.tsx                 |   2 +-
 src/client/views/collections/CollectionMenu.tsx    | 125 +++-
 .../views/collections/CollectionNoteTakingView.tsx | 739 +++++++++++++++++++++
 .../CollectionNoteTakingViewFieldColumn.tsx        | 359 ++++++++++
 .../views/collections/CollectionStackingView.tsx   | 102 ++-
 .../CollectionStackingViewFieldColumn.tsx          |   7 +
 src/client/views/collections/CollectionView.tsx    |   7 +-
 src/client/views/collections/TreeView.tsx          |   1 +
 src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx |   3 +-
 src/client/views/nodes/button/FontIconBox.tsx      |   2 +-
 src/client/views/nodes/trails/PresBox.tsx          |   1 +
 src/fields/Doc.ts                                  |   2 +-
 17 files changed, 1343 insertions(+), 21 deletions(-)
 create mode 100644 src/client/views/collections/CollectionNoteTakingView.tsx
 create mode 100644 src/client/views/collections/CollectionNoteTakingViewFieldColumn.tsx

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index df573a377..0014c0c92 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -847,6 +847,10 @@ export namespace Docs {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Stacking }, id, undefined, protoId);
         }
 
+        export function NoteTakingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) {
+          return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.NoteTaking }, id, undefined, protoId);
+      }
+
         export function MulticolumnDocument(documents: Array<Doc>, options: DocumentOptions) {
             return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.Multicolumn });
         }
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index a8b0da369..8cb735d10 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -406,6 +406,7 @@ export class CurrentUserUtils {
         title: string, toolTip: string, icon: string, drag?: string, ignoreClick?: boolean,
         click?: string, backgroundColor?: string, dragFactory?: Doc, noviceMode?: boolean, clickFactory?: Doc
     }[] {
+      //TODO: we may need to add in note-teking view here
         if (doc.emptyPresentation === undefined) {
             doc.emptyPresentation = Docs.Create.PresDocument(new List<Doc>(),
                 { title: "Untitled Presentation", _viewType: CollectionViewType.Stacking, _fitWidth: true, _width: 400, _height: 500, targetDropAction: "alias", _chromeHidden: true, boxShadow: "0 0", system: true, cloneFieldFilter: new List<string>(["system"]) });
@@ -1058,7 +1059,7 @@ export class CurrentUserUtils {
                 CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Multicolumn,
                 CollectionViewType.Multirow, CollectionViewType.Time, CollectionViewType.Carousel,
                 CollectionViewType.Carousel3D, CollectionViewType.Linear, CollectionViewType.Map,
-                CollectionViewType.Grid],
+                CollectionViewType.NoteTaking, CollectionViewType.Grid],
                 script: 'setView',
             }, // Always show
             {
diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index aa9318310..2293da6c8 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -216,7 +216,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
         if (targetDoc) {
             TabDocView.PinDoc(targetDoc);
             const activeDoc = PresBox.Instance.childDocs[PresBox.Instance.childDocs.length - 1];
-            const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking;
+            const scrollable = [DocumentType.PDF, DocumentType.RTF, DocumentType.WEB].includes(targetDoc.type as any) || targetDoc._viewType === CollectionViewType.Stacking || targetDoc._viewType === CollectionViewType.NoteTaking;
             const pannable: boolean = ((targetDoc.type === DocumentType.COL && targetDoc._viewType === CollectionViewType.Freeform) || targetDoc.type === DocumentType.IMG);
             if (scrollable) {
                 const scroll = targetDoc._scrollTop;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index f9dab9f82..3cb57fc7c 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -208,7 +208,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         const isInk = layoutField instanceof InkField;
         const isMap = this.selectedDoc?.type === DocumentType.MAP;
         const isCollection = this.selectedDoc?.type === DocumentType.COL;
-        const isStacking = this.selectedDoc?._viewType === CollectionViewType.Stacking;
+        //TODO: will likely need to create separate note-taking view type here
+        const isStacking = this.selectedDoc?._viewType === CollectionViewType.Stacking || this.selectedDoc?._viewType === CollectionViewType.NoteTaking;
         const isFreeForm = this.selectedDoc?._viewType === CollectionViewType.Freeform;
         const isTree = this.selectedDoc?._viewType === CollectionViewType.Tree;
         const isTabView = this.selectedTabView;
diff --git a/src/client/views/PropertiesView.tsx b/src/client/views/PropertiesView.tsx
index 25b1381fe..df0455fa9 100644
--- a/src/client/views/PropertiesView.tsx
+++ b/src/client/views/PropertiesView.tsx
@@ -1349,7 +1349,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 const type = PresBox.Instance.activeItem?.type;
                 const viewType = PresBox.Instance.activeItem?._viewType;
                 const pannable: boolean = (type === DocumentType.COL && viewType === CollectionViewType.Freeform) || type === DocumentType.IMG;
-                const scrollable: boolean = type === DocumentType.PDF || type === DocumentType.WEB || type === DocumentType.RTF || viewType === CollectionViewType.Stacking;
+                const scrollable: boolean = type === DocumentType.PDF || type === DocumentType.WEB || type === DocumentType.RTF || viewType === CollectionViewType.Stacking || viewType === CollectionViewType.NoteTaking;
                 return <div className="propertiesView" style={{ width: this.props.width }}>
                     <div className="propertiesView-title" style={{ width: this.props.width }}>
                         Presentation
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 8ee673115..0b1cb3be0 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -112,7 +112,7 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.TitleHeight: return 15;
         case StyleProp.BorderPath: return comicStyle() && props?.renderDepth && doc?.type !== DocumentType.INK ? { path: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0), fill: wavyBorderPath(props?.PanelWidth?.() || 0, props?.PanelHeight?.() || 0, .08), width: 3 } : { path: undefined, width: 0 };
         case StyleProp.JitterRotation: return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0;
-        case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
+        case StyleProp.HeaderMargin: return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
             doc?.type === DocumentType.RTF) && showTitle() && !StrCast(doc?.showTitle).includes(":hover") ? 15 : 0;
         case StyleProp.BackgroundColor: {
             if (MainView.Instance.LastButton === doc) return Colors.LIGHT_GRAY;
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 131f5ba46..1ab4e9207 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -278,6 +278,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
 
     @computed get _freeform_commands() { return Doc.UserDoc().noviceMode ? [this._viewCommand, this._saveFilterCommand] : [this._viewCommand, this._saveFilterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand]; }
     @computed get _stacking_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
+    @computed get _notetaking_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
     @computed get _masonry_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._contentCommand, this._templateCommand]; }
     @computed get _schema_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._templateCommand, this._narrativeCommand]; }
     @computed get _doc_commands() { return Doc.UserDoc().noviceMode ? undefined : [this._openLinkInCommand, this._onClickCommand]; }
@@ -289,6 +290,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             case CollectionViewType.Tree: return this._tree_commands;
             case CollectionViewType.Schema: return this._schema_commands;
             case CollectionViewType.Stacking: return this._stacking_commands;
+            case CollectionViewType.NoteTaking: return this._notetaking_commands;
             case CollectionViewType.Masonry: return this._stacking_commands;
             case CollectionViewType.Time: return this._freeform_commands;
             case CollectionViewType.Carousel: return this._freeform_commands;
@@ -326,6 +328,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             case CollectionViewType.Invalid:
             case CollectionViewType.Freeform: return (<CollectionFreeFormViewChrome key="collchrome" {...this.props} isOverlay={this.props.type === CollectionViewType.Invalid} />);
             case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
+            case CollectionViewType.NoteTaking: return (<CollectionNoteTakingViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" {...this.props} />);
             case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" {...this.props} />);
@@ -496,7 +499,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewMenu
             const size: number = PresBox.Instance?._selectedArray.size;
             const presSelected: Doc | undefined = presArray && size ? presArray[size - 1] : undefined;
             const activeDoc = presSelected ? PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.indexOf(presSelected) + 1] : PresBox.Instance?.childDocs[PresBox.Instance?.childDocs.length - 1];
-            if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking) {
+            if (targetDoc.type === DocumentType.PDF || targetDoc.type === DocumentType.RTF || targetDoc.type === DocumentType.WEB || targetDoc._viewType === CollectionViewType.Stacking || targetDoc._viewType === CollectionViewType.NoteTaking) {
                 const scroll = targetDoc._scrollTop;
                 activeDoc.presPinView = true;
                 activeDoc.presPinViewScroll = scroll;
@@ -987,6 +990,126 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
     }
 }
 
+@observer
+export class CollectionNoteTakingViewChrome extends React.Component<CollectionViewMenuProps> {
+    @observable private _currentKey: string = "";
+    @observable private suggestions: string[] = [];
+
+    get document() { return this.props.docView.props.Document; }
+
+    @computed private get descending() { return StrCast(this.document._columnsSort) === "descending"; }
+    @computed get pivotField() { return StrCast(this.document._pivotField); }
+
+    getKeySuggestions = async (value: string): Promise<string[]> => {
+        const val = value.toLowerCase();
+        const docs = DocListCast(this.document[this.props.fieldKey]);
+
+        if (Doc.UserDoc().noviceMode) {
+            if (docs instanceof Doc) {
+                const keys = Object.keys(docs).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
+                    key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
+                    (key[0].toUpperCase() === key[0] && key[0] !== "_"));
+                return keys.filter(key => key.toLowerCase().indexOf(val) > -1);
+            } else {
+                const keys = new Set<string>();
+                docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+                const noviceKeys = Array.from(keys).filter(key => key.indexOf("title") >= 0 || key.indexOf("author") >= 0 ||
+                    key.indexOf("creationDate") >= 0 || key.indexOf("lastModified") >= 0 ||
+                    (key[0]?.toUpperCase() === key[0] && key[0] !== "_"));
+                return noviceKeys.filter(key => key.toLowerCase().indexOf(val) > -1);
+            }
+        }
+
+        if (docs instanceof Doc) {
+            return Object.keys(docs).filter(key => key.toLowerCase().indexOf(val) > -1);
+        } else {
+            const keys = new Set<string>();
+            docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+            return Array.from(keys).filter(key => key.toLowerCase().indexOf(val) > -1);
+        }
+    }
+
+    @action
+    onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
+        this._currentKey = newValue;
+    }
+
+    getSuggestionValue = (suggestion: string) => suggestion;
+
+    renderSuggestion = (suggestion: string) => {
+        return <p>{suggestion}</p>;
+    }
+
+    onSuggestionFetch = async ({ value }: { value: string }) => {
+        const sugg = await this.getKeySuggestions(value);
+        runInAction(() => {
+            this.suggestions = sugg;
+        });
+    }
+
+    @action
+    onSuggestionClear = () => {
+        this.suggestions = [];
+    }
+
+    @action
+    setValue = (value: string) => {
+        this.document._pivotField = value;
+        return true;
+    }
+
+    @action toggleSort = () => {
+        this.document._columnsSort =
+            this.document._columnsSort === "descending" ? "ascending" :
+                this.document._columnsSort === "ascending" ? undefined : "descending";
+    }
+    @action resetValue = () => { this._currentKey = this.pivotField; };
+
+    render() {
+        const doctype = this.props.docView.Document.type;
+        const isPres: boolean = (doctype === DocumentType.PRES);
+        return (
+            isPres ? (null) : <div className="collectionStackingViewChrome-cont">
+                <div className="collectionStackingViewChrome-pivotField-cont">
+                    <div className="collectionStackingViewChrome-pivotField-label">
+                        GROUP BY:
+                    </div>
+                    <div className="collectionStackingViewChrome-sortIcon" onClick={this.toggleSort} style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}>
+                        <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
+                    </div>
+                    <div className="collectionStackingViewChrome-pivotField">
+                        <EditableView
+                            GetValue={() => this.pivotField}
+                            autosuggestProps={
+                                {
+                                    resetValue: this.resetValue,
+                                    value: this._currentKey,
+                                    onChange: this.onKeyChange,
+                                    autosuggestProps: {
+                                        inputProps:
+                                        {
+                                            value: this._currentKey,
+                                            onChange: this.onKeyChange
+                                        },
+                                        getSuggestionValue: this.getSuggestionValue,
+                                        suggestions: this.suggestions,
+                                        alwaysRenderSuggestions: true,
+                                        renderSuggestion: this.renderSuggestion,
+                                        onSuggestionsFetchRequested: this.onSuggestionFetch,
+                                        onSuggestionsClearRequested: this.onSuggestionClear
+                                    }
+                                }}
+                            oneLine
+                            SetValue={this.setValue}
+                            contents={this.pivotField ? this.pivotField : "N/A"}
+                        />
+                    </div>
+                </div>
+            </div>
+        );
+    }
+}
+
 
 @observer
 export class CollectionSchemaViewChrome extends React.Component<CollectionViewMenuProps> {
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
new file mode 100644
index 000000000..9e16de327
--- /dev/null
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -0,0 +1,739 @@
+import React = require("react");
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { CursorProperty } from "csstype";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
+import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
+import { Id } from "../../../fields/FieldSymbols";
+import { List } from "../../../fields/List";
+import { listSpec, makeInterface } from "../../../fields/Schema";
+import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
+import { TraceMobx } from "../../../fields/util";
+import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, returnZero, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils";
+import { Docs, DocUtils } from "../../documents/Documents";
+import { DragManager, dropActionType } from "../../util/DragManager";
+import { SnappingManager } from "../../util/SnappingManager";
+import { Transform } from "../../util/Transform";
+import { undoBatch } from "../../util/UndoManager";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
+import { EditableView } from "../EditableView";
+import { LightboxView } from "../LightboxView";
+import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
+import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView";
+import { StyleProp } from "../StyleProvider";
+import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
+import "./CollectionStackingView.scss";
+import { CollectionStackingViewFieldColumn } from "./CollectionStackingViewFieldColumn";
+import { CollectionSubView } from "./CollectionSubView";
+import { CollectionViewType } from "./CollectionView";
+import internal = require("events");
+const _global = (window /* browser */ || global /* node */) as any;
+
+type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
+const StackingDocument = makeInterface(collectionSchema, documentSchema);
+
+export type collectionStackingViewProps = {
+    chromeHidden?: boolean;
+    // view type is stacking
+    viewType?: CollectionViewType;
+    NativeWidth?: () => number;
+    NativeHeight?: () => number;
+};
+
+@observer
+export class CollectionNoteTakingView extends CollectionSubView<StackingDocument, Partial<collectionStackingViewProps>>(StackingDocument) {
+    // do we need a masonry grid here? We think that they are sharing data
+    _masonryGridRef: HTMLDivElement | null = null;
+    // used in a column dragger, likely due for the masonry grid view. We want to use this 
+    _draggerRef = React.createRef<HTMLDivElement>();
+    // Not sure what a pivot field is. Seems like we cause reaction in MobX get rid of it once we exit this view
+    _pivotFieldDisposer?: IReactionDisposer;
+    // Seems like we cause reaction in MobX get rid of our height once we exit this view
+    _autoHeightDisposer?: IReactionDisposer;
+    // keeping track of documents. Updated on internal and external drops. What's the difference?
+    _docXfs: { height: () => number, width: () => number, stackedDocTransform: () => Transform }[] = [];
+    // Doesn't look like this field is being used anywhere. Obsolete?
+    _columnStart: number = 0;
+    // map of node headers to their heights. Used in Masonry
+    @observable _heightMap = new Map<string, number>();
+    // Assuming that this is the current css cursor style
+    @observable _cursor: CursorProperty = "grab";
+    // gets reset whenever we scroll. Not sure what it is
+    @observable _scroll = 0; // used to force the document decoration to update when scrolling
+    // does this mean whether the browser is hidden? Or is chrome something else entirely?
+    @computed get chromeHidden() { return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden); }
+    // it looks like this gets the column headers that Mehek was showing just now
+    @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null); }
+    // Still not sure what a pivot is, but it appears that we can actually filter docs somehow?
+    @computed get pivotField() { return StrCast(this.layoutDoc._pivotField); }
+    // filteredChildren is what you want to work with. It's the list of things that you're currently displaying
+    @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); }
+    // how much margin we give the header
+    @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); }
+    @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
+    @computed get yMargin() { return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); }
+    @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); }
+    // are we stacking or masonry?
+    //TODO: we might need to remove the notetaking view type
+    @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking); }
+    // this is the number of StackingViewFieldColumns that we have
+    @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
+    // reveals a button to add a group in masonry view
+    @computed get showAddAGroup() { return this.pivotField && !this.chromeHidden; }
+    // columnWidth handles the margin on the left and right side of the documents
+    @computed get columnWidth() {
+        return Math.min(this.props.PanelWidth() - 2 * this.xMargin,
+            this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
+    }
+    
+    @computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; }
+
+    constructor(props: any) {
+        super(props);
+
+        if (this.columnHeaders === undefined) {
+          // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out?
+          // here we're making an empty list of column headers (again, what Mehek showed us)
+            this.layoutDoc._columnHeaders = new List<SchemaHeaderField>();
+        }
+    }
+
+    // TODO: plj - these are the children
+    children = (docs: Doc[]) => {
+      //TODO: can somebody explain me to what exactly TraceMobX is?
+        TraceMobx();
+        // appears that we are going to reset the _docXfs. TODO: what is Xfs?
+        this._docXfs.length = 0;
+        // Go through each of the documents that are contained
+        return docs.map((d, i) => {
+            const height = () => this.getDocHeight(d);
+            const width = () => this.getDocWidth(d);
+            // assuming we need to get rowSpan because we might be dealing with many columns. Grid gap makes sense if multiple columns
+            const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
+            // just getting the style
+            const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+            // So we're choosing whether we're going to render a column or a masonry doc
+            return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} style={style} >
+                {/* <div className="hoverButtons"> */}
+                  {/* We'll want to add an onPointerDown that uses DragManager.DocumentDragData
+                   -- we also want to remember to preventDefault (so other drag events are not recognized over this one)
+                   -- Design discussion as to whether we want dragging to be on the document itself or with a drag button
+                   -- Do we want clicking on this button to do anything as well?
+                   -- Design Question: Schema view also has the notion of a drag manager (different from this one), do we want
+                   the same functionality?
+                   -- Problem: This only shows when the outer container is selected...
+                  */}
+                  {/* <div className="buttonWrapper">
+                    <FontAwesomeIcon icon={"grip-vertical"} onPointerDown={ e => e.stopPropagation()} />
+                  </div>
+                </div> */}
+                {/* some sort of filtering is being done here to actually get layout and make the doc look pretty*/}
+                {this.getDisplayDoc(d, width)} 
+            </div>
+        });
+    }
+    @action
+    setDocHeight = (key: string, sectionHeight: number) => {
+        this._heightMap.set(key, sectionHeight);
+    }
+
+    // is sections that all collections inherit? I think this is how we show the masonry/columns
+    //TODO: this seems important
+    get Sections() {
+        // appears that pivot field IS actually for sorting
+        if (!this.pivotField || this.columnHeaders instanceof Promise) return new Map<SchemaHeaderField, Doc[]>();
+
+        if (this.columnHeaders === undefined) {
+            setTimeout(() => this.layoutDoc._columnHeaders = new List<SchemaHeaderField>(), 0);
+            return new Map<SchemaHeaderField, Doc[]>();
+        }
+        const columnHeaders = Array.from(this.columnHeaders);
+        const fields = new Map<SchemaHeaderField, Doc[]>(columnHeaders.map(sh => [sh, []] as [SchemaHeaderField, []]));
+        let changed = false;
+        this.filteredChildren.map(d => {
+            const sectionValue = (d[this.pivotField] ? d[this.pivotField] : `NO ${this.pivotField.toUpperCase()} VALUE`) as object;
+            // the next five lines ensures that floating point rounding errors don't create more than one section -syip
+            const parsed = parseInt(sectionValue.toString());
+            const castedSectionValue = !isNaN(parsed) ? parsed : sectionValue;
+
+            // look for if header exists already
+            const existingHeader = columnHeaders.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `NO ${this.pivotField.toUpperCase()} VALUE`));
+            if (existingHeader) {
+                fields.get(existingHeader)!.push(d);
+            }
+            else {
+                const newSchemaHeader = new SchemaHeaderField(castedSectionValue ? castedSectionValue.toString() : `NO ${this.pivotField.toUpperCase()} VALUE`);
+                fields.set(newSchemaHeader, [d]);
+                columnHeaders.push(newSchemaHeader);
+                changed = true;
+            }
+        });
+        // remove all empty columns if hideHeadings is set
+        // we will want to have something like this, so that we can hide columns and add them back in
+        if (this.layoutDoc._columnsHideIfEmpty) {
+            Array.from(fields.keys()).filter(key => !fields.get(key)!.length).map(header => {
+                fields.delete(header);
+                columnHeaders.splice(columnHeaders.indexOf(header), 1);
+                changed = true;
+            });
+        }
+        changed && setTimeout(action(() => this.columnHeaders?.splice(0, this.columnHeaders.length, ...columnHeaders)), 0);
+        return fields;
+    }
+
+    componentDidMount() {
+        super.componentDidMount?.();
+
+        // reset section headers when a new filter is inputted
+        this._pivotFieldDisposer = reaction(
+            () => this.pivotField,
+            () => this.layoutDoc._columnHeaders = new List()
+        );
+        //TODO: where the heck are we getting filters from?
+        this._autoHeightDisposer = reaction(() => this.layoutDoc._autoHeight,
+            autoHeight => autoHeight && this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
+                this.headerMargin + (this.isStackingView ?
+                    Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))) :
+                    this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0)))));
+    }
+
+    componentWillUnmount() {
+        super.componentWillUnmount();
+        this._pivotFieldDisposer?.();
+        this._autoHeightDisposer?.();
+    }
+
+    @action
+    moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean): boolean => {
+        return this.props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
+    }
+    createRef = (ele: HTMLDivElement | null) => {
+        this._masonryGridRef = ele;
+        this.createDashEventsTarget(ele!); //so the whole grid is the drop target?
+    }
+
+    @computed get onChildClickHandler() { return () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); }
+    @computed get onChildDoubleClickHandler() { return () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); }
+
+    addDocTab = (doc: Doc, where: string) => {
+        if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) {
+            this.dataDoc[this.props.fieldKey] = new List<Doc>([doc]);
+            return true;
+        }
+        return this.props.addDocTab(doc, where);
+    }
+
+    scrollToBottom = () => {
+        smoothScroll(500, this._mainCont!, this._mainCont!.scrollHeight);
+    }
+
+    // let's dive in and get the actual document we want to drag/move around
+    focusDocument = (doc: Doc, options?: DocFocusOptions) => {
+        Doc.BrushDoc(doc);
+
+        let focusSpeed = 0;
+        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName("documentView-node")).find((node: any) => node.id === doc[Id]);
+        if (found) {
+            const top = found.getBoundingClientRect().top;
+            const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top);
+            if (Math.floor(localTop[1]) !== 0) {
+                smoothScroll(focusSpeed = doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
+            }
+        }
+        const endFocus = async (moved: boolean) => options?.afterFocus ? options?.afterFocus(moved) : ViewAdjustment.doNothing;
+        this.props.focus(this.rootDoc, {
+            willZoom: options?.willZoom, scale: options?.scale, afterFocus: (didFocus: boolean) =>
+                new Promise<ViewAdjustment>(res => setTimeout(async () => res(await endFocus(didFocus)), focusSpeed))
+        });
+    }
+
+    styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
+        if (property === StyleProp.Opacity && doc) {
+            if (this.props.childOpacity) {
+                return this.props.childOpacity();
+            }
+            if (this.Document._currentFrame !== undefined) {
+                return CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity;
+            }
+        }
+        return this.props.styleProvider?.(doc, props, property);
+    }
+    isContentActive = () => this.props.isSelected() || this.props.isContentActive();
+
+    // this is what renders the document that you see on the screen
+    // called in Children: this actually adds a document to our children list
+    getDisplayDoc(doc: Doc, width: () => number) {
+        const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc;
+        const height = () => this.getDocHeight(doc);
+
+        let dref: Opt<DocumentView>;
+        const stackedDocTransform = () => this.getDocTransform(doc, dref);
+        this._docXfs.push({ stackedDocTransform, width, height });
+        //DocumentView is how the node will be rendered
+        return <DocumentView ref={r => dref = r || undefined}
+            Document={doc}
+            DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
+            renderDepth={this.props.renderDepth + 1}
+            PanelWidth={width}
+            PanelHeight={height}
+            styleProvider={this.styleProvider}
+            layerProvider={this.props.layerProvider}
+            docViewPath={this.props.docViewPath}
+            fitWidth={this.props.childFitWidth}
+            isContentActive={emptyFunction}
+            isDocumentActive={this.isContentActive}
+            LayoutTemplate={this.props.childLayoutTemplate}
+            LayoutTemplateString={this.props.childLayoutString}
+            freezeDimensions={this.props.childFreezeDimensions}
+            NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeWidth(doc) ? width : undefined}  // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
+            NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeHeight(doc) ? height : undefined}
+            dontCenter={this.props.childIgnoreNativeSize ? "xy" : undefined}
+            dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)}
+            rootSelected={this.rootSelected}
+            showTitle={this.props.childShowTitle}
+            dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
+            onClick={this.onChildClickHandler}
+            onDoubleClick={this.onChildDoubleClickHandler}
+            ScreenToLocalTransform={stackedDocTransform}
+            focus={this.focusDocument}
+            docFilters={this.childDocFilters}
+            hideDecorationTitle={this.props.childHideDecorationTitle?.()}
+            hideResizeHandles={this.props.childHideResizeHandles?.()}
+            hideTitle={this.props.childHideTitle?.()}
+            docRangeFilters={this.childDocRangeFilters}
+            searchFilterDocs={this.searchFilterDocs}
+            ContainingCollectionDoc={this.props.CollectionView?.props.Document}
+            ContainingCollectionView={this.props.CollectionView}
+            addDocument={this.props.addDocument}
+            moveDocument={this.props.moveDocument}
+            removeDocument={this.props.removeDocument}
+            contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
+            whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
+            addDocTab={this.addDocTab}
+            bringToFront={returnFalse}
+            scriptContext={this.props.scriptContext}
+            pinToPres={this.props.pinToPres}
+        />;
+    }
+
+    getDocTransform(doc: Doc, dref?: DocumentView) {
+        const y = this._scroll; // required for document decorations to update when the text box container is scrolled
+        const { scale, translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined);
+        // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform.  so we have to subtract that off 
+        return new Transform(- translateX + (dref?.centeringX || 0), - translateY + (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale);
+    }
+    getDocWidth(d?: Doc) {
+        if (!d) return 0;
+        const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
+        // TODO: pj - replace with a better way to calculate the margin
+        let margin = 25;
+        d.margin = 25;
+        if (this.columnWidth < 150){
+          margin = 0;
+        }
+        const maxWidth = (this.columnWidth / this.numGroupColumns) - (margin * 2);
+        if (!this.layoutDoc._columnsFill && !(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d))) {
+            return Math.min(d[WidthSym](), maxWidth);
+        }
+        return maxWidth;
+    }
+    getDocHeight(d?: Doc) {
+        if (!d || d.hidden) return 0;
+        const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
+        const childDataDoc = (!d.isTemplateDoc && !d.isTemplateForField && !d.PARAMS) ? undefined : this.props.DataDoc;
+        const maxHeight = (lim => lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim)(NumCast(this.layoutDoc.childLimitHeight, -1));
+        const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[WidthSym]() : 0);
+        const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[HeightSym]() : 0);
+        if (nw && nh) {
+            const colWid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1);
+            const docWid = this.layoutDoc._columnsFill ? colWid : Math.min(this.getDocWidth(d), colWid);
+            return Math.min(
+                maxHeight,
+                docWid * nh / nw);
+        }
+        const childHeight = NumCast(childLayoutDoc._height);
+        const panelHeight = (childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? Number.MAX_SAFE_INTEGER : this.props.PanelHeight() - 2 * this.yMargin;
+        return Math.min(childHeight, maxHeight, panelHeight);
+    }
+
+    // This following three functions must be from the view Mehek showed
+    columnDividerDown = (e: React.PointerEvent) => {
+        runInAction(() => this._cursor = "grabbing");
+        setupMoveUpEvents(this, e, this.onDividerMove, action(() => this._cursor = "grab"), emptyFunction);
+    }
+    @action
+    onDividerMove = (e: PointerEvent, down: number[], delta: number[]) => {
+        this.layoutDoc._columnWidth = Math.max(10, this.columnWidth + delta[0]);
+        return false;
+    }
+
+    @computed get columnDragger() {
+        return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef}
+            style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px`, top: `${Math.max(0, this.yMargin - 9)}px` }} >
+            <FontAwesomeIcon icon={"arrows-alt-h"} />
+        </div>;
+    }
+
+    // TODO: plj
+    @action
+    onPointerOver = (e: React.PointerEvent) => {
+      // console.log("hovering over something")
+      if (DragManager.docsBeingDragged.length) {
+        // essentially copying code from onInternalDrop for this:
+        const doc = DragManager.docsBeingDragged[0]
+        // console.log(doc[LayoutSym]())
+
+        console.log(doc[DataSym])
+        console.log(Doc.IndexOf(doc, this.childDocs))
+
+      }
+      
+
+    }
+
+    //used in onPointerOver to swap two nodes in the rendered filtered children list
+    swapNodes = (i: number, j: number) => {
+      
+    }
+
+    //plj added this 
+    @action
+    onPointerDown = (e: React.PointerEvent) => {
+
+    }
+
+    // TODO: plj - look at this. Start with making changes to db, and then transition to client side 
+    @undoBatch
+    @action
+    onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+      // Fairly confident that this is where the swapping of nodes in the various arrays happens
+        console.log('drop')
+        const where = [de.x, de.y];
+        // start at -1 until we're sure we want to add it to the column
+        let dropInd = -1;
+        let dropAfter = 0;
+        if (de.complete.docDragData) {
+            // going to re-add the docs to the _docXFs based on position of where we just dropped
+            this._docXfs.map((cd, i) => {
+                const pos = cd.stackedDocTransform().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
+                const pos1 = cd.stackedDocTransform().inverse().transformPoint(cd.width(), cd.height());
+                if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && (i === this._docXfs.length - 1 || where[1] < pos1[1])) {
+                    dropInd = i;
+                    const axis = this.isStackingView ? 1 : 0;
+                    dropAfter = where[axis] > (pos[axis] + pos1[axis]) / 2 ? 1 : 0;
+                }
+            });
+            const oldDocs = this.childDocs.length;
+            if (super.onInternalDrop(e, de)) {
+              // check to see if we actually need anything to the new column of nodes (if droppedDocs != empty)
+                const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
+                const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments; // if nothing was added to the end of the list, then presumably the dropped documents were already in the list, but possibly got reordered so we use them.
+
+                const docs = this.childDocList;
+                // reset drag manager docs, because we just dropped
+                DragManager.docsBeingDragged = [];
+                // still figuring out where to add the document
+                if (docs && newDocs.length) {
+                    const insertInd = dropInd === -1 ? docs.length : dropInd + dropAfter;
+                    const offset = newDocs.reduce((off, ndoc) => this.filteredChildren.find((fdoc, i) => ndoc === fdoc && i < insertInd) ? off + 1 : off, 0);
+                    newDocs.filter(ndoc => docs.indexOf(ndoc) !== -1).forEach(ndoc => docs.splice(docs.indexOf(ndoc), 1));
+                    docs.splice(insertInd - offset, 0, ...newDocs);
+                }
+            }
+        } // it seems like we're creating a link here. Weird. I didn't know that you could establish links by dragging
+        else if (de.complete.linkDragData?.dragDocument.context === this.props.Document && de.complete.linkDragData?.linkDragView?.props.CollectionFreeFormDocumentView?.()) {
+            const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, _fitWidth: true, title: "dropped annotation" });
+            this.props.addDocument?.(source);
+            de.complete.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: de.complete.linkDragData.linkSourceGetAnchor() }, "doc annotation", ""); // TODODO this is where in text links get passed
+            e.stopPropagation();
+        }
+        else if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de.complete.annoDragData);
+        return false;
+    }
+
+    @undoBatch
+    internalAnchorAnnoDrop(e: Event, annoDragData: DragManager.AnchorAnnoDragData) {
+        const dropCreator = annoDragData.dropDocCreator;
+        annoDragData.dropDocCreator = (annotationOn: Doc | undefined) => {
+            const dropDoc = dropCreator(annotationOn);
+            return dropDoc || this.rootDoc;
+        };
+        return true;
+    }
+
+    @undoBatch
+    @action
+    //What is the difference between internal and external drop?? Does internal mean we're dropping inside of a collection?
+    // I take it back: external drop means we took it out of column/collection that we were just in
+    onExternalDrop = async (e: React.DragEvent): Promise<void> => {
+        console.log('external drop')
+        const where = [e.clientX, e.clientY];
+        let targInd = -1;
+        this._docXfs.map((cd, i) => {
+            const pos = cd.stackedDocTransform().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
+            const pos1 = cd.stackedDocTransform().inverse().transformPoint(cd.width(), cd.height());
+            if (where[0] > pos[0] && where[0] < pos1[0] && where[1] > pos[1] && where[1] < pos1[1]) {
+                targInd = i;
+            }
+        });
+        super.onExternalDrop(e, {}, () => {
+            if (targInd !== -1) {
+                const newDoc = this.childDocs[this.childDocs.length - 1];
+                const docs = this.childDocList;
+                if (docs) {
+                    docs.splice(docs.length - 1, 1);
+                    docs.splice(targInd, 0, newDoc);
+                }
+            }
+        });
+    }
+    // sections are important 
+    headings = () => Array.from(this.Sections);
+    refList: any[] = [];
+    // what a section looks like if we're in stacking view
+    sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
+        const key = this.pivotField;
+        let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
+        if (this.pivotField) {
+            const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
+            if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
+                type = types[0];
+            }
+        }
+        //TODO: I think that we only have one of these atm
+        return <CollectionStackingViewFieldColumn
+            unobserveHeight={ref => this.refList.splice(this.refList.indexOf(ref), 1)}
+            observeHeight={ref => {
+                if (ref) {
+                    this.refList.push(ref);
+                    this.observer = new _global.ResizeObserver(action((entries: any) => {
+                        if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) {
+                            const height = this.headerMargin +
+                                Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
+                                    Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))));
+                            if (!LightboxView.IsLightboxDocView(this.props.docViewPath())) {
+                                this.props.setHeight(height);
+                            }
+                        }
+                    }));
+                    this.observer.observe(ref);
+                }
+            }}
+            addDocument={this.addDocument}
+            chromeHidden={this.chromeHidden}
+            columnHeaders={this.columnHeaders}
+            Document={this.props.Document}
+            DataDoc={this.props.DataDoc}
+            renderChildren={this.children}
+            columnWidth={this.columnWidth}
+            numGroupColumns={this.numGroupColumns}
+            gridGap={this.gridGap}
+            pivotField={this.pivotField}
+            key={heading?.heading ?? ""}
+            headings={this.headings}
+            heading={heading?.heading ?? ""}
+            headingObject={heading}
+            docList={docList}
+            yMargin={this.yMargin}
+            type={type}
+            createDropTarget={this.createDashEventsTarget}
+            screenToLocalTransform={this.props.ScreenToLocalTransform}
+        />;
+    }
+
+    // what a section looks like if we're in masonry. Shouldn't actually need to use this.
+    sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[], first: boolean) => {
+        const key = this.pivotField;
+        let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
+        const types = docList.length ? docList.map(d => typeof d[key]) : this.filteredChildren.map(d => typeof d[key]);
+        if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
+            type = types[0];
+        }
+        const rows = () => !this.isStackingView ? 1 : Math.max(1, Math.min(docList.length,
+            Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
+        return <CollectionMasonryViewFieldRow
+            showHandle={first}
+            Document={this.props.Document}
+            chromeHidden={this.chromeHidden}
+            pivotField={this.pivotField}
+            unobserveHeight={(ref) => this.refList.splice(this.refList.indexOf(ref), 1)}
+            observeHeight={(ref) => {
+                if (ref) {
+                    this.refList.push(ref);
+                    this.observer = new _global.ResizeObserver(action((entries: any) => {
+                        if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) {
+                            const height = this.refList.reduce((p, r) => p + Number(getComputedStyle(r).height.replace("px", "")), 0);
+                            this.props.setHeight(this.headerMargin + height);
+                        }
+                    }));
+                    this.observer.observe(ref);
+                }
+            }}
+            key={heading ? heading.heading : ""}
+            rows={rows}
+            headings={this.headings}
+            heading={heading ? heading.heading : ""}
+            headingObject={heading}
+            docList={docList}
+            parent={this}
+            type={type}
+            createDropTarget={this.createDashEventsTarget}
+            screenToLocalTransform={this.props.ScreenToLocalTransform}
+            setDocHeight={this.setDocHeight}
+        />;
+    }
+
+    @action
+    // What are we adding a group to?
+    addGroup = (value: string) => {
+        if (value && this.columnHeaders) {
+            const schemaHdrField = new SchemaHeaderField(value);
+            this.columnHeaders.push(schemaHdrField);
+            DocUtils.addFieldEnumerations(undefined, this.pivotField, [{ title: value, _backgroundColor: "schemaHdrField.color" }]);
+            return true;
+        }
+        return false;
+    }
+
+    sortFunc = (a: [SchemaHeaderField, Doc[]], b: [SchemaHeaderField, Doc[]]): 1 | -1 => {
+        const descending = StrCast(this.layoutDoc._columnsSort) === "descending";
+        const firstEntry = descending ? b : a;
+        const secondEntry = descending ? a : b;
+        return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1;
+    }
+
+    onContextMenu = (e: React.MouseEvent): void => {
+        // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
+        if (!e.isPropagationStopped()) {
+            const subItems: ContextMenuProps[] = [];
+            subItems.push({ description: `${this.layoutDoc._columnsFill ? "Variable Size" : "Autosize"} Column`, event: () => this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill, icon: "plus" });
+            subItems.push({ description: `${this.layoutDoc._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" });
+            subItems.push({ description: "Clear All", event: () => this.dataDoc.data = new List([]), icon: "times" });
+            ContextMenu.Instance.addItem({ description: "Options...", subitems: subItems, icon: "eye" });
+        }
+    }
+
+    // 
+    @computed get renderedSections() {
+        TraceMobx();
+        let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
+        if (this.pivotField) {
+            const entries = Array.from(this.Sections.entries());
+            sections = this.layoutDoc._columnsSort ? entries.sort(this.sortFunc) : entries;
+        }
+        // a section will have a header and a list of docs. Ok cool.
+        return sections.map((section, i) => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0));
+    }
+
+    @computed get buttonMenu() {
+        const menuDoc: Doc = Cast(this.rootDoc.buttonMenuDoc, Doc, null);
+        // TODO:glr Allow support for multiple buttons
+        if (menuDoc) {
+            const width: number = NumCast(menuDoc._width, 30);
+            const height: number = NumCast(menuDoc._height, 30);
+            console.log(menuDoc.title, width, height);
+            return (<div className="buttonMenu-docBtn"
+                style={{ width: width, height: height }}>
+                <DocumentView
+                    Document={menuDoc}
+                    DataDoc={menuDoc}
+                    isContentActive={this.props.isContentActive}
+                    isDocumentActive={returnTrue}
+                    addDocument={this.props.addDocument}
+                    moveDocument={this.props.moveDocument}
+                    addDocTab={this.props.addDocTab}
+                    pinToPres={emptyFunction}
+                    rootSelected={this.props.isSelected}
+                    removeDocument={this.props.removeDocument}
+                    ScreenToLocalTransform={Transform.Identity}
+                    PanelWidth={() => 35}
+                    PanelHeight={() => 35}
+                    renderDepth={this.props.renderDepth}
+                    focus={emptyFunction}
+                    styleProvider={this.props.styleProvider}
+                    layerProvider={this.props.layerProvider}
+                    docViewPath={returnEmptyDoclist}
+                    whenChildContentsActiveChanged={emptyFunction}
+                    bringToFront={emptyFunction}
+                    docFilters={this.props.docFilters}
+                    docRangeFilters={this.props.docRangeFilters}
+                    searchFilterDocs={this.props.searchFilterDocs}
+                    ContainingCollectionView={undefined}
+                    ContainingCollectionDoc={undefined}
+                />
+            </div>
+            );
+        }
+    }
+
+
+    @computed get nativeWidth() { return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc); }
+    @computed get nativeHeight() { return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc); }
+
+    @computed get scaling() { return !this.nativeWidth ? 1 : this.props.PanelHeight() / this.nativeHeight; }
+
+    @computed get backgroundEvents() { return SnappingManager.GetIsDragging(); }
+    observer: any;
+    render() {
+        TraceMobx();
+        const editableViewProps = {
+            GetValue: () => "",
+            SetValue: this.addGroup,
+            // I don't recall ever seeing this add a group button
+            contents: "+ ADD A GROUP"
+        };
+        const buttonMenu = this.rootDoc.buttonMenu;
+        const noviceExplainer = this.rootDoc.explainer;
+        return (
+            <>
+                {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
+                    {buttonMenu ? this.buttonMenu : null}
+                    {Doc.UserDoc().noviceMode && noviceExplainer ?
+                        <div className="documentExplanation">
+                            {noviceExplainer}
+                        </div>
+                        : null
+                    }
+                </div> : null}
+                <div className="collectionStackingMasonry-cont" >
+                    <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
+                        ref={this.createRef}
+                        style={{
+                            overflowY: this.props.isContentActive() ? "auto" : "hidden",
+                            background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
+                            pointerEvents: this.backgroundEvents ? "all" : undefined
+                        }}
+                        onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
+                        onPointerOver={this.onPointerOver}
+                        onPointerDown={this.onPointerDown}
+                        onDrop={this.onExternalDrop.bind(this)}
+                        onContextMenu={this.onContextMenu}
+                        // Todo: what is wheel? Are we talking about a mouse wheel?
+                        onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
+                        {/* so it appears that we are actually rendering the sections. Maybe this is what we're looking for? */}
+                        {this.renderedSections}
+                        {/* I think that showAddGroup must be passed in as false, which is why we can't find what Mehek showed 
+                        Or it's because we aren't passing a pivot field */}
+                        {!this.showAddAGroup ? (null) :
+                            <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
+                                style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
+                                <EditableView {...editableViewProps} />
+                            </div>}
+                        {/* {this.chromeHidden || !this.props.isSelected() ? (null) :
+                            <Switch
+                                onChange={this.onToggle}
+                                onClick={this.onToggle}
+                                defaultChecked={true}
+                                checkedChildren="edit"
+                                unCheckedChildren="view"
+                            />} */}
+                    </div>
+                </div>
+            </>
+
+        );
+    }
+}
diff --git a/src/client/views/collections/CollectionNoteTakingViewFieldColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewFieldColumn.tsx
new file mode 100644
index 000000000..c191445e7
--- /dev/null
+++ b/src/client/views/collections/CollectionNoteTakingViewFieldColumn.tsx
@@ -0,0 +1,359 @@
+import React = require("react");
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, observable } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
+import { RichTextField } from "../../../fields/RichTextField";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
+import { ScriptField } from "../../../fields/ScriptField";
+import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { ImageField } from "../../../fields/URLField";
+import { TraceMobx } from "../../../fields/util";
+import { emptyFunction, setupMoveUpEvents, returnFalse, returnEmptyString } from "../../../Utils";
+import { Docs, DocUtils } from "../../documents/Documents";
+import { DocumentType } from "../../documents/DocumentTypes";
+import { DragManager } from "../../util/DragManager";
+import { SnappingManager } from "../../util/SnappingManager";
+import { Transform } from "../../util/Transform";
+import { undoBatch } from "../../util/UndoManager";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
+import { EditableView } from "../EditableView";
+import "./CollectionStackingView.scss";
+import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
+import { Id } from "../../../fields/FieldSymbols";
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+
+// So this is how we are storing a column
+interface CSVFieldColumnProps {
+    Document: Doc;
+    DataDoc: Opt<Doc>;
+    docList: Doc[];
+    heading: string;
+    pivotField: string;
+    chromeHidden?: boolean;
+    columnHeaders: SchemaHeaderField[] | undefined;
+    headingObject: SchemaHeaderField | undefined;
+    yMargin: number;
+    columnWidth: number;
+    numGroupColumns: number;
+    gridGap: number;
+    type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
+    headings: () => object[];
+    // I think that stacking view actually has a single column and then supposedly you can add more columns? Unsure
+    renderChildren: (docs: Doc[]) => JSX.Element[];
+    addDocument: (doc: Doc | Doc[]) => boolean;
+    createDropTarget: (ele: HTMLDivElement) => void;
+    screenToLocalTransform: () => Transform;
+    observeHeight: (myref: any) => void;
+    unobserveHeight: (myref: any) => void;
+}
+
+@observer
+export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldColumnProps> {
+    @observable private _background = "inherit";
+
+    private dropDisposer?: DragManager.DragDropDisposer;
+    private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
+
+    @observable _paletteOn = false;
+    @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
+    @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+    _ele: HTMLElement | null = null;
+
+    // This is likely similar to what we will be doing. Why do we need to make these refs?
+    // is that the only way to have drop targets?
+    createColumnDropRef = (ele: HTMLDivElement | null) => {
+        this.dropDisposer?.();
+        if (ele) {
+            this._ele = ele;
+            this.props.observeHeight(ele);
+            this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
+        }
+    }
+    componentWillUnmount() {
+        this.props.unobserveHeight(this._ele);
+    }
+
+    //TODO: what is scripting? I found it in SetInPlace def but don't know what that is
+    @undoBatch
+    columnDrop = action((e: Event, de: DragManager.DropEvent) => {
+        const drop = { docs: de.complete.docDragData?.droppedDocuments, val: this.getValue(this._heading) };
+        drop.docs?.forEach(d => Doc.SetInPlace(d, this.props.pivotField, drop.val, false));
+    });
+    getValue = (value: string): any => {
+        const parsed = parseInt(value);
+        if (!isNaN(parsed)) return parsed;
+        if (value.toLowerCase().indexOf("true") > -1) return true;
+        if (value.toLowerCase().indexOf("false") > -1) return false;
+        return value;
+    }
+
+    @action
+    headingChanged = (value: string, shiftDown?: boolean) => {
+        const castedValue = this.getValue(value);
+        if (castedValue) {
+            if (this.props.columnHeaders?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
+                return false;
+            }
+            this.props.docList.forEach(d => d[this.props.pivotField] = castedValue);
+            if (this.props.headingObject) {
+                this.props.headingObject.setHeading(castedValue.toString());
+                this._heading = this.props.headingObject.heading;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @action
+    changeColumnColor = (color: string) => {
+        this.props.headingObject?.setColor(color);
+        this._color = color;
+    }
+
+    @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = "#b4b4b4");
+    @action pointerLeave = () => this._background = "inherit";
+    textCallback = (char: string) => this.addNewTextDoc("-typed text-", false, true);
+
+    @action
+    addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
+        if (!value && !forceEmptyNote) return false;
+        const key = this.props.pivotField;
+        const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _fitWidth: true, title: value, _autoHeight: true });
+        newDoc[key] = this.getValue(this.props.heading);
+        const maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
+        const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
+        newDoc.heading = heading;
+        FormattedTextBox.SelectOnLoad = newDoc[Id];
+        FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? "" : " ";
+        return this.props.addDocument?.(newDoc) || false;
+    }
+
+    @action
+    deleteColumn = () => {
+        this.props.docList.forEach(d => d[this.props.pivotField] = undefined);
+        if (this.props.columnHeaders && this.props.headingObject) {
+            const index = this.props.columnHeaders.indexOf(this.props.headingObject);
+            this.props.columnHeaders.splice(index, 1);
+        }
+    }
+
+    @action
+    collapseSection = () => {
+        this.props.headingObject?.setCollapsed(!this.props.headingObject.collapsed);
+        this.toggleVisibility();
+    }
+
+    headerDown = (e: React.PointerEvent<HTMLDivElement>) => setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
+
+    //TODO: I think this is where I'm supposed to edit stuff 
+    startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
+        // is MakeAlias a way to make a copy of a doc without rendering it?
+        const alias = Doc.MakeAlias(this.props.Document);
+        alias._width = this.props.columnWidth / (this.props.columnHeaders?.length || 1);
+        alias._pivotField = undefined;
+        let value = this.getValue(this._heading);
+        value = typeof value === "string" ? `"${value}"` : value;
+        alias.viewSpecScript = ScriptField.MakeFunction(`doc.${this.props.pivotField} === ${value}`, { doc: Doc.name });
+        if (alias.viewSpecScript) {
+            DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY);
+            return true;
+        }
+        return false;
+    }
+
+    renderColorPicker = () => {
+        const gray = "#f1efeb";
+        const selected = this.props.headingObject ? this.props.headingObject.color : gray;
+        const colors = ["pink2", "purple4", "bluegreen1", "yellow4", "gray", "red2", "bluegreen7", "bluegreen5", "orange1"];
+        return <div className="collectionStackingView-colorPicker">
+            <div className="colorOptions">
+                {colors.map(col => {
+                    const palette = PastelSchemaPalette.get(col);
+                    return <div className={"colorPicker" + (selected === palette ? " active" : "")}
+                        style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
+                })}
+            </div>
+        </div>;
+    }
+
+    renderMenu = () => {
+        return <div className="collectionStackingView-optionPicker">
+            <div className="optionOptions">
+                <div className={"optionPicker" + (true ? " active" : "")} onClick={action(() => { })}>Add options here</div>
+            </div>
+        </div >;
+    }
+
+    @observable private collapsed: boolean = false;
+
+    private toggleVisibility = action(() => this.collapsed = !this.collapsed);
+
+    menuCallback = (x: number, y: number) => {
+        ContextMenu.Instance.clearItems();
+        const layoutItems: ContextMenuProps[] = [];
+        const docItems: ContextMenuProps[] = [];
+        const dataDoc = this.props.DataDoc || this.props.Document;
+
+        DocUtils.addDocumentCreatorMenuItems((doc) => {
+            FormattedTextBox.SelectOnLoad = doc[Id];
+            return this.props.addDocument?.(doc);
+        }, this.props.addDocument, x, y, true);
+
+        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey =>
+            docItems.push({
+                description: ":" + fieldKey, event: () => {
+                    const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
+                    if (created) {
+                        if (this.props.Document.isTemplateDoc) {
+                            Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+                        }
+                        return this.props.addDocument?.(created);
+                    }
+                }, icon: "compress-arrows-alt"
+            }));
+        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => DocListCast(dataDoc[fieldKey]).length).map(fieldKey =>
+            docItems.push({
+                description: ":" + fieldKey, event: () => {
+                    const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
+                    if (created) {
+                        const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
+                        if (container.isTemplateDoc) {
+                            Doc.MakeMetadataFieldTemplate(created, container);
+                            return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+                        }
+                        return this.props.addDocument?.(created) || false;
+                    }
+                }, icon: "compress-arrows-alt"
+            }));
+        !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" });
+        !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" });
+        ContextMenu.Instance.setDefaultItem("::", (name: string): void => {
+            Doc.GetProto(this.props.Document)[name] = "";
+            const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true });
+            if (created) {
+                if (this.props.Document.isTemplateDoc) {
+                    Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+                }
+                this.props.addDocument?.(created);
+            }
+        });
+        const pt = this.props.screenToLocalTransform().inverse().transformPoint(x, y);
+        ContextMenu.Instance.displayMenu(x, y, undefined, true);
+    }
+    @computed get innards() {
+        TraceMobx();
+        const key = this.props.pivotField;
+        const headings = this.props.headings();
+        const heading = this._heading;
+        const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin;
+        const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
+        const evContents = heading ? heading : this.props?.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
+        const headingView = this.props.headingObject ?
+            <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
+                style={{
+                    marginTop: this.props.yMargin,
+                    width: (this.props.columnWidth) /
+                        ((uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1)) || 1)
+                }}>
+                <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
+                {/* the default bucket (no key value) has a tooltip that describes what it is.
+                    Further, it does not have a color and cannot be deleted. */}
+                <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
+                    title={evContents === `NO ${key.toUpperCase()} VALUE` ?
+                        `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
+                    style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "inherit" }}>
+                    <EditableView
+                        GetValue={() => evContents}
+                        SetValue={this.headingChanged}
+                        contents={evContents}
+                        oneLine={true}
+                        toggle={this.toggleVisibility} />
+                    {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+                        <div className="collectionStackingView-sectionColor">
+                            <button className="collectionStackingView-sectionColorButton" onClick={action(e => this._paletteOn = !this._paletteOn)}>
+                                <FontAwesomeIcon icon="palette" size="lg" />
+                            </button>
+                            {this._paletteOn ? this.renderColorPicker() : (null)}
+                        </div>
+                    }
+                    {<button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
+                        <FontAwesomeIcon icon="trash" size="lg" />
+                    </button>}
+                    {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
+                        <div className="collectionStackingView-sectionOptions">
+                            <Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
+                                <button className="collectionStackingView-sectionOptionButton">
+                                    <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
+                                </button>
+                            </Flyout>
+                        </div>
+                    }
+                </div>
+            </div> : (null);
+        const templatecols = `${this.props.columnWidth / this.props.numGroupColumns}px `;
+        const type = this.props.Document.type;
+        return <>
+            {this.props.Document._columnsHideIfEmpty ? (null) : headingView}
+            {
+                this.collapsed ? (null) :
+                    <div>
+                        <div key={`${heading}-stack`} className={`collectionStackingView-masonrySingle`}
+                            style={{
+                                padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`,
+                                margin: "auto",
+                                width: "max-content", //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
+                                height: 'max-content',
+                                position: "relative",
+                                gridGap: this.props.gridGap,
+                                gridTemplateColumns: templatecols,
+                                gridAutoRows: "0px"
+                            }}>
+                            {this.props.renderChildren(this.props.docList)}
+                        </div>
+                        {!this.props.chromeHidden && type !== DocumentType.PRES ?
+                        // TODO: this is the "new" button: see what you can work with here
+                        // change cursor to pointer for this, and update dragging cursor
+                        //TODO: there is a bug that occurs when adding a freeform document and trying to move it around 
+                        //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
+                        // bottom note
+                        //TODO: ok, so we are using a single column, and this is it!
+                            <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
+                                style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10, marginLeft: 25 }}>
+                                <EditableView
+                                    GetValue={returnEmptyString}
+                                    SetValue={this.addNewTextDoc}
+                                    textCallback={this.textCallback}
+                                    placeholder={"Type ':' for commands"}
+                                    contents={<FontAwesomeIcon icon={"plus"}/>}
+                                    toggle={this.toggleVisibility}
+                                    menuCallback={this.menuCallback} 
+                                />
+                            </div> : null}
+                    </div>
+            }
+        </>;
+    }
+
+
+    render() {
+        TraceMobx();
+        const headings = this.props.headings();
+        const heading = this._heading;
+        const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
+        return (
+            <div className={"collectionStackingViewFieldColumn" + (SnappingManager.GetIsDragging() ? "Dragging" : "")} key={heading}
+                style={{
+                    width: `${100 / (uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1) || 1)}%`,
+                    height: undefined, // DraggingManager.GetIsDragging() ? "100%" : undefined,
+                    background: this._background
+                }}
+                ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
+                {this.innards}
+            </div >
+        );
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 419b9a943..9d83e13de 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { CursorProperty } from "csstype";
 import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { DataSym, Doc, HeightSym, Opt, WidthSym, DocListCast } from "../../../fields/Doc";
+import { DataSym, Doc, HeightSym, Opt, WidthSym, DocListCast, AclSym, FieldsSym, Initializing, LayoutSym, DirectLinksSym } from "../../../fields/Doc";
 import { collectionSchema, documentSchema } from "../../../fields/documentSchemas";
 import { Id } from "../../../fields/FieldSymbols";
 import { List } from "../../../fields/List";
@@ -31,6 +31,7 @@ import { CollectionSubView } from "./CollectionSubView";
 import { CollectionViewType } from "./CollectionView";
 import { FontIconBox } from "../nodes/button/FontIconBox";
 import { CurrentUserUtils } from "../../util/CurrentUserUtils";
+import internal = require("events");
 const _global = (window /* browser */ || global /* node */) as any;
 
 type StackingDocument = makeInterface<[typeof collectionSchema, typeof documentSchema]>;
@@ -38,6 +39,7 @@ const StackingDocument = makeInterface(collectionSchema, documentSchema);
 
 export type collectionStackingViewProps = {
     chromeHidden?: boolean;
+    // view type is stacking
     viewType?: CollectionViewType;
     NativeWidth?: () => number;
     NativeHeight?: () => number;
@@ -45,53 +47,78 @@ export type collectionStackingViewProps = {
 
 @observer
 export class CollectionStackingView extends CollectionSubView<StackingDocument, Partial<collectionStackingViewProps>>(StackingDocument) {
+    // do we need a masonry grid here? We think that they are sharing data
     _masonryGridRef: HTMLDivElement | null = null;
+    // used in a column dragger, likely due for the masonry grid view. We want to use this 
     _draggerRef = React.createRef<HTMLDivElement>();
+    // Not sure what a pivot field is. Seems like we cause reaction in MobX get rid of it once we exit this view
     _pivotFieldDisposer?: IReactionDisposer;
+    // Seems like we cause reaction in MobX get rid of our height once we exit this view
     _autoHeightDisposer?: IReactionDisposer;
+    // keeping track of documents. Updated on internal and external drops. What's the difference?
     _docXfs: { height: () => number, width: () => number, stackedDocTransform: () => Transform }[] = [];
+    // Doesn't look like this field is being used anywhere. Obsolete?
     _columnStart: number = 0;
+    // map of node headers to their heights. Used in Masonry
     @observable _heightMap = new Map<string, number>();
+    // Assuming that this is the current css cursor style
     @observable _cursor: CursorProperty = "grab";
+    // gets reset whenever we scroll. Not sure what it is
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
+    // does this mean whether the browser is hidden? Or is chrome something else entirely?
     @computed get chromeHidden() { return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden); }
+    // it looks like this gets the column headers that Mehek was showing just now
     @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null); }
+    // Still not sure what a pivot is, but it appears that we can actually filter docs somehow?
     @computed get pivotField() { return StrCast(this.layoutDoc._pivotField); }
+    // filteredChildren is what you want to work with. It's the list of things that you're currently displaying
     @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); }
+    // how much margin we give the header
     @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); }
     @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
     @computed get yMargin() { return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); }
     @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); }
-    @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === CollectionViewType.Stacking; }
+    // are we stacking or masonry?
+    @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking); }
+    // this is the number of StackingViewFieldColumns that we have
     @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
+    // reveals a button to add a group in masonry view
     @computed get showAddAGroup() { return this.pivotField && !this.chromeHidden; }
     // columnWidth handles the margin on the left and right side of the documents
     @computed get columnWidth() {
         return Math.min(this.props.PanelWidth() - 2 * this.xMargin,
             this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
     }
+    
     @computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; }
 
     constructor(props: any) {
         super(props);
 
         if (this.columnHeaders === undefined) {
+          // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out?
+          // here we're making an empty list of column headers (again, what Mehek showed us)
             this.layoutDoc._columnHeaders = new List<SchemaHeaderField>();
         }
     }
 
     // TODO: plj - these are the children
     children = (docs: Doc[]) => {
+      //TODO: can somebody explain me to what exactly TraceMobX is?
         TraceMobx();
+        // appears that we are going to reset the _docXfs. TODO: what is Xfs?
         this._docXfs.length = 0;
         // Go through each of the documents that are contained
         return docs.map((d, i) => {
             const height = () => this.getDocHeight(d);
             const width = () => this.getDocWidth(d);
+            // assuming we need to get rowSpan because we might be dealing with many columns. Grid gap makes sense if multiple columns
             const rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
+            // just getting the style
             const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+            // So we're choosing whether we're going to render a column or a masonry doc
             return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} style={style} >
-                <div className="hoverButtons">
+                {/* <div className="hoverButtons"> */}
                   {/* We'll want to add an onPointerDown that uses DragManager.DocumentDragData
                    -- we also want to remember to preventDefault (so other drag events are not recognized over this one)
                    -- Design discussion as to whether we want dragging to be on the document itself or with a drag button
@@ -100,11 +127,12 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                    the same functionality?
                    -- Problem: This only shows when the outer container is selected...
                   */}
-                  <div className="buttonWrapper">
-                    <FontAwesomeIcon icon={"grip-vertical"} onPointerDown={e => e.stopPropagation()} />
+                  {/* <div className="buttonWrapper">
+                    <FontAwesomeIcon icon={"grip-vertical"} onPointerDown={ e => e.stopPropagation()} />
                   </div>
-                </div>
-                {this.getDisplayDoc(d, width)}
+                </div> */}
+                {/* some sort of filtering is being done here to actually get layout and make the doc look pretty*/}
+                {this.getDisplayDoc(d, width)} 
             </div>
         });
     }
@@ -113,7 +141,10 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         this._heightMap.set(key, sectionHeight);
     }
 
+    // is sections that all collections inherit? I think this is how we show the masonry/columns
+    //TODO: this seems important
     get Sections() {
+        // appears that pivot field IS actually for sorting
         if (!this.pivotField || this.columnHeaders instanceof Promise) return new Map<SchemaHeaderField, Doc[]>();
 
         if (this.columnHeaders === undefined) {
@@ -142,6 +173,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             }
         });
         // remove all empty columns if hideHeadings is set
+        // we will want to have something like this, so that we can hide columns and add them back in
         if (this.layoutDoc._columnsHideIfEmpty) {
             Array.from(fields.keys()).filter(key => !fields.get(key)!.length).map(header => {
                 fields.delete(header);
@@ -161,6 +193,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             () => this.pivotField,
             () => this.layoutDoc._columnHeaders = new List()
         );
+        //TODO: where the heck are we getting filters from?
         this._autoHeightDisposer = reaction(() => this.layoutDoc._autoHeight,
             autoHeight => autoHeight && this.props.setHeight(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
                 this.headerMargin + (this.isStackingView ?
@@ -198,6 +231,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         smoothScroll(500, this._mainCont!, this._mainCont!.scrollHeight);
     }
 
+    // let's dive in and get the actual document we want to drag/move around
     focusDocument = (doc: Doc, options?: DocFocusOptions) => {
         Doc.BrushDoc(doc);
 
@@ -229,6 +263,9 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         return this.props.styleProvider?.(doc, props, property);
     }
     isContentActive = () => this.props.isSelected() || this.props.isContentActive();
+
+    // this is what renders the document that you see on the screen
+    // called in Children: this actually adds a document to our children list
     getDisplayDoc(doc: Doc, width: () => number) {
         const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc;
         const height = () => this.getDocHeight(doc);
@@ -236,6 +273,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         let dref: Opt<DocumentView>;
         const stackedDocTransform = () => this.getDocTransform(doc, dref);
         this._docXfs.push({ stackedDocTransform, width, height });
+        //DocumentView is how the node will be rendered
         return <DocumentView ref={r => dref = r || undefined}
             Document={doc}
             DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
@@ -322,6 +360,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         return Math.min(childHeight, maxHeight, panelHeight);
     }
 
+    // This following three functions must be from the view Mehek showed
     columnDividerDown = (e: React.PointerEvent) => {
         runInAction(() => this._cursor = "grabbing");
         setupMoveUpEvents(this, e, this.onDividerMove, action(() => this._cursor = "grab"), emptyFunction);
@@ -342,20 +381,43 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
     // TODO: plj
     @action
     onPointerOver = (e: React.PointerEvent) => {
-      if (DragManager.docsBeingDragged.length){
-        console.log(DragManager.docsBeingDragged[0].title)
+      // console.log("hovering over something")
+      if (DragManager.docsBeingDragged.length) {
+        // essentially copying code from onInternalDrop for this:
+        const doc = DragManager.docsBeingDragged[0]
+        // console.log(doc[LayoutSym]())
+
+        console.log(doc[DataSym])
+        console.log(Doc.IndexOf(doc, this.childDocs))
+
       }
+      
+
+    }
+
+    //used in onPointerOver to swap two nodes in the rendered filtered children list
+    swapNodes = (i: number, j: number) => {
+      
+    }
+
+    //plj added this 
+    @action
+    onPointerDown = (e: React.PointerEvent) => {
+
     }
 
-    // TODO: plj - look at this
+    // TODO: plj - look at this. Start with making changes to db, and then transition to client side 
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+      // Fairly confident that this is where the swapping of nodes in the various arrays happens
         console.log('drop')
         const where = [de.x, de.y];
+        // start at -1 until we're sure we want to add it to the column
         let dropInd = -1;
         let dropAfter = 0;
         if (de.complete.docDragData) {
+            // going to re-add the docs to the _docXFs based on position of where we just dropped
             this._docXfs.map((cd, i) => {
                 const pos = cd.stackedDocTransform().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
                 const pos1 = cd.stackedDocTransform().inverse().transformPoint(cd.width(), cd.height());
@@ -367,11 +429,14 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             });
             const oldDocs = this.childDocs.length;
             if (super.onInternalDrop(e, de)) {
+              // check to see if we actually need anything to the new column of nodes (if droppedDocs != empty)
                 const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
                 const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments; // if nothing was added to the end of the list, then presumably the dropped documents were already in the list, but possibly got reordered so we use them.
 
                 const docs = this.childDocList;
+                // reset drag manager docs, because we just dropped
                 DragManager.docsBeingDragged = [];
+                // still figuring out where to add the document
                 if (docs && newDocs.length) {
                     const insertInd = dropInd === -1 ? docs.length : dropInd + dropAfter;
                     const offset = newDocs.reduce((off, ndoc) => this.filteredChildren.find((fdoc, i) => ndoc === fdoc && i < insertInd) ? off + 1 : off, 0);
@@ -379,7 +444,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                     docs.splice(insertInd - offset, 0, ...newDocs);
                 }
             }
-        }
+        } // it seems like we're creating a link here. Weird. I didn't know that you could establish links by dragging
         else if (de.complete.linkDragData?.dragDocument.context === this.props.Document && de.complete.linkDragData?.linkDragView?.props.CollectionFreeFormDocumentView?.()) {
             const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, _fitWidth: true, title: "dropped annotation" });
             this.props.addDocument?.(source);
@@ -402,6 +467,8 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
 
     @undoBatch
     @action
+    //What is the difference between internal and external drop?? Does internal mean we're dropping inside of a collection?
+    // I take it back: external drop means we took it out of column/collection that we were just in
     onExternalDrop = async (e: React.DragEvent): Promise<void> => {
         console.log('external drop')
         const where = [e.clientX, e.clientY];
@@ -424,8 +491,10 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             }
         });
     }
+    // sections are important 
     headings = () => Array.from(this.Sections);
     refList: any[] = [];
+    // what a section looks like if we're in stacking view
     sectionStacking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
         const key = this.pivotField;
         let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
@@ -435,6 +504,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                 type = types[0];
             }
         }
+        //TODO: I think that we only have one of these atm
         return <CollectionStackingViewFieldColumn
             unobserveHeight={ref => this.refList.splice(this.refList.indexOf(ref), 1)}
             observeHeight={ref => {
@@ -475,6 +545,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         />;
     }
 
+    // what a section looks like if we're in masonry. Shouldn't actually need to use this.
     sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[], first: boolean) => {
         const key = this.pivotField;
         let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
@@ -517,6 +588,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
     }
 
     @action
+    // What are we adding a group to?
     addGroup = (value: string) => {
         if (value && this.columnHeaders) {
             const schemaHdrField = new SchemaHeaderField(value);
@@ -545,6 +617,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         }
     }
 
+    // 
     @computed get renderedSections() {
         TraceMobx();
         let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
@@ -552,6 +625,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
             const entries = Array.from(this.Sections.entries());
             sections = this.layoutDoc._columnsSort ? entries.sort(this.sortFunc) : entries;
         }
+        // a section will have a header and a list of docs. Ok cool.
         return sections.map((section, i) => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1], i === 0));
     }
 
@@ -609,6 +683,7 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
         const editableViewProps = {
             GetValue: () => "",
             SetValue: this.addGroup,
+            // I don't recall ever seeing this add a group button
             contents: "+ ADD A GROUP"
         };
         const buttonMenu = this.rootDoc.buttonMenu;
@@ -634,10 +709,15 @@ export class CollectionStackingView extends CollectionSubView<StackingDocument,
                         }}
                         onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
                         onPointerOver={this.onPointerOver}
+                        onPointerDown={this.onPointerDown}
                         onDrop={this.onExternalDrop.bind(this)}
                         onContextMenu={this.onContextMenu}
+                        // Todo: what is wheel? Are we talking about a mouse wheel?
                         onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} >
+                        {/* so it appears that we are actually rendering the sections. Maybe this is what we're looking for? */}
                         {this.renderedSections}
+                        {/* I think that showAddGroup must be passed in as false, which is why we can't find what Mehek showed 
+                        Or it's because we aren't passing a pivot field */}
                         {!this.showAddAGroup ? (null) :
                             <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
                                 style={{ width: !this.isStackingView ? "100%" : this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 1a27be764..c191445e7 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -26,6 +26,7 @@ const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
 
+// So this is how we are storing a column
 interface CSVFieldColumnProps {
     Document: Doc;
     DataDoc: Opt<Doc>;
@@ -41,6 +42,7 @@ interface CSVFieldColumnProps {
     gridGap: number;
     type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
     headings: () => object[];
+    // I think that stacking view actually has a single column and then supposedly you can add more columns? Unsure
     renderChildren: (docs: Doc[]) => JSX.Element[];
     addDocument: (doc: Doc | Doc[]) => boolean;
     createDropTarget: (ele: HTMLDivElement) => void;
@@ -61,6 +63,8 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
     _ele: HTMLElement | null = null;
 
+    // This is likely similar to what we will be doing. Why do we need to make these refs?
+    // is that the only way to have drop targets?
     createColumnDropRef = (ele: HTMLDivElement | null) => {
         this.dropDisposer?.();
         if (ele) {
@@ -73,6 +77,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         this.props.unobserveHeight(this._ele);
     }
 
+    //TODO: what is scripting? I found it in SetInPlace def but don't know what that is
     @undoBatch
     columnDrop = action((e: Event, de: DragManager.DropEvent) => {
         const drop = { docs: de.complete.docDragData?.droppedDocuments, val: this.getValue(this._heading) };
@@ -146,6 +151,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     //TODO: I think this is where I'm supposed to edit stuff 
     startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
+        // is MakeAlias a way to make a copy of a doc without rendering it?
         const alias = Doc.MakeAlias(this.props.Document);
         alias._width = this.props.columnWidth / (this.props.columnHeaders?.length || 1);
         alias._pivotField = undefined;
@@ -314,6 +320,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                         //TODO: there is a bug that occurs when adding a freeform document and trying to move it around 
                         //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
                         // bottom note
+                        //TODO: ok, so we are using a single column, and this is it!
                             <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
                                 style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10, marginLeft: 25 }}>
                                 <EditableView
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 681a15e3d..6f94efa41 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -37,9 +37,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import './CollectionView.scss';
 import { returnEmptyString } from '../../../Utils';
 import { InkTool } from '../../../fields/InkField';
+import { CollectionNoteTakingView } from './CollectionNoteTakingView';
 export const COLLECTION_BORDER_WIDTH = 2;
 const path = require('path');
 
+//TODO: see everywhere that this exists
 export enum CollectionViewType {
     Invalid = "invalid",
     Freeform = "freeform",
@@ -58,7 +60,8 @@ export enum CollectionViewType {
     Map = "map",
     Grid = "grid",
     Pile = "pileup",
-    StackedTimeline = "stacked timeline"
+    StackedTimeline = "stacked timeline",
+    NoteTaking = "notetaking"
 }
 export interface CollectionViewProps extends FieldViewProps {
     isAnnotationOverlay?: boolean;  // is the collection an annotation overlay (eg an overlay on an image/video/etc)
@@ -142,6 +145,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
             case CollectionViewType.Carousel: return <CollectionCarouselView key="collview" {...props} />;
             case CollectionViewType.Carousel3D: return <CollectionCarousel3DView key="collview" {...props} />;
             case CollectionViewType.Stacking: return <CollectionStackingView key="collview" {...props} />;
+            case CollectionViewType.NoteTaking: return <CollectionNoteTakingView key="collview" {...props} />;
             case CollectionViewType.Masonry: return <CollectionStackingView key="collview" {...props} />;
             case CollectionViewType.Time: return <CollectionTimeView key="collview" {...props} />;
             case CollectionViewType.Grid: return <CollectionGridView key="collview" {...props} />;
@@ -158,6 +162,7 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
         subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" });
         subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" });
         subItems.push({ description: "Stacking", event: () => func(CollectionViewType.Stacking)._autoHeight = true, icon: "ellipsis-v" });
+        subItems.push({ description: "Note taking", event: () => func(CollectionViewType.NoteTaking)._autoHeight = true, icon: "ellipsis-v" });
         subItems.push({ description: "Multicolumn", event: () => func(CollectionViewType.Multicolumn), icon: "columns" });
         subItems.push({ description: "Multirow", event: () => func(CollectionViewType.Multirow), icon: "columns" });
         subItems.push({ description: "Masonry", event: () => func(CollectionViewType.Masonry), icon: "columns" });
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index eedb353e3..f30a6ac67 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -214,6 +214,7 @@ export class TreeView extends React.Component<TreeViewProps> {
         document.removeEventListener("pointerup", this.onDragUp, true);
         document.removeEventListener("pointermove", this.onDragMove, true);
     }
+    // TODO: Parker look at this
     onDragMove = (e: PointerEvent): void => {
         Doc.UnBrushDoc(this.dataDoc);
         const pt = [e.clientX, e.clientY];
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 0d5fedb7b..5e5f6cd74 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -7,6 +7,7 @@ import { Id } from '../../../../fields/FieldSymbols';
 import { emptyFunction, OmitKeys, returnEmptyFilter, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents } from '../../../../Utils';
 import { Docs } from '../../../documents/Documents';
 import { DocumentType } from '../../../documents/DocumentTypes';
+import { CollectionNoteTakingView } from '../../collections/CollectionNoteTakingView';
 import { CollectionStackingView } from '../../collections/CollectionStackingView';
 import { CollectionViewType } from '../../collections/CollectionView';
 import { ViewBoxAnnotatableProps } from '../../DocComponent';
@@ -44,7 +45,7 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
     }
 
 
-    _stack: CollectionStackingView | null | undefined;
+    _stack: CollectionStackingView | CollectionNoteTakingView | null | undefined;
 
     // Collection stacking view for documents in the infowindow of a map marker
     @computed get renderChildDocs() {
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index bd103dcf7..423318519 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -259,7 +259,7 @@ export class FontIconBox extends DocComponent<ButtonProps, FontIconDocument>(Fon
                 icon = "globe-asia";
                 text = "User Default";
             }
-            noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking];
+            noviceList = [CollectionViewType.Freeform, CollectionViewType.Schema, CollectionViewType.Stacking, CollectionViewType.NoteTaking];
         } else if (script === 'setFont') {
             const editorView = RichTextMenu.Instance?.TextView?.EditorView;
             text = StrCast((editorView ? RichTextMenu.Instance : Doc.UserDoc()).fontFamily);
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 14d6e8be6..b08955b48 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -113,6 +113,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
     @computed get activeItem() { return Cast(this.childDocs[NumCast(this.rootDoc._itemIndex)], Doc, null); }
     @computed get targetDoc() { return Cast(this.activeItem?.presentationTargetDoc, Doc, null); }
     @computed get scrollable(): boolean {
+      //TODO: likely do NOT have to update this for note-taking view, but still worth putting here
         if (this.targetDoc.type === DocumentType.PDF || this.targetDoc.type === DocumentType.WEB || this.targetDoc.type === DocumentType.RTF || this.targetDoc._viewType === CollectionViewType.Stacking) return true;
         else return false;
     }
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 8a5491b4b..6b71ed24f 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -216,7 +216,7 @@ export class Doc extends RefField {
         return self.resolvedDataDoc && !self.isTemplateForField ? self :
             Doc.GetProto(Cast(Doc.Layout(self).resolvedDataDoc, Doc, null) || self);
     }
-    @computed get __LAYOUT__() {
+    @computed get __LAYOUT__(): any {
         const templateLayoutDoc = Cast(Doc.LayoutField(this[SelfProxy]), Doc, null);
         if (templateLayoutDoc) {
             let renderFieldKey: any;
-- 
cgit v1.2.3-70-g09d2


From bb907c6c10c1515c555c0ad12bd2eebb17edfb73 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 3 Aug 2022 09:24:34 -0400
Subject: from last

---
 .../views/collections/CollectionStackingView.tsx   | 211 +++++++------
 .../CollectionStackingViewFieldColumn.tsx          | 335 +++++++++++----------
 src/client/views/collections/CollectionView.tsx    |  24 +-
 3 files changed, 308 insertions(+), 262 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ff7594e5a..d3a8af03a 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -43,62 +43,85 @@ export type collectionStackingViewProps = {
 @observer
 export class CollectionStackingView extends CollectionSubView<Partial<collectionStackingViewProps>>() {
     _masonryGridRef: HTMLDivElement | null = null;
-    // used in a column dragger, likely due for the masonry grid view. We want to use this 
+    // used in a column dragger, likely due for the masonry grid view. We want to use this
     _draggerRef = React.createRef<HTMLDivElement>();
     // Not sure what a pivot field is. Seems like we cause reaction in MobX get rid of it once we exit this view
     _pivotFieldDisposer?: IReactionDisposer;
     // Seems like we cause reaction in MobX get rid of our height once we exit this view
     _autoHeightDisposer?: IReactionDisposer;
     // keeping track of documents. Updated on internal and external drops. What's the difference?
-    _docXfs: { height: () => number, width: () => number, stackedDocTransform: () => Transform }[] = [];
+    _docXfs: { height: () => number; width: () => number; stackedDocTransform: () => Transform }[] = [];
     // Doesn't look like this field is being used anywhere. Obsolete?
     _columnStart: number = 0;
     // map of node headers to their heights. Used in Masonry
     @observable _heightMap = new Map<string, number>();
     // Assuming that this is the current css cursor style
-    @observable _cursor: CursorProperty = "grab";
+    @observable _cursor: CursorProperty = 'grab';
     // gets reset whenever we scroll. Not sure what it is
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
     // does this mean whether the browser is hidden? Or is chrome something else entirely?
-    @computed get chromeHidden() { return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden); }
+    @computed get chromeHidden() {
+        return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
+    }
     // it looks like this gets the column headers that Mehek was showing just now
-    @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null); }
+    @computed get columnHeaders() {
+        return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null);
+    }
     // Still not sure what a pivot is, but it appears that we can actually filter docs somehow?
-    @computed get pivotField() { return StrCast(this.layoutDoc._pivotField); }
+    @computed get pivotField() {
+        return StrCast(this.layoutDoc._pivotField);
+    }
     // filteredChildren is what you want to work with. It's the list of things that you're currently displaying
-    @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); }
+    @computed get filteredChildren() {
+        return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout);
+    }
     // how much margin we give the header
-    @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); }
-    @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
-    @computed get yMargin() { return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); }
-    @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); }
+    @computed get headerMargin() {
+        return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin);
+    }
+    @computed get xMargin() {
+        return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, 0.05 * this.props.PanelWidth()));
+    }
+    @computed get yMargin() {
+        return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5);
+    } // 2 * this.gridGap)); }
+    @computed get gridGap() {
+        return NumCast(this.layoutDoc._gridGap, 10);
+    }
     // are we stacking or masonry?
-    @computed get isStackingView() { return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking); }
+    @computed get isStackingView() {
+        return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking);
+    }
     // this is the number of StackingViewFieldColumns that we have
-    @computed get numGroupColumns() { return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1; }
+    @computed get numGroupColumns() {
+        return this.isStackingView ? Math.max(1, this.Sections.size + (this.showAddAGroup ? 1 : 0)) : 1;
+    }
     // reveals a button to add a group in masonry view
-    @computed get showAddAGroup() { return this.pivotField && !this.chromeHidden; }
+    @computed get showAddAGroup() {
+        return this.pivotField && !this.chromeHidden;
+    }
     // columnWidth handles the margin on the left and right side of the documents
     @computed get columnWidth() {
-        return Math.min(this.props.PanelWidth() - 2 * this.xMargin,
-            this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
+        return Math.min(this.props.PanelWidth() - 2 * this.xMargin, this.isStackingView ? Number.MAX_VALUE : this.layoutDoc._columnWidth === -1 ? this.props.PanelWidth() - 2 * this.xMargin : NumCast(this.layoutDoc._columnWidth, 250));
+    }
+
+    @computed get NodeWidth() {
+        return this.props.PanelWidth() - this.gridGap;
     }
-    
-    @computed get NodeWidth() { return this.props.PanelWidth() - this.gridGap; }
 
     constructor(props: any) {
         super(props);
 
         if (this.columnHeaders === undefined) {
-          // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out?
-          // here we're making an empty list of column headers (again, what Mehek showed us)
+            // TODO: what is a layout doc? Is it literally how this document is supposed to be layed out?
+            // here we're making an empty list of column headers (again, what Mehek showed us)
             this.layoutDoc._columnHeaders = new List<SchemaHeaderField>();
         }
     }
 
     // TODO: plj - these are the children
     children = (docs: Doc[]) => {
-      //TODO: can somebody explain me to what exactly TraceMobX is?
+        //TODO: can somebody explain me to what exactly TraceMobX is?
         TraceMobx();
         // appears that we are going to reset the _docXfs. TODO: what is Xfs?
         this._docXfs.length = 0;
@@ -110,9 +133,11 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             // just getting the style
             const style = this.isStackingView ? { width: width(), marginTop: i ? this.gridGap : 0, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             // So we're choosing whether we're going to render a column or a masonry doc
-            return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} style={style} >
-                {this.getDisplayDoc(d, width)}
-            </div>;
+            return (
+                <div className={`collectionStackingView-${this.isStackingView ? 'columnDoc' : 'masonryDoc'}`} key={d[Id]} style={style}>
+                    {this.getDisplayDoc(d, width)}
+                </div>
+            );
         });
     };
     @action
@@ -288,49 +313,52 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         const stackedDocTransform = () => this.getDocTransform(doc, dref);
         this._docXfs.push({ stackedDocTransform, width, height });
         //DocumentView is how the node will be rendered
-        return <DocumentView ref={r => dref = r || undefined}
-            Document={doc}
-            DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
-            renderDepth={this.props.renderDepth + 1}
-            PanelWidth={width}
-            PanelHeight={height}
-            styleProvider={this.styleProvider}
-            docViewPath={this.props.docViewPath}
-            fitWidth={this.props.childFitWidth}
-            isContentActive={this.isChildContentActive}
-            onKey={this.onKeyDown}
-            isDocumentActive={this.isContentActive}
-            LayoutTemplate={this.props.childLayoutTemplate}
-            LayoutTemplateString={this.props.childLayoutString}
-            NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeWidth(doc) ? width : undefined}  // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
-            NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeHeight(doc) ? height : undefined}
-            dontCenter={this.props.childIgnoreNativeSize ? "xy" : undefined}
-            dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't autoHeight resize if dontRegisterView is set, but they need to.
+        return (
+            <DocumentView
+                ref={r => (dref = r || undefined)}
+                Document={doc}
+                DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
+                renderDepth={this.props.renderDepth + 1}
+                PanelWidth={width}
+                PanelHeight={height}
+                styleProvider={this.styleProvider}
+                docViewPath={this.props.docViewPath}
+                fitWidth={this.props.childFitWidth}
+                isContentActive={this.isChildContentActive}
+                onKey={this.onKeyDown}
+                isDocumentActive={this.isContentActive}
+                LayoutTemplate={this.props.childLayoutTemplate}
+                LayoutTemplateString={this.props.childLayoutString}
+                NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || (doc._fitWidth && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
+                NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || (doc._fitWidth && !Doc.NativeHeight(doc)) ? height : undefined}
+                dontCenter={this.props.childIgnoreNativeSize ? 'xy' : undefined}
+                dontRegisterView={BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)} // used to be true if DataDoc existed, but template textboxes won't autoHeight resize if dontRegisterView is set, but they need to.
                 rootSelected={this.rootSelected}
-            showTitle={this.props.childShowTitle}
-            dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
-            onClick={this.onChildClickHandler}
-            onDoubleClick={this.onChildDoubleClickHandler}
-            ScreenToLocalTransform={stackedDocTransform}
-            focus={this.focusDocument}
-            docFilters={this.childDocFilters}
-            hideDecorationTitle={this.props.childHideDecorationTitle?.()}
-            hideResizeHandles={this.props.childHideResizeHandles?.()}
-            hideTitle={this.props.childHideTitle?.()}
-            docRangeFilters={this.childDocRangeFilters}
-            searchFilterDocs={this.searchFilterDocs}
-            ContainingCollectionDoc={this.props.CollectionView?.props.Document}
-            ContainingCollectionView={this.props.CollectionView}
-            addDocument={this.props.addDocument}
-            moveDocument={this.props.moveDocument}
-            removeDocument={this.props.removeDocument}
-            contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
-            whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
-            addDocTab={this.addDocTab}
-            bringToFront={returnFalse}
-            scriptContext={this.props.scriptContext}
-            pinToPres={this.props.pinToPres}
-        />;
+                showTitle={this.props.childShowTitle}
+                dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
+                onClick={this.onChildClickHandler}
+                onDoubleClick={this.onChildDoubleClickHandler}
+                ScreenToLocalTransform={stackedDocTransform}
+                focus={this.focusDocument}
+                docFilters={this.childDocFilters}
+                hideDecorationTitle={this.props.childHideDecorationTitle?.()}
+                hideResizeHandles={this.props.childHideResizeHandles?.()}
+                hideTitle={this.props.childHideTitle?.()}
+                docRangeFilters={this.childDocRangeFilters}
+                searchFilterDocs={this.searchFilterDocs}
+                ContainingCollectionDoc={this.props.CollectionView?.props.Document}
+                ContainingCollectionView={this.props.CollectionView}
+                addDocument={this.props.addDocument}
+                moveDocument={this.props.moveDocument}
+                removeDocument={this.props.removeDocument}
+                contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
+                whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
+                addDocTab={this.addDocTab}
+                bringToFront={returnFalse}
+                scriptContext={this.props.scriptContext}
+                pinToPres={this.props.pinToPres}
+            />
+        );
     }
 
     getDocTransform(doc: Doc, dref?: DocumentView) {
@@ -345,10 +373,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         // TODO: pj - replace with a better way to calculate the margin
         let margin = 25;
         d.margin = 25;
-        if (this.columnWidth < 150){
-          margin = 0;
+        if (this.columnWidth < 150) {
+            margin = 0;
         }
-        const maxWidth = (this.columnWidth / this.numGroupColumns) - (margin * 2);
+        const maxWidth = this.columnWidth / this.numGroupColumns - margin * 2;
         if (!this.layoutDoc._columnsFill && !(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d))) {
             return Math.min(d[WidthSym](), maxWidth);
         }
@@ -399,37 +427,30 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     // TODO: plj
     @action
     onPointerOver = (e: React.PointerEvent) => {
-      // console.log("hovering over something")
-      if (DragManager.docsBeingDragged.length) {
-        // essentially copying code from onInternalDrop for this:
-        const doc = DragManager.docsBeingDragged[0]
-        // console.log(doc[LayoutSym]())
-
-        console.log(doc[DataSym])
-        console.log(Doc.IndexOf(doc, this.childDocs))
-
-      }
-      
-
-    }
+        // console.log("hovering over something")
+        if (DragManager.docsBeingDragged.length) {
+            // essentially copying code from onInternalDrop for this:
+            const doc = DragManager.docsBeingDragged[0];
+            // console.log(doc[LayoutSym]())
+
+            console.log(doc[DataSym]);
+            console.log(Doc.IndexOf(doc, this.childDocs));
+        }
+    };
 
     //used in onPointerOver to swap two nodes in the rendered filtered children list
-    swapNodes = (i: number, j: number) => {
-      
-    }
+    swapNodes = (i: number, j: number) => {};
 
-    //plj added this 
+    //plj added this
     @action
-    onPointerDown = (e: React.PointerEvent) => {
-
-    }
+    onPointerDown = (e: React.PointerEvent) => {};
 
-    // TODO: plj - look at this. Start with making changes to db, and then transition to client side 
+    // TODO: plj - look at this. Start with making changes to db, and then transition to client side
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
-      // Fairly confident that this is where the swapping of nodes in the various arrays happens
-        console.log('drop')
+        // Fairly confident that this is where the swapping of nodes in the various arrays happens
+        console.log('drop');
         const where = [de.x, de.y];
         // start at -1 until we're sure we want to add it to the column
         let dropInd = -1;
@@ -450,7 +471,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             });
             const oldDocs = this.childDocs.length;
             if (super.onInternalDrop(e, de)) {
-              // check to see if we actually need anything to the new column of nodes (if droppedDocs != empty)
+                // check to see if we actually need anything to the new column of nodes (if droppedDocs != empty)
                 const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= oldDocs); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
                 const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments; // if nothing was added to the end of the list, then presumably the dropped documents were already in the list, but possibly got reordered so we use them.
 
@@ -489,7 +510,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     //What is the difference between internal and external drop?? Does internal mean we're dropping inside of a collection?
     // I take it back: external drop means we took it out of column/collection that we were just in
     onExternalDrop = async (e: React.DragEvent): Promise<void> => {
-        console.log('external drop')
+        console.log('external drop');
         const where = [e.clientX, e.clientY];
         let targInd = -1;
         this._docXfs.map((cd, i) => {
@@ -641,7 +662,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         }
     };
 
-    // 
+    //
     @computed get renderedSections() {
         TraceMobx();
         let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index d29c0b183..7b268cd49 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -1,28 +1,28 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, DocListCast, Opt } from "../../../fields/Doc";
-import { RichTextField } from "../../../fields/RichTextField";
-import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { ScriptField } from "../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
-import { ImageField } from "../../../fields/URLField";
-import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, setupMoveUpEvents, returnFalse, returnEmptyString } from "../../../Utils";
-import { Docs, DocUtils } from "../../documents/Documents";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { DragManager } from "../../util/DragManager";
-import { SnappingManager } from "../../util/SnappingManager";
-import { Transform } from "../../util/Transform";
-import { undoBatch } from "../../util/UndoManager";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { EditableView } from "../EditableView";
-import "./CollectionStackingView.scss";
-import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
-import { Id } from "../../../fields/FieldSymbols";
-const higflyout = require("@hig/flyout");
+import React = require('react');
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { RichTextField } from '../../../fields/RichTextField';
+import { PastelSchemaPalette, SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { ScriptField } from '../../../fields/ScriptField';
+import { Cast, NumCast, StrCast } from '../../../fields/Types';
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
+import { emptyFunction, setupMoveUpEvents, returnFalse, returnEmptyString } from '../../../Utils';
+import { Docs, DocUtils } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DragManager } from '../../util/DragManager';
+import { SnappingManager } from '../../util/SnappingManager';
+import { Transform } from '../../util/Transform';
+import { undoBatch } from '../../util/UndoManager';
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
+import { EditableView } from '../EditableView';
+import './CollectionStackingView.scss';
+import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import { Id } from '../../../fields/FieldSymbols';
+const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
 
@@ -40,7 +40,7 @@ interface CSVFieldColumnProps {
     columnWidth: number;
     numGroupColumns: number;
     gridGap: number;
-    type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
+    type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined;
     headings: () => object[];
     // I think that stacking view actually has a single column and then supposedly you can add more columns? Unsure
     renderChildren: (docs: Doc[]) => JSX.Element[];
@@ -53,14 +53,14 @@ interface CSVFieldColumnProps {
 
 @observer
 export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldColumnProps> {
-    @observable private _background = "inherit";
+    @observable private _background = 'inherit';
 
     private dropDisposer?: DragManager.DragDropDisposer;
     private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
 
     @observable _paletteOn = false;
     @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
-    @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+    @observable _color = this.props.headingObject ? this.props.headingObject.color : '#f1efeb';
 
     _ele: HTMLElement | null = null;
 
@@ -73,7 +73,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             this.props.observeHeight(ele);
             this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
         }
-    }
+    };
 
     componentWillUnmount() {
         this.props.unobserveHeight(this._ele);
@@ -88,10 +88,10 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     getValue = (value: string): any => {
         const parsed = parseInt(value);
         if (!isNaN(parsed)) return parsed;
-        if (value.toLowerCase().indexOf("true") > -1) return true;
-        if (value.toLowerCase().indexOf("false") > -1) return false;
+        if (value.toLowerCase().indexOf('true') > -1) return true;
+        if (value.toLowerCase().indexOf('false') > -1) return false;
         return value;
-    }
+    };
 
     @action
     headingChanged = (value: string, shiftDown?: boolean) => {
@@ -100,7 +100,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             if (this.props.columnHeaders?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
                 return false;
             }
-            this.props.docList.forEach(d => d[this.props.pivotField] = castedValue);
+            this.props.docList.forEach(d => (d[this.props.pivotField] = castedValue));
             if (this.props.headingObject) {
                 this.props.headingObject.setHeading(castedValue.toString());
                 this._heading = this.props.headingObject.heading;
@@ -108,17 +108,17 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             return true;
         }
         return false;
-    }
+    };
 
     @action
     changeColumnColor = (color: string) => {
         this.props.headingObject?.setColor(color);
         this._color = color;
-    }
+    };
 
-    @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = "#b4b4b4");
-    @action pointerLeave = () => this._background = "inherit";
-    textCallback = (char: string) => this.addNewTextDoc("-typed text-", false, true);
+    @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4');
+    @action pointerLeave = () => (this._background = 'inherit');
+    textCallback = (char: string) => this.addNewTextDoc('-typed text-', false, true);
 
     @action
     addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
@@ -126,73 +126,78 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         const key = this.props.pivotField;
         const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _fitWidth: true, title: value, _autoHeight: true });
         newDoc[key] = this.getValue(this.props.heading);
-        const maxHeading = this.props.docList.reduce((maxHeading, doc) => NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading, 0);
+        const maxHeading = this.props.docList.reduce((maxHeading, doc) => (NumCast(doc.heading) > maxHeading ? NumCast(doc.heading) : maxHeading), 0);
         const heading = maxHeading === 0 || this.props.docList.length === 0 ? 1 : maxHeading === 1 ? 2 : 3;
         newDoc.heading = heading;
         FormattedTextBox.SelectOnLoad = newDoc[Id];
-        FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? "" : " ";
+        FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
         return this.props.addDocument?.(newDoc) || false;
-    }
+    };
 
     @action
     deleteColumn = () => {
-        this.props.docList.forEach(d => d[this.props.pivotField] = undefined);
+        this.props.docList.forEach(d => (d[this.props.pivotField] = undefined));
         if (this.props.columnHeaders && this.props.headingObject) {
             const index = this.props.columnHeaders.indexOf(this.props.headingObject);
             this.props.columnHeaders.splice(index, 1);
         }
-    }
+    };
 
     @action
     collapseSection = () => {
         this.props.headingObject?.setCollapsed(!this.props.headingObject.collapsed);
         this.toggleVisibility();
-    }
+    };
 
     headerDown = (e: React.PointerEvent<HTMLDivElement>) => setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
 
-    //TODO: I think this is where I'm supposed to edit stuff 
+    //TODO: I think this is where I'm supposed to edit stuff
     startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
         // is MakeAlias a way to make a copy of a doc without rendering it?
         const alias = Doc.MakeAlias(this.props.Document);
         alias._width = this.props.columnWidth / (this.props.columnHeaders?.length || 1);
         alias._pivotField = undefined;
         let value = this.getValue(this._heading);
-        value = typeof value === "string" ? `"${value}"` : value;
+        value = typeof value === 'string' ? `"${value}"` : value;
         alias.viewSpecScript = ScriptField.MakeFunction(`doc.${this.props.pivotField} === ${value}`, { doc: Doc.name });
         if (alias.viewSpecScript) {
             DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY);
             return true;
         }
         return false;
-    }
+    };
 
     renderColorPicker = () => {
-        const gray = "#f1efeb";
+        const gray = '#f1efeb';
         const selected = this.props.headingObject ? this.props.headingObject.color : gray;
-        const colors = ["pink2", "purple4", "bluegreen1", "yellow4", "gray", "red2", "bluegreen7", "bluegreen5", "orange1"];
-        return <div className="collectionStackingView-colorPicker">
-            <div className="colorOptions">
-                {colors.map(col => {
-                    const palette = PastelSchemaPalette.get(col);
-                    return <div className={"colorPicker" + (selected === palette ? " active" : "")}
-                        style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
-                })}
+        const colors = ['pink2', 'purple4', 'bluegreen1', 'yellow4', 'gray', 'red2', 'bluegreen7', 'bluegreen5', 'orange1'];
+        return (
+            <div className="collectionStackingView-colorPicker">
+                <div className="colorOptions">
+                    {colors.map(col => {
+                        const palette = PastelSchemaPalette.get(col);
+                        return <div className={'colorPicker' + (selected === palette ? ' active' : '')} style={{ backgroundColor: palette }} onClick={() => this.changeColumnColor(palette!)} />;
+                    })}
+                </div>
             </div>
-        </div>;
-    }
+        );
+    };
 
     renderMenu = () => {
-        return <div className="collectionStackingView-optionPicker">
-            <div className="optionOptions">
-                <div className={"optionPicker" + (true ? " active" : "")} onClick={action(() => { })}>Add options here</div>
+        return (
+            <div className="collectionStackingView-optionPicker">
+                <div className="optionOptions">
+                    <div className={'optionPicker' + (true ? ' active' : '')} onClick={action(() => {})}>
+                        Add options here
+                    </div>
+                </div>
             </div>
-        </div >;
-    }
+        );
+    };
 
     @observable private collapsed: boolean = false;
 
-    private toggleVisibility = action(() => this.collapsed = !this.collapsed);
+    private toggleVisibility = action(() => (this.collapsed = !this.collapsed));
 
     menuCallback = (x: number, y: number) => {
         ContextMenu.Instance.clearItems();
@@ -200,42 +205,58 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         const docItems: ContextMenuProps[] = [];
         const dataDoc = this.props.DataDoc || this.props.Document;
 
-        DocUtils.addDocumentCreatorMenuItems((doc) => {
-            FormattedTextBox.SelectOnLoad = doc[Id];
-            return this.props.addDocument?.(doc);
-        }, this.props.addDocument, x, y, true);
+        DocUtils.addDocumentCreatorMenuItems(
+            doc => {
+                FormattedTextBox.SelectOnLoad = doc[Id];
+                return this.props.addDocument?.(doc);
+            },
+            this.props.addDocument,
+            x,
+            y,
+            true
+        );
 
-        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey =>
-            docItems.push({
-                description: ":" + fieldKey, event: () => {
-                    const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
-                    if (created) {
-                        if (this.props.Document.isTemplateDoc) {
-                            Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+        Array.from(Object.keys(Doc.GetProto(dataDoc)))
+            .filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof dataDoc[fieldKey] === 'string')
+            .map(fieldKey =>
+                docItems.push({
+                    description: ':' + fieldKey,
+                    event: () => {
+                        const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
+                        if (created) {
+                            if (this.props.Document.isTemplateDoc) {
+                                Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+                            }
+                            return this.props.addDocument?.(created);
                         }
-                        return this.props.addDocument?.(created);
-                    }
-                }, icon: "compress-arrows-alt"
-            }));
-        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => DocListCast(dataDoc[fieldKey]).length).map(fieldKey =>
-            docItems.push({
-                description: ":" + fieldKey, event: () => {
-                    const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
-                    if (created) {
-                        const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
-                        if (container.isTemplateDoc) {
-                            Doc.MakeMetadataFieldTemplate(created, container);
-                            return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+                    },
+                    icon: 'compress-arrows-alt',
+                })
+            );
+        Array.from(Object.keys(Doc.GetProto(dataDoc)))
+            .filter(fieldKey => DocListCast(dataDoc[fieldKey]).length)
+            .map(fieldKey =>
+                docItems.push({
+                    description: ':' + fieldKey,
+                    event: () => {
+                        const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
+                        if (created) {
+                            const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
+                            if (container.isTemplateDoc) {
+                                Doc.MakeMetadataFieldTemplate(created, container);
+                                return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+                            }
+                            return this.props.addDocument?.(created) || false;
                         }
-                        return this.props.addDocument?.(created) || false;
-                    }
-                }, icon: "compress-arrows-alt"
-            }));
-        !Doc.noviceMode && ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" });
-        !Doc.noviceMode && ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" });
-        ContextMenu.Instance.setDefaultItem("::", (name: string): void => {
-            Doc.GetProto(this.props.Document)[name] = "";
-            const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true });
+                    },
+                    icon: 'compress-arrows-alt',
+                })
+            );
+        !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' });
+        !Doc.noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' });
+        ContextMenu.Instance.setDefaultItem('::', (name: string): void => {
+            Doc.GetProto(this.props.Document)[name] = '';
+            const created = Docs.Create.TextDocument('', { title: name, _width: 250, _autoHeight: true });
             if (created) {
                 if (this.props.Document.isTemplateDoc) {
                     Doc.MakeMetadataFieldTemplate(created, this.props.Document);
@@ -245,9 +266,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         });
         const pt = this.props.screenToLocalTransform().inverse().transformPoint(x, y);
         ContextMenu.Instance.displayMenu(x, y, undefined, true);
-    }
-
-
+    };
 
     @computed get innards() {
         TraceMobx();
@@ -256,39 +275,39 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         const heading = this._heading;
         const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin;
         const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
-        const evContents = heading ? heading : this.props?.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
-        const headingView = this.props.headingObject ?
-            <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
+        const evContents = heading ? heading : this.props?.type === 'number' ? '0' : `NO ${key.toUpperCase()} VALUE`;
+        const headingView = this.props.headingObject ? (
+            <div
+                key={heading}
+                className="collectionStackingView-sectionHeader"
+                ref={this._headerRef}
                 style={{
                     marginTop: this.props.yMargin,
-                    width: (this.props.columnWidth) /
-                        ((uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1)) || 1)
+                    width: this.props.columnWidth / (uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1) || 1),
                 }}>
-                <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
+                <div className={'collectionStackingView-collapseBar' + (this.props.headingObject.collapsed === true ? ' active' : '')} onClick={this.collapseSection}></div>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
                     Further, it does not have a color and cannot be deleted. */}
-                <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
-                    title={evContents === `NO ${key.toUpperCase()} VALUE` ?
-                        `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
-                    style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "inherit" }}>
-                    <EditableView
-                        GetValue={() => evContents}
-                        SetValue={this.headingChanged}
-                        contents={evContents}
-                        oneLine={true}
-                        toggle={this.toggleVisibility} />
-                    {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+                <div
+                    className="collectionStackingView-sectionHeader-subCont"
+                    onPointerDown={this.headerDown}
+                    title={evContents === `NO ${key.toUpperCase()} VALUE` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
+                    style={{ background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : 'inherit' }}>
+                    <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} toggle={this.toggleVisibility} />
+                    {evContents === `NO ${key.toUpperCase()} VALUE` ? null : (
                         <div className="collectionStackingView-sectionColor">
-                            <button className="collectionStackingView-sectionColorButton" onClick={action(e => this._paletteOn = !this._paletteOn)}>
+                            <button className="collectionStackingView-sectionColorButton" onClick={action(e => (this._paletteOn = !this._paletteOn))}>
                                 <FontAwesomeIcon icon="palette" size="lg" />
                             </button>
-                            {this._paletteOn ? this.renderColorPicker() : (null)}
+                            {this._paletteOn ? this.renderColorPicker() : null}
                         </div>
+                    )}
+                    {
+                        <button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
+                            <FontAwesomeIcon icon="trash" size="lg" />
+                        </button>
                     }
-                    {<button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
-                        <FontAwesomeIcon icon="trash" size="lg" />
-                    </button>}
-                    {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
+                    {evContents === `NO  ${key.toUpperCase()} VALUE` ? null : (
                         <div className="collectionStackingView-sectionOptions">
                             <Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
                                 <button className="collectionStackingView-sectionOptionButton">
@@ -296,70 +315,76 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                                 </button>
                             </Flyout>
                         </div>
-                    }
+                    )}
                 </div>
-            </div> : (null);
+            </div>
+        ) : null;
         const templatecols = `${this.props.columnWidth / this.props.numGroupColumns}px `;
         const type = this.props.Document.type;
-        return <>
-            {this.props.Document._columnsHideIfEmpty ? (null) : headingView}
-            {
-                this.collapsed ? (null) :
+        return (
+            <>
+                {this.props.Document._columnsHideIfEmpty ? null : headingView}
+                {this.collapsed ? null : (
                     <div>
-                        <div key={`${heading}-stack`} className={`collectionStackingView-masonrySingle`}
+                        <div
+                            key={`${heading}-stack`}
+                            className={`collectionStackingView-masonrySingle`}
                             style={{
                                 padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`,
-                                margin: "auto",
-                                width: "max-content", //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
+                                margin: 'auto',
+                                width: 'max-content', //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
                                 height: 'max-content',
-                                position: "relative",
+                                position: 'relative',
                                 gridGap: this.props.gridGap,
                                 gridTemplateColumns: templatecols,
-                                gridAutoRows: "0px"
+                                gridAutoRows: '0px',
                             }}>
                             {this.props.renderChildren(this.props.docList)}
                         </div>
-                        {!this.props.chromeHidden && type !== DocumentType.PRES ?
-                        // TODO: this is the "new" button: see what you can work with here
-                        // change cursor to pointer for this, and update dragging cursor
-                        //TODO: there is a bug that occurs when adding a freeform document and trying to move it around 
-                        //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
-                        // bottom note
-                        //TODO: ok, so we are using a single column, and this is it!
-                            <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
-                                style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10, marginLeft: 25 }}>
+                        {!this.props.chromeHidden && type !== DocumentType.PRES ? (
+                            // TODO: this is the "new" button: see what you can work with here
+                            // change cursor to pointer for this, and update dragging cursor
+                            //TODO: there is a bug that occurs when adding a freeform document and trying to move it around
+                            //TODO: would be great if there was additional space beyond the frame, so that you can actually see your
+                            // bottom note
+                            //TODO: ok, so we are using a single column, and this is it!
+                            <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton" style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10, marginLeft: 25 }}>
                                 <EditableView
                                     GetValue={returnEmptyString}
                                     SetValue={this.addNewTextDoc}
                                     textCallback={this.textCallback}
                                     placeholder={"Type ':' for commands"}
-                                    contents={<FontAwesomeIcon icon={"plus"}/>}
+                                    contents={<FontAwesomeIcon icon={'plus'} />}
                                     toggle={this.toggleVisibility}
-                                    menuCallback={this.menuCallback} />
+                                    menuCallback={this.menuCallback}
+                                />
                             </div>
-                            : null
-                        }
+                        ) : null}
                     </div>
-            }
-        </>;
+                )}
+            </>
+        );
     }
 
-
     render() {
         TraceMobx();
         const headings = this.props.headings();
         const heading = this._heading;
         const uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
         return (
-            <div className={"collectionStackingViewFieldColumn" + (SnappingManager.GetIsDragging() ? "Dragging" : "")} key={heading}
+            <div
+                className={'collectionStackingViewFieldColumn' + (SnappingManager.GetIsDragging() ? 'Dragging' : '')}
+                key={heading}
                 style={{
                     width: `${100 / (uniqueHeadings.length + (this.props.chromeHidden ? 0 : 1) || 1)}%`,
                     height: undefined, // DraggingManager.GetIsDragging() ? "100%" : undefined,
-                    background: this._background
+                    background: this._background,
                 }}
-                ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
+                ref={this.createColumnDropRef}
+                onPointerEnter={this.pointerEntered}
+                onPointerLeave={this.pointerLeave}>
                 {this.innards}
-            </div >
+            </div>
         );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 4ea675d35..1ee77d4ce 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -140,18 +140,18 @@ export class CollectionView extends ViewBoxAnnotatableComponent<ViewBoxAnnotatab
         if (addExtras && CollectionView._safeMode) {
             ContextMenu.Instance.addItem({ description: 'Test Freeform', event: () => func(CollectionViewType.Invalid), icon: 'project-diagram' });
         }
-        subItems.push({ description: "Schema", event: () => func(CollectionViewType.Schema), icon: "th-list" });
-        subItems.push({ description: "Tree", event: () => func(CollectionViewType.Tree), icon: "tree" });
-        subItems.push({ description: "Stacking", event: () => func(CollectionViewType.Stacking)._autoHeight = true, icon: "ellipsis-v" });
-        subItems.push({ description: "Notetaking", event: () => func(CollectionViewType.NoteTaking)._autoHeight = true, icon: "ellipsis-v" });
-        subItems.push({ description: "Multicolumn", event: () => func(CollectionViewType.Multicolumn), icon: "columns" });
-        subItems.push({ description: "Multirow", event: () => func(CollectionViewType.Multirow), icon: "columns" });
-        subItems.push({ description: "Masonry", event: () => func(CollectionViewType.Masonry), icon: "columns" });
-        subItems.push({ description: "Carousel", event: () => func(CollectionViewType.Carousel), icon: "columns" });
-        subItems.push({ description: "3D Carousel", event: () => func(CollectionViewType.Carousel3D), icon: "columns" });
-        !Doc.noviceMode && subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" });
-        !Doc.noviceMode && subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" });
-        subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "th-list" });
+        subItems.push({ description: 'Schema', event: () => func(CollectionViewType.Schema), icon: 'th-list' });
+        subItems.push({ description: 'Tree', event: () => func(CollectionViewType.Tree), icon: 'tree' });
+        subItems.push({ description: 'Stacking', event: () => (func(CollectionViewType.Stacking)._autoHeight = true), icon: 'ellipsis-v' });
+        subItems.push({ description: 'Notetaking', event: () => (func(CollectionViewType.NoteTaking)._autoHeight = true), icon: 'ellipsis-v' });
+        subItems.push({ description: 'Multicolumn', event: () => func(CollectionViewType.Multicolumn), icon: 'columns' });
+        subItems.push({ description: 'Multirow', event: () => func(CollectionViewType.Multirow), icon: 'columns' });
+        subItems.push({ description: 'Masonry', event: () => func(CollectionViewType.Masonry), icon: 'columns' });
+        subItems.push({ description: 'Carousel', event: () => func(CollectionViewType.Carousel), icon: 'columns' });
+        subItems.push({ description: '3D Carousel', event: () => func(CollectionViewType.Carousel3D), icon: 'columns' });
+        !Doc.noviceMode && subItems.push({ description: 'Pivot/Time', event: () => func(CollectionViewType.Time), icon: 'columns' });
+        !Doc.noviceMode && subItems.push({ description: 'Map', event: () => func(CollectionViewType.Map), icon: 'globe-americas' });
+        subItems.push({ description: 'Grid', event: () => func(CollectionViewType.Grid), icon: 'th-list' });
 
         if (!Doc.IsSystem(this.rootDoc) && !this.rootDoc.isGroup && !this.rootDoc.annotationOn) {
             const existingVm = ContextMenu.Instance.findByDescription(category);
-- 
cgit v1.2.3-70-g09d2


From 4ad4936393d11227934fdda2c18bea3446b20795 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 3 Aug 2022 09:52:05 -0400
Subject: more cleanup of parker branch

---
 .../views/collections/CollectionNoteTakingView.tsx | 842 +++++++++++----------
 .../views/collections/CollectionStackingView.scss  |  52 +-
 .../views/collections/CollectionStackingView.tsx   |  39 +-
 3 files changed, 452 insertions(+), 481 deletions(-)

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

diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index eb81f6e5e..f442559fb 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,35 +1,32 @@
-import React = require("react");
-import { CursorProperty } from "csstype";
-import { action, computed, IReactionDisposer, observable, reaction } from "mobx";
-import { observer } from "mobx-react";
-import { DataSym, Doc, HeightSym, Opt, WidthSym } from "../../../fields/Doc";
-import { Copy, Id, ToScriptString, ToString } from "../../../fields/FieldSymbols";
-import { List } from "../../../fields/List";
-import { listSpec } from "../../../fields/Schema";
-import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
-import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, returnZero, smoothScroll, Utils } from "../../../Utils";
-import { Docs, DocUtils } from "../../documents/Documents";
-import { DocumentType } from '../../documents/DocumentTypes';
-import { DragManager, dropActionType } from "../../util/DragManager";
-import { SnappingManager } from "../../util/SnappingManager";
-import { Transform } from "../../util/Transform";
-import { undoBatch } from "../../util/UndoManager";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { LightboxView } from "../LightboxView";
-import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from "../nodes/DocumentView";
-import { StyleProp } from "../StyleProvider";
-import "./CollectionNoteTakingView.scss";
-import CollectionNoteTakingViewDivider from "./CollectionNoteTakingViewDivider";
-import { CollectionNoteTakingViewColumn } from "./CollectionNoteTakingViewColumn";
-import { CollectionSubView } from "./CollectionSubView";
-import { CollectionViewType } from "./CollectionView";
-import { ObjectField } from "../../../fields/ObjectField";
-import { faThumbsDown } from "@fortawesome/free-solid-svg-icons";
-const _global = (window /* browser */ || global /* node */) as any;
+import React = require('react');
+import { CursorProperty } from 'csstype';
+import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { observer } from 'mobx-react';
+import { DataSym, Doc, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
+import { List } from '../../../fields/List';
+import { listSpec } from '../../../fields/Schema';
+import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
+import { TraceMobx } from '../../../fields/util';
+import { emptyFunction, returnEmptyDoclist, returnFalse, returnTrue, returnZero, smoothScroll, Utils } from '../../../Utils';
+import { Docs, DocUtils } from '../../documents/Documents';
+import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
+import { DragManager, dropActionType } from '../../util/DragManager';
+import { SnappingManager } from '../../util/SnappingManager';
+import { Transform } from '../../util/Transform';
+import { undoBatch } from '../../util/UndoManager';
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
+import { LightboxView } from '../LightboxView';
+import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
+import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from '../nodes/DocumentView';
+import { StyleProp } from '../StyleProvider';
+import './CollectionNoteTakingView.scss';
+import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
+import CollectionNoteTakingViewDivider from './CollectionNoteTakingViewDivider';
+import { CollectionSubView } from './CollectionSubView';
+const _global = (window /* browser */ || global) /* node */ as any;
 
 export type collectionNoteTakingViewProps = {
     chromeHidden?: boolean;
@@ -38,7 +35,7 @@ export type collectionNoteTakingViewProps = {
     NativeHeight?: () => number;
 };
 
-//TODO: somehow need to update the mapping and then have everything else rerender. Maybe with a refresh boolean like 
+//TODO: somehow need to update the mapping and then have everything else rerender. Maybe with a refresh boolean like
 // in Hypermedia?
 
 @observer
@@ -51,32 +48,54 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     // @observable _docsByColumnHeader = new Map<string, Doc[]>();
     //TODO: need to make sure that we save the mapping
     @observable docsDraggedRowCol: number[] = [];
-    @observable _cursor: CursorProperty = "grab";
+    @observable _cursor: CursorProperty = 'grab';
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
-    @computed get chromeHidden() { return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden); }
-    @computed get columnHeaders() { return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null); }
-    @computed get pivotField() { return "Col" }
-    @computed get filteredChildren() { return this.childLayoutPairs.filter(pair => (pair.layout instanceof Doc) && !pair.layout.hidden).map(pair => pair.layout); }
-    @computed get headerMargin() { return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin); }
-    @computed get xMargin() { return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, .05 * this.props.PanelWidth())); }
-    @computed get yMargin() { return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5); } // 2 * this.gridGap)); }
-    @computed get gridGap() { return NumCast(this.layoutDoc._gridGap, 10); }
-    @computed get numGroupColumns() { return this.columnHeaders.length; }
-    @observable columnStartXCoords: number[] = []
-    @computed get PanelWidth() {return this.props.PanelWidth()}
-    @computed get maxColWdith() {return this.props.PanelWidth() - 2 * this.xMargin;}
-
-    // If the user has not yet created any docs (in another view), this will create a single column. Otherwise, 
-    // it will adjust according to the 
+    @computed get chromeHidden() {
+        return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
+    }
+    @computed get columnHeaders() {
+        return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null);
+    }
+    @computed get pivotField() {
+        return 'Col';
+    }
+    @computed get filteredChildren() {
+        return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout);
+    }
+    @computed get headerMargin() {
+        return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin);
+    }
+    @computed get xMargin() {
+        return NumCast(this.layoutDoc._xMargin, 2 * Math.min(this.gridGap, 0.05 * this.props.PanelWidth()));
+    }
+    @computed get yMargin() {
+        return this.props.yPadding || NumCast(this.layoutDoc._yMargin, 5);
+    } // 2 * this.gridGap)); }
+    @computed get gridGap() {
+        return NumCast(this.layoutDoc._gridGap, 10);
+    }
+    @computed get numGroupColumns() {
+        return this.columnHeaders.length;
+    }
+    @observable columnStartXCoords: number[] = [];
+    @computed get PanelWidth() {
+        return this.props.PanelWidth();
+    }
+    @computed get maxColWdith() {
+        return this.props.PanelWidth() - 2 * this.xMargin;
+    }
+
+    // If the user has not yet created any docs (in another view), this will create a single column. Otherwise,
+    // it will adjust according to the
     constructor(props: any) {
         super(props);
         if (this.columnHeaders === undefined) {
-          this.layoutDoc._columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
-          this.columnStartXCoords = [0]
-          // add all of the docs that have not been added to a column to this new column
+            this.layoutDoc._columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
+            this.columnStartXCoords = [0];
+            // add all of the docs that have not been added to a column to this new column
         } else {
-          const numHeaders = this.columnHeaders.length
-          this.resizeColumns(numHeaders)
+            const numHeaders = this.columnHeaders.length;
+            this.resizeColumns(numHeaders);
         }
     }
 
@@ -88,49 +107,51 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
             const height = () => this.getDocHeight(d);
             const width = () => this.getDocWidth(d);
             const style = { width: width(), marginTop: this.gridGap, height: height() };
-            return <div className={`collectionNoteTakingView-columnDoc`} key={d[Id]} style={style} >
-                {this.getDisplayDoc(d, width)}
-            </div>;
+            return (
+                <div className={`collectionNoteTakingView-columnDoc`} key={d[Id]} style={style}>
+                    {this.getDisplayDoc(d, width)}
+                </div>
+            );
         });
-    }
+    };
 
     // [CAVEATS] (1) keep track of the offsetting
     // (2) documentView gets unmounted as you remove it from the list
     get Sections() {
         const columnHeaders = this.columnHeaders;
         const sections = new Map<SchemaHeaderField, Doc[]>(columnHeaders.map(sh => [sh, []] as [SchemaHeaderField, []]));
-        let docs = this.childDocs
-        const rowCol = this.docsDraggedRowCol
-        
+        let docs = this.childDocs;
+        const rowCol = this.docsDraggedRowCol;
+
         // filter out the currently dragged docs from the child docs, since we will insert them later
         if (rowCol.length && DragManager.docsBeingDragged.length) {
-          const docIdsToRemove = new Set()
-          DragManager.docsBeingDragged.forEach(d => {
-            docIdsToRemove.add(d[Id])
-          })
-          docs = docs.filter(d => !docIdsToRemove.has(d[Id]))
+            const docIdsToRemove = new Set();
+            DragManager.docsBeingDragged.forEach(d => {
+                docIdsToRemove.add(d[Id]);
+            });
+            docs = docs.filter(d => !docIdsToRemove.has(d[Id]));
         }
 
         // this will sort the docs into the correct columns (minus the ones you're currently dragging)
         docs.map(d => {
-          if (!d[this.pivotField]) {
-            d[this.pivotField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`
-          };
-          const sectionValue = d[this.pivotField] as object;
-
-          // look for if header exists already
-          const existingHeader = columnHeaders.find(sh => sh.heading === sectionValue.toString());
-          if (existingHeader) {
-              sections.get(existingHeader)!.push(d);
-          }
+            if (!d[this.pivotField]) {
+                d[this.pivotField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
+            }
+            const sectionValue = d[this.pivotField] as object;
+
+            // look for if header exists already
+            const existingHeader = columnHeaders.find(sh => sh.heading === sectionValue.toString());
+            if (existingHeader) {
+                sections.get(existingHeader)!.push(d);
+            }
         });
 
         // now we add back in the docs that we're dragging
         if (rowCol.length && DragManager.docsBeingDragged.length) {
-          const colHeader = columnHeaders[rowCol[1]]
-          // TODO: get the actual offset that occurs if the docs were in that column
-          const offset = 0
-          sections.get(colHeader)?.splice(rowCol[0] - offset, 0, ...DragManager.docsBeingDragged)
+            const colHeader = columnHeaders[rowCol[1]];
+            // TODO: get the actual offset that occurs if the docs were in that column
+            const offset = 0;
+            sections.get(colHeader)?.splice(rowCol[0] - offset, 0, ...DragManager.docsBeingDragged);
         }
         return sections;
     }
@@ -140,12 +161,13 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         // reset section headers when a new filter is inputted
         this._pivotFieldDisposer = reaction(
             () => this.pivotField,
-            () => this.layoutDoc._columnHeaders = new List()
+            () => (this.layoutDoc._columnHeaders = new List())
         );
 
-        this._autoHeightDisposer = reaction(() => this.layoutDoc._autoHeight,
-            autoHeight => autoHeight && this.props.setHeight?.(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
-                this.headerMargin + Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))))));
+        this._autoHeightDisposer = reaction(
+            () => this.layoutDoc._autoHeight,
+            autoHeight => autoHeight && this.props.setHeight?.(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), this.headerMargin + Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace('px', ''))))))
+        );
     }
 
     componentWillUnmount() {
@@ -157,47 +179,52 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     @action
     moveDocument = (doc: Doc, targetCollection: Doc | undefined, addDocument: (document: Doc) => boolean): boolean => {
         return this.props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
-    }
+    };
 
     createRef = (ele: HTMLDivElement | null) => {
         this._masonryGridRef = ele;
         this.createDashEventsTarget(ele!); //so the whole grid is the drop target?
-    }
+    };
 
-    @computed get onChildClickHandler() { return () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); }
-    @computed get onChildDoubleClickHandler() { return () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); }
+    @computed get onChildClickHandler() {
+        return () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
+    }
+    @computed get onChildDoubleClickHandler() {
+        return () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
+    }
 
     addDocTab = (doc: Doc, where: string) => {
-        if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) {
+        if (where === 'inPlace' && this.layoutDoc.isInPlaceContainer) {
             this.dataDoc[this.props.fieldKey] = new List<Doc>([doc]);
             return true;
         }
         return this.props.addDocTab(doc, where);
-    }
+    };
 
     scrollToBottom = () => {
         smoothScroll(500, this._mainCont!, this._mainCont!.scrollHeight);
-    }
+    };
 
     // let's dive in and get the actual document we want to drag/move around
     focusDocument = (doc: Doc, options?: DocFocusOptions) => {
         Doc.BrushDoc(doc);
 
         let focusSpeed = 0;
-        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName("documentView-node")).find((node: any) => node.id === doc[Id]);
+        const found = this._mainCont && Array.from(this._mainCont.getElementsByClassName('documentView-node')).find((node: any) => node.id === doc[Id]);
         if (found) {
             const top = found.getBoundingClientRect().top;
             const localTop = this.props.ScreenToLocalTransform().transformPoint(0, top);
             if (Math.floor(localTop[1]) !== 0) {
-                smoothScroll(focusSpeed = doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500, this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
+                smoothScroll((focusSpeed = doc.presTransition || doc.presTransition === 0 ? NumCast(doc.presTransition) : 500), this._mainCont!, localTop[1] + this._mainCont!.scrollTop);
             }
         }
-        const endFocus = async (moved: boolean) => options?.afterFocus ? options?.afterFocus(moved) : ViewAdjustment.doNothing;
+        const endFocus = async (moved: boolean) => (options?.afterFocus ? options?.afterFocus(moved) : ViewAdjustment.doNothing);
         this.props.focus(this.rootDoc, {
-            willZoom: options?.willZoom, scale: options?.scale, afterFocus: (didFocus: boolean) =>
-                new Promise<ViewAdjustment>(res => setTimeout(async () => res(await endFocus(didFocus)), focusSpeed))
+            willZoom: options?.willZoom,
+            scale: options?.scale,
+            afterFocus: (didFocus: boolean) => new Promise<ViewAdjustment>(res => setTimeout(async () => res(await endFocus(didFocus)), focusSpeed)),
         });
-    }
+    };
 
     styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
         if (property === StyleProp.Opacity && doc) {
@@ -209,241 +236,243 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
             }
         }
         return this.props.styleProvider?.(doc, props, property);
-    }
+    };
 
     isContentActive = () => this.props.isSelected() || this.props.isContentActive();
 
     // rules for displaying the documents
     getDisplayDoc(doc: Doc, width: () => number) {
-        const dataDoc = (!doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS) ? undefined : this.props.DataDoc;
+        const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField && !doc.PARAMS ? undefined : this.props.DataDoc;
         const height = () => this.getDocHeight(doc);
         let dref: Opt<DocumentView>;
         const noteTakingDocTransform = () => this.getDocTransform(doc, dref);
-        return <DocumentView ref={r => dref = r || undefined}
-            Document={doc}
-            DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
-            renderDepth={this.props.renderDepth + 1}
-            PanelWidth={width}
-            PanelHeight={height}
-            styleProvider={this.styleProvider}
-            docViewPath={this.props.docViewPath}
-            fitWidth={this.props.childFitWidth}
-            isContentActive={emptyFunction}
-            originalBackgroundColor={StrCast(doc.backgroundColor)}
-            //TODO: change this from a prop to a parameter passed into a function
-            isNoteTakingView={true}
-            isDocumentActive={this.isContentActive}
-            LayoutTemplate={this.props.childLayoutTemplate}
-            LayoutTemplateString={this.props.childLayoutString}
-            NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeWidth(doc) ? width : undefined}  // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
-            NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || doc._fitWidth && !Doc.NativeHeight(doc) ? height : undefined}
-            dontCenter={this.props.childIgnoreNativeSize ? "xy" : undefined}
-            dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)}
-            rootSelected={this.rootSelected}
-            showTitle={this.props.childShowTitle}
-            dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
-            onClick={this.onChildClickHandler}
-            onDoubleClick={this.onChildDoubleClickHandler}
-            ScreenToLocalTransform={noteTakingDocTransform}
-            focus={this.focusDocument}
-            docFilters={this.childDocFilters}
-            hideDecorationTitle={this.props.childHideDecorationTitle?.()}
-            hideResizeHandles={this.props.childHideResizeHandles?.()}
-            hideTitle={this.props.childHideTitle?.()}
-            docRangeFilters={this.childDocRangeFilters}
-            searchFilterDocs={this.searchFilterDocs}
-            ContainingCollectionDoc={this.props.CollectionView?.props.Document}
-            ContainingCollectionView={this.props.CollectionView}
-            addDocument={this.props.addDocument}
-            moveDocument={this.props.moveDocument}
-            removeDocument={this.props.removeDocument}
-            contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
-            whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
-            addDocTab={this.addDocTab}
-            bringToFront={returnFalse}
-            scriptContext={this.props.scriptContext}
-            pinToPres={this.props.pinToPres}
-        />;
+        return (
+            <DocumentView
+                ref={r => (dref = r || undefined)}
+                Document={doc}
+                DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])}
+                renderDepth={this.props.renderDepth + 1}
+                PanelWidth={width}
+                PanelHeight={height}
+                styleProvider={this.styleProvider}
+                docViewPath={this.props.docViewPath}
+                fitWidth={this.props.childFitWidth}
+                isContentActive={emptyFunction}
+                originalBackgroundColor={StrCast(doc.backgroundColor)}
+                //TODO: change this from a prop to a parameter passed into a function
+                isNoteTakingView={true}
+                isDocumentActive={this.isContentActive}
+                LayoutTemplate={this.props.childLayoutTemplate}
+                LayoutTemplateString={this.props.childLayoutString}
+                NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || (doc._fitWidth && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
+                NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childFitWidth?.(doc) || (doc._fitWidth && !Doc.NativeHeight(doc)) ? height : undefined}
+                dontCenter={this.props.childIgnoreNativeSize ? 'xy' : undefined}
+                dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)}
+                rootSelected={this.rootSelected}
+                showTitle={this.props.childShowTitle}
+                dropAction={StrCast(this.layoutDoc.childDropAction) as dropActionType}
+                onClick={this.onChildClickHandler}
+                onDoubleClick={this.onChildDoubleClickHandler}
+                ScreenToLocalTransform={noteTakingDocTransform}
+                focus={this.focusDocument}
+                docFilters={this.childDocFilters}
+                hideDecorationTitle={this.props.childHideDecorationTitle?.()}
+                hideResizeHandles={this.props.childHideResizeHandles?.()}
+                hideTitle={this.props.childHideTitle?.()}
+                docRangeFilters={this.childDocRangeFilters}
+                searchFilterDocs={this.searchFilterDocs}
+                ContainingCollectionDoc={this.props.CollectionView?.props.Document}
+                ContainingCollectionView={this.props.CollectionView}
+                addDocument={this.props.addDocument}
+                moveDocument={this.props.moveDocument}
+                removeDocument={this.props.removeDocument}
+                contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents)}
+                whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
+                addDocTab={this.addDocTab}
+                bringToFront={returnFalse}
+                scriptContext={this.props.scriptContext}
+                pinToPres={this.props.pinToPres}
+            />
+        );
     }
 
     // This is used to get the coordinates of a document when we go from a view like freeform to columns
     getDocTransform(doc: Doc, dref?: DocumentView) {
         const y = this._scroll; // required for document decorations to update when the text box container is scrolled
         const { scale, translateX, translateY } = Utils.GetScreenTransform(dref?.ContentDiv || undefined);
-        // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform.  so we have to subtract that off 
-        return new Transform(- translateX + (dref?.centeringX || 0), - translateY + (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale);
+        // the document view may center its contents and if so, will prepend that onto the screenToLocalTansform.  so we have to subtract that off
+        return new Transform(-translateX + (dref?.centeringX || 0), -translateY + (dref?.centeringY || 0), 1).scale(this.props.ScreenToLocalTransform().Scale);
     }
 
     // how to get the width of a document. Currently returns the width of the column (minus margins)
     // if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
     getDocWidth(d: Doc) {
-      const heading = d[this.pivotField] as object
-      const castedSectionValue = heading.toString()
-      const existingHeader = this.columnHeaders.find(sh => sh.heading === (castedSectionValue));
-      const colStartXCoords = this.columnStartXCoords
-      if (!existingHeader) {
-        return 1000
-      }
-      const index = this.columnHeaders.indexOf(existingHeader)
-      const endColValue = index == this.columnHeaders.length - 1 ? this.PanelWidth : this.columnStartXCoords[index+1]
-      const maxWidth = endColValue - colStartXCoords[index] - 3 * this.xMargin
-      if (d.type === DocumentType.RTF) {
-        return maxWidth
-      }
-      const width = d[WidthSym]()
-      return width < maxWidth ? width : maxWidth
+        const heading = d[this.pivotField] as object;
+        const castedSectionValue = heading.toString();
+        const existingHeader = this.columnHeaders.find(sh => sh.heading === castedSectionValue);
+        const colStartXCoords = this.columnStartXCoords;
+        if (!existingHeader) {
+            return 1000;
+        }
+        const index = this.columnHeaders.indexOf(existingHeader);
+        const endColValue = index == this.columnHeaders.length - 1 ? this.PanelWidth : this.columnStartXCoords[index + 1];
+        const maxWidth = endColValue - colStartXCoords[index] - 3 * this.xMargin;
+        if (d.type === DocumentType.RTF) {
+            return maxWidth;
+        }
+        const width = d[WidthSym]();
+        return width < maxWidth ? width : maxWidth;
     }
 
     // how to get the height of a document. Nothing special here.
     getDocHeight(d?: Doc) {
         if (!d || d.hidden) return 0;
         const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
-        const childDataDoc = (!d.isTemplateDoc && !d.isTemplateForField && !d.PARAMS) ? undefined : this.props.DataDoc;
-        const maxHeight = (lim => lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim)(NumCast(this.layoutDoc.childLimitHeight, -1));
+        const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField && !d.PARAMS ? undefined : this.props.DataDoc;
+        const maxHeight = (lim => (lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
         const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[WidthSym]() : 0);
         const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? d[HeightSym]() : 0);
         if (nw && nh) {
             // const colWid = this.columnWidth / this.numGroupColumns;
             // const docWid = this.layoutDoc._columnsFill ? colWid : Math.min(this.getDocWidth(d), colWid);
-            const docWid = this.getDocWidth(d)
-            return Math.min(
-                maxHeight,
-                docWid * nh / nw);
+            const docWid = this.getDocWidth(d);
+            return Math.min(maxHeight, (docWid * nh) / nw);
         }
         const childHeight = NumCast(childLayoutDoc._height);
-        const panelHeight = (childLayoutDoc._fitWidth || this.props.childFitWidth?.(d)) ? Number.MAX_SAFE_INTEGER : this.props.PanelHeight() - 2 * this.yMargin;
+        const panelHeight = childLayoutDoc._fitWidth || this.props.childFitWidth?.(d) ? Number.MAX_SAFE_INTEGER : this.props.PanelHeight() - 2 * this.yMargin;
         return Math.min(childHeight, maxHeight, panelHeight);
     }
 
     // called when a column is either added or deleted. This function creates n evenly spaced columns
     resizeColumns = (n: number) => {
-      const totalWidth = this.PanelWidth
-      const dividerWidth = 32
-      const totaldividerWidth = (n - 1) * dividerWidth
-      const colWidth = (totalWidth - totaldividerWidth)  / n
-      const newColXCoords: number[] = []
-      let colStart = 0
-      for (let i = 0; i < n; i++) {
-          newColXCoords.push(colStart)
-          colStart += colWidth + dividerWidth
-      }
-      this.columnStartXCoords = newColXCoords
-    }
+        const totalWidth = this.PanelWidth;
+        const dividerWidth = 32;
+        const totaldividerWidth = (n - 1) * dividerWidth;
+        const colWidth = (totalWidth - totaldividerWidth) / n;
+        const newColXCoords: number[] = [];
+        let colStart = 0;
+        for (let i = 0; i < n; i++) {
+            newColXCoords.push(colStart);
+            colStart += colWidth + dividerWidth;
+        }
+        this.columnStartXCoords = newColXCoords;
+    };
 
     // This function is used to preview where a document will drop in a column once a drag is complete.
     @action
     onPointerOver = (e: React.PointerEvent) => {
-      if (DragManager.docsBeingDragged.length && this.childDocList) {
-        // get the current docs for the column based on the mouse's x coordinate
-        // will use again later, which is why we're saving as local
-        const xCoord = e.clientX - 2 * this.gridGap
-        const colDocs = this.getDocsFromXCoord(xCoord)
-        // get the index for where you need to insert the doc you are currently dragging
-        const clientY = e.clientY
-        let dropInd = -1;
-        // unsure whether we still want this dropAfter field
-        // let dropAfter = 0;
-        // manually set to 140, because not sure how to get exact value
-        let pos0 = 140
-        colDocs.forEach((doc, i) => {
-          const noteTakingDocTransform = () => this.getDocTransform(doc);
-          let pos1 = noteTakingDocTransform().inverse().transformPoint(0, this.getDocHeight(doc) + 2 * this.gridGap)[1];
-          pos1 += pos0
-          // updating drop position based on y coordinates
-          const yCoordInBetween = clientY > pos0 && (clientY < pos1 || i == colDocs.length - 1)
-          if (yCoordInBetween) {
-            dropInd = i;
-            // dropAfter = 0;
-            if (clientY > (pos0 + pos1) / 2) {
-              // dropAfter = 1;
-            }
-          }
-          pos0 = pos1
-        })
-        // we alter the pivot fields of the docs in case they are moved to a new column.
-        const colIndex = this.getColumnFromXCoord(xCoord)
-        const colHeader = StrCast(this.columnHeaders[colIndex].heading)
-        DragManager.docsBeingDragged.forEach(d => d[this.pivotField] = colHeader)
-        // used to notify sections to re-render
-        // console.log([dropInd, this.getColumnFromXCoord(xCoord)])
-        this.docsDraggedRowCol = [dropInd, this.getColumnFromXCoord(xCoord)]
-      }
-    }
+        if (DragManager.docsBeingDragged.length && this.childDocList) {
+            // get the current docs for the column based on the mouse's x coordinate
+            // will use again later, which is why we're saving as local
+            const xCoord = e.clientX - 2 * this.gridGap;
+            const colDocs = this.getDocsFromXCoord(xCoord);
+            // get the index for where you need to insert the doc you are currently dragging
+            const clientY = e.clientY;
+            let dropInd = -1;
+            // unsure whether we still want this dropAfter field
+            // let dropAfter = 0;
+            // manually set to 140, because not sure how to get exact value
+            let pos0 = 140;
+            colDocs.forEach((doc, i) => {
+                const noteTakingDocTransform = () => this.getDocTransform(doc);
+                let pos1 = noteTakingDocTransform()
+                    .inverse()
+                    .transformPoint(0, this.getDocHeight(doc) + 2 * this.gridGap)[1];
+                pos1 += pos0;
+                // updating drop position based on y coordinates
+                const yCoordInBetween = clientY > pos0 && (clientY < pos1 || i == colDocs.length - 1);
+                if (yCoordInBetween) {
+                    dropInd = i;
+                    // dropAfter = 0;
+                    if (clientY > (pos0 + pos1) / 2) {
+                        // dropAfter = 1;
+                    }
+                }
+                pos0 = pos1;
+            });
+            // we alter the pivot fields of the docs in case they are moved to a new column.
+            const colIndex = this.getColumnFromXCoord(xCoord);
+            const colHeader = StrCast(this.columnHeaders[colIndex].heading);
+            DragManager.docsBeingDragged.forEach(d => (d[this.pivotField] = colHeader));
+            // used to notify sections to re-render
+            // console.log([dropInd, this.getColumnFromXCoord(xCoord)])
+            this.docsDraggedRowCol = [dropInd, this.getColumnFromXCoord(xCoord)];
+        }
+    };
 
     // returns the column index for a given x-coordinate
     getColumnFromXCoord = (xCoord: number): number => {
-        const numColumns = this.columnHeaders.length
-        const coords = this.columnStartXCoords.slice()
-        coords.push(this.PanelWidth)
-        let colIndex = 0
+        const numColumns = this.columnHeaders.length;
+        const coords = this.columnStartXCoords.slice();
+        coords.push(this.PanelWidth);
+        let colIndex = 0;
         for (let i = 0; i < numColumns; i++) {
             if (xCoord > coords[i] && xCoord < coords[i + 1]) {
-              colIndex = i
-              break
+                colIndex = i;
+                break;
             }
         }
-        return colIndex
-    }
+        return colIndex;
+    };
 
-    // returns the docs of a column based on the x-coordinate provided. 
+    // returns the docs of a column based on the x-coordinate provided.
     getDocsFromXCoord = (xCoord: number): Doc[] => {
-      const colIndex = this.getColumnFromXCoord(xCoord)
-      const colHeader = StrCast(this.columnHeaders[colIndex].heading)
-      // const docs = this.childDocList
-      const docs = this.childDocs
-      const docsMatchingHeader: Doc[] = []
-      if (docs) {
-        docs.map(d => {
-          if (d instanceof Promise) return;
-          const sectionValue = d[this.pivotField] as object;
-          if (sectionValue.toString() == colHeader) {
-            docsMatchingHeader.push(d)
-          }
-        })
-      }
-      return docsMatchingHeader;
-    }
+        const colIndex = this.getColumnFromXCoord(xCoord);
+        const colHeader = StrCast(this.columnHeaders[colIndex].heading);
+        // const docs = this.childDocList
+        const docs = this.childDocs;
+        const docsMatchingHeader: Doc[] = [];
+        if (docs) {
+            docs.map(d => {
+                if (d instanceof Promise) return;
+                const sectionValue = d[this.pivotField] as object;
+                if (sectionValue.toString() == colHeader) {
+                    docsMatchingHeader.push(d);
+                }
+            });
+        }
+        return docsMatchingHeader;
+    };
 
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
         if (de.complete.docDragData) {
             if (super.onInternalDrop(e, de)) {
-              DragManager.docsBeingDragged = []
-              // this.docsDraggedRowCol = []
-              // filter out the currently dragged docs from the child docs, since we will insert them later
-              const rowCol = this.docsDraggedRowCol
-              const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= this.childDocs.length); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
-              const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments;
-              
-              // const docs = this.childDocs
-              const docs = this.childDocList
-              if (docs && newDocs.length) {
-                // remove the dragged documents from the childDocList
-                newDocs.filter(d => docs.indexOf(d) !== -1).forEach(d => docs.splice(docs.indexOf(d), 1))
-                // if the doc starts a columnm (or the drop index is undefined), we can just push it to the front. Otherwise we need to add it to the column properly
-                //TODO: you need to update childDocList instead. It seems that childDocs is a copy of the actual array we want to modify
-                if (rowCol[0] <= 0) {
-                  docs.splice(0, 0, ...newDocs)
-                } else {
-                  const colDocs = this.getDocsFromXCoord(de.x)
-                  const previousDoc = colDocs[rowCol[0] - 1]
-                  const previousDocIndex = docs.indexOf(previousDoc)
-                  console.log(`docs: ${previousDocIndex}`)
-                  docs.splice(previousDocIndex + 1, 0, ...newDocs)
+                DragManager.docsBeingDragged = [];
+                // this.docsDraggedRowCol = []
+                // filter out the currently dragged docs from the child docs, since we will insert them later
+                const rowCol = this.docsDraggedRowCol;
+                const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= this.childDocs.length); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
+                const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments;
+
+                // const docs = this.childDocs
+                const docs = this.childDocList;
+                if (docs && newDocs.length) {
+                    // remove the dragged documents from the childDocList
+                    newDocs.filter(d => docs.indexOf(d) !== -1).forEach(d => docs.splice(docs.indexOf(d), 1));
+                    // if the doc starts a columnm (or the drop index is undefined), we can just push it to the front. Otherwise we need to add it to the column properly
+                    //TODO: you need to update childDocList instead. It seems that childDocs is a copy of the actual array we want to modify
+                    if (rowCol[0] <= 0) {
+                        docs.splice(0, 0, ...newDocs);
+                    } else {
+                        const colDocs = this.getDocsFromXCoord(de.x);
+                        const previousDoc = colDocs[rowCol[0] - 1];
+                        const previousDocIndex = docs.indexOf(previousDoc);
+                        console.log(`docs: ${previousDocIndex}`);
+                        docs.splice(previousDocIndex + 1, 0, ...newDocs);
+                    }
                 }
-              }
             }
         } // it seems like we're creating a link here. Weird. I didn't know that you could establish links by dragging
         else if (de.complete.linkDragData?.dragDocument.context === this.props.Document && de.complete.linkDragData?.linkDragView?.props.CollectionFreeFormDocumentView?.()) {
-            const source = Docs.Create.TextDocument("", { _width: 200, _height: 75, _fitWidth: true, title: "dropped annotation" });
+            const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, _fitWidth: true, title: 'dropped annotation' });
             this.props.addDocument?.(source);
-            de.complete.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: de.complete.linkDragData.linkSourceGetAnchor() }, "doc annotation", ""); // TODODO this is where in text links get passed
+            de.complete.linkDocument = DocUtils.MakeLink({ doc: source }, { doc: de.complete.linkDragData.linkSourceGetAnchor() }, 'doc annotation', ''); // TODODO this is where in text links get passed
             e.stopPropagation();
-        }
-        else if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de.complete.annoDragData);
+        } else if (de.complete.annoDragData?.dragDocument && super.onInternalDrop(e, de)) return this.internalAnchorAnnoDrop(e, de.complete.annoDragData);
         return false;
-    }
+    };
 
     @undoBatch
     internalAnchorAnnoDrop(e: Event, annoDragData: DragManager.AnchorAnnoDragData) {
@@ -461,16 +490,18 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     onExternalDrop = async (e: React.DragEvent): Promise<void> => {
         const where = [e.clientX, e.clientY];
         let targInd = -1;
-        const docs = this.getDocsFromXCoord(where[0])
+        const docs = this.getDocsFromXCoord(where[0]);
         docs.map((d, i) => {
-          const pos0 = this.getDocTransform(d).inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
-          const pos1 = this.getDocTransform(d).inverse().transformPoint(this.getDocWidth(d), this.getDocHeight(d));
-          // const pos0 = cd.noteTakingDocTransform().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
-          // const pos1 = cd.noteTakingDocTransform().inverse().transformPoint(cd.width(), cd.height());
-          if (where[0] > pos0[0] && where[0] < pos1[0] && where[1] > pos0[1] && where[1] < pos1[1]) {
-              targInd = i;
-          }
-        })
+            const pos0 = this.getDocTransform(d)
+                .inverse()
+                .transformPoint(-2 * this.gridGap, -2 * this.gridGap);
+            const pos1 = this.getDocTransform(d).inverse().transformPoint(this.getDocWidth(d), this.getDocHeight(d));
+            // const pos0 = cd.noteTakingDocTransform().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
+            // const pos1 = cd.noteTakingDocTransform().inverse().transformPoint(cd.width(), cd.height());
+            if (where[0] > pos0[0] && where[0] < pos1[0] && where[1] > pos0[1] && where[1] < pos1[1]) {
+                targInd = i;
+            }
+        });
         // this._docXfs.map((cd, i) => {
         //     const pos = cd.noteTakingDocTransform().inverse().transformPoint(-2 * this.gridGap, -2 * this.gridGap);
         //     const pos1 = cd.noteTakingDocTransform().inverse().transformPoint(cd.width(), cd.height());
@@ -488,7 +519,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
                 }
             }
         });
-    }
+    };
 
     // setDocsForColHeader = (key: string, docs: Doc[]) => {
     //   this._docsByColumnHeader = new Map(this._docsByColumnHeader.set(key, docs))
@@ -499,94 +530,96 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     refList: any[] = [];
 
     sectionNoteTaking = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
-        const type = "number";
-        return <CollectionNoteTakingViewColumn
-            unobserveHeight={ref => this.refList.splice(this.refList.indexOf(ref), 1)}
-            observeHeight={ref => {
-                if (ref) {
-                    this.refList.push(ref);
-                    this.observer = new _global.ResizeObserver(action((entries: any) => {
-                        if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) {
-                            const height = this.headerMargin +
-                                Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER),
-                                    Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace("px", "")))));
-                            if (!LightboxView.IsLightboxDocView(this.props.docViewPath())) {
-                                this.props.setHeight?.(height);
-                            }
-                        }
-                    }));
-                    this.observer.observe(ref);
-                }
-            }}
-            addDocument={this.addDocument}
-            // docsByColumnHeader={this._docsByColumnHeader}
-            // setDocsForColHeader={this.setDocsForColHeader}
-            chromeHidden={this.chromeHidden}
-            columnHeaders={this.columnHeaders}
-            Document={this.props.Document}
-            DataDoc={this.props.DataDoc}
-            resizeColumns={this.resizeColumns.bind(this)}
-            renderChildren={this.children}
-            numGroupColumns={this.numGroupColumns}
-            gridGap={this.gridGap}
-            pivotField={this.pivotField}
-            columnStartXCoords={this.columnStartXCoords}
-            maxColWidth={this.maxColWdith}
-            PanelWidth={this.PanelWidth}
-            key={heading?.heading ?? ""}
-            headings={this.headings}
-            heading={heading?.heading ?? ""}
-            headingObject={heading}
-            docList={docList}
-            yMargin={this.yMargin}
-            type={type}
-            createDropTarget={this.createDashEventsTarget}
-            screenToLocalTransform={this.props.ScreenToLocalTransform}
-            editableViewProps={{
-              GetValue: () => "",
-              SetValue: this.addGroup,
-              contents: "+ New Column"
-          }}
-        />;
-    }
+        const type = 'number';
+        return (
+            <CollectionNoteTakingViewColumn
+                unobserveHeight={ref => this.refList.splice(this.refList.indexOf(ref), 1)}
+                observeHeight={ref => {
+                    if (ref) {
+                        this.refList.push(ref);
+                        this.observer = new _global.ResizeObserver(
+                            action((entries: any) => {
+                                if (this.layoutDoc._autoHeight && ref && this.refList.length && !SnappingManager.GetIsDragging()) {
+                                    const height = this.headerMargin + Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace('px', '')))));
+                                    if (!LightboxView.IsLightboxDocView(this.props.docViewPath())) {
+                                        this.props.setHeight?.(height);
+                                    }
+                                }
+                            })
+                        );
+                        this.observer.observe(ref);
+                    }
+                }}
+                addDocument={this.addDocument}
+                // docsByColumnHeader={this._docsByColumnHeader}
+                // setDocsForColHeader={this.setDocsForColHeader}
+                chromeHidden={this.chromeHidden}
+                columnHeaders={this.columnHeaders}
+                Document={this.props.Document}
+                DataDoc={this.props.DataDoc}
+                resizeColumns={this.resizeColumns.bind(this)}
+                renderChildren={this.children}
+                numGroupColumns={this.numGroupColumns}
+                gridGap={this.gridGap}
+                pivotField={this.pivotField}
+                columnStartXCoords={this.columnStartXCoords}
+                maxColWidth={this.maxColWdith}
+                PanelWidth={this.PanelWidth}
+                key={heading?.heading ?? ''}
+                headings={this.headings}
+                heading={heading?.heading ?? ''}
+                headingObject={heading}
+                docList={docList}
+                yMargin={this.yMargin}
+                type={type}
+                createDropTarget={this.createDashEventsTarget}
+                screenToLocalTransform={this.props.ScreenToLocalTransform}
+                editableViewProps={{
+                    GetValue: () => '',
+                    SetValue: this.addGroup,
+                    contents: '+ New Column',
+                }}
+            />
+        );
+    };
 
     // called when adding a new columnHeader
     @action
     addGroup = (value: string) => {
         if (value && this.columnHeaders) {
-            this.resizeColumns(this.columnHeaders.length + 1)
+            this.resizeColumns(this.columnHeaders.length + 1);
             const schemaHdrField = new SchemaHeaderField(value);
             this.columnHeaders.push(schemaHdrField);
             return true;
         }
         return false;
-    }
+    };
 
     sortFunc = (a: [SchemaHeaderField, Doc[]], b: [SchemaHeaderField, Doc[]]): 1 | -1 => {
-        const descending = StrCast(this.layoutDoc._columnsSort) === "descending";
+        const descending = StrCast(this.layoutDoc._columnsSort) === 'descending';
         const firstEntry = descending ? b : a;
         const secondEntry = descending ? a : b;
         return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1;
-    }
+    };
 
     onContextMenu = (e: React.MouseEvent): void => {
         // need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
         if (!e.isPropagationStopped()) {
             const subItems: ContextMenuProps[] = [];
-            subItems.push({ description: `${this.layoutDoc._columnsFill ? "Variable Size" : "Autosize"} Column`, event: () => this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill, icon: "plus" });
-            subItems.push({ description: `${this.layoutDoc._autoHeight ? "Variable Height" : "Auto Height"}`, event: () => this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight, icon: "plus" });
-            subItems.push({ description: "Clear All", event: () => this.dataDoc.data = new List([]), icon: "times" });
-            ContextMenu.Instance.addItem({ description: "Options...", subitems: subItems, icon: "eye" });
+            subItems.push({ description: `${this.layoutDoc._columnsFill ? 'Variable Size' : 'Autosize'} Column`, event: () => (this.layoutDoc._columnsFill = !this.layoutDoc._columnsFill), icon: 'plus' });
+            subItems.push({ description: `${this.layoutDoc._autoHeight ? 'Variable Height' : 'Auto Height'}`, event: () => (this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight), icon: 'plus' });
+            subItems.push({ description: 'Clear All', event: () => (this.dataDoc.data = new List([])), icon: 'times' });
+            ContextMenu.Instance.addItem({ description: 'Options...', subitems: subItems, icon: 'eye' });
         }
-    }
+    };
 
     // used to reset column sizes when using the drag handlers
     @action
     setColumnStartXCoords = (movementX: number, colIndex: number) => {
-      const coords = [...this.columnStartXCoords]
-      coords[colIndex] += movementX
-      this.columnStartXCoords = coords
-    }
+        const coords = [...this.columnStartXCoords];
+        coords[colIndex] += movementX;
+        this.columnStartXCoords = coords;
+    };
 
     @computed get renderedSections() {
         TraceMobx();
@@ -596,22 +629,16 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         //     sections = this.layoutDoc._columnsSort ? entries.sort(this.sortFunc) : entries;
         // }
         const entries = Array.from(this.Sections.entries());
-        const sections = entries.sort(this.sortFunc)
-        const eles: JSX.Element[] = []
+        const sections = entries.sort(this.sortFunc);
+        const eles: JSX.Element[] = [];
         for (let i = 0; i < sections.length; i++) {
-            const col = this.sectionNoteTaking(sections[i][0], sections[i][1])
-            eles.push(col)
+            const col = this.sectionNoteTaking(sections[i][0], sections[i][1]);
+            eles.push(col);
             if (i < sections.length - 1) {
-              eles.push(
-                <CollectionNoteTakingViewDivider
-                  index={i + 1}
-                  setColumnStartXCoords={this.setColumnStartXCoords.bind(this)}
-                  xMargin={this.xMargin}
-                />
-              )
+                eles.push(<CollectionNoteTakingViewDivider index={i + 1} setColumnStartXCoords={this.setColumnStartXCoords.bind(this)} xMargin={this.xMargin} />);
             }
         }
-        return eles
+        return eles;
     }
 
     @computed get buttonMenu() {
@@ -620,79 +647,82 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         if (menuDoc) {
             const width: number = NumCast(menuDoc._width, 30);
             const height: number = NumCast(menuDoc._height, 30);
-            return (<div className="buttonMenu-docBtn"
-                style={{ width: width, height: height }}>
-                <DocumentView
-                    Document={menuDoc}
-                    DataDoc={menuDoc}
-                    isContentActive={this.props.isContentActive}
-                    isDocumentActive={returnTrue}
-                    addDocument={this.props.addDocument}
-                    moveDocument={this.props.moveDocument}
-                    addDocTab={this.props.addDocTab}
-                    pinToPres={emptyFunction}
-                    rootSelected={this.props.isSelected}
-                    removeDocument={this.props.removeDocument}
-                    ScreenToLocalTransform={Transform.Identity}
-                    PanelWidth={() => 35}
-                    PanelHeight={() => 35}
-                    renderDepth={this.props.renderDepth}
-                    focus={emptyFunction}
-                    styleProvider={this.props.styleProvider}
-                    docViewPath={returnEmptyDoclist}
-                    whenChildContentsActiveChanged={emptyFunction}
-                    bringToFront={emptyFunction}
-                    docFilters={this.props.docFilters}
-                    docRangeFilters={this.props.docRangeFilters}
-                    searchFilterDocs={this.props.searchFilterDocs}
-                    ContainingCollectionView={undefined}
-                    ContainingCollectionDoc={undefined}
-                />
-            </div>
+            return (
+                <div className="buttonMenu-docBtn" style={{ width: width, height: height }}>
+                    <DocumentView
+                        Document={menuDoc}
+                        DataDoc={menuDoc}
+                        isContentActive={this.props.isContentActive}
+                        isDocumentActive={returnTrue}
+                        addDocument={this.props.addDocument}
+                        moveDocument={this.props.moveDocument}
+                        addDocTab={this.props.addDocTab}
+                        pinToPres={emptyFunction}
+                        rootSelected={this.props.isSelected}
+                        removeDocument={this.props.removeDocument}
+                        ScreenToLocalTransform={Transform.Identity}
+                        PanelWidth={() => 35}
+                        PanelHeight={() => 35}
+                        renderDepth={this.props.renderDepth}
+                        focus={emptyFunction}
+                        styleProvider={this.props.styleProvider}
+                        docViewPath={returnEmptyDoclist}
+                        whenChildContentsActiveChanged={emptyFunction}
+                        bringToFront={emptyFunction}
+                        docFilters={this.props.docFilters}
+                        docRangeFilters={this.props.docRangeFilters}
+                        searchFilterDocs={this.props.searchFilterDocs}
+                        ContainingCollectionView={undefined}
+                        ContainingCollectionDoc={undefined}
+                    />
+                </div>
             );
         }
     }
 
+    @computed get nativeWidth() {
+        return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc);
+    }
+    @computed get nativeHeight() {
+        return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc);
+    }
 
-    @computed get nativeWidth() { return this.props.NativeWidth?.() ?? Doc.NativeWidth(this.layoutDoc); }
-    @computed get nativeHeight() { return this.props.NativeHeight?.() ?? Doc.NativeHeight(this.layoutDoc); }
-
-    @computed get scaling() { return !this.nativeWidth ? 1 : this.props.PanelHeight() / this.nativeHeight; }
+    @computed get scaling() {
+        return !this.nativeWidth ? 1 : this.props.PanelHeight() / this.nativeHeight;
+    }
 
-    @computed get backgroundEvents() { return SnappingManager.GetIsDragging(); }
+    @computed get backgroundEvents() {
+        return SnappingManager.GetIsDragging();
+    }
     observer: any;
     render() {
         TraceMobx();
         const buttonMenu = this.rootDoc.buttonMenu;
-        const noviceExplainer = this.rootDoc.explainer;
+        const noviceExplainer = StrCast(this.rootDoc.explainer);
         return (
             <>
-                {buttonMenu || noviceExplainer ? <div className="documentButtonMenu">
-                    {buttonMenu ? this.buttonMenu : null}
-                    {Doc.UserDoc().noviceMode && noviceExplainer ?
-                        <div className="documentExplanation">
-                            {noviceExplainer}
-                        </div>
-                        : null
-                    }
-                </div> : null}
-                <div className="collectionNoteTakingView"
+                {buttonMenu || noviceExplainer ? (
+                    <div className="documentButtonMenu">
+                        {buttonMenu ? this.buttonMenu : null}
+                        {Doc.UserDoc().noviceMode && noviceExplainer ? <div className="documentExplanation">{noviceExplainer}</div> : null}
+                    </div>
+                ) : null}
+                <div
+                    className="collectionNoteTakingView"
                     ref={this.createRef}
                     style={{
-                        overflowY: this.props.isContentActive() ? "auto" : "hidden",
+                        overflowY: this.props.isContentActive() ? 'auto' : 'hidden',
                         background: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor),
-                        pointerEvents: this.backgroundEvents ? "all" : undefined
+                        pointerEvents: this.backgroundEvents ? 'all' : undefined,
                     }}
-                    onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
+                    onScroll={action(e => (this._scroll = e.currentTarget.scrollTop))}
                     onPointerOver={this.onPointerOver}
                     onDrop={this.onExternalDrop.bind(this)}
                     onContextMenu={this.onContextMenu}
-                    onWheel={e => this.props.isContentActive(true) && e.stopPropagation()} 
-                  >
+                    onWheel={e => this.props.isContentActive(true) && e.stopPropagation()}>
                     {this.renderedSections}
                 </div>
             </>
-
         );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 9a498858a..7385f933b 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -1,4 +1,4 @@
-@import "../global/globalCssVariables";
+@import '../global/globalCssVariables';
 
 .collectionMasonryView {
     display: inline;
@@ -33,7 +33,7 @@
         color: $medium-blue;
         padding: 10px;
         border-radius: 5px;
-        border: solid .5px $medium-blue;
+        border: solid 0.5px $medium-blue;
     }
 }
 
@@ -46,9 +46,9 @@
     overflow-y: auto;
     overflow-x: hidden;
     flex-wrap: wrap;
-    transition: top .5s;
+    transition: top 0.5s;
 
-    >div {
+    > div {
         position: relative;
         display: block;
     }
@@ -133,34 +133,8 @@
     // Documents in stacking view
     .collectionStackingView-columnDoc {
         display: flex;
-        // margin: auto; // Removed auto so that it is no longer center aligned - this could be something we change 
+        // margin: auto; // Removed auto so that it is no longer center aligned - this could be something we change
         position: relative;
-
-        &:hover {
-          .hoverButtons{
-            opacity: 1;
-          }
-        }
-
-        .hoverButtons {
-          display: flex;
-          opacity: 0;
-          position: absolute;
-          height: 100%;
-          left: -35px;
-          justify-content: center;
-          align-items: center;
-          padding: 0px 10px;
-
-          .buttonWrapper {
-            padding: 3px;
-            border-radius: 3px;
-            
-            &:hover {
-              background: rgba(0, 0, 0, 0.26);
-            }
-          }
-        }
     }
 
     .collectionStackingView-masonryDoc {
@@ -201,7 +175,7 @@
 
         span::before,
         span::after {
-            content: "";
+            content: '';
             width: 50%;
             border-top: dashed gray 1px;
             position: relative;
@@ -242,7 +216,7 @@
         .editableView-input:hover,
         .editableView-container-editing:hover,
         .editableView-container-editing-oneLine:hover {
-            cursor: text
+            cursor: text;
         }
 
         .collectionStackingView-sectionHeader-subCont {
@@ -288,7 +262,7 @@
             height: 100%;
             display: none;
 
-            [class*="css"] {
+            [class*='css'] {
                 max-width: 102px;
             }
 
@@ -330,7 +304,7 @@
             height: 100%;
             display: none;
 
-            [class*="css"] {
+            [class*='css'] {
                 max-width: 102px;
             }
 
@@ -339,7 +313,6 @@
             }
 
             .collectionStackingView-optionPicker {
-
                 .optionOptions {
                     display: inline;
                 }
@@ -399,7 +372,7 @@
         .editableView-input:hover,
         .editableView-container-editing:hover,
         .editableView-container-editing-oneLine:hover {
-            cursor: text
+            cursor: text;
         }
 
         .editableView-input {
@@ -452,7 +425,7 @@
         top: 4px;
         border-radius: 50% 50%;
         background-color: #fff;
-        content: " ";
+        content: ' ';
         cursor: pointer;
         box-shadow: 0 2px 5px rgba(0, 0, 0, 0.26);
         -webkit-transform: scale(1);
@@ -482,7 +455,6 @@
 }
 
 @media only screen and (max-device-width: 480px) {
-
     .collectionStackingView .collectionStackingView-columnDragger,
     .collectionMasonryView .collectionStackingView-columnDragger {
         width: 0.1;
@@ -490,4 +462,4 @@
         opacity: 0;
         font-size: 0;
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index d3a8af03a..1927db51e 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -90,7 +90,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     }
     // are we stacking or masonry?
     @computed get isStackingView() {
-        return (this.props.viewType ?? this.layoutDoc._viewType) === (CollectionViewType.Stacking || CollectionViewType.NoteTaking);
+        return (this.props.viewType ?? this.layoutDoc._viewType) === CollectionViewType.Stacking;
     }
     // this is the number of StackingViewFieldColumns that we have
     @computed get numGroupColumns() {
@@ -370,13 +370,7 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
     getDocWidth(d?: Doc) {
         if (!d) return 0;
         const childLayoutDoc = Doc.Layout(d, this.props.childLayoutTemplate?.());
-        // TODO: pj - replace with a better way to calculate the margin
-        let margin = 25;
-        d.margin = 25;
-        if (this.columnWidth < 150) {
-            margin = 0;
-        }
-        const maxWidth = this.columnWidth / this.numGroupColumns - margin * 2;
+        const maxWidth = this.columnWidth / this.numGroupColumns;
         if (!this.layoutDoc._columnsFill && !(childLayoutDoc._fitWidth || this.props.childFitWidth?.(d))) {
             return Math.min(d[WidthSym](), maxWidth);
         }
@@ -424,33 +418,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         );
     }
 
-    // TODO: plj
-    @action
-    onPointerOver = (e: React.PointerEvent) => {
-        // console.log("hovering over something")
-        if (DragManager.docsBeingDragged.length) {
-            // essentially copying code from onInternalDrop for this:
-            const doc = DragManager.docsBeingDragged[0];
-            // console.log(doc[LayoutSym]())
-
-            console.log(doc[DataSym]);
-            console.log(Doc.IndexOf(doc, this.childDocs));
-        }
-    };
-
-    //used in onPointerOver to swap two nodes in the rendered filtered children list
-    swapNodes = (i: number, j: number) => {};
-
-    //plj added this
-    @action
-    onPointerDown = (e: React.PointerEvent) => {};
-
-    // TODO: plj - look at this. Start with making changes to db, and then transition to client side
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
         // Fairly confident that this is where the swapping of nodes in the various arrays happens
-        console.log('drop');
         const where = [de.x, de.y];
         // start at -1 until we're sure we want to add it to the column
         let dropInd = -1;
@@ -505,12 +476,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         return true;
     }
 
+    /// an item from outside of Dash is being dropped onto this stacking view (e.g, a document from the file system)
     @undoBatch
     @action
-    //What is the difference between internal and external drop?? Does internal mean we're dropping inside of a collection?
-    // I take it back: external drop means we took it out of column/collection that we were just in
     onExternalDrop = async (e: React.DragEvent): Promise<void> => {
-        console.log('external drop');
         const where = [e.clientX, e.clientY];
         let targInd = -1;
         this._docXfs.map((cd, i) => {
@@ -633,8 +602,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
         );
     };
 
+    /// add a new group category (column) to the active set of note categories.  (e.g., if the pivot field is 'transportation', groups might be 'car', 'plane', 'bike', etc)
     @action
-    // What are we adding a group to?
     addGroup = (value: string) => {
         if (value && this.columnHeaders) {
             const schemaHdrField = new SchemaHeaderField(value);
-- 
cgit v1.2.3-70-g09d2


From 55bac585fa0b8d6c3f513ccecb22456d1d361040 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 3 Aug 2022 13:33:38 -0400
Subject: fixes for dragging notes so that they highlight properly and go to
 the right place when embedded in freeform views.

---
 src/client/documents/Documents.ts                  |   9 +-
 src/client/util/CurrentUserUtils.ts                |   3 +-
 src/client/util/DragManager.ts                     |  12 +-
 src/client/views/DocumentDecorations.tsx           |   2 +-
 src/client/views/StyleProvider.tsx                 |   8 +-
 .../views/collections/CollectionNoteTakingView.tsx |  91 +++---
 .../collections/CollectionNoteTakingViewColumn.tsx | 358 +++++++++++----------
 .../CollectionNoteTakingViewDivider.tsx            | 112 +++----
 .../views/collections/CollectionStackingView.tsx   |   4 +-
 src/client/views/nodes/DocumentView.tsx            |  30 +-
 .../views/nodes/formattedText/FormattedTextBox.tsx |   6 +-
 11 files changed, 332 insertions(+), 303 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 32d7152fd..9d00664ad 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -1036,7 +1036,14 @@ export namespace Docs {
         }
 
         export function NoteTakingDocument(documents: Array<Doc>, options: DocumentOptions, id?: string, protoId?: string) {
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { ...options, _viewType: CollectionViewType.NoteTaking }, id, undefined, protoId);
+            return InstanceFromProto(
+                Prototypes.get(DocumentType.COL),
+                new List(documents),
+                { columnHeaders: new List<SchemaHeaderField>([new SchemaHeaderField('Untitled')]), ...options, _viewType: CollectionViewType.NoteTaking },
+                id,
+                undefined,
+                protoId
+            );
         }
 
         export function MulticolumnDocument(documents: Array<Doc>, options: DocumentOptions) {
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 28dc44c25..7856c913b 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -135,7 +135,6 @@ export class CurrentUserUtils {
         return DocUtils.AssignOpts(tempClicks, reqdOpts, reqdClickList) ?? (doc[field] = Docs.Create.TreeDocument(reqdClickList, reqdOpts));
     }
 
-
     /// Initializes templates that can be applied to notes
     static setupNoteTemplates(doc: Doc, field="template-notes") {
         const tempNotes = DocCast(doc[field]);
@@ -255,6 +254,7 @@ export class CurrentUserUtils {
                           creator:(opts:DocumentOptions)=> any // how to create the empty thing if it doesn't exist
               }[] = [
             {key: "Note",       creator: opts => Docs.Create.TextDocument("", opts),        opts: { _width: 200, _autoHeight: true }},
+            {key: "Noteboard",  creator: opts => Docs.Create.NoteTakingDocument([], opts),  opts: { _width: 250, _height: 200 }},
             {key: "Collection", creator: opts => Docs.Create.FreeformDocument([], opts),    opts: { _width: 150, _height: 100 }},
             {key: "Equation",   creator: opts => Docs.Create.EquationDocument(opts),        opts: { _width: 300, _height: 35, _fitWidth:false, _backgroundGridShow: true, }},
             {key: "Webpage",    creator: opts => Docs.Create.WebDocument("",opts),          opts: { _width: 400, _height: 512, _nativeWidth: 850, useCors: true, }},
@@ -280,6 +280,7 @@ export class CurrentUserUtils {
         
         return [
             { toolTip: "Tap or drag to create a note",            title: "Note", icon: "sticky-note",   dragFactory: doc.emptyNote as Doc, },
+            { toolTip: "Tap or drag to create a note board",      title: "Notes", icon: "folder",       dragFactory: doc.emptyNoteboard as Doc, },
             { toolTip: "Tap or drag to create a collection",      title: "Col", icon: "folder",         dragFactory: doc.emptyCollection as Doc, clickFactory: DocCast(doc.emptyTab),  scripts: { onClick: 'openOnRight(copyDragFactory(this.clickFactory))', onDragStart: '{ return copyDragFactory(this.dragFactory);}'}, },
             { toolTip: "Tap or drag to create an equation",       title: "Math", icon: "calculator",    dragFactory: doc.emptyEquation as Doc, },
             { toolTip: "Tap or drag to create a webpage",         title: "Web", icon: "globe-asia",     dragFactory: doc.emptyWebpage as Doc, },
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 3a1bb1673..f4987cf34 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -1,4 +1,4 @@
-import { action } from 'mobx';
+import { action, observable, runInAction } from 'mobx';
 import { DateField } from '../../fields/DateField';
 import { Doc, Field, Opt } from '../../fields/Doc';
 import { List } from '../../fields/List';
@@ -320,7 +320,7 @@ export namespace DragManager {
             y: snapVal([yFromTop, yFromBottom], e.pageY, SnappingManager.horizSnapLines()),
         };
     }
-    export let docsBeingDragged: Doc[] = [];
+    export let docsBeingDragged: Doc[] = observable([] as Doc[]);
     export let CanEmbed = false;
     export let DocDragData: DocumentDragData | undefined;
     export function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: DragCompleteEvent) => void) {
@@ -349,13 +349,13 @@ export namespace DragManager {
             xs: number[] = [],
             ys: number[] = [];
 
-        docsBeingDragged = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnchorAnnoDragData ? [dragData.dragDocument] : [];
         const elesCont = {
             left: Number.MAX_SAFE_INTEGER,
             right: Number.MIN_SAFE_INTEGER,
             top: Number.MAX_SAFE_INTEGER,
             bottom: Number.MIN_SAFE_INTEGER,
         };
+        const docsToDrag = dragData instanceof DocumentDragData ? dragData.draggedDocuments : dragData instanceof AnchorAnnoDragData ? [dragData.dragDocument] : [];
         const dragElements = eles.map(ele => {
             if (!ele.parentNode) dragDiv.appendChild(ele);
             const dragElement = ele.parentNode === dragDiv ? ele : (ele.cloneNode(true) as HTMLElement);
@@ -405,7 +405,7 @@ export namespace DragManager {
             });
             dragLabel.style.transform = `translate(${rect.left + (options?.offsetX || 0)}px, ${rect.top + (options?.offsetY || 0) - 20}px)`;
 
-            if (docsBeingDragged.length) {
+            if (docsToDrag.length) {
                 const pdfBox = dragElement.getElementsByTagName('canvas');
                 const pdfBoxSrc = ele.getElementsByTagName('canvas');
                 Array.from(pdfBox)
@@ -429,6 +429,8 @@ export namespace DragManager {
             return dragElement;
         });
 
+        runInAction(() => docsBeingDragged.push(...docsToDrag));
+
         const hideDragShowOriginalElements = (hide: boolean) => {
             dragLabel.style.display = hide ? '' : 'none';
             !hide && dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
@@ -456,7 +458,7 @@ export namespace DragManager {
             SnappingManager.SetIsDragging(false);
             SnappingManager.clearSnapLines();
             batch.end();
-            docsBeingDragged = [];
+            docsBeingDragged.length = 0;
         });
         var startWindowDragTimer: any;
         const moveHandler = (e: PointerEvent) => {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index c53e61699..0db9eab69 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -351,7 +351,7 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number; P
 
     @action
     onPointerDown = (e: React.PointerEvent): void => {
-        DragManager.docsBeingDragged = SelectionManager.Views().map(dv => dv.rootDoc);
+        DragManager.docsBeingDragged.push(...SelectionManager.Views().map(dv => dv.rootDoc));
         this._inkDragDocs = DragManager.docsBeingDragged
             .filter(doc => doc.type === DocumentType.INK)
             .map(doc => {
diff --git a/src/client/views/StyleProvider.tsx b/src/client/views/StyleProvider.tsx
index 692f7b98e..a83163eb0 100644
--- a/src/client/views/StyleProvider.tsx
+++ b/src/client/views/StyleProvider.tsx
@@ -110,8 +110,8 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
             return undefined;
         case StyleProp.WidgetColor:
             return isAnnotated ? Colors.LIGHT_BLUE : darkScheme() ? 'lightgrey' : 'dimgrey';
-            // return doc = dragManager.dragDocument ? props.dragEffects.opacity??CastofOpacityonline94 : Cast())
-            // same idea for background Color
+        // return doc = dragManager.dragDocument ? props.dragEffects.opacity??CastofOpacityonline94 : Cast())
+        // same idea for background Color
         case StyleProp.Opacity:
             return Cast(doc?._opacity, 'number', Cast(doc?.opacity, 'number', null));
         case StyleProp.HideLinkButton:
@@ -156,7 +156,9 @@ export function DefaultStyleProvider(doc: Opt<Doc>, props: Opt<DocumentViewProps
         case StyleProp.JitterRotation:
             return comicStyle() ? random(-1, 1, NumCast(doc?.x), NumCast(doc?.y)) * ((props?.PanelWidth() || 0) > (props?.PanelHeight() || 0) ? 5 : 10) : 0;
         case StyleProp.HeaderMargin:
-            return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) || (doc?.type === DocumentType.RTF && !showTitle()?.includes('noMargin')) || doc?.type === DocumentType.LABEL) &&
+            return ([CollectionViewType.Stacking, CollectionViewType.NoteTaking, CollectionViewType.Masonry, CollectionViewType.Tree].includes(doc?._viewType as any) ||
+                (doc?.type === DocumentType.RTF && !showTitle()?.includes('noMargin')) ||
+                doc?.type === DocumentType.LABEL) &&
                 showTitle() &&
                 !StrCast(doc?.showTitle).includes(':hover')
                 ? 15
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index f442559fb..1854a4213 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -1,6 +1,6 @@
 import React = require('react');
 import { CursorProperty } from 'csstype';
-import { action, computed, IReactionDisposer, observable, reaction } from 'mobx';
+import { action, computed, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from 'mobx-react';
 import { DataSym, Doc, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
 import { Id } from '../../../fields/FieldSymbols';
@@ -21,10 +21,12 @@ import { ContextMenuProps } from '../ContextMenuItem';
 import { LightboxView } from '../LightboxView';
 import { CollectionFreeFormDocumentView } from '../nodes/CollectionFreeFormDocumentView';
 import { DocFocusOptions, DocumentView, DocumentViewProps, ViewAdjustment } from '../nodes/DocumentView';
+import { FieldViewProps } from '../nodes/FieldView';
+import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import { StyleProp } from '../StyleProvider';
 import './CollectionNoteTakingView.scss';
 import { CollectionNoteTakingViewColumn } from './CollectionNoteTakingViewColumn';
-import CollectionNoteTakingViewDivider from './CollectionNoteTakingViewDivider';
+import { CollectionNoteTakingViewDivider } from './CollectionNoteTakingViewDivider';
 import { CollectionSubView } from './CollectionSubView';
 const _global = (window /* browser */ || global) /* node */ as any;
 
@@ -40,7 +42,6 @@ export type collectionNoteTakingViewProps = {
 
 @observer
 export class CollectionNoteTakingView extends CollectionSubView<Partial<collectionNoteTakingViewProps>>() {
-    _pivotFieldDisposer?: IReactionDisposer;
     _autoHeightDisposer?: IReactionDisposer;
     _masonryGridRef: HTMLDivElement | null = null;
     _draggerRef = React.createRef<HTMLDivElement>();
@@ -54,10 +55,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         return this.props.chromeHidden || BoolCast(this.layoutDoc.chromeHidden);
     }
     @computed get columnHeaders() {
-        return Cast(this.layoutDoc._columnHeaders, listSpec(SchemaHeaderField), null);
+        return Cast(this.dataDoc.columnHeaders, listSpec(SchemaHeaderField), null);
     }
-    @computed get pivotField() {
-        return 'Col';
+    @computed get notetakingCategoryField() {
+        return 'noteTakingCategory';
     }
     @computed get filteredChildren() {
         return this.childLayoutPairs.filter(pair => pair.layout instanceof Doc && !pair.layout.hidden).map(pair => pair.layout);
@@ -90,7 +91,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     constructor(props: any) {
         super(props);
         if (this.columnHeaders === undefined) {
-            this.layoutDoc._columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
+            this.dataDoc.columnHeaders = new List<SchemaHeaderField>([new SchemaHeaderField('New Column')]);
             this.columnStartXCoords = [0];
             // add all of the docs that have not been added to a column to this new column
         } else {
@@ -126,18 +127,16 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         // filter out the currently dragged docs from the child docs, since we will insert them later
         if (rowCol.length && DragManager.docsBeingDragged.length) {
             const docIdsToRemove = new Set();
-            DragManager.docsBeingDragged.forEach(d => {
-                docIdsToRemove.add(d[Id]);
-            });
+            DragManager.docsBeingDragged.forEach(d => docIdsToRemove.add(d[Id]));
             docs = docs.filter(d => !docIdsToRemove.has(d[Id]));
         }
 
         // this will sort the docs into the correct columns (minus the ones you're currently dragging)
         docs.map(d => {
-            if (!d[this.pivotField]) {
-                d[this.pivotField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
+            if (!d[this.notetakingCategoryField]) {
+                d[this.notetakingCategoryField] = columnHeaders.length > 0 ? columnHeaders[0].heading : `New Column`;
             }
-            const sectionValue = d[this.pivotField] as object;
+            const sectionValue = d[this.notetakingCategoryField] as object;
 
             // look for if header exists already
             const existingHeader = columnHeaders.find(sh => sh.heading === sectionValue.toString());
@@ -156,14 +155,15 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         return sections;
     }
 
+    removeDocDragHighlight = () => {
+        setTimeout(
+            action(() => (this.docsDraggedRowCol.length = 0)),
+            100
+        );
+    };
     componentDidMount() {
         super.componentDidMount?.();
-        // reset section headers when a new filter is inputted
-        this._pivotFieldDisposer = reaction(
-            () => this.pivotField,
-            () => (this.layoutDoc._columnHeaders = new List())
-        );
-
+        document.addEventListener('pointerup', this.removeDocDragHighlight, true);
         this._autoHeightDisposer = reaction(
             () => this.layoutDoc._autoHeight,
             autoHeight => autoHeight && this.props.setHeight?.(Math.min(NumCast(this.layoutDoc._maxHeight, Number.MAX_SAFE_INTEGER), this.headerMargin + Math.max(...this.refList.map(r => Number(getComputedStyle(r).height.replace('px', ''))))))
@@ -171,8 +171,8 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     }
 
     componentWillUnmount() {
+        document.removeEventListener('pointerup', this.removeDocDragHighlight, true);
         super.componentWillUnmount();
-        this._pivotFieldDisposer?.();
         this._autoHeightDisposer?.();
     }
 
@@ -227,6 +227,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     };
 
     styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewProps>, property: string) => {
+        if (property === StyleProp.BoxShadow && doc && DragManager.docsBeingDragged.includes(doc)) {
+            return `#9c9396  ${StrCast(doc?.boxShadow, '10px 10px 0.9vw')}`;
+        }
         if (property === StyleProp.Opacity && doc) {
             if (this.props.childOpacity) {
                 return this.props.childOpacity();
@@ -258,9 +261,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
                 docViewPath={this.props.docViewPath}
                 fitWidth={this.props.childFitWidth}
                 isContentActive={emptyFunction}
-                originalBackgroundColor={StrCast(doc.backgroundColor)}
+                onKey={this.onKeyDown}
                 //TODO: change this from a prop to a parameter passed into a function
-                isNoteTakingView={true}
+                dontHideOnDrag={true}
                 isDocumentActive={this.isContentActive}
                 LayoutTemplate={this.props.childLayoutTemplate}
                 LayoutTemplateString={this.props.childLayoutString}
@@ -307,7 +310,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
     // how to get the width of a document. Currently returns the width of the column (minus margins)
     // if a note doc. Otherwise, returns the normal width (for graphs, images, etc...)
     getDocWidth(d: Doc) {
-        const heading = d[this.pivotField] as object;
+        const heading = d[this.notetakingCategoryField] as object;
         const castedSectionValue = heading.toString();
         const existingHeader = this.columnHeaders.find(sh => sh.heading === castedSectionValue);
         const colStartXCoords = this.columnStartXCoords;
@@ -364,20 +367,14 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         if (DragManager.docsBeingDragged.length && this.childDocList) {
             // get the current docs for the column based on the mouse's x coordinate
             // will use again later, which is why we're saving as local
-            const xCoord = e.clientX - 2 * this.gridGap;
+            const xCoord = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0] - 2 * this.gridGap;
             const colDocs = this.getDocsFromXCoord(xCoord);
             // get the index for where you need to insert the doc you are currently dragging
-            const clientY = e.clientY;
+            const clientY = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[1];
             let dropInd = -1;
-            // unsure whether we still want this dropAfter field
-            // let dropAfter = 0;
-            // manually set to 140, because not sure how to get exact value
-            let pos0 = 140;
+            let pos0 = (this.refList.lastElement() as HTMLDivElement).children[0].getBoundingClientRect().height + this.yMargin * 2;
             colDocs.forEach((doc, i) => {
-                const noteTakingDocTransform = () => this.getDocTransform(doc);
-                let pos1 = noteTakingDocTransform()
-                    .inverse()
-                    .transformPoint(0, this.getDocHeight(doc) + 2 * this.gridGap)[1];
+                let pos1 = this.getDocHeight(doc) + 2 * this.gridGap;
                 pos1 += pos0;
                 // updating drop position based on y coordinates
                 const yCoordInBetween = clientY > pos0 && (clientY < pos1 || i == colDocs.length - 1);
@@ -393,10 +390,10 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
             // we alter the pivot fields of the docs in case they are moved to a new column.
             const colIndex = this.getColumnFromXCoord(xCoord);
             const colHeader = StrCast(this.columnHeaders[colIndex].heading);
-            DragManager.docsBeingDragged.forEach(d => (d[this.pivotField] = colHeader));
+            DragManager.docsBeingDragged.forEach(d => (d[this.notetakingCategoryField] = colHeader));
             // used to notify sections to re-render
-            // console.log([dropInd, this.getColumnFromXCoord(xCoord)])
-            this.docsDraggedRowCol = [dropInd, this.getColumnFromXCoord(xCoord)];
+            this.docsDraggedRowCol.length = 0;
+            this.docsDraggedRowCol.push(dropInd, this.getColumnFromXCoord(xCoord));
         }
     };
 
@@ -425,7 +422,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         if (docs) {
             docs.map(d => {
                 if (d instanceof Promise) return;
-                const sectionValue = d[this.pivotField] as object;
+                const sectionValue = d[this.notetakingCategoryField] as object;
                 if (sectionValue.toString() == colHeader) {
                     docsMatchingHeader.push(d);
                 }
@@ -434,13 +431,24 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
         return docsMatchingHeader;
     };
 
+    @undoBatch
+    @action
+    onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
+        const docView = fieldProps.DocumentView?.();
+        if (docView && (e.ctrlKey || docView.rootDoc._singleLine) && ['Enter'].includes(e.key)) {
+            e.stopPropagation?.();
+            const newDoc = Doc.MakeCopy(docView.rootDoc, true);
+            Doc.GetProto(newDoc).text = undefined;
+            FormattedTextBox.SelectOnLoad = newDoc[Id];
+            return this.addDocument?.(newDoc);
+        }
+    };
+
     @undoBatch
     @action
     onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
         if (de.complete.docDragData) {
             if (super.onInternalDrop(e, de)) {
-                DragManager.docsBeingDragged = [];
-                // this.docsDraggedRowCol = []
                 // filter out the currently dragged docs from the child docs, since we will insert them later
                 const rowCol = this.docsDraggedRowCol;
                 const droppedDocs = this.childDocs.slice().filter((d: Doc, ind: number) => ind >= this.childDocs.length); // if the drop operation adds something to the end of the list, then use that as the new document (may be different than what was dropped e.g., in the case of a button which is dropped but which creates say, a note).
@@ -456,10 +464,9 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
                     if (rowCol[0] <= 0) {
                         docs.splice(0, 0, ...newDocs);
                     } else {
-                        const colDocs = this.getDocsFromXCoord(de.x);
+                        const colDocs = this.getDocsFromXCoord(this.props.ScreenToLocalTransform().transformPoint(de.x, de.y)[0]);
                         const previousDoc = colDocs[rowCol[0] - 1];
                         const previousDocIndex = docs.indexOf(previousDoc);
-                        console.log(`docs: ${previousDocIndex}`);
                         docs.splice(previousDocIndex + 1, 0, ...newDocs);
                     }
                 }
@@ -561,7 +568,7 @@ export class CollectionNoteTakingView extends CollectionSubView<Partial<collecti
                 renderChildren={this.children}
                 numGroupColumns={this.numGroupColumns}
                 gridGap={this.gridGap}
-                pivotField={this.pivotField}
+                pivotField={this.notetakingCategoryField}
                 columnStartXCoords={this.columnStartXCoords}
                 maxColWidth={this.maxColWdith}
                 PanelWidth={this.PanelWidth}
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index bdcb9c399..55d032498 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,27 +1,27 @@
-import React = require("react");
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable } from "mobx";
-import { observer } from "mobx-react";
-import { Doc, DocListCast, Opt } from "../../../fields/Doc";
-import { Id } from "../../../fields/FieldSymbols";
-import { RichTextField } from "../../../fields/RichTextField";
-import { SchemaHeaderField } from "../../../fields/SchemaHeaderField";
-import { ScriptField } from "../../../fields/ScriptField";
-import { ImageField } from "../../../fields/URLField";
-import { TraceMobx } from "../../../fields/util";
-import { emptyFunction, returnEmptyString, setupMoveUpEvents } from "../../../Utils";
-import { Docs, DocUtils } from "../../documents/Documents";
-import { DocumentType } from "../../documents/DocumentTypes";
-import { DragManager } from "../../util/DragManager";
-import { SnappingManager } from "../../util/SnappingManager";
-import { Transform } from "../../util/Transform";
-import { undoBatch } from "../../util/UndoManager";
-import { ContextMenu } from "../ContextMenu";
-import { ContextMenuProps } from "../ContextMenuItem";
-import { EditableView } from "../EditableView";
-import { FormattedTextBox } from "../nodes/formattedText/FormattedTextBox";
-import "./CollectionNoteTakingView.scss";
-const higflyout = require("@hig/flyout");
+import React = require('react');
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { action, computed, observable } from 'mobx';
+import { observer } from 'mobx-react';
+import { Doc, DocListCast, Opt } from '../../../fields/Doc';
+import { Id } from '../../../fields/FieldSymbols';
+import { RichTextField } from '../../../fields/RichTextField';
+import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
+import { ScriptField } from '../../../fields/ScriptField';
+import { ImageField } from '../../../fields/URLField';
+import { TraceMobx } from '../../../fields/util';
+import { emptyFunction, returnEmptyString, setupMoveUpEvents } from '../../../Utils';
+import { Docs, DocUtils } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DragManager } from '../../util/DragManager';
+import { SnappingManager } from '../../util/SnappingManager';
+import { Transform } from '../../util/Transform';
+import { undoBatch } from '../../util/UndoManager';
+import { ContextMenu } from '../ContextMenu';
+import { ContextMenuProps } from '../ContextMenuItem';
+import { EditableView } from '../EditableView';
+import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
+import './CollectionNoteTakingView.scss';
+const higflyout = require('@hig/flyout');
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
 
@@ -39,7 +39,7 @@ interface CSVFieldColumnProps {
     // columnWidth: number;
     numGroupColumns: number;
     gridGap: number;
-    type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
+    type: 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function' | undefined;
     headings: () => object[];
     renderChildren: (docs: Doc[]) => JSX.Element[];
     addDocument: (doc: Doc | Doc[]) => boolean;
@@ -48,37 +48,37 @@ interface CSVFieldColumnProps {
     observeHeight: (myref: any) => void;
     unobserveHeight: (myref: any) => void;
     editableViewProps: any;
-    resizeColumns: (n: number) => void
-    columnStartXCoords: number[]
-    PanelWidth: number
-    maxColWidth: number
+    resizeColumns: (n: number) => void;
+    columnStartXCoords: number[];
+    PanelWidth: number;
+    maxColWidth: number;
     // docsByColumnHeader: Map<string, Doc[]>
     // setDocsForColHeader: (key: string, docs: Doc[]) => void
 }
 
 @observer
 export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColumnProps> {
-    @observable private _background = "inherit";
+    @observable private _background = 'inherit';
 
     @computed get columnWidth() {
-      // base cases
-      if (!this.props.columnHeaders || !this.props.headingObject || this.props.columnHeaders.length == 1) {
-        return this.props.maxColWidth
-      }
-      const i = this.props.columnHeaders.indexOf(this.props.headingObject)
-      if (i < 0) {
-        return this.props.maxColWidth
-      }
-      const endColValue = i == this.props.numGroupColumns - 1 ? this.props.PanelWidth : this.props.columnStartXCoords[i+1]
-      // TODO make the math work here. 35 is half of 70, which is the current width of the divider
-      return endColValue - this.props.columnStartXCoords[i] - 30
+        // base cases
+        if (!this.props.columnHeaders || !this.props.headingObject || this.props.columnHeaders.length == 1) {
+            return this.props.maxColWidth;
+        }
+        const i = this.props.columnHeaders.indexOf(this.props.headingObject);
+        if (i < 0) {
+            return this.props.maxColWidth;
+        }
+        const endColValue = i == this.props.numGroupColumns - 1 ? this.props.PanelWidth : this.props.columnStartXCoords[i + 1];
+        // TODO make the math work here. 35 is half of 70, which is the current width of the divider
+        return endColValue - this.props.columnStartXCoords[i] - 30;
     }
 
     private dropDisposer?: DragManager.DragDropDisposer;
     private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
 
     @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
-    @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+    @observable _color = this.props.headingObject ? this.props.headingObject.color : '#f1efeb';
     _ele: HTMLElement | null = null;
 
     // This is likely similar to what we will be doing. Why do we need to make these refs?
@@ -90,7 +90,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
             this.props.observeHeight(ele);
             this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
         }
-    }
+    };
 
     componentWillUnmount() {
         this.props.unobserveHeight(this._ele);
@@ -105,10 +105,10 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
     getValue = (value: string): any => {
         const parsed = parseInt(value);
         if (!isNaN(parsed)) return parsed;
-        if (value.toLowerCase().indexOf("true") > -1) return true;
-        if (value.toLowerCase().indexOf("false") > -1) return false;
+        if (value.toLowerCase().indexOf('true') > -1) return true;
+        if (value.toLowerCase().indexOf('false') > -1) return false;
         return value;
-    }
+    };
 
     @action
     headingChanged = (value: string, shiftDown?: boolean) => {
@@ -117,7 +117,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
             if (this.props.columnHeaders?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
                 return false;
             }
-            this.props.docList.forEach(d => d[this.props.pivotField] = castedValue);
+            this.props.docList.forEach(d => (d[this.props.pivotField] = castedValue));
             if (this.props.headingObject) {
                 this.props.headingObject.setHeading(castedValue.toString());
                 this._heading = this.props.headingObject.heading;
@@ -125,11 +125,11 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
             return true;
         }
         return false;
-    }
+    };
 
-    @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = "#b4b4b4");
-    @action pointerLeave = () => this._background = "inherit";
-    textCallback = (char: string) => this.addNewTextDoc("-typed text-", false, true);
+    @action pointerEntered = () => SnappingManager.GetIsDragging() && (this._background = '#b4b4b4');
+    @action pointerLeave = () => (this._background = 'inherit');
+    textCallback = (char: string) => this.addNewTextDoc('-typed text-', false, true);
 
     @action
     addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
@@ -139,46 +139,46 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
         const colValue = this.getValue(this.props.heading);
         newDoc[key] = colValue;
         FormattedTextBox.SelectOnLoad = newDoc[Id];
-        FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? "" : " ";
+        FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
         return this.props.addDocument?.(newDoc) || false;
-    }
+    };
 
     @action
     deleteColumn = () => {
         if (!this.props.columnHeaders) {
-          return
+            return;
         }
         if (this.props.headingObject) {
-          const index = this.props.columnHeaders.indexOf(this.props.headingObject);
-          const newIndex = index == 0 ? 1 : index - 1
-          const newHeader = this.props.columnHeaders[newIndex];
-          this.props.docList.forEach(d => d[this.props.pivotField] = newHeader.heading.toString())
-          this.props.columnHeaders.splice(index, 1);
-          this.props.resizeColumns(this.props.columnHeaders.length)
+            const index = this.props.columnHeaders.indexOf(this.props.headingObject);
+            const newIndex = index == 0 ? 1 : index - 1;
+            const newHeader = this.props.columnHeaders[newIndex];
+            this.props.docList.forEach(d => (d[this.props.pivotField] = newHeader.heading.toString()));
+            this.props.columnHeaders.splice(index, 1);
+            this.props.resizeColumns(this.props.columnHeaders.length);
         }
-    }
+    };
 
     headerDown = (e: React.PointerEvent<HTMLDivElement>) => setupMoveUpEvents(this, e, this.startDrag, emptyFunction, emptyFunction);
 
-    //TODO: I think this is where I'm supposed to edit stuff 
+    //TODO: I think this is where I'm supposed to edit stuff
     startDrag = (e: PointerEvent, down: number[], delta: number[]) => {
-        console.log('in startDrag')
+        console.log('in startDrag');
         // is MakeAlias a way to make a copy of a doc without rendering it?
         const alias = Doc.MakeAlias(this.props.Document);
         // alias._width = this.props.columnWidth / (this.props.columnHeaders?.length || 1);
         alias._width = this.columnWidth;
         alias._pivotField = undefined;
         let value = this.getValue(this._heading);
-        value = typeof value === "string" ? `"${value}"` : value;
+        value = typeof value === 'string' ? `"${value}"` : value;
         alias.viewSpecScript = ScriptField.MakeFunction(`doc.${this.props.pivotField} === ${value}`, { doc: Doc.name });
         if (alias.viewSpecScript) {
-            const options = {hideSource: false}
+            const options = { hideSource: false };
             DragManager.StartDocumentDrag([this._headerRef.current!], new DragManager.DocumentDragData([alias]), e.clientX, e.clientY, options);
-            console.log('in startDrag')
+            console.log('in startDrag');
             return true;
         }
         return false;
-    }
+    };
 
     menuCallback = (x: number, y: number) => {
         ContextMenu.Instance.clearItems();
@@ -187,44 +187,62 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
         const dataDoc = this.props.DataDoc || this.props.Document;
         const pivotValue = this.getValue(this.props.heading);
 
-        DocUtils.addDocumentCreatorMenuItems((doc) => {
-            const key = this.props.pivotField;
-            doc[key] = this.getValue(this.props.heading);
-            FormattedTextBox.SelectOnLoad = doc[Id];
-            return this.props.addDocument?.(doc);
-        }, this.props.addDocument, x, y, true, this.props.pivotField, pivotValue);
+        DocUtils.addDocumentCreatorMenuItems(
+            doc => {
+                const key = this.props.pivotField;
+                doc[key] = this.getValue(this.props.heading);
+                FormattedTextBox.SelectOnLoad = doc[Id];
+                return this.props.addDocument?.(doc);
+            },
+            this.props.addDocument,
+            x,
+            y,
+            true,
+            this.props.pivotField,
+            pivotValue
+        );
 
-        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof (dataDoc[fieldKey]) === "string").map(fieldKey =>
-            docItems.push({
-                description: ":" + fieldKey, event: () => {
-                    const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
-                    if (created) {
-                        if (this.props.Document.isTemplateDoc) {
-                            Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+        Array.from(Object.keys(Doc.GetProto(dataDoc)))
+            .filter(fieldKey => dataDoc[fieldKey] instanceof RichTextField || dataDoc[fieldKey] instanceof ImageField || typeof dataDoc[fieldKey] === 'string')
+            .map(fieldKey =>
+                docItems.push({
+                    description: ':' + fieldKey,
+                    event: () => {
+                        const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
+                        if (created) {
+                            if (this.props.Document.isTemplateDoc) {
+                                Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+                            }
+                            return this.props.addDocument?.(created);
                         }
-                        return this.props.addDocument?.(created);
-                    }
-                }, icon: "compress-arrows-alt"
-            }));
-        Array.from(Object.keys(Doc.GetProto(dataDoc))).filter(fieldKey => DocListCast(dataDoc[fieldKey]).length).map(fieldKey =>
-            docItems.push({
-                description: ":" + fieldKey, event: () => {
-                    const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
-                    if (created) {
-                        const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
-                        if (container.isTemplateDoc) {
-                            Doc.MakeMetadataFieldTemplate(created, container);
-                            return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+                    },
+                    icon: 'compress-arrows-alt',
+                })
+            );
+        Array.from(Object.keys(Doc.GetProto(dataDoc)))
+            .filter(fieldKey => DocListCast(dataDoc[fieldKey]).length)
+            .map(fieldKey =>
+                docItems.push({
+                    description: ':' + fieldKey,
+                    event: () => {
+                        const created = Docs.Create.CarouselDocument([], { _width: 400, _height: 200, title: fieldKey });
+                        if (created) {
+                            const container = this.props.Document.resolvedDataDoc ? Doc.GetProto(this.props.Document) : this.props.Document;
+                            if (container.isTemplateDoc) {
+                                Doc.MakeMetadataFieldTemplate(created, container);
+                                return Doc.AddDocToList(container, Doc.LayoutFieldKey(container), created);
+                            }
+                            return this.props.addDocument?.(created) || false;
                         }
-                        return this.props.addDocument?.(created) || false;
-                    }
-                }, icon: "compress-arrows-alt"
-            }));
-        !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Doc Fields ...", subitems: docItems, icon: "eye" });
-        !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: "Containers ...", subitems: layoutItems, icon: "eye" });
-        ContextMenu.Instance.setDefaultItem("::", (name: string): void => {
-            Doc.GetProto(this.props.Document)[name] = "";
-            const created = Docs.Create.TextDocument("", { title: name, _width: 250, _autoHeight: true });
+                    },
+                    icon: 'compress-arrows-alt',
+                })
+            );
+        !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Doc Fields ...', subitems: docItems, icon: 'eye' });
+        !Doc.UserDoc().noviceMode && ContextMenu.Instance.addItem({ description: 'Containers ...', subitems: layoutItems, icon: 'eye' });
+        ContextMenu.Instance.setDefaultItem('::', (name: string): void => {
+            Doc.GetProto(this.props.Document)[name] = '';
+            const created = Docs.Create.TextDocument('', { title: name, _width: 250, _autoHeight: true });
             if (created) {
                 if (this.props.Document.isTemplateDoc) {
                     Doc.MakeMetadataFieldTemplate(created, this.props.Document);
@@ -233,98 +251,100 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
             }
         });
         ContextMenu.Instance.displayMenu(x, y, undefined, true);
-    }
+    };
 
     @computed get innards() {
         TraceMobx();
         const key = this.props.pivotField;
         const heading = this._heading;
         const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin;
-        const evContents = heading ? heading : "25";
-        const headingView = this.props.headingObject ?
-            <div key={heading} className="collectionNoteTakingView-sectionHeader" ref={this._headerRef}
+        const evContents = heading ? heading : '25';
+        const headingView = this.props.headingObject ? (
+            <div
+                key={heading}
+                className="collectionNoteTakingView-sectionHeader"
+                ref={this._headerRef}
                 style={{
                     marginTop: 2 * this.props.yMargin,
                     // width: (this.props.columnWidth) /
                     //     ((uniqueHeadings.length) || 1)
-                    width: this.columnWidth - 20
+                    width: this.columnWidth - 20,
                 }}>
-                <div className="collectionNoteTakingView-sectionHeader-subCont" onPointerDown={this.headerDown}
-                    title={evContents === `No Value` ?
-                        `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
-                    style={{ background: evContents !== `No Value` ? this._color : "inherit" }}>
-                    <EditableView
-                        GetValue={() => evContents}
-                        SetValue={this.headingChanged}
-                        contents={evContents}
-                        oneLine={true}
-                    />
+                <div
+                    className="collectionNoteTakingView-sectionHeader-subCont"
+                    onPointerDown={this.headerDown}
+                    title={evContents === `No Value` ? `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ''}
+                    style={{ background: evContents !== `No Value` ? this._color : 'inherit' }}>
+                    <EditableView GetValue={() => evContents} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
                 </div>
-            </div> : (null);
+            </div>
+        ) : null;
         // const templatecols = `${this.props.columnWidth / this.props.numGroupColumns}px `;
         const templatecols = `${this.columnWidth}px `;
         const type = this.props.Document.type;
-        return <>
-            {headingView}
-            {<div>
-              <div key={`${heading}-stack`} className={`collectionNoteTakingView-Nodes`}
-                  style={{
-                      padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`,
-                      margin: "auto",
-                      width: "max-content", //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
-                      height: 'max-content',
-                      position: "relative",
-                      gridGap: this.props.gridGap,
-                      gridTemplateColumns: templatecols,
-                      gridAutoRows: "0px"
-                  }}>
-                  {this.props.renderChildren(this.props.docList)}
-              </div>
+        return (
+            <>
+                {headingView}
+                {
+                    <div>
+                        <div
+                            key={`${heading}-stack`}
+                            className={`collectionNoteTakingView-Nodes`}
+                            style={{
+                                padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`,
+                                margin: 'auto',
+                                width: 'max-content', //singleColumn ? undefined : `${cols * (style.columnWidth + style.gridGap) + 2 * style.xMargin - style.gridGap}px`,
+                                height: 'max-content',
+                                position: 'relative',
+                                gridGap: this.props.gridGap,
+                                gridTemplateColumns: templatecols,
+                                gridAutoRows: '0px',
+                            }}>
+                            {this.props.renderChildren(this.props.docList)}
+                        </div>
 
-              {!this.props.chromeHidden && type !== DocumentType.PRES ?
-                  <div className="collectionNoteTakingView-DocumentButtons"
-                      // style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10 }}>
-                      style={{ width: this.columnWidth - 20, marginBottom: 10 }}>
-                      <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton">
-                          <EditableView
-                              GetValue={returnEmptyString}
-                              SetValue={this.addNewTextDoc}
-                              textCallback={this.textCallback}
-                              placeholder={"Type ':' for commands"}
-                              contents={"+ New Node"}
-                              menuCallback={this.menuCallback}
-                          />
-                      </div>
-                      <div key={`${this.props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton">
-                          <EditableView {...this.props.editableViewProps} />
-                      </div>
-                      {(this.props.columnHeaders?.length && this.props.columnHeaders.length > 1) && 
-                          <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
-                          <FontAwesomeIcon icon="trash" size="lg" />
-                      </button>
-                      }
-                  </div>
-                  : null}
-              </div>
-            }
-        </>;
+                        {!this.props.chromeHidden && type !== DocumentType.PRES ? (
+                            <div
+                                className="collectionNoteTakingView-DocumentButtons"
+                                // style={{ width: this.props.columnWidth / this.props.numGroupColumns, marginBottom: 10 }}>
+                                style={{ width: this.columnWidth - 20, marginBottom: 10 }}>
+                                <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton">
+                                    <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.textCallback} placeholder={"Type ':' for commands"} contents={'+ New Node'} menuCallback={this.menuCallback} />
+                                </div>
+                                <div key={`${this.props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton">
+                                    <EditableView {...this.props.editableViewProps} />
+                                </div>
+                                {this.props.columnHeaders?.length && this.props.columnHeaders.length > 1 && (
+                                    <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
+                                        <FontAwesomeIcon icon="trash" size="lg" />
+                                    </button>
+                                )}
+                            </div>
+                        ) : null}
+                    </div>
+                }
+            </>
+        );
     }
 
-
     render() {
         TraceMobx();
         const heading = this._heading;
         return (
-            <div className={"collectionNoteTakingViewFieldColumn" + (SnappingManager.GetIsDragging() ? "Dragging" : "")} key={heading}
+            <div
+                className={'collectionNoteTakingViewFieldColumn' + (SnappingManager.GetIsDragging() ? 'Dragging' : '')}
+                key={heading}
                 style={{
-                  //TODO: change this so that it's based on the column width 
+                    //TODO: change this so that it's based on the column width
                     width: this.columnWidth,
-                    height: "100%",
-                    background: this._background
+                    height: '100%',
+                    background: this._background,
                 }}
-                ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
+                ref={this.createColumnDropRef}
+                onPointerEnter={this.pointerEntered}
+                onPointerLeave={this.pointerLeave}>
                 {this.innards}
-            </div >
+            </div>
         );
     }
-}
\ No newline at end of file
+}
diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index ed5dc3715..7d31b3193 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -1,61 +1,63 @@
-import { action, observable } from "mobx";
-import * as React from "react";
+import { action, observable } from 'mobx';
+import * as React from 'react';
 
 interface DividerProps {
-  index: number
-  xMargin: number
-  setColumnStartXCoords: (movementX: number, colIndex: number) => void
+    index: number;
+    xMargin: number;
+    setColumnStartXCoords: (movementX: number, colIndex: number) => void;
 }
 
-export default class Divider extends React.Component<DividerProps>{
-  @observable private isHoverActive = false;
-  @observable private isResizingActive = false;
-  
-  @action
-  private registerResizing = (e: React.PointerEvent<HTMLDivElement>) => {
-      e.stopPropagation();
-      e.preventDefault();
-      window.removeEventListener("pointermove", this.onPointerMove);
-      window.removeEventListener("pointerup", this.onPointerUp);
-      window.addEventListener("pointermove", this.onPointerMove);
-      window.addEventListener("pointerup", this.onPointerUp);
-      this.isResizingActive = true;
-  }
+export class CollectionNoteTakingViewDivider extends React.Component<DividerProps> {
+    @observable private isHoverActive = false;
+    @observable private isResizingActive = false;
 
-  @action
-  private onPointerUp = () => {
-      this.isResizingActive = false;
-      this.isHoverActive = false;
-      window.removeEventListener("pointermove", this.onPointerMove);
-      window.removeEventListener("pointerup", this.onPointerUp);
-  }
+    @action
+    private registerResizing = (e: React.PointerEvent<HTMLDivElement>) => {
+        e.stopPropagation();
+        e.preventDefault();
+        window.removeEventListener('pointermove', this.onPointerMove);
+        window.removeEventListener('pointerup', this.onPointerUp);
+        window.addEventListener('pointermove', this.onPointerMove);
+        window.addEventListener('pointerup', this.onPointerUp);
+        this.isResizingActive = true;
+    };
 
-  @action
-  onPointerMove = ({ movementX }: PointerEvent) => {
-    this.props.setColumnStartXCoords(movementX, this.props.index)
-  }
-  
-  render() {
-    return (
-      <div className="columnResizer"
-        style={{
-          display: "flex", 
-          alignItems: "center", 
-          cursor: "col-resize"
-        }}
-        onPointerEnter={action(() => this.isHoverActive = true)}
-        onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}
-      >
-        <div className="columnResizer-handler" onPointerDown={e => this.registerResizing(e)}
-          style={{
-            height: "95%",
-            width: 12,
-            borderRight: "4px solid #282828",
-            borderLeft: "4px solid #282828",
-            margin: "0px 10px"
-          }}
-        />
-      </div>
-    )
-  }
-}
\ No newline at end of file
+    @action
+    private onPointerUp = () => {
+        this.isResizingActive = false;
+        this.isHoverActive = false;
+        window.removeEventListener('pointermove', this.onPointerMove);
+        window.removeEventListener('pointerup', this.onPointerUp);
+    };
+
+    @action
+    onPointerMove = ({ movementX }: PointerEvent) => {
+        this.props.setColumnStartXCoords(movementX, this.props.index);
+    };
+
+    render() {
+        return (
+            <div
+                className="columnResizer"
+                style={{
+                    display: 'flex',
+                    alignItems: 'center',
+                    cursor: 'col-resize',
+                }}
+                onPointerEnter={action(() => (this.isHoverActive = true))}
+                onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}>
+                <div
+                    className="columnResizer-handler"
+                    onPointerDown={e => this.registerResizing(e)}
+                    style={{
+                        height: '95%',
+                        width: 12,
+                        borderRight: '4px solid #282828',
+                        borderLeft: '4px solid #282828',
+                        margin: '0px 10px',
+                    }}
+                />
+            </div>
+        );
+    }
+}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 1927db51e..ef68cadd7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -447,8 +447,6 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                 const newDocs = droppedDocs.length ? droppedDocs : de.complete.docDragData.droppedDocuments; // if nothing was added to the end of the list, then presumably the dropped documents were already in the list, but possibly got reordered so we use them.
 
                 const docs = this.childDocList;
-                // reset drag manager docs, because we just dropped
-                DragManager.docsBeingDragged = [];
                 // still figuring out where to add the document
                 if (docs && newDocs.length) {
                     const insertInd = dropInd === -1 ? docs.length : dropInd + dropAfter;
@@ -456,6 +454,8 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
                     newDocs.filter(ndoc => docs.indexOf(ndoc) !== -1).forEach(ndoc => docs.splice(docs.indexOf(ndoc), 1));
                     docs.splice(insertInd - offset, 0, ...newDocs);
                 }
+                // reset drag manager docs, because we just dropped
+                DragManager.docsBeingDragged.length = 0;
             }
         } else if (de.complete.linkDragData?.dragDocument.context === this.props.Document && de.complete.linkDragData?.linkDragView?.props.CollectionFreeFormDocumentView?.()) {
             const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, _fitWidth: true, title: 'dropped annotation' });
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index afb618b34..1ee1aec5a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -156,9 +156,7 @@ export interface DocumentViewSharedProps {
     scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
     createNewFilterDoc?: () => void;
     updateFilterDoc?: (doc: Doc) => void;
-    // Parker added both of these
-    originalBackgroundColor?: string;
-    isNoteTakingView?: boolean;
+    dontHideOnDrag?: boolean;
 }
 
 // these props are specific to DocuentViews
@@ -494,12 +492,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
     startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) {
         if (this._mainCont.current) {
             const dragData = new DragManager.DocumentDragData([this.props.Document]);
-            if (this.props.isNoteTakingView) {
-                dragData.draggedDocuments.forEach((doc) => {
-                doc.backgroundColor = "#C9DAEF";
-                doc.opacity = 0.5;
-              });
-            }
             const [left, top] = this.props.ScreenToLocalTransform().scale(this.NativeDimScaling).inverse().transformPoint(0, 0);
             dragData.offset = this.props
                 .ScreenToLocalTransform()
@@ -511,22 +503,16 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
             dragData.treeViewDoc = this.props.treeViewDoc;
             dragData.removeDocument = this.props.removeDocument;
             dragData.moveDocument = this.props.moveDocument;
-            //dragData.dimSource : 
-            // dragEffects field, set dim 
+            //dragData.dimSource :
+            // dragEffects field, set dim
             // add kv pairs to a doc, swap properties with the node while dragging, and then swap when dropping
             // add a dragEffects prop to DocumentView as a function that sets up. Each view has its own prop, when you start dragging:
-            // in Draganager, figure out which doc(s) you're dragging and change what opacity function returns  
+            // in Draganager, figure out which doc(s) you're dragging and change what opacity function returns
             const ffview = this.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
-            ffview && runInAction(() => (ffview.ChildDrag = this.props.DocumentView()));            
-            DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStar && !this.props.isNoteTakingView)},
-                () => setTimeout(action(() => {
-                  ffview && (ffview.ChildDrag = undefined)
-                  //TODO: is there a better way than adding another field to the props? Not quite sure how "this" works tbh
-                  if (this.props.isNoteTakingView) {
-                    this.props.Document.backgroundColor = "";
-                    this.props.Document.opacity = 1;
-                  }
-                }))); // this needs to happen after the drop event is processed.
+            ffview && runInAction(() => (ffview.ChildDrag = this.props.DocumentView()));
+            DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: hideSource || (!dropAction && !this.layoutDoc.onDragStart && !this.props.dontHideOnDrag) }, () =>
+                setTimeout(action(() => ffview && (ffview.ChildDrag = undefined)))
+            ); // this needs to happen after the drop event is processed.
             ffview?.setupDragLines(false);
         }
     }
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index b8ee89ef2..add83f4e0 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1001,7 +1001,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
             () => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, autoHeight: this.autoHeight, marginsHeight: this.autoHeightMargins }),
             ({ sidebarHeight, textHeight, autoHeight, marginsHeight }) => {
                 const newHeight = this.contentScaling * (marginsHeight + Math.max(sidebarHeight, textHeight));
-                autoHeight && newHeight && this.props.setHeight?.(newHeight);
+                if (autoHeight && newHeight && newHeight !== this.rootDoc.height) {
+                    this.props.setHeight?.(newHeight);
+                }
             },
             { fireImmediately: true }
         );
@@ -1695,7 +1697,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
             if (this.props.setHeight && scrollHeight && this.props.renderDepth && !this.props.dontRegisterView) {
                 // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
                 const setScrollHeight = () => (this.rootDoc[this.fieldKey + '-scrollHeight'] = scrollHeight);
-                if (this.rootDoc === this.layoutDoc.doc || this.layoutDoc.resolvedDataDoc) {
+                if (this.rootDoc === this.layoutDoc || this.layoutDoc.resolvedDataDoc) {
                     setScrollHeight();
                 } else {
                     setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template.  So set a timeout and hope its arrived...
-- 
cgit v1.2.3-70-g09d2


From a63f017c213563728f45f2caa7415843f50f3559 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 9 Aug 2022 19:50:33 -0400
Subject: fixed click on menu button for text box with hyperlink to not bring
 up buttonBar.  fixed right click on hyperlink to just bring up button bar,
 but not native context menu.  fixe stacking view child pointer events so that
 sidebar documents in lightbox are editable.

---
 src/client/views/DocumentButtonBar.tsx                    |  7 +------
 src/client/views/collections/CollectionStackingView.tsx   |  5 +++--
 src/client/views/nodes/formattedText/FormattedTextBox.tsx | 10 +++++-----
 3 files changed, 9 insertions(+), 13 deletions(-)

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

diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx
index 81e417fca..1f8550ad6 100644
--- a/src/client/views/DocumentButtonBar.tsx
+++ b/src/client/views/DocumentButtonBar.tsx
@@ -274,12 +274,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV
     get menuButton() {
         const targetDoc = this.view0?.props.Document;
         return !targetDoc ? null : (
-            <Tooltip
-                title={
-                    <>
-                        <div className="dash-tooltip">{`Open Context Menu`}</div>
-                    </>
-                }>
+            <Tooltip title={<div className="dash-tooltip">{`Open Context Menu`}</div>}>
                 <div className="documentButtonBar-icon" style={{ color: 'white', cursor: 'pointer' }} onClick={e => this.openContextMenu(e)}>
                     <FontAwesomeIcon className="documentdecorations-icon" icon="bars" />
                 </div>
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index ef68cadd7..d4efef47a 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -300,9 +300,10 @@ export class CollectionStackingView extends CollectionSubView<Partial<collection
             return this.addDocument?.(newDoc);
         }
     };
-    isContentActive = () => this.props.isSelected() || this.props.isContentActive();
+    isContentActive = () => (this.props.isSelected() || this.props.isContentActive() ? true : this.props.isSelected() === false || this.props.isContentActive() === false ? false : undefined);
 
-    isChildContentActive = () => this.props.isDocumentActive?.() && (this.props.childDocumentsActive?.() || BoolCast(this.rootDoc.childDocumentsActive));
+    isChildContentActive = () =>
+        this.props.isDocumentActive?.() && (this.props.childDocumentsActive?.() || BoolCast(this.rootDoc.childDocumentsActive)) ? true : this.props.childDocumentsActive?.() === false || this.rootDoc.childDocumentsActive === false ? false : undefined;
     // this is what renders the document that you see on the screen
     // called in Children: this actually adds a document to our children list
     getDisplayDoc(doc: Doc, width: () => number) {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index e027ab0bd..f61533619 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -703,9 +703,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
 
         const editor = this._editorView!;
         const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
-        let target = (e.target as any).parentElement; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
+        let target = e.target as any; // hrefs are stored on the database of the <a> node that wraps the hyerlink <span>
         while (target && !target.dataset?.targethrefs) target = target.parentElement;
-        if (target) {
+        if (target && !(e.nativeEvent as any).dash) {
             const hrefs = (target.dataset?.targethrefs as string)
                 ?.trim()
                 .split(' ')
@@ -724,6 +724,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                         AnchorMenu.Instance.jumpTo(e.clientX, e.clientY, true);
                     })
                 );
+            e.preventDefault();
             e.stopPropagation();
             return;
         }
@@ -1474,10 +1475,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
         document.removeEventListener('pointermove', this.onSelectMove);
     };
     onPointerUp = (e: React.PointerEvent): void => {
-        if (!this._editorView?.state.selection.empty && FormattedTextBox._canAnnotate) this.setupAnchorMenu();
+        if (!this._editorView?.state.selection.empty && FormattedTextBox._canAnnotate && !(e.nativeEvent as any).dash) this.setupAnchorMenu();
         if (!this._downEvent) return;
         this._downEvent = false;
-        if (this.props.isContentActive(true)) {
+        if (this.props.isContentActive(true) && !(e.nativeEvent as any).dash) {
             const editor = this._editorView!;
             const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
             !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0))));
@@ -1795,7 +1796,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
                 />
             ) : (
                 <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.props.DocumentView?.()!, false), true)}>
-                    //@ts-ignore
                     <ComponentTag
                         {...OmitKeys(this.props, ['NativeWidth', 'NativeHeight', 'setContentView']).omit}
                         NativeWidth={returnZero}
-- 
cgit v1.2.3-70-g09d2

