From 9b9f54a43793ca6ffb26c56f962d11ba8325abd2 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Fri, 29 Dec 2023 17:01:40 -0500
Subject: cleaned up imports, mobx observable initialization and some compile
 errors.

---
 src/client/views/collections/CollectionNoteTakingViewDivider.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index af822d917..2aad48d4a 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -1,4 +1,4 @@
-import { action, observable, trace } from 'mobx';
+import { action, observable } from 'mobx';
 import { observer } from 'mobx-react';
 import * as React from 'react';
 import { emptyFunction, setupMoveUpEvents } from '../../../Utils';
-- 
cgit v1.2.3-70-g09d2


From de3ca90be367a8c763b07e315caaad6de79f3f96 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 4 Jan 2024 22:29:17 -0500
Subject: fixed notetaking & pile views with _props

---
 src/client/util/SelectionManager.ts                |   2 +-
 .../views/collections/CollectionNoteTakingView.tsx | 103 +++++++++---------
 .../collections/CollectionNoteTakingViewColumn.tsx | 119 ++++++++++-----------
 .../CollectionNoteTakingViewDivider.tsx            |  13 +--
 .../views/collections/CollectionPileView.tsx       |  17 ++-
 5 files changed, 123 insertions(+), 131 deletions(-)

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

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 53e4a2853..f2a327445 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -58,7 +58,7 @@ export class SelectionManager {
             dv.IsSelected = false;
             dv._props.whenChildContentsActiveChanged(false);
         });
-        this.Instance.SelectedViews.length = 0;
+        runInAction(() => (this.Instance.SelectedViews.length = 0));
         if (found) this.SelectView(found, false);
     };
 
diff --git a/src/client/views/collections/CollectionNoteTakingView.tsx b/src/client/views/collections/CollectionNoteTakingView.tsx
index 527b72213..302ccd2db 100644
--- a/src/client/views/collections/CollectionNoteTakingView.tsx
+++ b/src/client/views/collections/CollectionNoteTakingView.tsx
@@ -51,7 +51,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     }
 
     @computed get chromeHidden() {
-        return BoolCast(this.layoutDoc.chromeHidden) || this.props.onBrowseClick?.() ? true : false;
+        return BoolCast(this.layoutDoc.chromeHidden) || this._props.onBrowseClick?.() ? true : false;
     }
     // columnHeaders returns the list of SchemaHeaderFields currently being used by the layout doc to render the columns
     @computed get colHeaderData() {
@@ -70,7 +70,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         return colHeaderData ?? ([] as SchemaHeaderField[]);
     }
     @computed get headerMargin() {
-        return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin);
+        return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin);
     }
     @computed get xMargin() {
         return NumCast(this.layoutDoc._xMargin, 5);
@@ -87,11 +87,11 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     }
     // PanelWidth returns the size of the total available space the view occupies
     @computed get PanelWidth() {
-        return this.props.PanelWidth();
+        return this._props.PanelWidth();
     }
     // maxColWidth returns the maximum column width, which is slightly less than the total available space.
     @computed get maxColWidth() {
-        return this.props.PanelWidth();
+        return this._props.PanelWidth();
     }
     // availableWidth is the total amount of non-divider width. Since widths are stored relatively,
     // we use availableWidth to convert from a percentage to a pixel count.
@@ -157,7 +157,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         this._disposers.layout_autoHeight = reaction(
             () => this.layoutDoc._layout_autoHeight,
             layout_autoHeight =>
-                layout_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', ''))))))
+                layout_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', ''))))))
         );
     }
 
@@ -167,9 +167,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         Object.keys(this._disposers).forEach(key => this._disposers[key]());
     }
 
