From fb76a0d66fc074a458706adf6fbb02492205b6e4 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Tue, 20 Aug 2019 12:54:44 -0400
Subject: factoring out masonry code into new file

---
 .../views/collections/CollectionStackingView.tsx   | 104 +++++++++++++--------
 1 file changed, 66 insertions(+), 38 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 2e4f6aff5..c2342eb50 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -23,6 +23,7 @@ import { CollectionSubView } from "./CollectionSubView";
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from "../ContextMenuItem";
 import { ScriptBox } from "../ScriptBox";
+import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
@@ -125,7 +126,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     }
     createRef = (ele: HTMLDivElement | null) => {
         this._masonryGridRef = ele;
-        this.createDropTarget(ele!);
+        this.createDropTarget(ele!); //so the whole grid is the drop target?
     }
 
     overlays = (doc: Doc) => {
@@ -282,45 +283,72 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             translate(offset[0], offset[1]).
             scale(NumCast(doc.width, 1) / this.columnWidth);
     }
-    masonryChildren(docs: Doc[]) {
-        this._docXfs.length = 0;
-        return docs.map((d, i) => {
-            let dref = React.createRef<HTMLDivElement>();
-            let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc);
-            let width = () => (d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth);/// (uniqueHeadings.length + 1);
-            let height = () => this.getDocHeight(layoutDoc);
-            let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
-            let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
-            this._docXfs.push({ dxf: dxf, width: width, height: height });
-            return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} >
-                {this.getDisplayDoc(layoutDoc, d, dxf, width)}
-            </div>;
-        });
-    }
+    // masonryChildren(docs: Doc[]) {
+    //     this._docXfs.length = 0;
+    //     return docs.map((d, i) => {
+    //         let dref = React.createRef<HTMLDivElement>();
+    //         let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc);
+    //         let width = () => (d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth);/// (uniqueHeadings.length + 1);
+    //         let height = () => this.getDocHeight(layoutDoc);
+    //         let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
+    //         let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
+    //         this._docXfs.push({ dxf: dxf, width: width, height: height });
+    //         return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} >
+    //             {this.getDisplayDoc(layoutDoc, d, dxf, width)}
+    //         </div>;
+    //     });
+    // }
+
+    // @observable _headingsHack: number = 1;
+    // sectionMasonry(heading: SchemaHeaderField | undefined, docList: Doc[]) {
+    //     let cols = Math.max(1, Math.min(docList.length,
+    //         Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
+    //     // let specialCols = () => this.isMasonryView ? 1 : Math.max(1, Math.min(docList.length,
+    //     //     Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
+    //     // let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
+    //     return <div ref={} key={heading ? heading.heading : "empty"} className="collectionStackingView-masonrySection">
+    //         {!heading ? (null) :
+    //             <div key={`${heading.heading}`} className="collectionStackingView-sectionHeader" style={{ background: heading.color }}
+    //                 onClick={action(() => this._headingsHack++ && heading.setCollapsed(!heading.collapsed))} >
+    //                 {heading.heading}
+    //             </div>}
+    //         {this._headingsHack && heading && heading.collapsed ? (null) :
+    //             <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
+    //                 style={{
+    //                     padding: `${this.yMargin}px ${this.xMargin}px`,
+    //                     width: `${cols * (this.columnWidth + this.gridGap) + 2 * this.xMargin - this.gridGap}px`,
+    //                     gridGap: this.gridGap,
+    //                     gridTemplateColumns: numberRange(cols).reduce((list, i) => list + ` ${this.columnWidth}px`, ""),
+    //                 }}>
+    //                 {this.masonryChildren(docList)}
+    //                 {this.columnDragger}
+    //             </div>
+    //         }
+    //     </div>;
+    // }
 
