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

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 377 +++++++++++++++++++++
 1 file changed, 377 insertions(+)
 create mode 100644 src/client/views/collections/CollectionMasonryViewFieldRow.tsx

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
new file mode 100644
index 000000000..f0d574132
--- /dev/null
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -0,0 +1,377 @@
+import React = require("react");
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faPalette } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, observable } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, WidthSym } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/FieldSymbols";
+import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { ScriptField } from "../../../new_fields/ScriptField";
+import { NumCast, StrCast } from "../../../new_fields/Types";
+import { Utils, numberRange } from "../../../Utils";
+import { Docs } from "../../documents/Documents";
+import { DragManager } from "../../util/DragManager";
+import { CompileScript } from "../../util/Scripting";
+import { SelectionManager } from "../../util/SelectionManager";
+import { Transform } from "../../util/Transform";
+import { undoBatch } from "../../util/UndoManager";
+import { anchorPoints, Flyout } from "../DocumentDecorations";
+import { EditableView } from "../EditableView";
+import { CollectionStackingView } from "./CollectionStackingView";
+import "./CollectionStackingView.scss";
+
+library.add(faPalette);
+
+interface CMVFieldRowProps {
+    rows: () => number;
+    headings: () => object[];
+    heading: string;
+    headingObject: SchemaHeaderField | undefined;
+    docList: Doc[];
+    parent: CollectionStackingView;
+    type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | undefined;
+    createDropTarget: (ele: HTMLDivElement) => void;
+    screenToLocalTransform: () => Transform;
+    color: string | undefined;
+}
+
+@observer
+export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowProps> {
+    @observable private _background = "inherit";
+
+    private _dropRef: HTMLDivElement | null = null;
+    private dropDisposer?: DragManager.DragDropDisposer;
+    private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
+    private _startDragPosition: { x: number, y: number } = { x: 0, y: 0 };
+    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) => {
+        this._dropRef = ele;
+        this.dropDisposer && this.dropDisposer();
+        if (ele) {
+            this.dropDisposer = DragManager.MakeDropTarget(ele, { handlers: { drop: this.rowDrop.bind(this) } });
+        }
+    }
+
+    @undoBatch
+    @action
+    rowDrop = (e: Event, de: DragManager.DropEvent) => {
+        if (de.data instanceof DragManager.DocumentDragData) {
+            let key = StrCast(this.props.parent.props.Document.sectionFilter);
+            let castedValue = this.getValue(this._heading);
+            if (castedValue) {
+                de.data.droppedDocuments.forEach(d => d[key] = castedValue);
+            }
+            else {
+                de.data.droppedDocuments.forEach(d => d[key] = undefined);
+            }
+            this.props.parent.drop(e, de);
+            e.stopPropagation();
+        }
+    }
+
+    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, 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)}
+            </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)) {
+            return parsed;
+        }
+        if (value.toLowerCase().indexOf("true") > -1) {
+            return true;
+        }
+        if (value.toLowerCase().indexOf("false") > -1) {
+            return false;
+        }
+        return value;
+    }
+
+    @action
+    headingChanged = (value: string, shiftDown?: boolean) => {
+        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        let castedValue = this.getValue(value);
+        if (castedValue) {
+            if (this.props.parent.sectionHeaders) {
+                if (this.props.parent.sectionHeaders.map(i => i.heading).indexOf(castedValue.toString()) > -1) {
+                    return false;
+                }
+            }
+            this.props.docList.forEach(d => d[key] = castedValue);
+            if (this.props.headingObject) {
+                this.props.headingObject.setHeading(castedValue.toString());
+                this._heading = this.props.headingObject.heading;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @action
+    changeColumnColor = (color: string) => {
+        if (this.props.headingObject) {
+            this.props.headingObject.setColor(color);
+            this._color = color;
+        }
+    }
+
+    @action
+    pointerEntered = () => {
+        if (SelectionManager.GetIsDragging()) {
+            this._background = "#b4b4b4";
+        }
+    }
+
+    @action
+    pointerLeave = () => {
+        this._background = "inherit";
+        document.removeEventListener("pointermove", this.startDrag);
+    }
+
+    @action
+    addDocument = (value: string, shiftDown?: boolean) => {
+        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
+        newDoc[key] = this.getValue(this.props.heading);
+        return this.props.parent.props.addDocument(newDoc);
+    }
+
+    @action
+    deleteColumn = () => {
+        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        this.props.docList.forEach(d => d[key] = undefined);
+        if (this.props.parent.sectionHeaders && this.props.headingObject) {
+            let index = this.props.parent.sectionHeaders.indexOf(this.props.headingObject);
+            this.props.parent.sectionHeaders.splice(index, 1);
+        }
+    }
+
+    startDrag = (e: PointerEvent) => {
+        let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
+        if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
+            let alias = Doc.MakeAlias(this.props.parent.props.Document);
+            let key = StrCast(this.props.parent.props.Document.sectionFilter);
+            let value = this.getValue(this._heading);
+            value = typeof value === "string" ? `"${value}"` : value;
+            let script = `return doc.${key} === ${value}`;
+            let compiled = CompileScript(script, { params: { doc: Doc.name } });
+            if (compiled.compiled) {
+                let scriptField = new ScriptField(compiled);
+                alias.viewSpecScript = scriptField;
+                let dragData = new DragManager.DocumentDragData([alias], [alias.proto]);
+                DragManager.StartDocumentDrag([this._headerRef.current!], dragData, e.clientX, e.clientY);
+            }
+
+            e.stopPropagation();
+            document.removeEventListener("pointermove", this.startDrag);
+            document.removeEventListener("pointerup", this.pointerUp);
+        }
+    }
+
+    pointerUp = (e: PointerEvent) => {
+        e.stopPropagation();
+        e.preventDefault();
+
+        document.removeEventListener("pointermove", this.startDrag);
+        document.removeEventListener("pointerup", this.pointerUp);
+    }
+
+    headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+        e.stopPropagation();
+        e.preventDefault();
+
+        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);
+    }
+
+    renderColorPicker = () => {
+        let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+
+        let pink = PastelSchemaPalette.get("pink2");
+        let purple = PastelSchemaPalette.get("purple4");
+        let blue = PastelSchemaPalette.get("bluegreen1");
+        let yellow = PastelSchemaPalette.get("yellow4");
+        let red = PastelSchemaPalette.get("red2");
+        let green = PastelSchemaPalette.get("bluegreen7");
+        let cyan = PastelSchemaPalette.get("bluegreen5");
+        let orange = PastelSchemaPalette.get("orange1");
+        let gray = "#f1efeb";
+
+        return (
+            <div className="collectionStackingView-colorPicker">
+                <div className="colorOptions">
+                    <div className={"colorPicker" + (selected === pink ? " active" : "")} style={{ backgroundColor: pink }} onClick={() => this.changeColumnColor(pink!)}></div>
+                    <div className={"colorPicker" + (selected === purple ? " active" : "")} style={{ backgroundColor: purple }} onClick={() => this.changeColumnColor(purple!)}></div>
+                    <div className={"colorPicker" + (selected === blue ? " active" : "")} style={{ backgroundColor: blue }} onClick={() => this.changeColumnColor(blue!)}></div>
+                    <div className={"colorPicker" + (selected === yellow ? " active" : "")} style={{ backgroundColor: yellow }} onClick={() => this.changeColumnColor(yellow!)}></div>
+                    <div className={"colorPicker" + (selected === red ? " active" : "")} style={{ backgroundColor: red }} onClick={() => this.changeColumnColor(red!)}></div>
+                    <div className={"colorPicker" + (selected === gray ? " active" : "")} style={{ backgroundColor: gray }} onClick={() => this.changeColumnColor(gray)}></div>
+                    <div className={"colorPicker" + (selected === green ? " active" : "")} style={{ backgroundColor: green }} onClick={() => this.changeColumnColor(green!)}></div>
+                    <div className={"colorPicker" + (selected === cyan ? " active" : "")} style={{ backgroundColor: cyan }} onClick={() => this.changeColumnColor(cyan!)}></div>
+                    <div className={"colorPicker" + (selected === orange ? " active" : "")} style={{ backgroundColor: orange }} onClick={() => this.changeColumnColor(orange!)}></div>
+                </div>
+            </div>
+        );
+    }
+
+    @observable _headingsHack: number = 1;
+    render() {
+        let cols = this.props.rows();
+        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        let templatecols = "";
+        let headings = this.props.headings();
+        let heading = this._heading;
+        let style = this.props.parent;
+        let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
+        let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
+        let headerEditableViewProps = {
+            GetValue: () => evContents,
+            SetValue: this.headingChanged,
+            contents: evContents,
+            oneLine: true
+        };
+        let newEditableViewProps = {
+            GetValue: () => "",
+            SetValue: this.addDocument,
+            contents: "+ NEW"
+        };
+        // let headingView = this.props.headingObject ?
+        let headingView =
+            <div>
+                <div key={`${this.props.heading}`} className="collectionStackingView-sectionHeader" style={{ background: this.props.color }}
+                // onClick={action(() => this._headingsHack++ && instHeading.setCollapsed(!instHeading.collapsed))} 
+                >
+                    {this.props.heading}
+                </div >
+                {/* <div className="red-box"></div> */}
+                <EditableView {...headerEditableViewProps} />
+                {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
+                    <div className="collectionStackingView-sectionColor">
+                        <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderColorPicker()}>
+                            <button className="collectionStackingView-sectionColorButton">
+                                <FontAwesomeIcon icon="palette" size="sm" />
+                            </button>
+                        </ Flyout >
+                    </div>
+                }
+            </div>;
+
+
+        // <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
+        //     style={{
+        //         width: (style.columnWidth) /
+        //             ((uniqueHeadings.length +
+        //                 ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
+        //     }}>
+        //     {/* the default bucket (no key value) has a tooltip that describes what it is.
+        //         Further, it does not have a color and cannot be deleted. */}
+        // <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
+        //     title={evContents === `NO ${key.toUpperCase()} VALUE` ?
+        //         `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
+        //     style={{
+        //         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.TOP_CENTER} 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.deleteColumn}>
+        //             <FontAwesomeIcon icon="trash" />
+        //         </button>}
+        // </div>;
+        // </div> : (null);
+        // for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
+        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} >
+                {headingView}
+                {/* {!heading ? (null) :
+                    <div key={`${instHeading.heading}`} className="collectionStackingView-sectionHeader" style={{ background: instHeading.color }}
+                        onClick={action(() => this._headingsHack++ && instHeading.setCollapsed(!instHeading.collapsed))} >
+                        {instHeading.heading}
+                    </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.masonryChildren(this.props.docList)}
+                    {singleColumn ? (null) : this.props.parent.columnDragger}
+                </div> */}
+                {
+                    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>
+                }
+                { //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') ?
+                        <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
+                            style={{ width: style.columnWidth / style.numGroupColumns }}>
+                            <EditableView {...newEditableViewProps} />
+                        </div> : null
+                }
+            </div >
+        );
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From fff1e2429235022774b0ab8d40de5d24d122b698 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Wed, 21 Aug 2019 09:58:58 -0400
Subject: masonry: no content; has stacking's sec headers

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 97 ++++++----------------
 1 file changed, 26 insertions(+), 71 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index f0d574132..630d510a1 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -164,7 +164,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     @action