-    @action
     moveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[], annotationKey?: string) => boolean, annotationKey?: string): boolean => {
-        return this.props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
+        return this._props.removeDocument?.(doc) && addDocument?.(doc) ? true : false;
     };
 
     createRef = (ele: HTMLDivElement | null) => {
@@ -178,11 +177,11 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     };
 
     @computed get onChildClickHandler() {
-        return () => this.props.childClickScript || ScriptCast(this.Document.onChildClick);
+        return () => this._props.childClickScript || ScriptCast(this.Document.onChildClick);
     }
 
     @computed get onChildDoubleClickHandler() {
-        return () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
+        return () => this._props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick);
     }
 
     scrollToBottom = () => {
@@ -196,7 +195,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
         if (found) {
             const top = found.getBoundingClientRect().top;
             const localTop = this.ScreenToLocalBoxXf().transformPoint(0, top);
-            if (Math.floor(localTop[1]) !== 0 && Math.ceil(this.props.PanelHeight()) < (this._mainCont?.scrollHeight || 0)) {
+            if (Math.floor(localTop[1]) !== 0 && Math.ceil(this._props.PanelHeight()) < (this._mainCont?.scrollHeight || 0)) {
                 let focusSpeed = options.zoomTime ?? 500;
                 smoothScroll(focusSpeed, this._mainCont!, localTop[1] + this._mainCont!.scrollTop, options.easeFunc);
                 return focusSpeed;
@@ -212,20 +211,20 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 }
                 break;
             case StyleProp.Opacity:
-                if (doc && this.props.childOpacity) {
-                    return this.props.childOpacity();
+                if (doc && this._props.childOpacity) {
+                    return this._props.childOpacity();
                 }
                 break;
         }
-        return this.props.styleProvider?.(doc, props, property);
+        return this._props.styleProvider?.(doc, props, property);
     };
 
-    isContentActive = () => this.props.isContentActive();
+    isContentActive = () => this._props.isContentActive();
 
     blockPointerEventsWhenDragging = () => (this.docsDraggedRowCol.length ? 'none' : undefined);
     // getDisplayDoc returns the rules for displaying a document in this view (ie. DocumentView)
     getDisplayDoc(doc: Doc, width: () => number) {
-        const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this.props.TemplateDataDocument;
+        const dataDoc = !doc.isTemplateDoc && !doc.isTemplateForField ? undefined : this._props.TemplateDataDocument;
         const height = () => this.getDocHeight(doc);
         let dref: Opt<DocumentView>;
         const noteTakingDocTransform = () => this.getDocTransform(doc, dref);
@@ -235,44 +234,44 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 Document={doc}
                 TemplateDataDocument={dataDoc ?? (!Doc.AreProtosEqual(doc[DocData], doc) ? doc[DocData] : undefined)}
                 pointerEvents={this.blockPointerEventsWhenDragging}
-                renderDepth={this.props.renderDepth + 1}
+                renderDepth={this._props.renderDepth + 1}
                 PanelWidth={width}
                 PanelHeight={height}
                 styleProvider={this.styleProvider}
-                docViewPath={this.props.docViewPath}
-                layout_fitWidth={this.props.childLayoutFitWidth}
+                docViewPath={this._props.docViewPath}
+                layout_fitWidth={this._props.childLayoutFitWidth}
                 isContentActive={emptyFunction}
                 onKey={this.onKeyDown}
                 //TODO: change this from a prop to a parameter passed into a function
                 dontHideOnDrag={true}
                 isDocumentActive={this.isContentActive}
-                LayoutTemplate={this.props.childLayoutTemplate}
-                LayoutTemplateString={this.props.childLayoutString}
-                NativeWidth={this.props.childIgnoreNativeSize ? returnZero : this.props.childLayoutFitWidth?.(doc) || (doc._layout_fitWidth && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
-                NativeHeight={this.props.childIgnoreNativeSize ? returnZero : this.props.childLayoutFitWidth?.(doc) || (doc._layout_fitWidth && !Doc.NativeHeight(doc)) ? height : undefined}
-                dontCenter={this.props.childIgnoreNativeSize ? 'xy' : undefined}
-                dontRegisterView={dataDoc ? true : BoolCast(this.layoutDoc.childDontRegisterViews, this.props.dontRegisterView)}
+                LayoutTemplate={this._props.childLayoutTemplate}
+                LayoutTemplateString={this._props.childLayoutString}
+                NativeWidth={this._props.childIgnoreNativeSize ? returnZero : this._props.childLayoutFitWidth?.(doc) || (doc._layout_fitWidth && !Doc.NativeWidth(doc)) ? width : undefined} // explicitly ignore nativeWidth/height if childIgnoreNativeSize is set- used by PresBox
+                NativeHeight={this._props.childIgnoreNativeSize ? returnZero : this._props.childLayoutFitWidth?.(doc) || (doc._layout_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}
-                layout_showTitle={this.props.childlayout_showTitle}
+                layout_showTitle={this._props.childlayout_showTitle}
                 dragAction={StrCast(this.layoutDoc.childDragAction) as dropActionType}
                 onClick={this.onChildClickHandler}
-                onBrowseClick={this.props.onBrowseClick}
+                onBrowseClick={this._props.onBrowseClick}
                 onDoubleClick={this.onChildDoubleClickHandler}
                 ScreenToLocalTransform={noteTakingDocTransform}
                 focus={this.focusDocument}
                 childFilters={this.childDocFilters}
-                hideDecorationTitle={this.props.childHideDecorationTitle}
-                hideResizeHandles={this.props.childHideResizeHandles}
+                hideDecorationTitle={this._props.childHideDecorationTitle}
+                hideResizeHandles={this._props.childHideResizeHandles}
                 childFiltersByRanges={this.childDocRangeFilters}
                 searchFilterDocs={this.searchFilterDocs}
-                addDocument={this.props.addDocument}
-                moveDocument={this.props.moveDocument}
-                removeDocument={this.props.removeDocument}
+                addDocument={this._props.addDocument}
+                moveDocument={this._props.moveDocument}
+                removeDocument={this._props.removeDocument}
                 contentPointerEvents={StrCast(this.layoutDoc.contentPointerEvents) as any}
-                whenChildContentsActiveChanged={this.props.whenChildContentsActiveChanged}
-                addDocTab={this.props.addDocTab}
+                whenChildContentsActiveChanged={this._props.whenChildContentsActiveChanged}
+                addDocTab={this._props.addDocTab}
                 bringToFront={returnFalse}
-                pinToPres={this.props.pinToPres}
+                pinToPres={this._props.pinToPres}
             />
         );
     }
@@ -299,17 +298,17 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     // 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 ? undefined : this.props.TemplateDataDocument;
-        const maxHeight = (lim => (lim === 0 ? this.props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
-        const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._width) : 0);
-        const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d)) ? NumCast(d._height) : 0);
+        const childLayoutDoc = Doc.Layout(d, this._props.childLayoutTemplate?.());
+        const childDataDoc = !d.isTemplateDoc && !d.isTemplateForField ? undefined : this._props.TemplateDataDocument;
+        const maxHeight = (lim => (lim === 0 ? this._props.PanelWidth() : lim === -1 ? 10000 : lim))(NumCast(this.layoutDoc.childLimitHeight, -1));
+        const nw = Doc.NativeWidth(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this._props.childLayoutFitWidth?.(d)) ? NumCast(d._width) : 0);
+        const nh = Doc.NativeHeight(childLayoutDoc, childDataDoc) || (!(childLayoutDoc._layout_fitWidth || this._props.childLayoutFitWidth?.(d)) ? NumCast(d._height) : 0);
         if (nw && nh) {
             const docWid = this.getDocWidth(d);
             return Math.min(maxHeight, (docWid * nh) / nw);
         }
         const childHeight = NumCast(childLayoutDoc._height);