-    @observable _headingsHack: number = 1;
-    sectionMasonry(heading: SchemaHeaderField | undefined, docList: Doc[]) {
-        let cols = Math.max(1, Math.min(docList.length,
+    sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
+        let key = this.sectionFilter;
+        let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
+        let types = docList.length ? docList.map(d => typeof d[key]) : this.childDocs.map(d => typeof d[key]);
+        if (types.map((i, idx) => types.indexOf(i) === idx).length === 1) {
+            type = types[0];
+        }
+        let rows = () => !this.isStackingView ? 1 : Math.max(1, Math.min(docList.length,
             Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
-        return <div key={heading ? heading.heading : "empty"} className="collectionStackingView-masonrySection">
-            {!heading ? (null) :
-                <div key={`${heading.heading}`} className="collectionStackingView-sectionHeader" style={{ background: heading.color }}
-                    onClick={action(() => this._headingsHack++ && heading.setCollapsed(!heading.collapsed))} >
-                    {heading.heading}
-                </div>}
-            {this._headingsHack && heading && heading.collapsed ? (null) :
-                <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-                    style={{
-                        padding: `${this.yMargin}px ${this.xMargin}px`,
-                        width: `${cols * (this.columnWidth + this.gridGap) + 2 * this.xMargin - this.gridGap}px`,
-                        gridGap: this.gridGap,
-                        gridTemplateColumns: numberRange(cols).reduce((list, i) => list + ` ${this.columnWidth}px`, ""),
-                    }}>
-                    {this.masonryChildren(docList)}
-                    {this.columnDragger}
-                </div>
-            }
-        </div>;
+        return <CollectionMasonryViewFieldRow
+            key={heading ? heading.heading : ""}
+            rows={rows}
+            headings={this.headings}
+            heading={heading ? heading.heading : ""}
+            headingObject={heading}
+            docList={docList}
+            parent={this}
+            type={type}
+            createDropTarget={this.createDropTarget}
+            screenToLocalTransform={this.props.ScreenToLocalTransform}
+            color={heading ? heading.color : ""}
+        />;
     }
 
     @action
-- 
cgit v1.2.3-70-g09d2


From 86eac2d13f619f0e7d7ba4abeed0bd7d53d7e2d6 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Wed, 21 Aug 2019 12:03:25 -0400
Subject: can drag-drop in masonry

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 34 ++++++++++++----------
 .../views/collections/CollectionStackingView.scss  |  8 -----
 .../views/collections/CollectionStackingView.tsx   |  3 ++
 3 files changed, 21 insertions(+), 24 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 630d510a1..dbd7f9e3c 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -143,14 +143,14 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     @action
-    pointerEntered = () => {
+    pointerEnteredRow = () => {
         if (SelectionManager.GetIsDragging()) {
             this._background = "#b4b4b4";
         }
     }
 
     @action
-    pointerLeave = () => {
+    pointerLeaveRow = () => {
         this._background = "inherit";
         document.removeEventListener("pointermove", this.startDrag);
     }
@@ -249,6 +249,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @observable _headingsHack: number = 1;
     render() {
         let cols = this.props.rows();
+        let rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         let templatecols = "";
         let headings = this.props.headings();
@@ -302,22 +303,23 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         return (
             <div className="collectionStackingView-masonrySection"
                 key={heading = "empty"}
-                style={{ width: `${100 / ((uniqueHeadings.length + ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }}
-                ref={this.createRowDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave} >
+                style={{ width: this.props.parent.NodeWidth }}
+                ref={this.createRowDropRef}
+                onPointerEnter={this.pointerEnteredRow}
+                onPointerLeave={this.pointerLeaveRow}
+            >
                 {headingView}
                 {
-                    this._headingsHack && heading ? (null) :
-                        <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-                            style={{
-                                padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
-                                width: `${cols * (this.props.parent.columnWidth + this.props.parent.gridGap) + 2 * this.props.parent.xMargin - this.props.parent.gridGap}px`,
-                                gridGap: this.props.parent.gridGap,
-                                // gridTemplateColumns: undefined,
-                                gridTemplateColumns: numberRange(cols).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
-                            }}>
-                            {this.masonryChildren(this.props.docList)}
-                            {this.props.parent.columnDragger}
-                        </div>
+                    <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
+                        style={{
+                            padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
+                            width: this.props.parent.NodeWidth,
+                            gridGap: this.props.parent.gridGap,
+                            gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
+                        }}>
+                        {this.masonryChildren(this.props.docList)}
+                        {this.props.parent.columnDragger}
+                    </div>
                 }
                 { //controls the +NEW for each row
                     (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index a83c97624..deb295a41 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -294,12 +294,4 @@
     .rc-switch-checked .rc-switch-inner {
         left: 8px;
     }
-
-
-}
-
-.red-box {
-    width: 200px;
-    height: 200px;
-    background: red;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index c2342eb50..289c3a1fa 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -48,6 +48,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin,
             this.isStackingView ? Number.MAX_VALUE : NumCast(this.props.Document.columnWidth, 250));
     }
+    @computed get NodeWidth() {
+        return this.props.PanelWidth();
+    }
 
     childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); }
 
-- 
cgit v1.2.3-70-g09d2


From b895fcf2f63c4bddf413f9572964dfdfa083fd37 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Fri, 23 Aug 2019 12:59:17 -0400
Subject: masonry + stacking color, delete, collapse, drag

---
 src/client/views/EditableView.tsx                  | 30 +++++-----
 .../collections/CollectionMasonryViewFieldRow.tsx  | 32 +++++------
 .../views/collections/CollectionStackingView.tsx   | 43 --------------
 .../CollectionStackingViewFieldColumn.tsx          | 66 ++++++++++++++--------
 src/new_fields/SchemaHeaderField.ts                |  3 +-
 5 files changed, 75 insertions(+), 99 deletions(-)

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

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 87af19062..757ddbad1 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -41,8 +41,10 @@ export interface EditableProps {
     editing?: boolean;
     onClick?: (e: React.MouseEvent) => boolean;
     isEditingCallback?: (isEditing: boolean) => void;
-    // HeadingObject: SchemaHeaderField | undefined;
-    // HeadingsHack: number;
+    HeadingObject?: SchemaHeaderField | undefined;
+    HeadingsHack?: number;
+    toggle?: () => void;
+    color?: string | undefined;
 }
 
 /**
@@ -53,7 +55,6 @@ export interface EditableProps {
 @observer
 export class EditableView extends React.Component<EditableProps> {
     @observable _editing: boolean = false;
-    @observable _collapsed: boolean = false;
     @observable _headingsHack: number = 1;
 
     constructor(props: EditableProps) {
@@ -71,14 +72,13 @@ export class EditableView extends React.Component<EditableProps> {
         }
     }
 
-    // collapseSection() {
-    //     if (this.props.HeadingObject) {
-    //         this._headingsHack++;
-    //         this.props.HeadingObject.setCollapsed(!this.props.HeadingObject.collapsed);
-    //         this._collapsed = !this._collapsed;
-    //         console.log("THIS IS COLLAPSE FROM EDITABLEVIEW" + this._collapsed);
-    //     }
-    // }
+    collapseSection() {
+        if (this.props.HeadingObject) {
+            this._headingsHack++;
+            this.props.HeadingObject.setCollapsed(!this.props.HeadingObject.collapsed);
+            this.props.toggle && this.props.toggle();
+        }
+    }
 
     @action
     onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
@@ -107,13 +107,15 @@ export class EditableView extends React.Component<EditableProps> {
     @action
     onClick = (e: React.MouseEvent) => {
         e.nativeEvent.stopPropagation();
-        // if (e.ctrlKey) {
-        //     this.collapseSection();
-        // }
         if (!this.props.onClick || !this.props.onClick(e)) {
             this._editing = true;
             this.props.isEditingCallback && this.props.isEditingCallback(true);
         }
+        if (e.ctrlKey) {
+            this._editing = false;
+            this.props.isEditingCallback && this.props.isEditingCallback(false);
+            this.collapseSection();
+        }
         e.stopPropagation();
     }
 
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 8943fea3b..ca386f91b 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -248,7 +248,12 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @observable private collapsed: boolean = false;
 
+    private toggleVisibility = action(() => {
+        this.collapsed = !this.collapsed;
+    });
+
     @observable _headingsHack: number = 1;
+
     render() {
         let cols = this.props.rows();
         let rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
@@ -264,30 +269,23 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             SetValue: this.headingChanged,
             contents: evContents,
             oneLine: true,
-            // HeadingObject: this.props.headingObject,
-            // HeadingsHack: this._headingsHack
+            HeadingObject: this.props.headingObject,
+            HeadingsHack: this._headingsHack,
+            toggle: this.toggleVisibility,
+            color: this.props.color
         };
         let newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
             contents: "+ NEW",
-            // HeadingObject: this.props.headingObject,
-            // HeadingsHack: this._headingsHack
+            HeadingObject: this.props.headingObject,
+            HeadingsHack: this._headingsHack,
+            toggle: this.toggleVisibility,
+            color: this.props.color
         };
-        // let headingView = this.props.headingObject ?
         let headingView =
             <div>
-                <div key={`${this.props.heading}`} className="collectionStackingView-sectionHeader" style={{ background: this.props.color }}
-                    onClick={action(() => {
-                        if (this.props.headingObject) {
-                            this._headingsHack++;
-                            this.props.headingObject.setCollapsed(!this.props.headingObject.collapsed);
-                            this.collapsed = !this.collapsed;
-                            console.log("value of collapse: " + this.collapsed);
-                        }
-                    })}
-                >
-                    {this.props.heading}
+                <div className="collectionStackingView-sectionHeader">
                     <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.` : ""}
@@ -324,7 +322,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             >
                 {headingView}
                 {this.collapsed ? (null) :
-                    <div>
+                    < div >
                         <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
                             style={{
                                 padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 289c3a1fa..f0a8741af 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -286,49 +286,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             translate(offset[0], offset[1]).
             scale(NumCast(doc.width, 1) / this.columnWidth);
     }
-    // masonryChildren(docs: Doc[]) {
-    //     this._docXfs.length = 0;
-    //     return docs.map((d, i) => {
-    //         let dref = React.createRef<HTMLDivElement>();
-    //         let layoutDoc = Doc.expandTemplateLayout(d, this.props.DataDoc);
-    //         let width = () => (d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? Math.min(d[WidthSym](), this.columnWidth) : this.columnWidth);/// (uniqueHeadings.length + 1);
-    //         let height = () => this.getDocHeight(layoutDoc);
-    //         let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
-    //         let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
-    //         this._docXfs.push({ dxf: dxf, width: width, height: height });
-    //         return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} >
-    //             {this.getDisplayDoc(layoutDoc, d, dxf, width)}
-    //         </div>;
-    //     });
-    // }
-
-    // @observable _headingsHack: number = 1;
-    // sectionMasonry(heading: SchemaHeaderField | undefined, docList: Doc[]) {
-    //     let cols = Math.max(1, Math.min(docList.length,
-    //         Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
-    //     // let specialCols = () => this.isMasonryView ? 1 : Math.max(1, Math.min(docList.length,
-    //     //     Math.floor((this.props.PanelWidth() - 2 * this.xMargin) / (this.columnWidth + this.gridGap))));
-    //     // let type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined = undefined;
-    //     return <div ref={} key={heading ? heading.heading : "empty"} className="collectionStackingView-masonrySection">
-    //         {!heading ? (null) :
-    //             <div key={`${heading.heading}`} className="collectionStackingView-sectionHeader" style={{ background: heading.color }}
-    //                 onClick={action(() => this._headingsHack++ && heading.setCollapsed(!heading.collapsed))} >
-    //                 {heading.heading}
-    //             </div>}
-    //         {this._headingsHack && heading && heading.collapsed ? (null) :
-    //             <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-    //                 style={{
-    //                     padding: `${this.yMargin}px ${this.xMargin}px`,
-    //                     width: `${cols * (this.columnWidth + this.gridGap) + 2 * this.xMargin - this.gridGap}px`,
-    //                     gridGap: this.gridGap,
-    //                     gridTemplateColumns: numberRange(cols).reduce((list, i) => list + ` ${this.columnWidth}px`, ""),
-    //                 }}>
-    //                 {this.masonryChildren(docList)}
-    //                 {this.columnDragger}
-    //             </div>
-    //         }
-    //     </div>;
-    // }
 
     sectionMasonry = (heading: SchemaHeaderField | undefined, docList: Doc[]) => {
         let key = this.sectionFilter;
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index a3db46584..01bfd813b 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -247,6 +247,14 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         );
     }
 
+    @observable private collapsed: boolean = false;
+
+    private toggleVisibility = action(() => {
+        this.collapsed = !this.collapsed;
+    });
+
+    @observable _headingsHack: number = 1;
+
     render() {
         let cols = this.props.cols();
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
@@ -261,12 +269,20 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             GetValue: () => evContents,
             SetValue: this.headingChanged,
             contents: evContents,
-            oneLine: true
+            oneLine: true,
+            HeadingObject: this.props.headingObject,
+            HeadingsHack: this._headingsHack,
+            toggle: this.toggleVisibility,
+            color: this._color
         };
         let newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
-            contents: "+ NEW"
+            contents: "+ NEW",
+            HeadingObject: this.props.headingObject,
+            HeadingsHack: this._headingsHack,
+            toggle: this.toggleVisibility,
+            color: this._color
         };
         let headingView = this.props.headingObject ?
             <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
@@ -307,27 +323,31 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             <div className="collectionStackingViewFieldColumn" key={heading} style={{ width: `${100 / ((uniqueHeadings.length + ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)}%`, background: this._background }}
                 ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
                 {headingView}
-                <div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
-                    style={{
-                        padding: singleColumn ? `${style.yMargin}px ${0}px ${style.yMargin}px ${0}px` : `${style.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: style.gridGap,
-                        gridTemplateColumns: singleColumn ? undefined : templatecols,
-                        gridAutoRows: singleColumn ? undefined : "0px"
-                    }}
-                // ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}
-                >
-                    {this.children(this.props.docList)}
-                    {singleColumn ? (null) : this.props.parent.columnDragger}
-                </div>
-                {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
-                    <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
-                        style={{ width: style.columnWidth / style.numGroupColumns }}>
-                        <EditableView {...newEditableViewProps} />
-                    </div> : null}
+                {this.collapsed ? (null) :
+                    <div>
+                        <div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
+                            style={{
+                                padding: singleColumn ? `${style.yMargin}px ${0}px ${style.yMargin}px ${0}px` : `${style.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: style.gridGap,
+                                gridTemplateColumns: singleColumn ? undefined : templatecols,
+                                gridAutoRows: singleColumn ? undefined : "0px"
+                            }}
+                        // ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}
+                        >
+                            {this.children(this.props.docList)}
+                            {singleColumn ? (null) : this.props.parent.columnDragger}
+                        </div>
+                        {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
+                            <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
+                                style={{ width: style.columnWidth / style.numGroupColumns }}>
+                                <EditableView {...newEditableViewProps} />
+                            </div> : null}
+                    </div>
+                }
             </div>
         );
     }
diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts
index 7494c9bd1..92d0aec9a 100644
--- a/src/new_fields/SchemaHeaderField.ts
+++ b/src/new_fields/SchemaHeaderField.ts
@@ -105,5 +105,4 @@ export class SchemaHeaderField extends ObjectField {
     [ToScriptString]() {
         return `invalid`;
     }
-}
-
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 0ac0fd9cf2d93bf328b167710631cc46b1c27187 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Fri, 23 Aug 2019 16:27:25 -0400
Subject: autoheight works for masonry

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 56 +++++++++++-----------
 .../views/collections/CollectionStackingView.tsx   | 12 +++--
 src/client/views/pdf/Page.tsx                      |  2 +-
 3 files changed, 36 insertions(+), 34 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 04a94b9b9..e93ef673e 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -82,11 +82,11 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             let layoutDoc = Doc.expandTemplateLayout(d, parent.props.DataDoc);
             let width = () => (d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? Math.min(d[WidthSym](), parent.columnWidth) : parent.columnWidth);/// (uniqueHeadings.length + 1);
             let height = () => parent.getDocHeight(layoutDoc);
-            let dxf = () => parent.getDocTransform(layoutDoc, dref.current!);
+            let dxf = () => parent.getDocTransform(layoutDoc as Doc, dref.current!);
             let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
             parent._docXfs.push({ dxf: dxf, width: width, height: height });
             return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} >
-                {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)}
+                {this.props.parent.getDisplayDoc(layoutDoc as Doc, d, dxf, width)}
             </div>;
         });
     }
@@ -284,33 +284,31 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             color: this.props.color
         };
         let headingView =
-            <div>
-                <div className="collectionStackingView-sectionHeader">
-                    <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={{
-                            width: "100%",
-                            background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey",
-                            color: "grey"
-                        }}>
-                        {<EditableView {...headerEditableViewProps} />}
-                        {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
-                            <div className="collectionStackingView-sectionColor">
-                                <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
-                                    <button className="collectionStackingView-sectionColorButton">
-                                        <FontAwesomeIcon icon="palette" size="sm" />
-                                    </button>
-                                </ Flyout >
-                            </div>
-                        }
-                        {evContents === `NO ${key.toUpperCase()} VALUE` ?
-                            (null) :
-                            <button className="collectionStackingView-sectionDelete" onClick={this.deleteRow}>
-                                <FontAwesomeIcon icon="trash" />
-                            </button>}
-                    </div>
-                </div >
+            <div className="collectionStackingView-sectionHeader">
+                <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={{
+                        width: "100%",
+                        background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey",
+                        color: "grey"
+                    }}>
+                    {<EditableView {...headerEditableViewProps} />}
+                    {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+                        <div className="collectionStackingView-sectionColor">
+                            <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
+                                <button className="collectionStackingView-sectionColorButton">
+                                    <FontAwesomeIcon icon="palette" size="sm" />
+                                </button>
+                            </ Flyout >
+                        </div>
+                    }
+                    {evContents === `NO ${key.toUpperCase()} VALUE` ?
+                        (null) :
+                        <button className="collectionStackingView-sectionDelete" onClick={this.deleteRow}>
+                            <FontAwesomeIcon icon="trash" />
+                        </button>}
+                </div>
             </div >;
         return (
             <div className="collectionStackingView-masonrySection"
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 6d4ac54d6..678e10dc5 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -96,11 +96,15 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
         // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking views (masonry isn't yet supported).
         this._heightDisposer = reaction(() => {
-            if (this.isStackingView && BoolCast(this.props.Document.autoHeight)) {
+            if (BoolCast(this.props.Document.autoHeight)) {
                 let sectionsList = Array.from(this.Sections.size ? this.Sections.values() : [this.filteredChildren]);
-                return this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => Math.max(maxHght,
-                    (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)
-                ), 0);
+                if (this.isStackingView) {
+                    return this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => Math.max(maxHght,
+                        (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)), 0);
+                } else {
+                    return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
+                        (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 40, 0);
+                }
             }
             return -1;
         },
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 0de1777e6..6b039a6bc 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -64,7 +64,7 @@ export default class Page extends React.Component<IPageProps> {
         // lower scale = easier to read at small sizes, higher scale = easier to read at large sizes
         if (this._state !== "rendering" && !this._page && this._canvas.current && this._textLayer.current) {
             this._state = "rendering";
-            let viewport = page.getViewport(scale);
+            let viewport = page.getViewport(scale as any);
             this._canvas.current.width = this._width = viewport.width;
             this._canvas.current.height = this._height = viewport.height;
             this.props.pageLoaded(viewport);
-- 
cgit v1.2.3-70-g09d2


From 6770b483ad4ec1bfec8733ee86dd67e9146bf474 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Mon, 26 Aug 2019 14:18:57 -0400
Subject: create aliases using alt; still has orig problems

---
 .../collections/CollectionMasonryViewFieldRow.tsx     | 10 ++++++----
 .../views/collections/CollectionStackingView.tsx      |  2 +-
 .../collections/CollectionStackingViewFieldColumn.tsx | 19 +++++++++----------
 3 files changed, 16 insertions(+), 15 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index e93ef673e..bae2a1ff4 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -210,10 +210,12 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
 
-        document.removeEventListener("pointermove", this.startDrag);
-        document.addEventListener("pointermove", this.startDrag);
-        document.removeEventListener("pointerup", this.pointerUp);
-        document.addEventListener("pointerup", this.pointerUp);
+        if (e.altKey) { //release alt key before dropping alias; also, things must have existed outside of the collection first in order to be in the alias...
+            document.removeEventListener("pointermove", this.startDrag);
+            document.addEventListener("pointermove", this.startDrag);
+            document.removeEventListener("pointerup", this.pointerUp);
+            document.addEventListener("pointerup", this.pointerUp);
+        }
     }
 
     renderColorPicker = () => {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 678e10dc5..9c7816c39 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -94,7 +94,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             async (args) => args[1] instanceof Doc &&
                 this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined)));
 
-        // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking views (masonry isn't yet supported).
+        // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking and masonry views -eeng.
         this._heightDisposer = reaction(() => {
             if (BoolCast(this.props.Document.autoHeight)) {
                 let sectionsList = Array.from(this.Sections.size ? this.Sections.values() : [this.filteredChildren]);
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 5df58b0a0..4ec968438 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -78,19 +78,16 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         let parent = this.props.parent;
         parent._docXfs.length = 0;
         return docs.map((d, i) => {
-            const pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d);
-            if (!pair.layout || pair.data instanceof Promise) {
-                return (null);
-            }
+            let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d);
             let width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, parent.columnWidth / parent.numGroupColumns);
             let height = () => parent.getDocHeight(pair.layout);
             let dref = React.createRef<HTMLDivElement>();
-            let dxf = () => this.getDocTransform(pair.layout!, dref.current!);
+            let dxf = () => this.getDocTransform(pair.layout as Doc, dref.current!);
             this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height });
             let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
             let style = parent.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : parent.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
             return <div className={`collectionStackingView-${parent.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
-                {this.props.parent.getDisplayDoc(pair.layout, pair.data, dxf, width)}
+                {this.props.parent.getDisplayDoc(pair.layout as Doc, pair.data, dxf, width)}
             </div>;
         });
     }
@@ -214,10 +211,12 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
 
-        document.removeEventListener("pointermove", this.startDrag);
-        document.addEventListener("pointermove", this.startDrag);
-        document.removeEventListener("pointerup", this.pointerUp);
-        document.addEventListener("pointerup", this.pointerUp);
+        if (e.altKey) { //release alt key before dropping alias; also, things must have existed outside of the collection first in order to be in the alias...
+            document.removeEventListener("pointermove", this.startDrag);
+            document.addEventListener("pointermove", this.startDrag);
+            document.removeEventListener("pointerup", this.pointerUp);
+            document.addEventListener("pointerup", this.pointerUp);
+        }
     }
 
     renderColorPicker = () => {
-- 
cgit v1.2.3-70-g09d2


From 5a7ec36e558bdf5333cb7c16faad8f31bfcf314e Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Tue, 27 Aug 2019 11:53:00 -0400
Subject: fixed autoheight for masonry

---
 .../views/collections/CollectionMasonryViewFieldRow.tsx     | 13 ++++++-------
 src/client/views/collections/CollectionStackingView.tsx     |  3 +--
 .../views/collections/CollectionStackingViewFieldColumn.tsx |  1 -
 3 files changed, 7 insertions(+), 10 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index bae2a1ff4..1c1e44bb5 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -33,7 +33,6 @@ interface CMVFieldRowProps {
     type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
     createDropTarget: (ele: HTMLDivElement) => void;
     screenToLocalTransform: () => Transform;
-    color: string | undefined;
 }
 
 @observer
@@ -274,7 +273,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             HeadingObject: this.props.headingObject,
             HeadingsHack: this._headingsHack,
             toggle: this.toggleVisibility,
-            color: this.props.color
+            color: this._color
         };
         let newEditableViewProps = {
             GetValue: () => "",
@@ -283,10 +282,10 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             HeadingObject: this.props.headingObject,
             HeadingsHack: this._headingsHack,
             toggle: this.toggleVisibility,
-            color: this.props.color
+            color: this._color
         };
-        let headingView =
-            <div className="collectionStackingView-sectionHeader">
+        let headingView = this.props.headingObject ?
+            <div className="collectionStackingView-sectionHeader" ref={this._headerRef} >
                 <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.` : ""}
@@ -311,11 +310,11 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                             <FontAwesomeIcon icon="trash" />
                         </button>}
                 </div>