-    deleteColumn = () => {
+    deleteRow = () => {
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         this.props.docList.forEach(d => d[key] = undefined);
         if (this.props.parent.sectionHeaders && this.props.headingObject) {
@@ -273,83 +273,38 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                 <div key={`${this.props.heading}`} className="collectionStackingView-sectionHeader" style={{ background: this.props.color }}
                 // onClick={action(() => this._headingsHack++ && instHeading.setCollapsed(!instHeading.collapsed))} 
                 >
-                    {this.props.heading}
-                </div >
-                {/* <div className="red-box"></div> */}
-                <EditableView {...headerEditableViewProps} />
-                {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
-                    <div className="collectionStackingView-sectionColor">
-                        <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderColorPicker()}>
-                            <button className="collectionStackingView-sectionColorButton">
-                                <FontAwesomeIcon icon="palette" size="sm" />
-                            </button>
-                        </ Flyout >
+                    <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.TOP_CENTER} 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 key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
-        //     style={{
-        //         width: (style.columnWidth) /
-        //             ((uniqueHeadings.length +
-        //                 ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
-        //     }}>
-        //     {/* the default bucket (no key value) has a tooltip that describes what it is.
-        //         Further, it does not have a color and cannot be deleted. */}
-        // <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
-        //     title={evContents === `NO ${key.toUpperCase()} VALUE` ?
-        //         `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
-        //     style={{
-        //         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.TOP_CENTER} 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.deleteColumn}>
-        //             <FontAwesomeIcon icon="trash" />
-        //         </button>}
-        // </div>;
-        // </div> : (null);
-        // for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth / style.numGroupColumns}px `;
+                </div >
+            </div >;
         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} >
                 {headingView}
-                {/* {!heading ? (null) :
-                    <div key={`${instHeading.heading}`} className="collectionStackingView-sectionHeader" style={{ background: instHeading.color }}
-                        onClick={action(() => this._headingsHack++ && instHeading.setCollapsed(!instHeading.collapsed))} >
-                        {instHeading.heading}
-                    </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.masonryChildren(this.props.docList)}
-                    {singleColumn ? (null) : this.props.parent.columnDragger}
-                </div> */}
                 {
                     this._headingsHack && heading ? (null) :
                         <div key={`${heading}-stack`} className={`collectionStackingView-masonryGrid`}
-- 
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/CollectionMasonryViewFieldRow.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 0513a1bda8dc923ef5e72ecac0d3d61680b9e60e Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Wed, 21 Aug 2019 18:09:10 -0400
Subject: masonry is kinda collapsible

---
 src/client/views/EditableView.tsx                  | 17 +++++++
 .../collections/CollectionMasonryViewFieldRow.tsx  | 57 ++++++++++++++--------
 2 files changed, 53 insertions(+), 21 deletions(-)

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

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index c3612fee9..87af19062 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -3,6 +3,7 @@ import { observer } from 'mobx-react';
 import { observable, action, trace } from 'mobx';
 import "./EditableView.scss";
 import * as Autosuggest from 'react-autosuggest';
+import { SchemaHeaderField } from '../../new_fields/SchemaHeaderField';
 
 export interface EditableProps {
     /**
@@ -40,6 +41,8 @@ export interface EditableProps {
     editing?: boolean;
     onClick?: (e: React.MouseEvent) => boolean;
     isEditingCallback?: (isEditing: boolean) => void;
+    // HeadingObject: SchemaHeaderField | undefined;
+    // HeadingsHack: number;
 }
 
 /**
@@ -50,6 +53,8 @@ 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) {
         super(props);
@@ -66,6 +71,15 @@ 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);
+    //     }
+    // }
+
     @action
     onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
         if (e.key === "Tab") {
@@ -93,6 +107,9 @@ 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);
diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index dbd7f9e3c..8943fea3b 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -246,6 +246,8 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         );
     }
 
+    @observable private collapsed: boolean = false;
+
     @observable _headingsHack: number = 1;
     render() {
         let cols = this.props.rows();
@@ -261,19 +263,31 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             GetValue: () => evContents,
             SetValue: this.headingChanged,
             contents: evContents,
-            oneLine: true
+            oneLine: true,
+            // HeadingObject: this.props.headingObject,
+            // HeadingsHack: this._headingsHack
         };
         let newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
-            contents: "+ NEW"
+            contents: "+ NEW",
+            // HeadingObject: this.props.headingObject,
+            // HeadingsHack: this._headingsHack
         };
         // let headingView = this.props.headingObject ?
         let headingView =
             <div>
                 <div key={`${this.props.heading}`} className="collectionStackingView-sectionHeader" style={{ background: this.props.color }}
-                // onClick={action(() => this._headingsHack++ && instHeading.setCollapsed(!instHeading.collapsed))} 
+                    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-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.` : ""}
@@ -282,7 +296,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                             background: evContents !== `NO ${key.toUpperCase()} VALUE` ? this._color : "lightgrey",
                             color: "grey"
                         }}>
-                        <EditableView {...headerEditableViewProps} />
+                        {<EditableView {...headerEditableViewProps} />}
                         {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
                             <div className="collectionStackingView-sectionColor">
                                 <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderColorPicker()}>
@@ -309,25 +323,26 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                 onPointerLeave={this.pointerLeaveRow}
             >
                 {headingView}
-                {
-                    <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}
+                {this.collapsed ? (null) :
+                    <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>
+                        {(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>
                 }
-                { //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') ?
-                        <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
-                            style={{ width: style.columnWidth / style.numGroupColumns }}>
-                            <EditableView {...newEditableViewProps} />
-                        </div> : null
-                }
             </div >
         );
     }
-- 
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/CollectionMasonryViewFieldRow.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 601c8d2b0b8197e324f9cbadf525fe03fac5b345 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Fri, 23 Aug 2019 13:10:59 -0400
Subject: fixed colorpicker flyout anchorPoint

---
 src/client/views/collections/CollectionMasonryViewFieldRow.tsx     | 2 +-
 src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index ca386f91b..04a94b9b9 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -297,7 +297,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                         {<EditableView {...headerEditableViewProps} />}
                         {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
                             <div className="collectionStackingView-sectionColor">
-                                <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderColorPicker()}>
+                                <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
                                     <button className="collectionStackingView-sectionColorButton">
                                         <FontAwesomeIcon icon="palette" size="sm" />
                                     </button>
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 01bfd813b..a99aa67a4 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -304,7 +304,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                     <EditableView {...headerEditableViewProps} />
                     {evContents === `NO ${key.toUpperCase()} VALUE` ? (null) :
                         <div className="collectionStackingView-sectionColor">
-                            <Flyout anchorPoint={anchorPoints.TOP_CENTER} content={this.renderColorPicker()}>
+                            <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
                                 <button className="collectionStackingView-sectionColorButton">
                                     <FontAwesomeIcon icon="palette" size="sm" />
                                 </button>
-- 
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/CollectionMasonryViewFieldRow.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/CollectionMasonryViewFieldRow.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/CollectionMasonryViewFieldRow.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/CollectionMasonryViewFieldRow.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/CollectionMasonryViewFieldRow.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 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/CollectionMasonryViewFieldRow.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 16e511e35ecbe6166ced813d27884b367f6c6fbb Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Sat, 28 Sep 2019 16:53:13 -0400
Subject: delete and menu button for group header

---
 .../collections/CollectionMasonryViewFieldRow.tsx  | 26 +++++++++++++++++++---
 .../views/collections/CollectionStackingView.scss  |  2 +-
 .../CollectionStackingViewFieldColumn.tsx          | 12 +++++-----
 3 files changed, 31 insertions(+), 9 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 38f7493de..ad84b7635 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -261,6 +261,17 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         );
     }
 
+    renderMenu = () => {
+        let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+        return (
+            <div className="collectionStackingView-optionPicker">
+                <div className="optionOptions">
+                    <div className="optionPicker">Create Alias</div>
+                </div>
+            </div>
+        );
+    }
+
     @observable private collapsed: boolean = false;
 
     private toggleVisibility = action(() => {
@@ -327,10 +338,19 @@ 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" size="lg" />
+                        </button>}
                     {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
-                        <button className="collectionStackingView-sectionOptions" onClick={this.deleteRow}>
-                            <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
-                        </button>
+                        <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);
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index f34b3768b..d3deff9f1 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -226,7 +226,7 @@
 
         .collectionStackingView-sectionDelete {
             position: absolute;
-            right: 0;
+            right: 25px;
             top: 0;
             height: 100%;
         }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index b04e1fc73..e94a7d7f6 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -257,10 +257,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
-                    <div className="optionPicker" onClick={() => this.deleteColumn()}>Delete</div>
-                    <div className="optionPicker">Edit</div>
-                    <div className="optionPicker">Collapse</div>
-                    <div className="optionPicker">Alias</div>
+                    <div className="optionPicker">Create Alias</div>
                 </div>
             </div>
         );
@@ -325,11 +322,16 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                         <div className="collectionStackingView-sectionColor">
                             <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
                                 <button className="collectionStackingView-sectionColorButton">
-                                    <FontAwesomeIcon icon="palette" size="sm" />
+                                    <FontAwesomeIcon icon="palette" size="lg" />
                                 </button>
                             </ Flyout >
                         </div>
                     }
+                    {evContents === `NO ${key.toUpperCase()} VALUE` ?
+                        (null) :
+                        <button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
+                            <FontAwesomeIcon icon="trash" size="lg" />
+                        </button>}
                     {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
                         <div className="collectionStackingView-sectionOptions">
                             <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderMenu()}>
-- 
cgit v1.2.3-70-g09d2


From 2b26a9e8b718fb595a0f40914741e4f7d7c19d14 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Tue, 1 Oct 2019 18:52:53 -0400
Subject: UI changes: 3 buttons, bar, menu w/ alias

---
 src/client/views/EditableView.tsx                  | 13 ----------
 .../collections/CollectionMasonryViewFieldRow.tsx  | 25 +++++++++++++++----
 .../views/collections/CollectionStackingView.scss  | 10 +++++++-
 .../CollectionStackingViewFieldColumn.tsx          | 28 ++++++++++++++++------
 4 files changed, 51 insertions(+), 25 deletions(-)

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

diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 4a77db3d6..58f5d662d 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -73,14 +73,6 @@ export class EditableView extends React.Component<EditableProps> {
         }
     }
 
-    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>) => {
         if (e.key === "Tab") {
@@ -110,11 +102,6 @@ export class EditableView extends React.Component<EditableProps> {
             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 ad84b7635..8ba33b38d 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -40,6 +40,7 @@ interface CMVFieldRowProps {
 @observer
 export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowProps> {
     @observable private _background = "inherit";
+    @observable private _createAliasSelected: boolean = false;
 
     private _dropRef: HTMLDivElement | null = null;
     private dropDisposer?: DragManager.DragDropDisposer;
@@ -186,6 +187,15 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         }
     }
 
+    @action
+    collapseSection = () => {
+        if (this.props.headingObject) {
+            this._headingsHack++;
+            this.props.headingObject.setCollapsed(!this.props.headingObject.collapsed);
+            this.toggleVisibility();
+        }
+    }
+
     startDrag = (e: PointerEvent) => {
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
         if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
@@ -223,12 +233,13 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
 
-        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...
+        if (this._createAliasSelected) {
             document.removeEventListener("pointermove", this.startDrag);
             document.addEventListener("pointermove", this.startDrag);
             document.removeEventListener("pointerup", this.pointerUp);
             document.addEventListener("pointerup", this.pointerUp);
         }
+        this._createAliasSelected = false;
     }
 
     renderColorPicker = () => {
@@ -261,12 +272,17 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         );
     }
 
+    @action
+    toggleAlias = () => {
+        this._createAliasSelected = true;
+    }
+
     renderMenu = () => {
         let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
-                    <div className="optionPicker">Create Alias</div>
+                    <div className="optionPicker" onClick={this.toggleAlias}>Create Alias</div>
                 </div>
             </div>
         );
@@ -320,6 +336,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         };
         let headingView = this.props.headingObject ?
             <div className="collectionStackingView-sectionHeader" ref={this._headerRef} >
+                <div className="collectionStackingView-collapseBar" onClick={this.collapseSection}></div>
                 <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.` : ""}
@@ -333,7 +350,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                         <div className="collectionStackingView-sectionColor">
                             <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderColorPicker()}>
                                 <button className="collectionStackingView-sectionColorButton">
-                                    <FontAwesomeIcon icon="palette" size="sm" />
+                                    <FontAwesomeIcon icon="palette" size="lg" />
                                 </button>
                             </ Flyout >
                         </div>
@@ -345,7 +362,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
                         </button>}
                     {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
                         <div className="collectionStackingView-sectionOptions">
-                            <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderMenu()}>
+                            <Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
                                 <button className="collectionStackingView-sectionOptionButton">
                                     <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
                                 </button>
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index d3deff9f1..818db1669 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -102,12 +102,20 @@
         margin: auto;
     }
 
+    .collectionStackingView-collapseBar {
+        margin-left: 2px;
+        margin-right: 2px;
+        margin-top: 2px;
+        background: $main-accent;
+        height: 5px;
+    }
+
     .collectionStackingView-sectionHeader {
         text-align: center;
         margin-left: 2px;
         margin-right: 2px;
         margin-top: 10px;
-        background: gray;
+        background: $main-accent;
         // overflow: hidden; overflow is visible so the color menu isn't hidden -ftong
 
         .editableView-input {
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index e94a7d7f6..a8015472a 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -39,9 +39,7 @@ 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;
+    @observable private _createAliasSelected: boolean = false;
 
     private _dropRef: HTMLDivElement | null = null;
     private dropDisposer?: DragManager.DragDropDisposer;
@@ -177,6 +175,15 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         }
     }
 
+    @action
+    collapseSection = () => {
+        if (this.props.headingObject) {
+            this._headingsHack++;
+            this.props.headingObject.setCollapsed(!this.props.headingObject.collapsed);
+            this.toggleVisibility();
+        }
+    }
+
     startDrag = (e: PointerEvent) => {
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX - this._startDragPosition.x, e.clientY - this._startDragPosition.y);
         if (Math.abs(dx) + Math.abs(dy) > this._sensitivity) {
@@ -214,12 +221,13 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         let [dx, dy] = this.props.screenToLocalTransform().transformDirection(e.clientX, e.clientY);
         this._startDragPosition = { x: dx, y: dy };
 
-        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...
+        if (this._createAliasSelected) {
             document.removeEventListener("pointermove", this.startDrag);
             document.addEventListener("pointermove", this.startDrag);
             document.removeEventListener("pointerup", this.pointerUp);
             document.addEventListener("pointerup", this.pointerUp);
         }
+        this._createAliasSelected = false;
     }
 
     renderColorPicker = () => {
@@ -252,14 +260,19 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         );
     }
 
+    @action
+    toggleAlias = () => {
+        this._createAliasSelected = true;
+    }
+
     renderMenu = () => {
         let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
-                    <div className="optionPicker">Create Alias</div>
+                    <div className={"optionPicker" + (selected === " active")} onClick={this.toggleAlias}>Create Alias</div>
                 </div>
-            </div>
+            </div >
         );
     }
 
@@ -307,6 +320,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                         ((uniqueHeadings.length +
                             ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
                 }}>
+                <div className="collectionStackingView-collapseBar" onClick={this.collapseSection}></div>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
                     Further, it does not have a color and cannot be deleted. */}
                 <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
@@ -334,7 +348,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                         </button>}
                     {evContents === `NO  ${key.toUpperCase()} VALUE` ? (null) :
                         <div className="collectionStackingView-sectionOptions">
-                            <Flyout anchorPoint={anchorPoints.CENTER_RIGHT} content={this.renderMenu()}>
+                            <Flyout anchorPoint={anchorPoints.TOP_RIGHT} content={this.renderMenu()}>
                                 <button className="collectionStackingView-sectionOptionButton">
                                     <FontAwesomeIcon icon="ellipsis-v" size="lg"></FontAwesomeIcon>
                                 </button>
-- 
cgit v1.2.3-70-g09d2


From c0055c5677489b4cc7896c6e0b36f4730d49b4eb Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Sun, 6 Oct 2019 14:47:22 -0400
Subject: indicator for create alias

---
 .../views/collections/CollectionMasonryViewFieldRow.tsx      | 12 ++++++++++--
 src/client/views/collections/CollectionStackingView.scss     |  3 +--
 .../views/collections/CollectionStackingViewFieldColumn.tsx  | 12 ++++++++++--
 3 files changed, 21 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 8ba33b38d..e3d7fc481 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -74,6 +74,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     @undoBatch
     @action
     rowDrop = (e: Event, de: DragManager.DropEvent) => {
+        this._createAliasSelected = false;
         if (de.data instanceof DragManager.DocumentDragData) {
             let key = StrCast(this.props.parent.props.Document.sectionFilter);
             let castedValue = this.getValue(this._heading);
@@ -130,6 +131,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     headingChanged = (value: string, shiftDown?: boolean) => {
+        this._createAliasSelected = false;
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         let castedValue = this.getValue(value);
         if (castedValue) {
@@ -150,6 +152,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     changeColumnColor = (color: string) => {
+        this._createAliasSelected = false;
         if (this.props.headingObject) {
             this.props.headingObject.setColor(color);
             this._color = color;
@@ -158,6 +161,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     pointerEnteredRow = () => {
+        this._createAliasSelected = false;
         if (SelectionManager.GetIsDragging()) {
             this._background = "#b4b4b4";
         }
@@ -165,12 +169,14 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     pointerLeaveRow = () => {
+        this._createAliasSelected = false;
         this._background = "inherit";
         document.removeEventListener("pointermove", this.startDrag);
     }
 
     @action
     addDocument = (value: string, shiftDown?: boolean) => {
+        this._createAliasSelected = false;
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
         newDoc[key] = this.getValue(this.props.heading);
@@ -179,6 +185,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     deleteRow = () => {
+        this._createAliasSelected = false;
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         this.props.docList.forEach(d => d[key] = undefined);
         if (this.props.parent.sectionHeaders && this.props.headingObject) {
@@ -189,6 +196,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     collapseSection = () => {
+        this._createAliasSelected = false;
         if (this.props.headingObject) {
             this._headingsHack++;
             this.props.headingObject.setCollapsed(!this.props.headingObject.collapsed);
@@ -278,11 +286,11 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     renderMenu = () => {
-        let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+        let selected = this._createAliasSelected;
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
-                    <div className="optionPicker" onClick={this.toggleAlias}>Create Alias</div>
+                    <div className={"optionPicker" + (selected === true ? " active" : "")} onClick={this.toggleAlias}>Create Alias</div>
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 818db1669..df3f7e70d 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -225,8 +225,7 @@
                     margin: 3px;
 
                     &.active {
-                        border: 2px solid white;
-                        box-shadow: 0 0 0 2px lightgray;
+                        color: red;
                     }
                 }
             }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index a8015472a..fabe19d52 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -61,6 +61,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @undoBatch
     @action
     columnDrop = (e: Event, de: DragManager.DropEvent) => {
+        this._createAliasSelected = false;
         if (de.data instanceof DragManager.DocumentDragData) {
             let key = StrCast(this.props.parent.props.Document.sectionFilter);
             let castedValue = this.getValue(this._heading);
@@ -118,6 +119,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     @action
     headingChanged = (value: string, shiftDown?: boolean) => {
+        this._createAliasSelected = false;
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         let castedValue = this.getValue(value);
         if (castedValue) {
@@ -138,6 +140,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     @action
     changeColumnColor = (color: string) => {
+        this._createAliasSelected = false;
         if (this.props.headingObject) {
             this.props.headingObject.setColor(color);
             this._color = color;
@@ -147,18 +150,21 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     @action
     pointerEntered = () => {
         if (SelectionManager.GetIsDragging()) {
+            this._createAliasSelected = false;
             this._background = "#b4b4b4";
         }
     }
 
     @action
     pointerLeave = () => {
+        this._createAliasSelected = false;
         this._background = "inherit";
         document.removeEventListener("pointermove", this.startDrag);
     }
 
     @action
     addDocument = (value: string, shiftDown?: boolean) => {
+        this._createAliasSelected = false;
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
         newDoc[key] = this.getValue(this.props.heading);
@@ -167,6 +173,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     @action
     deleteColumn = () => {
+        this._createAliasSelected = false;
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
         this.props.docList.forEach(d => d[key] = undefined);
         if (this.props.parent.sectionHeaders && this.props.headingObject) {
@@ -177,6 +184,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     @action
     collapseSection = () => {
+        this._createAliasSelected = false;
         if (this.props.headingObject) {
             this._headingsHack++;
             this.props.headingObject.setCollapsed(!this.props.headingObject.collapsed);
@@ -266,11 +274,11 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     }
 
     renderMenu = () => {
-        let selected = this.props.headingObject ? this.props.headingObject.color : "#f1efeb";
+        let selected = this._createAliasSelected;
         return (
             <div className="collectionStackingView-optionPicker">
                 <div className="optionOptions">
-                    <div className={"optionPicker" + (selected === " active")} onClick={this.toggleAlias}>Create Alias</div>
+                    <div className={"optionPicker" + (selected === true ? " active" : "")} onClick={this.toggleAlias}>Create Alias</div>
                 </div>
             </div >
         );
-- 
cgit v1.2.3-70-g09d2


From 9c980548765016911c0f7624ac15c9692243dfb5 Mon Sep 17 00:00:00 2001
From: eeng5 <eleanor_eng@brown.edu>
Date: Sun, 6 Oct 2019 15:31:46 -0400
Subject: masonry alias fixed, collapse inidicator added

---
 src/client/views/collections/CollectionMasonryViewFieldRow.tsx     | 3 +--
 src/client/views/collections/CollectionStackingView.scss           | 6 ++++++
 src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 2 +-
 3 files changed, 8 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index e3d7fc481..4505aeb70 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -161,7 +161,6 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
 
     @action
     pointerEnteredRow = () => {
-        this._createAliasSelected = false;
         if (SelectionManager.GetIsDragging()) {
             this._background = "#b4b4b4";
         }
@@ -344,7 +343,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
         };
         let headingView = this.props.headingObject ?
             <div className="collectionStackingView-sectionHeader" ref={this._headerRef} >
-                <div className="collectionStackingView-collapseBar" onClick={this.collapseSection}></div>
+                <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
                 <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.` : ""}
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index df3f7e70d..cf7da069c 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -108,6 +108,12 @@
         margin-top: 2px;
         background: $main-accent;
         height: 5px;
+
+        &.active {
+            margin-left: 0;
+            margin-right: 0;
+            background: red;
+        }
     }
 
     .collectionStackingView-sectionHeader {
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index fabe19d52..dccc9462a 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -328,7 +328,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                         ((uniqueHeadings.length +
                             ((this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' && this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ? 1 : 0)) || 1)
                 }}>
-                <div className="collectionStackingView-collapseBar" onClick={this.collapseSection}></div>
+                <div className={"collectionStackingView-collapseBar" + (this.props.headingObject.collapsed === true ? " active" : "")} onClick={this.collapseSection}></div>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
                     Further, it does not have a color and cannot be deleted. */}
                 <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
-- 
cgit v1.2.3-70-g09d2


From 2cc7ca6b267d9dd6b1683d59b6966a021339bc18 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Wed, 9 Oct 2019 22:48:00 -0400
Subject: fixed compile errors and exceptions

---
 src/client/views/collections/CollectionMasonryViewFieldRow.tsx     | 5 ++---
 src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 5 ++---
 src/server/authentication/config/passport.ts                       | 2 +-
 src/server/index.ts                                                | 6 +++---
 4 files changed, 8 insertions(+), 10 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
index 4505aeb70..f01a54001 100644
--- a/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
+++ b/src/client/views/collections/CollectionMasonryViewFieldRow.tsx
@@ -72,8 +72,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
     }
 
     @undoBatch
-    @action
-    rowDrop = (e: Event, de: DragManager.DropEvent) => {
+    rowDrop = action((e: Event, de: DragManager.DropEvent) => {
         this._createAliasSelected = false;
         if (de.data instanceof DragManager.DocumentDragData) {
             let key = StrCast(this.props.parent.props.Document.sectionFilter);
@@ -87,7 +86,7 @@ export class CollectionMasonryViewFieldRow extends React.Component<CMVFieldRowPr
             this.props.parent.drop(e, de);
             e.stopPropagation();
         }
-    }
+    })
 
     masonryChildren(docs: Doc[]) {
         let parent = this.props.parent;
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index bda6bdfae..fffa1dde5 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -58,8 +58,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     }
 
     @undoBatch
-    @action
-    columnDrop = (e: Event, de: DragManager.DropEvent) => {
+    columnDrop = action((e: Event, de: DragManager.DropEvent) => {
         this._createAliasSelected = false;
         if (de.data instanceof DragManager.DocumentDragData) {
             let key = StrCast(this.props.parent.props.Document.sectionFilter);
@@ -73,7 +72,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             this.props.parent.drop(e, de);
             e.stopPropagation();
         }
-    }
+    })
 
     children(docs: Doc[]) {
         let parent = this.props.parent;
diff --git a/src/server/authentication/config/passport.ts b/src/server/authentication/config/passport.ts
index d42741410..e87b93ddf 100644
--- a/src/server/authentication/config/passport.ts
+++ b/src/server/authentication/config/passport.ts
@@ -42,7 +42,7 @@ export let isAuthenticated = (req: Request, res: Response, next: NextFunction) =
 export let isAuthorized = (req: Request, res: Response, next: NextFunction) => {
     const provider = req.path.split("/").slice(-1)[0];
 
-    if (_.find(req.user.tokens, { kind: provider })) {
+    if (_.find((req.user as any).tokens, { kind: provider })) {
         next();
     } else {
         res.redirect(`/auth/${provider}`);
diff --git a/src/server/index.ts b/src/server/index.ts
index eeadef239..de46ebf71 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -116,7 +116,7 @@ function addSecureRoute(method: Method,
 ) {
     let abstracted = (req: express.Request, res: express.Response) => {
         if (req.user) {
-            handler(req.user, res, req);
+            handler(req.user as any, res, req);
         } else {
             req.session!.target = req.originalUrl;
             onRejection(res, req);
@@ -813,8 +813,8 @@ const EndpointHandlerMap = new Map<GoogleApiServerUtils.Action, GoogleApiServerU
 app.post(RouteStore.googleDocs + "/:sector/:action", (req, res) => {
     let sector = req.params.sector;
     let action = req.params.action;
-    GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Service[sector], { credentials, token }).then(endpoint => {
-        let handler = EndpointHandlerMap.get(action);
+    GoogleApiServerUtils.GetEndpoint(GoogleApiServerUtils.Service[sector as any], { credentials, token }).then(endpoint => {
+        let handler = EndpointHandlerMap.get(action as any);
         if (endpoint && handler) {
             let execute = handler(endpoint, req.body).then(
                 response => res.send(response.data),
-- 
cgit v1.2.3-70-g09d2