-        const panelHeight = childLayoutDoc._layout_fitWidth || this.props.childLayoutFitWidth?.(d) ? Number.MAX_SAFE_INTEGER : this.props.PanelHeight() - 2 * this.yMargin;
+        const panelHeight = childLayoutDoc._layout_fitWidth || this._props.childLayoutFitWidth?.(d) ? Number.MAX_SAFE_INTEGER : this._props.PanelHeight() - 2 * this.yMargin;
         return Math.min(childHeight, maxHeight, panelHeight);
     }
 
@@ -407,7 +406,6 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     };
 
     @undoBatch
-    @action
     onKeyDown = (e: React.KeyboardEvent, fieldProps: FieldViewProps) => {
         const docView = fieldProps.DocumentView?.();
         if (docView && (e.ctrlKey || docView.Document._createDocOnCR) && ['Enter'].includes(e.key)) {
@@ -445,9 +443,9 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 }
                 return true;
             }
-        } else if (de.complete.linkDragData?.dragDocument.embedContainer === this.props.Document && de.complete.linkDragData?.linkDragView?.CollectionFreeFormDocumentView) {
+        } else if (de.complete.linkDragData?.dragDocument.embedContainer === this._props.Document && de.complete.linkDragData?.linkDragView?.CollectionFreeFormDocumentView) {
             const source = Docs.Create.TextDocument('', { _width: 200, _height: 75, _layout_fitWidth: true, title: 'dropped annotation' });
-            if (!this.props.addDocument?.(source)) e.preventDefault();
+            if (!this._props.addDocument?.(source)) e.preventDefault();
             de.complete.linkDocument = DocUtils.MakeLink(source, de.complete.linkDragData.linkSourceGetAnchor(), { link_relationship: 'doc annotation' }); // TODODO this is where in text links get passed
             e.stopPropagation();
             return true;
@@ -513,8 +511,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                             action((entries: any) => {
                                 if (this.layoutDoc._layout_autoHeight && ref && this.refList.length && !SnappingManager.IsDragging) {
                                     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);
+                                    if (!LightboxView.IsLightboxDocView(this._props.docViewPath())) {
+                                        this._props.setHeight?.(height);
                                     }
                                 }
                             })