-            </div >;
+            </div > : (null);
         return (
             <div className="collectionStackingView-masonrySection"
                 key={heading = "empty"}
-                style={{ width: this.props.parent.NodeWidth }}
+                style={{ width: this.props.parent.NodeWidth, background: this._background }}
                 ref={this.createRowDropRef}
                 onPointerEnter={this.pointerEnteredRow}
                 onPointerLeave={this.pointerLeaveRow}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 9c7816c39..7ba177a7d 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -103,7 +103,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                         (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)), 0);
                 } else {
                     return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
-                        (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 40, 0);
+                        (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 47, 0);
                 }
             }
             return -1;
@@ -313,7 +313,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             type={type}
             createDropTarget={this.createDropTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
-            color={heading ? heading.color : ""}
         />;
     }
 
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 4ec968438..c0c4750eb 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -23,7 +23,6 @@ import "./CollectionStackingView.scss";
 
 library.add(faPalette);
 
-
 interface CSVFieldColumnProps {
     cols: () => number;
     headings: () => object[];
-- 
cgit v1.2.3-70-g09d2


From 5da8791dabdd3dd25e80fb320258ec809c22291e Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Thu, 5 Sep 2019 12:13:27 -0400
Subject: this is temporary

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 31 ++++++++++++++
 .../views/collections/CollectionStackingView.tsx   | 49 +++++++++++++++++++++-
 2 files changed, 78 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 1c1e44bb5..65e05ff28 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -33,6 +33,7 @@ interface CMVFieldRowProps {
     type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
     createDropTarget: (ele: HTMLDivElement) => void;
     screenToLocalTransform: () => Transform;
+    addToDocHeight: (thisHeight: number) => void;
 }
 
 @observer
@@ -43,17 +44,45 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     private dropDisposer?: DragManager.DragDropDisposer;
     private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
     private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+    private _contRef: React.RefObject<HTMLDivElement> = React.createRef();
     private _sensitivity: number = 16;
 
     @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
     @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
 
     createRowDropRef = (ele: HTMLDivElement | null) => {
+        console.log("createRowDropRef ran");
         this._dropRef = ele;
         this.dropDisposer && this.dropDisposer();
         if (ele) {
             this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
         }
+        // this.getTrueHeight();
+    }
+
+    getTrueHeight = () => { //handle collapse in here (if collapsed, return #)
+        //also, don't need to return anything
+        //call this in component did mount or something...
+        if (this.collapsed) {
+            this.props.addToDocHeight(20);
+            console.log("collapsed");
+        } else { //this is calculating the heights correctlty
+            let rawHeight = this._contRef.current!.getBoundingClientRect().height + 20;
+            let transformScale = this.props.screenToLocalTransform().Scale;
+            let trueHeight = rawHeight * transformScale;
+            this.props.addToDocHeight(trueHeight);
+            console.log("trueHeight: " + trueHeight);
+        }
+        this.props.addToDocHeight(20);
+    }
+
+    // componentDidMount = () => {
+    //     this.getTrueHeight();
+    // }
+
+    componentDidUpdate = () => {
+        console.log("componentDidUpdate");
+        this.getTrueHeight(); //why does this
     }
 
     @undoBatch
@@ -323,6 +352,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                 {this.collapsed ? (null) :
                     < div >
                         <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
+                            // ref={this.getTrueHeight}
+                            ref={this._contRef}
                             style={{
                                 padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
                                 width: this.props.parent.NodeWidth,
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 7ba177a7d..43a7333d0 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -25,6 +25,8 @@ import { ContextMenuProps } from "../ContextMenuItem";
 import { ScriptBox } from "../ScriptBox";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 
+let _height: number = 0;
+
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
@@ -34,7 +36,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _sectionFilterDisposer?: IReactionDisposer;
     _docXfs: any[] = [];
     _columnStart: number = 0;
+    // _height: number = 0;
     @observable private cursor: CursorProperty = "grab";
+    // @computed private _height: number = 0;
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
     @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
@@ -54,6 +58,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); }
 
+    addToDocHeight(sectionHeight: number) {
+        // if (_height !== undefined) {
+        console.log("indiv height: " + _height);
+        _height += sectionHeight;
+        // }
+        // return _height;
+    }
+
     get layoutDoc() {
         // if this document's layout field contains a document (ie, a rendering template), then we will use that
         // to determine the render JSX string, otherwise the layout field should directly contain a JSX layout string.
@@ -102,8 +114,40 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     return this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => Math.max(maxHght,
                         (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)), 0);
                 } else {
-                    return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
-                        (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 47, 0);
+                    // let rowArray: CollectionMasonryViewFieldRow[] = [];
+                    for (let i = 0; i < this.Sections.size; i++) {
+                        // rowArray.push(this._masonryGridRef);
+                    }
+                    let sum: number = 0;
+                    // let counter: number = 0;
+                    sum += _height; //calculated height of the node from the masonry prop
+                    // console.log("height: " + _height);
+                    if (this.sectionHeaders !== undefined) {
+                        // this.sectionHeaders.forEach(sec => {
+                        //     if (sec.collapsed) {
+                        //         sum += 20;
+                        //         console.log("sec collapsed");
+                        //     } else {
+                        //         // sum += sectionsList[counter].reduce((height, d, i) => height + this.childDocHeight(d) + (i === sectionsList[counter].length - 1 ? this.yMargin : this.gridGap), this.yMargin);
+                        //         // sum += NumCast(document.getElementsByClassName("collectionStackingView-sectionHeader-subCont").offsetHeight);
+                        //         // sum += this.addToDocHeight(this.Sections[counter]);
+                        //         // console.log("section is not collapsed");
+                        //         sum += _height;
+                        //         // this.addToDocHeight(40);
+                        //         // console.log("this._height in componentDidMount: " + _height);
+                        //     }
+                        //     // console.log("IN IF STATEMENT, sum is: " + sum);
+                        //     counter += 1;
+                        // });
+                    }
+                    // return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
+                    //     (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 47, 0);
+                    sum += 20; //allow space for the "add group" button
+                    console.log("sum: " + sum);
+                    _height = 0; //without this the height get HUGE (just keeps adding i think...)
+                    return this.props.ContentScaling() * (sum + (this.Sections.size ? 50 : 0)); //+47
+                    // return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
+                    //     (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 47, 0);
                 }
             }
             return -1;
@@ -313,6 +357,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             type={type}
             createDropTarget={this.createDropTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
+            addToDocHeight={this.addToDocHeight}
         />;
     }
 
-- 
cgit v1.2.3-70-g09d2


From a61a53106d799adb980773862ba28a1291221f2c Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Tue, 17 Sep 2019 18:09:16 -0400
Subject: autoheight works for masonry

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 108 +++++++++++----------
 .../views/collections/CollectionStackingView.tsx   |  65 ++++---------
 src/client/views/nodes/DocumentView.tsx            |   2 +-
 3 files changed, 74 insertions(+), 101 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 65e05ff28..b1afd09c2 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -20,6 +20,7 @@ import { anchorPoints, Flyout } from "../DocumentDecorations";
 import { EditableView } from "../EditableView";
 import { CollectionStackingView } from "./CollectionStackingView";
 import "./CollectionStackingView.scss";
+import Measure from "react-measure";
 
 library.add(faPalette);
 
@@ -33,7 +34,7 @@ interface CMVFieldRowProps {
     type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
     createDropTarget: (ele: HTMLDivElement) => void;
     screenToLocalTransform: () => Transform;
-    addToDocHeight: (thisHeight: number) => void;
+    setDocHeight: (key: string, thisHeight: number) => void;
 }
 
 @observer