@@ -522,13 +520,13 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                         this.observer.observe(ref);
                     }
                 }}
-                PanelWidth={this.props.PanelWidth}
-                select={this.props.select}
+                PanelWidth={this._props.PanelWidth}
+                select={this._props.select}
                 addDocument={this.addDocument}
                 chromeHidden={this.chromeHidden}
                 colHeaderData={this.colHeaderData}
                 Document={this.Document}
-                TemplateDataDocument={this.props.TemplateDataDocument}
+                TemplateDataDocument={this._props.TemplateDataDocument}
                 resizeColumns={this.resizeColumns}
                 renderChildren={this.children}
                 numGroupColumns={this.numGroupColumns}
@@ -555,7 +553,6 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     // addGroup is called when adding a new columnHeader, adding a SchemaHeaderField to our list of
     // columnHeaders and resizing the existing columns to make room for our new one.
     @undoBatch
-    @action
     addGroup = (value: string) => {
         if (this.colHeaderData) {
             for (const header of this.colHeaderData) {
@@ -619,7 +616,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
     }
 
     @computed get scaling() {
-        return !this.nativeWidth ? 1 : this.props.PanelHeight() / this.nativeHeight;
+        return !this.nativeWidth ? 1 : this._props.PanelHeight() / this.nativeHeight;
     }
 
     @computed get backgroundEvents() {
@@ -636,8 +633,8 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 ref={this.createRef}
                 key="notes"
                 style={{
-                    overflowY: this.props.isContentActive() ? 'auto' : 'hidden',
-                    background: this.props.styleProvider?.(this.Document, this.props, StyleProp.BackgroundColor),
+                    overflowY: this._props.isContentActive() ? 'auto' : 'hidden',
+                    background: this._props.styleProvider?.(this.Document, this._props, StyleProp.BackgroundColor),
                     pointerEvents: this.backgroundEvents,
                 }}
                 onScroll={action(e => (this._scroll = e.currentTarget.scrollTop))}
@@ -646,7 +643,7 @@ export class CollectionNoteTakingView extends CollectionSubView() {
                 onDragOver={e => this.onPointerMove(true, e.clientX, e.clientY)}
                 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>
         );
diff --git a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
index bb01a1782..265612d0d 100644
--- a/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewColumn.tsx
@@ -1,18 +1,17 @@
-import * as React from 'react';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, observable, trace } from 'mobx';
+import { action, computed, observable } from 'mobx';
 import { observer } from 'mobx-react';
+import * as React from 'react';
+import { returnEmptyString } from '../../../Utils';
 import { Doc, DocListCast, Opt } from '../../../fields/Doc';
-import { Copy, Id } from '../../../fields/FieldSymbols';
+import { Id } from '../../../fields/FieldSymbols';
 import { RichTextField } from '../../../fields/RichTextField';
 import { listSpec } from '../../../fields/Schema';
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { Cast, NumCast } from '../../../fields/Types';
 import { ImageField } from '../../../fields/URLField';
 import { TraceMobx } from '../../../fields/util';
-import { returnEmptyString } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
-import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils, Docs } from '../../documents/Documents';
 import { DragManager } from '../../util/DragManager';
 import { SnappingManager } from '../../util/SnappingManager';
 import { Transform } from '../../util/Transform';
@@ -20,6 +19,7 @@ import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from '../ContextMenu';
 import { ContextMenuProps } from '../ContextMenuItem';
 import { EditableView } from '../EditableView';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 import { FormattedTextBox } from '../nodes/formattedText/FormattedTextBox';
 import './CollectionNoteTakingView.scss';
 
@@ -58,41 +58,41 @@ interface CSVFieldColumnProps {
  * majority of functions here are for rendering styles.
  */
 @observer
-export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColumnProps> {
+export class CollectionNoteTakingViewColumn extends ObservableReactComponent<CSVFieldColumnProps> {
     @observable private _background = 'inherit';
 
     // columnWidth returns the width of a column in absolute pixels
     @computed get columnWidth() {
-        if (!this.props.colHeaderData || !this.props.headingObject || this.props.colHeaderData.length === 1) return `${(this.props.availableWidth / this.props.PanelWidth()) * 100}%`;
-        const i = this.props.colHeaderData.indexOf(this.props.headingObject);
-        return ((this.props.colHeaderData[i].width * this.props.availableWidth) / this.props.PanelWidth()) * 100 + '%';
+        if (!this._props.colHeaderData || !this._props.headingObject || this._props.colHeaderData.length === 1) return `${(this._props.availableWidth / this._props.PanelWidth()) * 100}%`;
+        const i = this._props.colHeaderData.indexOf(this._props.headingObject);
+        return ((this._props.colHeaderData[i].width * this._props.availableWidth) / this._props.PanelWidth()) * 100 + '%';
     }
 
     private dropDisposer?: DragManager.DragDropDisposer;
     private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
 
     public static ColumnMargin = 10;
-    @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
-    @observable _color = this.props.headingObject ? this.props.headingObject.color : '#f1efeb';
+    @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;
 
     createColumnDropRef = (ele: HTMLDivElement | null) => {
         this.dropDisposer?.();
         if (ele) {
             this._ele = ele;
-            this.props.observeHeight(ele);
+            this._props.observeHeight(ele);
             this.dropDisposer = DragManager.MakeDropTarget(ele, this.columnDrop.bind(this));
         }
     };
 
     componentWillUnmount() {
-        this.props.unobserveHeight(this._ele);
+        this._props.unobserveHeight(this._ele);
     }
 
     @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));
+        drop.docs?.forEach(d => Doc.SetInPlace(d, this._props.pivotField, drop.val, false));
         return true;
     });
 