@@ -51,38 +52,22 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @observable _color = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
 
     createRowDropRef = (ele: HTMLDivElement | null) => {
-        console.log("createRowDropRef ran");
         this._dropRef = ele;
         this.dropDisposer && this.dropDisposer();
         if (ele) {
             this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
         }
-        // this.getTrueHeight();
     }
 
-    getTrueHeight = () => { //handle collapse in here (if collapsed, return #)
-        //also, don't need to return anything
-        //call this in component did mount or something...
+    getTrueHeight = () => {
         if (this.collapsed) {
-            this.props.addToDocHeight(20);
-            console.log("collapsed");
-        } else { //this is calculating the heights correctlty
-            let rawHeight = this._contRef.current!.getBoundingClientRect().height + 20;
+            this.props.setDocHeight(this._heading, 20);
+        } else {
+            let rawHeight = this._contRef.current!.getBoundingClientRect().height + 15; //+ 15 accounts for the group header
             let transformScale = this.props.screenToLocalTransform().Scale;
             let trueHeight = rawHeight * transformScale;
-            this.props.addToDocHeight(trueHeight);
-            console.log("trueHeight: " + trueHeight);
+            this.props.setDocHeight(this._heading, trueHeight);
         }
-        this.props.addToDocHeight(20);
-    }
-
-    // componentDidMount = () => {
-    //     this.getTrueHeight();
-    // }
-
-    componentDidUpdate = () => {
-        console.log("componentDidUpdate");
-        this.getTrueHeight(); //why does this
     }
 
     @undoBatch
@@ -284,6 +269,15 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @observable _headingsHack: number = 1;
 
+    handleResize = (size: any) => {
+        this.counter += 1;
+        if (this.counter !== 1) {
+            this.getTrueHeight();
+        }
+    }
+
+    private counter: number = 0;
+
     render() {
         let cols = this.props.rows();
         let rows = Math.max(1, Math.min(this.props.docList.length, Math.floor((this.props.parent.props.PanelWidth() - 2 * this.props.parent.xMargin) / (this.props.parent.columnWidth + this.props.parent.gridGap))));
@@ -340,38 +334,46 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                         </button>}
                 </div>
             </div > : (null);
+        const background = this._background; //to account for observables in Measure
+        const collapsed = this.collapsed;
         return (
-            <div className="collectionStackingView-masonrySection"
-                key={heading = "empty"}
-                style={{ width: this.props.parent.NodeWidth, background: this._background }}
-                ref={this.createRowDropRef}
-                onPointerEnter={this.pointerEnteredRow}
-                onPointerLeave={this.pointerLeaveRow}
-            >
-                {headingView}
-                {this.collapsed ? (null) :
-                    < div >
-                        <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-                            // ref={this.getTrueHeight}
-                            ref={this._contRef}
-                            style={{
-                                padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
-                                width: this.props.parent.NodeWidth,
-                                gridGap: this.props.parent.gridGap,
-                                gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
-                            }}>
-                            {this.masonryChildren(this.props.docList)}
-                            {this.props.parent.columnDragger}
-                        </div>
-                        {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
-                            <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
-                                style={{ width: style.columnWidth / style.numGroupColumns }}>
-                                <EditableView {...newEditableViewProps} />
-                            </div> : null
-                        }
-                    </div>
-                }
-            </div >
+            <Measure offset onResize={this.handleResize}>
+                {({ measureRef }) => {
+                    return <div ref={measureRef}>
+                        <div className="collectionStackingView-masonrySection"
+                            key={heading = "empty"}
+                            style={{ width: this.props.parent.NodeWidth, background }}
+                            ref={this.createRowDropRef}
+                            onPointerEnter={this.pointerEnteredRow}
+                            onPointerLeave={this.pointerLeaveRow}
+                        >
+                            {headingView}
+                            {collapsed ? (null) :
+                                < div >
+                                    <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
+                                        // ref={this.getTrueHeight}
+                                        ref={this._contRef}
+                                        style={{
+                                            padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
+                                            width: this.props.parent.NodeWidth,
+                                            gridGap: this.props.parent.gridGap,
+                                            gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
+                                        }}>
+                                        {this.masonryChildren(this.props.docList)}
+                                        {this.props.parent.columnDragger}
+                                    </div>
+                                    {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
+                                        <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
+                                            style={{ width: style.columnWidth / style.numGroupColumns }}>
+                                            <EditableView {...newEditableViewProps} />
+                                        </div> : null
+                                    }
+                                </div>
+                            }
+                        </div >
+                    </div>;
+                }}
+            </Measure>
         );
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 43a7333d0..3cf4f98b7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -25,20 +25,19 @@ import { ContextMenuProps } from "../ContextMenuItem";
 import { ScriptBox } from "../ScriptBox";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 
-let _height: number = 0;
+// let _height: number = 0;
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
     _draggerRef = React.createRef<HTMLDivElement>();
+    @observable _heightMap = new Map<string, number>();
     _heightDisposer?: IReactionDisposer;
     _childLayoutDisposer?: IReactionDisposer;
     _sectionFilterDisposer?: IReactionDisposer;
     _docXfs: any[] = [];
     _columnStart: number = 0;
-    // _height: number = 0;
     @observable private cursor: CursorProperty = "grab";
-    // @computed private _height: number = 0;
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
     @computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
@@ -58,12 +57,9 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); }
 
-    addToDocHeight(sectionHeight: number) {
-        // if (_height !== undefined) {
-        console.log("indiv height: " + _height);
-        _height += sectionHeight;
-        // }
-        // return _height;
+    @action
+    setDocHeight = (key: string, sectionHeight: number) => {
+        this._heightMap.set(key, sectionHeight);
     }
 
     get layoutDoc() {
@@ -103,10 +99,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     componentDidMount() {
         this._childLayoutDisposer = reaction(() => [this.childDocs, Cast(this.props.Document.childLayout, Doc)],
-            async (args) => args[1] instanceof Doc &&
-                this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined)));
+            async (args) => {
+                args[1] instanceof Doc &&
+                    this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined));
+            })
+
 