@@ -108,13 +108,13 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
     headingChanged = (value: string, shiftDown?: boolean) => {
         const castedValue = this.getValue(value);
         if (castedValue) {
-            if (this.props.colHeaderData?.map(i => i.heading).indexOf(castedValue.toString()) !== -1) {
+            if (this._props.colHeaderData?.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;
+            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;
         }
@@ -130,26 +130,25 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
     @action
     addNewTextDoc = (value: string, shiftDown?: boolean, forceEmptyNote?: boolean) => {
         if (!value && !forceEmptyNote) return false;
-        const key = this.props.pivotField;
+        const key = this._props.pivotField;
         const newDoc = Docs.Create.TextDocument(value, { _height: 18, _width: 200, _layout_fitWidth: true, title: value, _layout_autoHeight: true });
-        const colValue = this.getValue(this.props.heading);
+        const colValue = this.getValue(this._props.heading);
         newDoc[key] = colValue;
         FormattedTextBox.SetSelectOnLoad(newDoc);
         FormattedTextBox.SelectOnLoadChar = forceEmptyNote ? '' : ' ';
-        return this.props.addDocument?.(newDoc) || false;
+        return this._props.addDocument?.(newDoc) || false;
     };
 
     // deleteColumn is called when a user deletes a column using the 'trash' icon in the button area.
     // If the user deletes the first column, the documents get moved to the second column. Otherwise,
     // all docs are added to the column directly to the left.
     @undoBatch
-    @action
     deleteColumn = () => {
-        const colHdrData = Array.from(Cast(this.props.Document[this.props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
-        if (this.props.headingObject) {
-            this.props.docList.forEach(d => (d[this.props.pivotField] = undefined));
-            colHdrData.splice(colHdrData.indexOf(this.props.headingObject), 1);
-            this.props.resizeColumns(colHdrData);
+        const colHdrData = Array.from(Cast(this._props.Document[this._props.fieldKey + '_columnHeaders'], listSpec(SchemaHeaderField), null));
+        if (this._props.headingObject) {
+            this._props.docList.forEach(d => (d[this._props.pivotField] = undefined));
+            colHdrData.splice(colHdrData.indexOf(this._props.headingObject), 1);
+            this._props.resizeColumns(colHdrData);
         }
     };
 
@@ -157,21 +156,21 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
         ContextMenu.Instance.clearItems();
         const layoutItems: ContextMenuProps[] = [];
         const docItems: ContextMenuProps[] = [];
-        const dataDoc = this.props.TemplateDataDocument || this.props.Document;
-        const pivotValue = this.getValue(this.props.heading);
+        const dataDoc = this._props.TemplateDataDocument || 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);
+                const key = this._props.pivotField;
+                doc[key] = this.getValue(this._props.heading);
                 FormattedTextBox.SetSelectOnLoad(doc);
-                return this.props.addDocument?.(doc);
+                return this._props.addDocument?.(doc);
             },
-            this.props.addDocument,
+            this._props.addDocument,
             x,
             y,
             true,
-            this.props.pivotField,
+            this._props.pivotField,
             pivotValue
         );
 
@@ -181,12 +180,12 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
                 docItems.push({
                     description: ':' + fieldKey,
                     event: () => {
-                        const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this.props.Document));
+                        const created = DocUtils.DocumentFromField(dataDoc, fieldKey, Doc.GetProto(this._props.Document));
                         if (created) {
-                            if (this.props.Document.isTemplateDoc) {
-                                Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+                            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',
@@ -200,12 +199,12 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
                     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;
+                            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',
@@ -214,13 +213,13 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
         !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] = '';
+            Doc.GetProto(this._props.Document)[name] = '';
             const created = Docs.Create.TextDocument('', { title: name, _width: 250, _layout_autoHeight: true });
             if (created) {
-                if (this.props.Document.isTemplateDoc) {
-                    Doc.MakeMetadataFieldTemplate(created, this.props.Document);
+                if (this._props.Document.isTemplateDoc) {
+                    Doc.MakeMetadataFieldTemplate(created, this._props.Document);
                 }
-                this.props.addDocument?.(created);
+                this._props.addDocument?.(created);
             }
         });
         ContextMenu.Instance.displayMenu(x, y, undefined, true);
@@ -228,26 +227,26 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
 
     @computed get innards() {
         TraceMobx();
-        const key = this.props.pivotField;
+        const key = this._props.pivotField;
         const heading = this._heading;
-        const columnYMargin = this.props.headingObject ? 0 : this.props.yMargin;
+        const columnYMargin = this._props.headingObject ? 0 : this._props.yMargin;
         const evContents = heading ? heading : '25';
-        const headingView = this.props.headingObject ? (
+        const headingView = this._props.headingObject ? (
             <div
                 key={heading}
                 className="collectionNoteTakingView-sectionHeader"
                 ref={this._headerRef}
                 style={{
-                    marginTop: 2 * this.props.yMargin,
+                    marginTop: 2 * this._props.yMargin,
                     width: 'calc(100% - 5px)',
                 }}>
                 <div
                     className="collectionNoteTakingView-sectionHeader-subCont"
                     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} isEditingCallback={isEditing => isEditing && this.props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
+                    <EditableView GetValue={() => evContents} isEditingCallback={isEditing => isEditing && this._props.select(false)} SetValue={this.headingChanged} contents={evContents} oneLine={true} />
                 </div>
-                {(this.props.colHeaderData?.length ?? 0) > 1 && (
+                {(this._props.colHeaderData?.length ?? 0) > 1 && (
                     <button className="collectionNoteTakingView-sectionDelete" onClick={this.deleteColumn}>
                         <FontAwesomeIcon icon="trash" size="lg" />
                     </button>
@@ -255,7 +254,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
             </div>
         ) : null;
         const templatecols = this.columnWidth;
-        const type = this.props.Document.type;
+        const type = this._props.Document.type;
         return (
             <>
                 {headingView}
@@ -265,20 +264,20 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
                             key={`${heading}-stack`}
                             className={`collectionNoteTakingView-Nodes`}
                             style={{
-                                padding: `${columnYMargin}px ${0}px ${this.props.yMargin}px ${0}px`,
-                                gridGap: this.props.gridGap,
+                                padding: `${columnYMargin}px ${0}px ${this._props.yMargin}px ${0}px`,
+                                gridGap: this._props.gridGap,
                                 gridTemplateColumns: templatecols,
                             }}>
-                            {this.props.renderChildren(this.props.docList)}
+                            {this._props.renderChildren(this._props.docList)}
                         </div>
 
-                        {!this.props.chromeHidden ? (
+                        {!this._props.chromeHidden ? (
                             <div className="collectionNoteTakingView-DocumentButtons" style={{ marginBottom: 10 }}>
                                 <div key={`${heading}-add-document`} className="collectionNoteTakingView-addDocumentButton">
                                     <EditableView GetValue={returnEmptyString} SetValue={this.addNewTextDoc} textCallback={this.addTextNote} 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 key={`${this._props.Document[Id]}-addGroup`} className="collectionNoteTakingView-addDocumentButton">
+                                    <EditableView {...this._props.editableViewProps()} />
                                 </div>
                             </div>
                         ) : null}
@@ -298,7 +297,7 @@ export class CollectionNoteTakingViewColumn extends React.Component<CSVFieldColu
                 style={{
                     width: this.columnWidth,
                     background: this._background,
-                    marginLeft: this.props.headings().findIndex((h: any) => h[0] === this.props.headingObject) === 0 ? NumCast(this.props.Document.xMargin) : 0,
+                    marginLeft: this._props.headings().findIndex((h: any) => h[0] === this._props.headingObject) === 0 ? NumCast(this._props.Document.xMargin) : 0,
                 }}
                 ref={this.createColumnDropRef}
                 onPointerEnter={this.pointerEntered}
diff --git a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
index 2aad48d4a..5e4bce19d 100644
--- a/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
+++ b/src/client/views/collections/CollectionNoteTakingViewDivider.tsx
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
 import * as React from 'react';
 import { emptyFunction, setupMoveUpEvents } from '../../../Utils';
 import { UndoManager } from '../../util/UndoManager';
+import { ObservableReactComponent } from '../ObservableReactComponent';
 
 interface DividerProps {
     index: number;
@@ -17,8 +18,7 @@ interface DividerProps {
  * are two simple vertical lines that allow the user to alter the widths of CollectionNoteTakingViewColumns.
  */
 @observer
-export class CollectionNoteTakingViewDivider extends React.Component<DividerProps> {
-    @observable private isHoverActive = false;
+export class CollectionNoteTakingViewDivider extends ObservableReactComponent<DividerProps> {
     @observable private isResizingActive = false;
 
     @action
@@ -29,12 +29,11 @@ export class CollectionNoteTakingViewDivider extends React.Component<DividerProp
             e,
             (e, down, delta) => {
                 if (!batch) batch = UndoManager.StartBatch('resizing');
-                this.props.setColumnStartXCoords(delta[0], this.props.index);
+                this._props.setColumnStartXCoords(delta[0], this._props.index);
                 return false;
             },
             action(() => {
                 this.isResizingActive = false;
-                this.isHoverActive = false;
                 batch?.end();
             }),
             emptyFunction
@@ -50,10 +49,8 @@ export class CollectionNoteTakingViewDivider extends React.Component<DividerProp
                     display: 'flex',
                     alignItems: 'center',
                     cursor: 'col-resize',
-                    pointerEvents: this.props.isContentActive() ? 'all' : 'none',
-                }}
-                onPointerEnter={action(() => (this.isHoverActive = true))}
-                onPointerLeave={action(() => !this.isResizingActive && (this.isHoverActive = false))}>
+                    pointerEvents: this._props.isContentActive() ? 'all' : 'none',
+                }}>
                 <div
                     className="columnResizer-handler"
                     onPointerDown={e => this.registerResizing(e)}
diff --git a/src/client/views/collections/CollectionPileView.tsx b/src/client/views/collections/CollectionPileView.tsx
index 359fdf543..b1d379631 100644
--- a/src/client/views/collections/CollectionPileView.tsx
+++ b/src/client/views/collections/CollectionPileView.tsx
@@ -41,14 +41,14 @@ export class CollectionPileView extends CollectionSubView() {
     @undoBatch
     addPileDoc = (doc: Doc | Doc[]) => {
         (doc instanceof Doc ? [doc] : doc).map(d => DocUtils.iconify(d));
-        return this.props.addDocument?.(doc) || false;
+        return this._props.addDocument?.(doc) || false;
     };
 
     @undoBatch
     removePileDoc = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
         (doc instanceof Doc ? [doc] : doc).forEach(d => Doc.deiconifyView(d));
-        const ret = this.props.moveDocument?.(doc, targetCollection, addDoc) || false;
-        if (ret && !DocListCast(this.dataDoc[this.fieldKey ?? 'data']).length) this.props.DocumentView?.()._props.removeDocument?.(this.Document);
+        const ret = this._props.moveDocument?.(doc, targetCollection, addDoc) || false;
+        if (ret && !DocListCast(this.dataDoc[this.fieldKey ?? 'data']).length) this._props.DocumentView?.()._props.removeDocument?.(this.Document);
         return ret;
     };
 
@@ -57,7 +57,7 @@ export class CollectionPileView extends CollectionSubView() {
     }
     @computed get contentEvents() {
         const isStarburst = this.layoutEngine() === computeStarburstLayout.name;
-        return this.props.isContentActive() && isStarburst ? undefined : 'none';
+        return this._props.isContentActive() && isStarburst ? undefined : 'none';
     }
 
     // returns the contents of the pileup in a CollectionFreeFormView
@@ -65,13 +65,13 @@ export class CollectionPileView extends CollectionSubView() {
         return (
             <div className="collectionPileView-innards" style={{ pointerEvents: this.contentEvents }}>
                 <CollectionFreeFormView
-                    {...this.props} //
+                    {...this._props} //
                     layoutEngine={this.layoutEngine}
                     addDocument={this.addPileDoc}
                     moveDocument={this.removePileDoc}
                     // pile children never have their contents active, but will be document active whenever the entire pile is.
                     childContentsActive={returnFalse}
-                    childDocumentsActive={this.props.isDocumentActive}
+                    childDocumentsActive={this._props.isDocumentActive}
                     childDragAction="move"
                     childClickScript={this.toggleIcon}
                 />
@@ -125,7 +125,7 @@ export class CollectionPileView extends CollectionSubView() {
                         const doc = this.childDocs[0];
                         doc.x = e.clientX;
                         doc.y = e.clientY;
-                        this.props.addDocTab(doc, OpenWhere.inParentFromScreen) && (this.props.removeDocument?.(doc) || false);
+                        this._props.addDocTab(doc, OpenWhere.inParentFromScreen) && (this._props.removeDocument?.(doc) || false);
                         dist = 0;
                     }
                 }
@@ -143,7 +143,6 @@ export class CollectionPileView extends CollectionSubView() {
 
     // onClick for toggling the pileup view
     @undoBatch
-    @action
     onClick = (e: React.MouseEvent) => {
         if (e.button === 0) {
             SelectionManager.DeselectAll();
@@ -154,7 +153,7 @@ export class CollectionPileView extends CollectionSubView() {
 
     render() {
         return (
-            <div className={`collectionPileView`} onClick={this.onClick} onPointerDown={this.pointerDown} style={{ width: this.props.PanelWidth(), height: '100%' }}>
+            <div className={`collectionPileView`} onClick={this.onClick} onPointerDown={this.pointerDown} style={{ width: this._props.PanelWidth(), height: '100%' }}>
                 {this.contents}
             </div>
         );
-- 
cgit v1.2.3-70-g09d2