-        // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking and masonry views -eeng.
+        // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking and masonry views -eeng
         this._heightDisposer = reaction(() => {
             if (BoolCast(this.props.Document.autoHeight)) {
                 let sectionsList = Array.from(this.Sections.size ? this.Sections.values() : [this.filteredChildren]);
@@ -114,40 +113,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     return this.props.ContentScaling() * sectionsList.reduce((maxHght, s) => Math.max(maxHght,
                         (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)), 0);
                 } else {
-                    // let rowArray: CollectionMasonryViewFieldRow[] = [];
-                    for (let i = 0; i < this.Sections.size; i++) {
-                        // rowArray.push(this._masonryGridRef);
-                    }
-                    let sum: number = 0;
-                    // let counter: number = 0;
-                    sum += _height; //calculated height of the node from the masonry prop
-                    // console.log("height: " + _height);
-                    if (this.sectionHeaders !== undefined) {
-                        // this.sectionHeaders.forEach(sec => {
-                        //     if (sec.collapsed) {
-                        //         sum += 20;
-                        //         console.log("sec collapsed");
-                        //     } else {
-                        //         // sum += sectionsList[counter].reduce((height, d, i) => height + this.childDocHeight(d) + (i === sectionsList[counter].length - 1 ? this.yMargin : this.gridGap), this.yMargin);
-                        //         // sum += NumCast(document.getElementsByClassName("collectionStackingView-sectionHeader-subCont").offsetHeight);
-                        //         // sum += this.addToDocHeight(this.Sections[counter]);
-                        //         // console.log("section is not collapsed");
-                        //         sum += _height;
-                        //         // this.addToDocHeight(40);
-                        //         // console.log("this._height in componentDidMount: " + _height);
-                        //     }
-                        //     // console.log("IN IF STATEMENT, sum is: " + sum);
-                        //     counter += 1;
-                        // });
-                    }
-                    // return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
-                    //     (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 47, 0);
-                    sum += 20; //allow space for the "add group" button
-                    console.log("sum: " + sum);
-                    _height = 0; //without this the height get HUGE (just keeps adding i think...)
-                    return this.props.ContentScaling() * (sum + (this.Sections.size ? 50 : 0)); //+47
-                    // return this.props.ContentScaling() * sectionsList.reduce((totalHeight, s) => totalHeight +
-                    //     (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin) + 47, 0);
+                    let sum = Array.from(this._heightMap.values()).reduce((acc: number, curr: number) => acc += curr, 0);
+                    // let transformScale = this.props.ScreenToLocalTransform().Scale;
+                    // let trueHeight = 30 * transformScale;
+                    // sum += trueHeight;
+                    sum += 30;
+                    return this.props.ContentScaling() * (sum + (this.Sections.size ? 50 : 0));
                 }
             }
             return -1;
@@ -357,7 +328,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             type={type}
             createDropTarget={this.createDropTarget}
             screenToLocalTransform={this.props.ScreenToLocalTransform}
-            addToDocHeight={this.addToDocHeight}
+            setDocHeight={this.setDocHeight}
         />;
     }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6c944c6b2..7cbd96354 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -601,7 +601,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
                 this.makeBtnClicked();
             }, icon: "window-restore"
         });
-        makes.push({ description: this.props.Document.ignoreClick ? "Selectable" : "Unselectable", event: () => this.props.Document.ignoreClick = !this.props.Document.ignoreClick, icon: this.props.Document.ignoreClick ? "unlock" : "lock" })
+        makes.push({ description: this.props.Document.ignoreClick ? "Selectable" : "Unselectable", event: () => this.props.Document.ignoreClick = !this.props.Document.ignoreClick, icon: this.props.Document.ignoreClick ? "unlock" : "lock" });
         !existingMake && cm.addItem({ description: "Make...", subitems: makes, icon: "hand-point-right" });
         let existing = ContextMenu.Instance.findByDescription("Layout...");
         let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : [];
-- 
cgit v1.2.3-70-g09d2


From d9b217a3a8f963096e0a1b8658a31b9df9a5f82c Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Tue, 17 Sep 2019 18:09:51 -0400
Subject: ;

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

(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 3cf4f98b7..3fec7a85f 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -102,7 +102,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             async (args) => {
                 args[1] instanceof Doc &&
                     this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined));
-            })
+            });
 
 
         // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking and masonry views -eeng
-- 
cgit v1.2.3-70-g09d2


From 2e6c8efbcea67d345023db679de15f294a792dc5 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Tue, 24 Sep 2019 18:09:31 -0400
Subject: Initial menu for header capabilities

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 11 +++----
 .../views/collections/CollectionStackingView.scss  | 38 +++++++++++++++++++++-
 .../views/collections/CollectionStackingView.tsx   |  7 ----
 .../CollectionStackingViewFieldColumn.tsx          | 31 +++++++++++++++---
 4 files changed, 68 insertions(+), 19 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index b1afd09c2..38f7493de 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -327,11 +327,11 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                             </ Flyout >
                         </div>
                     }
-                    {evContents === `NO ${key.toUpperCase()} VALUE` ?
-                        (null) :
-                        <button className="collectionStackingView-sectionDelete" onClick={this.deleteRow}>
-                            <FontAwesomeIcon icon="trash" />
-                        </button>}
+                    {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
+                        <button className="collectionStackingView-sectionOptions" onClick={this.deleteRow}>
+                            <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
+                        </button>
+                    }
                 </div>
             </div > : (null);
         const background = this._background; //to account for observables in Measure
@@ -351,7 +351,6 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                             {collapsed ? (null) :
                                 < div >
                                     <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-                                        // ref={this.getTrueHeight}
                                         ref={this._contRef}
                                         style={{
                                             padding: `${this.props.parent.yMargin}px ${this.props.parent.xMargin}px`,
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index deb295a41..f34b3768b 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -138,7 +138,7 @@
             .editableView-input:hover,
             .editableView-container-editing:hover,
             .editableView-container-editing-oneLine:hover {
-                cursor: text
+                cursor: text;
             }
 
             .editableView-input {
@@ -188,6 +188,42 @@
             }
         }
 
+        .collectionStackingView-sectionOptions {
+            position: absolute;
+            right: 0;
+            top: 0;
+            height: 100%;
+
+            [class*="css"] {
+                max-width: 102px;
+            }
+
+            .collectionStackingView-sectionOptionButton {
+                height: 35px;
+            }
+
+            .collectionStackingView-optionPicker {
+                width: 78px;
+
+                .optionOptions {
+                    display: inline;
+                }
+
+                .optionPicker {
+                    cursor: pointer;
+                    width: 20px;
+                    height: 20px;
+                    border-radius: 10px;
+                    margin: 3px;
+
+                    &.active {
+                        border: 2px solid white;
+                        box-shadow: 0 0 0 2px lightgray;
+                    }
+                }
+            }
+        }
+
         .collectionStackingView-sectionDelete {
             position: absolute;
             right: 0;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 3fec7a85f..9c6d5c52a 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -25,8 +25,6 @@ import { ContextMenuProps } from "../ContextMenuItem";
 import { ScriptBox } from "../ScriptBox";
 import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 
-// let _height: number = 0;
-
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
@@ -103,8 +101,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                 args[1] instanceof Doc &&
                     this.childDocs.map(async doc => !Doc.AreProtosEqual(args[1] as Doc, (await doc).layout as Doc) && Doc.ApplyTemplateTo(args[1] as Doc, (await doc), undefined));
             });
-
-
         // is there any reason this needs to exist? -syip.  yes, it handles autoHeight for stacking and masonry views -eeng
         this._heightDisposer = reaction(() => {
             if (BoolCast(this.props.Document.autoHeight)) {
@@ -114,9 +110,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                         (this.Sections.size ? 50 : 0) + s.reduce((height, d, i) => height + this.childDocHeight(d) + (i === s.length - 1 ? this.yMargin : this.gridGap), this.yMargin)), 0);
                 } else {
                     let sum = Array.from(this._heightMap.values()).reduce((acc: number, curr: number) => acc += curr, 0);
-                    // let transformScale = this.props.ScreenToLocalTransform().Scale;
-                    // let trueHeight = 30 * transformScale;
-                    // sum += trueHeight;
                     sum += 30;
                     return this.props.ContentScaling() * (sum + (this.Sections.size ? 50 : 0));
                 }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index c0c4750eb..aacf8ad4b 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -20,6 +20,7 @@ import { anchorPoints, Flyout } from "../DocumentDecorations";
 import { EditableView } from "../EditableView";
 import { CollectionStackingView } from "./CollectionStackingView";
 import "./CollectionStackingView.scss";
+import Measure from "react-measure";
 
 library.add(faPalette);
 
@@ -38,6 +39,9 @@ interface CSVFieldColumnProps {
 @observer
 export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldColumnProps> {
     @observable private _background = "inherit";
+    @observable private _selected: boolean = false;
+    @observable private _mouseX: number = 0;
+    @observable private _mouseY: number = 0;
 
     private _dropRef: HTMLDivElement | null = null;
     private dropDisposer?: DragManager.DragDropDisposer;
@@ -248,6 +252,19 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         );
     }
 
+    renderMenu = () => {
+        return (
+            <div className="collectionStackingView-optionPicker">
+                <div className="optionOptions">
+                    <div className="optionPicker">Delete</div>
+                    <div className="optionPicker">Edit</div>
+                    <div className="optionPicker">Collapse</div>
+                    <div className="optionPicker">Alias</div>
+                </div>
+            </div>
+        );
+    }
+
     @observable private collapsed: boolean = false;
 
     private toggleVisibility = action(() => {
@@ -312,11 +329,15 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                             </ Flyout >
                         </div>
                     }
-                    {evContents === `NO ${key.toUpperCase()} VALUE` ?
-                        (null) :
-                        <button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
-                            <FontAwesomeIcon icon="trash" />
-                        </button>}
+                    {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
+                        <div className="collectionStackingView-sectionOptions">
+                            <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderMenu()}>
+                                <button className="collectionStackingView-sectionOptionButton">
+                                    <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
+                                </button>
+                            </Flyout>
+                        </div>
+                    }
                 </div>
             </div> : (null);
         for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
-- 
cgit v1.2.3-70-g09d2


From ee10ec0995fa67d27edb9032ba6fadf79bbdaaa1 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 10 Oct 2019 01:22:27 -0400
Subject: fixed document decorations for masonry view & scrolling.  cleaned up
 duplicated code a bit.

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 28 +-------
 .../views/collections/CollectionStackingView.scss  |  8 ++-
 .../views/collections/CollectionStackingView.tsx   | 75 +++++++++++++---------
 .../CollectionStackingViewFieldColumn.tsx          | 21 +-----
 4 files changed, 53 insertions(+), 79 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index b744ce4a5..5c1960d53 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -88,32 +88,6 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         }
     })
 
-    masonryChildren(docs: Doc[]) {
-        let parent = this.props.parent;
-        parent._docXfs.length = 0;
-        return docs.map((d, i) => {
-            let dref = React.createRef<HTMLDivElement>();
-            let layoutDoc = Doc.expandTemplateLayout(d, parent.props.DataDoc);
-            let width = () => (d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? Math.min(d[WidthSym](), parent.columnWidth) : parent.columnWidth);/// (uniqueHeadings.length + 1);
-            let height = () => parent.getDocHeight(layoutDoc);
-            let dxf = () => parent.getDocTransform(layoutDoc as Doc, dref.current!);
-            let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
-            parent._docXfs.push({ dxf: dxf, width: width, height: height });
-            return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} >
-                {this.props.parent.getDisplayDoc(layoutDoc as Doc, d, dxf, width)}
-            </div>;
-        });
-    }
-
-    getDocTransform(doc: Doc, dref: HTMLDivElement) {
-        let { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
-        let outerXf = Utils.GetScreenTransform(this.props.parent._masonryGridRef!);
-        let offset = this.props.parent.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
-        return this.props.parent.props.ScreenToLocalTransform().
-            translate(offset[0], offset[1]).
-            scale(NumCast(doc.width, 1) / this.props.parent.columnWidth);
-    }
-
     getValue = (value: string): any => {
         let parsed = parseInt(value);
         if (!isNaN(parsed)) {
@@ -402,7 +376,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                                             gridGap: this.props.parent.gridGap,
                                             gridTemplateColumns: numberRange(rows).reduce((list: string, i: any) => list + ` ${this.props.parent.columnWidth}px`, ""),
                                         }}>
-                                        {this.masonryChildren(this.props.docList)}
+                                        {this.props.parent.children(this.props.docList)}
                                         {this.props.parent.columnDragger}
                                     </div>
                                     {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ?
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 7bf8348ff..b31f0b8e3 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -7,12 +7,16 @@
 .collectionStackingView {
     display: flex;
 }
-
+.collectionStackingMasonry-cont {
+    position:relative;
+    height:100%;
+    width:100%;
+}
 .collectionStackingView,
 .collectionMasonryView {
     height: 100%;
     width: 100%;
-    position: relative;
+    position: absolute;
     top: 0;
     overflow-y: auto;
     flex-wrap: wrap;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index cde015152..0dfd1d9cf 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -29,12 +29,12 @@ import { CollectionMasonryViewFieldRow } from "./CollectionMasonryViewFieldRow";
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
     _draggerRef = React.createRef<HTMLDivElement>();
-    @observable _heightMap = new Map<string, number>();
     _heightDisposer?: IReactionDisposer;
     _sectionFilterDisposer?: IReactionDisposer;
     _docXfs: any[] = [];
     _columnStart: number = 0;
-    @observable private cursor: CursorProperty = "grab";
+    @observable _heightMap = new Map<string, number>();
+    @observable _cursor: CursorProperty = "grab";
     @observable _scroll = 0; // used to force the document decoration to update when scrolling
     @computed get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get sectionFilter() { return StrCast(this.props.Document.sectionFilter); }
@@ -49,12 +49,26 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return Math.min(this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin,
             this.isStackingView ? Number.MAX_VALUE : NumCast(this.props.Document.columnWidth, 250));
     }
-    @computed get NodeWidth() {
-        return this.props.PanelWidth();
-    }
+    @computed get NodeWidth() { return this.props.PanelWidth(); }
 
     childDocHeight(child: Doc) { return this.getDocHeight(Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, child).layout); }
 
+    children(docs: Doc[]) {
+        this._docXfs.length = 0;
+        return docs.map((d, i) => {
+            let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
+            let width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !this.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, this.columnWidth / this.numGroupColumns);
+            let height = () => this.getDocHeight(pair.layout);
+            let dref = React.createRef<HTMLDivElement>();
+            let dxf = () => this.getDocTransform(pair.layout!, dref.current!);
+            this._docXfs.push({ dxf: dxf, width: width, height: height });
+            let rowSpan = Math.ceil((height() + this.gridGap) / this.gridGap);
+            let style = this.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : this.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
+            return <div className={`collectionStackingView-${this.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
+                {this.getDisplayDoc(pair.layout as Doc, pair.data, dxf, width)}
+            </div>;
+        });
+    }
     @action
     setDocHeight = (key: string, sectionHeight: number) => {
         this._heightMap.set(key, sectionHeight);
@@ -177,19 +191,19 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         if (!d) return 0;
         let nw = NumCast(d.nativeWidth);
         let nh = NumCast(d.nativeHeight);
+        let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1);
         if (!d.ignoreAspect && !d.fitWidth && nw && nh) {
             let aspect = nw && nh ? nh / nw : 1;
-            let wid = this.columnWidth / (this.isStackingView ? this.numGroupColumns : 1);
             if (!(d.nativeWidth && !d.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(d[WidthSym](), wid);
             return wid * aspect;
         }
-        return d.fitWidth ? this.props.PanelHeight() - 2 * this.yMargin : d[HeightSym]();
+        return d.fitWidth ? Math.min(wid * NumCast(d.scrollHeight, NumCast(d.nativeHeight)) / NumCast(d.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : d[HeightSym]();
     }
 
     columnDividerDown = (e: React.PointerEvent) => {
         e.stopPropagation();
         e.preventDefault();
-        runInAction(() => this.cursor = "grabbing");
+        runInAction(() => this._cursor = "grabbing");
         document.addEventListener("pointermove", this.onDividerMove);
         document.addEventListener('pointerup', this.onDividerUp);
         this._columnStart = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0];
@@ -204,13 +218,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
 
     @action
     onDividerUp = (e: PointerEvent): void => {
-        runInAction(() => this.cursor = "grab");
+        runInAction(() => this._cursor = "grab");
         document.removeEventListener("pointermove", this.onDividerMove);
         document.removeEventListener('pointerup', this.onDividerUp);
     }
 
     @computed get columnDragger() {
-        return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this.cursor, left: `${this.columnWidth + this.xMargin}px` }} >
+        return <div className="collectionStackingView-columnDragger" onPointerDown={this.columnDividerDown} ref={this._draggerRef} style={{ cursor: this._cursor, left: `${this.columnWidth + this.xMargin}px` }} >
             <FontAwesomeIcon icon={"arrows-alt-h"} />
         </div>;
     }
@@ -375,26 +389,27 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             sections = entries.sort(this.sortFunc);
         }
         return (
-            <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
-                ref={this.createRef}
-                onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
-                onDrop={this.onDrop.bind(this)}
-                onContextMenu={this.onContextMenu}
-                onWheel={(e: React.WheelEvent) => e.stopPropagation()} >
-                {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))}
-                {!this.showAddAGroup ? (null) :
-                    <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
-                        style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
-                        <EditableView {...editableViewProps} />
-                    </div>}
-                {this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled' ? <Switch
-                    onChange={this.onToggle}
-                    onClick={this.onToggle}
-                    defaultChecked={this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode'}
-                    checkedChildren="edit"
-                    unCheckedChildren="view"
-                /> : null}
-            </div>
+            <div className="collectionStackingMasonry-cont" >
+                <div className={this.isStackingView ? "collectionStackingView" : "collectionMasonryView"}
+                    ref={this.createRef}
+                    onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
+                    onDrop={this.onDrop.bind(this)}
+                    onContextMenu={this.onContextMenu}
+                    onWheel={(e: React.WheelEvent) => e.stopPropagation()} >
+                    {sections.map(section => this.isStackingView ? this.sectionStacking(section[0], section[1]) : this.sectionMasonry(section[0], section[1]))}
+                    {!this.showAddAGroup ? (null) :
+                        <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
+                            style={{ width: this.columnWidth / this.numGroupColumns - 10, marginTop: 10 }}>
+                            <EditableView {...editableViewProps} />
+                        </div>}
+                    {this.props.ContainingCollectionDoc && this.props.ContainingCollectionDoc.chromeStatus !== 'disabled' ? <Switch
+                        onChange={this.onToggle}
+                        onClick={this.onToggle}
+                        defaultChecked={this.props.ContainingCollectionDoc.chromeStatus !== 'view-mode'}
+                        checkedChildren="edit"
+                        unCheckedChildren="view"
+                    /> : null}
+                </div> </div>
         );
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index cc7fe2aa1..e8627780d 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -73,25 +73,6 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             e.stopPropagation();
         }
     })
-
-    children(docs: Doc[]) {
-        let parent = this.props.parent;
-        parent._docXfs.length = 0;
-        return docs.map((d, i) => {
-            let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d);
-            let width = () => Math.min(d.nativeWidth && !d.ignoreAspect && !parent.props.Document.fillColumn ? d[WidthSym]() : Number.MAX_VALUE, parent.columnWidth / parent.numGroupColumns);
-            let height = () => parent.getDocHeight(pair.layout);
-            let dref = React.createRef<HTMLDivElement>();
-            let dxf = () => parent.getDocTransform(pair.layout!, dref.current!);
-            parent._docXfs.push({ dxf: dxf, width: width, height: height });
-            let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
-            let style = parent.isStackingView ? { width: width(), margin: "auto", marginTop: i === 0 ? 0 : parent.gridGap, height: height() } : { gridRowEnd: `span ${rowSpan}` };
-            return <div className={`collectionStackingView-${parent.isStackingView ? "columnDoc" : "masonryDoc"}`} key={d[Id]} ref={dref} style={style} >
-                {parent.getDisplayDoc(pair.layout as Doc, pair.data, dxf, width)}
-            </div>;
-        });
-    }
-
     getValue = (value: string): any => {
         let parsed = parseInt(value);
         if (!isNaN(parsed)) {
@@ -373,7 +354,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                                     gridTemplateColumns: singleColumn ? undefined : templatecols,
                                     gridAutoRows: singleColumn ? undefined : "0px"
                                 }}>
-                                {this.children(this.props.docList)}
+                                {this.props.parent.children(this.props.docList)}
                                 {singleColumn ? (null) : this.props.parent.columnDragger}
                             </div>
                             {(chromeStatus !== 'view-mode' && chromeStatus !== 'disabled') ?
-- 
cgit v1.2.3-70-g09d2


From 9505eda799fdf3b0cd2e6bde2d80c18731caee2c Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 10 Oct 2019 21:36:26 -0400
Subject: switching sidebar to a stacking view...

---
 src/client/views/DocComponent.tsx                       |  3 ++-
 src/client/views/collections/CollectionDockingView.tsx  | 16 +++++++++-------
 src/client/views/collections/CollectionStackingView.tsx |  2 +-
 src/client/views/collections/CollectionTreeView.tsx     |  6 ++++--
 src/server/authentication/models/current_user_utils.ts  |  2 +-
 5 files changed, 17 insertions(+), 12 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 93e852bef..2c5992259 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -21,7 +21,8 @@ interface DocAnnotatableProps {
     fieldKey: string;
     fieldExt: string;
     whenActiveChanged: (isActive: boolean) => void;
-    isSelected: () => boolean, renderDepth: number
+    isSelected: () => boolean;
+    renderDepth: number;
 }
 export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schemaCtor: (doc: Doc) => T) {
     class Component extends React.Component<P> {
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index fe805a980..1f78c8c97 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -37,7 +37,8 @@ const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
 export class CollectionDockingView extends React.Component<SubCollectionViewProps> {
-    @observable public static Instance: CollectionDockingView;
+    @observable public static Instances: CollectionDockingView[] = [];
+    @computed public static get Instance() { return CollectionDockingView.Instances[0]; }
     public static makeDocumentConfig(document: Doc, dataDoc: Doc | undefined, width?: number) {
         return {
             type: 'react-component',
@@ -65,7 +66,7 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
 
     constructor(props: SubCollectionViewProps) {
         super(props);
-        !CollectionDockingView.Instance && runInAction(() => CollectionDockingView.Instance = this);
+        runInAction(() => !CollectionDockingView.Instances ? CollectionDockingView.Instances = [this] : CollectionDockingView.Instances.push(this));
         //Why is this here?
         (window as any).React = React;
         (window as any).ReactDOM = ReactDOM;
@@ -317,13 +318,14 @@ export class CollectionDockingView extends React.Component<SubCollectionViewProp
         } catch (e) {
 
         }
-        if (this._goldenLayout) this._goldenLayout.destroy();
-        runInAction(() => this._goldenLayout = null);
+        this._goldenLayout && this._goldenLayout.destroy();
+        runInAction(() => {
+            CollectionDockingView.Instances.splice(CollectionDockingView.Instances.indexOf(this), 1);
+            this._goldenLayout = null;
+        });
         window.removeEventListener('resize', this.onResize);
 
-        if (this.reactionDisposer) {
-            this.reactionDisposer();
-        }
+        this.reactionDisposer && this.reactionDisposer();
     }
     @action
     onResize = (event: any) => {
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 0dfd1d9cf..57722b9b7 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -197,7 +197,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             if (!(d.nativeWidth && !d.ignoreAspect && this.props.Document.fillColumn)) wid = Math.min(d[WidthSym](), wid);
             return wid * aspect;
         }
-        return d.fitWidth ? Math.min(wid * NumCast(d.scrollHeight, NumCast(d.nativeHeight)) / NumCast(d.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : d[HeightSym]();
+        return d.fitWidth ? !d.nativeHeight ? this.props.PanelHeight() - 2 * this.yMargin : Math.min(wid * NumCast(d.scrollHeight, NumCast(d.nativeHeight)) / NumCast(d.nativeWidth, 1), this.props.PanelHeight() - 2 * this.yMargin) : d[HeightSym]();
     }
 
     columnDividerDown = (e: React.PointerEvent) => {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 882a0f144..37eb151b1 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -28,6 +28,7 @@ import { CollectionSchemaPreview } from './CollectionSchemaView';
 import { CollectionSubView } from "./CollectionSubView";
 import "./CollectionTreeView.scss";
 import React = require("react");
+import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
 
 
 export interface TreeViewProps {
@@ -198,6 +199,7 @@ class TreeView extends React.Component<TreeViewProps> {
             } else {
                 ContextMenu.Instance.addItem({ description: "Open as Workspace", event: () => MainView.Instance.openWorkspace(this.dataDoc), icon: "caret-square-right" });
                 ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.props.deleteDoc(this.props.document), icon: "trash-alt" });
+                ContextMenu.Instance.addItem({ description: "Create New Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" });
             }
             ContextMenu.Instance.addItem({ description: "Open Fields", event: () => { let kvp = Docs.Create.KVPDocument(this.props.document, { width: 300, height: 300 }); this.props.addDocTab(kvp, this.props.dataDoc ? this.props.dataDoc : kvp, "onRight"); }, icon: "layer-group" });
             ContextMenu.Instance.addItem({ description: "Publish", event: () => DocUtils.Publish(this.props.document, StrCast(this.props.document.title), () => { }, () => { }), icon: "file" });
@@ -217,7 +219,7 @@ class TreeView extends React.Component<TreeViewProps> {
         if (de.data instanceof DragManager.LinkDragData) {
             let sourceDoc = de.data.linkSourceDocument;
             let destDoc = this.props.document;
-            DocUtils.MakeLink({doc:sourceDoc}, {doc:destDoc});
+            DocUtils.MakeLink({ doc: sourceDoc }, { doc: destDoc });
             e.stopPropagation();
         }
         if (de.data instanceof DragManager.DocumentDragData) {
@@ -538,7 +540,7 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     }
     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() && this.props.Document.workspaceLibrary) {
+        if (!e.isPropagationStopped() && this.props.Document === CurrentUserUtils.UserDocument.workspaces) {
             ContextMenu.Instance.addItem({ description: "Create Workspace", event: () => MainView.Instance.createNewWorkspace(), icon: "plus" });
             ContextMenu.Instance.addItem({ description: "Delete Workspace", event: () => this.remove(this.props.Document), icon: "minus" });
             e.stopPropagation();
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 0fbfbf2f3..f3d5555ed 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -99,7 +99,7 @@ export class CurrentUserUtils {
         }
 
         if (doc.sidebar === undefined) {
-            const sidebar = Docs.Create.StackingDocument([doc.workspaces as Doc, doc, doc.recentlyClosed as Doc], { title: "Sidebar" });
+            const sidebar = Docs.Create.TreeDocument([doc.workspaces as Doc, doc, doc.recentlyClosed as Doc], { title: "Sidebar" });
             sidebar.forceActive = true;
             sidebar.lockedPosition = true;
             sidebar.gridGap = 5;
-- 
cgit v1.2.3-70-g09d2

