From 83d282a6b5e607e3c7dae4b5e5d37a8b458f81cc Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sun, 24 May 2020 10:36:31 +0530
Subject: Added chrome to grid view and modified grid mechanism

---
 .../views/collections/CollectionViewChromes.tsx    | 57 +++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 5dc0b09ac..def20ae9b 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -2,7 +2,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc, DocListCast } from "../../../fields/Doc";
+import { Doc, DocListCast, HeightSym } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
 import { List } from "../../../fields/List";
 import { listSpec } from "../../../fields/Schema";
@@ -15,6 +15,8 @@ import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
 import { CollectionViewType } from "./CollectionView";
 import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
+import { CollectionGridView } from "./collectionGrid/CollectionGridView";
+import HeightLabel from "./collectionMulticolumn/MultirowHeightLabel";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -205,6 +207,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             case CollectionViewType.Schema: return (<CollectionSchemaViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
             case CollectionViewType.Tree: return (<CollectionTreeViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
             case CollectionViewType.Masonry: return (<CollectionStackingViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
+            case CollectionViewType.Grid: return (<CollectionGridViewChrome key="collchrome" PanelWidth={this.props.PanelWidth} CollectionView={this.props.CollectionView} type={this.props.type} />);
             default: return null;
         }
     }
@@ -504,3 +507,55 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro
     }
 }
 
+/**
+ * Chrome for grid view.
+ */
+@observer
+export class CollectionGridViewChrome extends React.Component<CollectionViewChromeProps> {
+
+    /**
+     * Sets the value of `numCols` on the grid's Document to the value entered.
+     */
+    @action
+    onNumColsEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
+        if (e.key === "Enter" || e.key === "Tab") {
+            if (this.props.CollectionView.props.Document.numCols as number !== e.currentTarget.valueAsNumber) {
+                this.props.CollectionView.props.Document.numCols = e.currentTarget.valueAsNumber;
+                //this.props.CollectionView.forceUpdate(); // to be used if CollectionGridView is not an observer
+            }
+
+        }
+    }
+
+    /**
+     * Sets the value of `rowHeight` on the grid's Document to the value entered.
+     */
+    @action
+    onRowHeightEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
+        if (e.key === "Enter" || e.key === "Tab") {
+            if (this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) {
+                this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber;
+                //this.props.CollectionView.forceUpdate();
+            }
+        }
+    }
+
+    render() {
+        return (
+            <div className="collectionTreeViewChrome-cont">
+                <span className={"search-icon"}>
+                    <span className="icon-background">
+                        <FontAwesomeIcon icon="columns" size="1x" />
+                    </span>
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.numCols as string} onKeyDown={this.onNumColsEnter} autoFocus />
+                </span>
+                <span className={"search-icon"}>
+                    <span className="icon-background">
+                        <FontAwesomeIcon icon="text-height" size="1x" />
+                    </span>
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} />
+                </span>
+            </div>
+        );
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From f3e27cbe32b53de551ed90aab71085f343f7efd4 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Tue, 26 May 2020 15:48:46 +0530
Subject: modified delete

---
 .../views/collections/CollectionViewChromes.tsx    |   9 ++
 .../collectionGrid/CollectionGridView.tsx          | 155 +++++++++++++++------
 .../views/collections/collectionGrid/Grid.tsx      |  13 +-
 3 files changed, 132 insertions(+), 45 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index def20ae9b..7e86995ac 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -540,6 +540,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         }
     }
 
+    onCheck = (event: React.ChangeEvent<HTMLInputElement>) => this.props.CollectionView.props.Document.flexGrid = event.target.checked;
+
     render() {
         return (
             <div className="collectionTreeViewChrome-cont">
@@ -555,6 +557,13 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     </span>
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} />
                 </span>
+                <span>
+                    <span className="icon-background">
+                        <FontAwesomeIcon icon="arrows-alt" size="1x" />
+                    </span>
+                    <input type="checkbox" onChange={this.onCheck} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
+                    <label>Flexible Grid</label>
+                </span>
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index d06bb3192..468665ee5 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -1,10 +1,9 @@
-import { computed, observable, action } from 'mobx';
+import { computed, observable } from 'mobx';
 import * as React from "react";
 import { Doc, DocListCast } from '../../../../fields/Doc';
 import { documentSchema } from '../../../../fields/documentSchemas';
-import { makeInterface, createSchema } from '../../../../fields/Schema';
-import { BoolCast, NumCast, ScriptCast, StrCast, Cast } from '../../../../fields/Types';
-import { DragManager } from '../../../util/DragManager';
+import { makeInterface } from '../../../../fields/Schema';
+import { BoolCast, NumCast, ScriptCast } from '../../../../fields/Types';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
 import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
@@ -16,7 +15,6 @@ import Grid, { Layout } from "./Grid";
 import { Id } from '../../../../fields/FieldSymbols';
 import { observer } from 'mobx-react';
 
-
 type GridSchema = makeInterface<[typeof documentSchema]>;
 const GridSchema = makeInterface(documentSchema);
 
@@ -28,6 +26,10 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
         this.props.Document.numCols = this.props.Document.numCols ? this.props.Document.numCols : 10;
         this.props.Document.rowHeight = this.props.Document.rowHeight ? this.props.Document.rowHeight : 100;
+        this.props.Document.flexGrid = (this.props.Document.flexGrid !== undefined) ? this.props.Document.flexGrid : true;
+
+        this.setLayout = this.setLayout.bind(this);
+        this.deleteInContext = this.deleteInContext.bind(this);
     }
 
     componentDidMount() {
@@ -40,9 +42,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             for (let i = 0; i < this.childLayoutPairs.length; i++) {
 
                 const layoutDoc: Doc = new Doc();
-                layoutDoc.i = layoutDoc[Id];
-                layoutDoc.x = 2 * (i % 5);
-                layoutDoc.y = 2 * Math.floor(i / 5);
+                layoutDoc.i = this.childLayoutPairs[i].layout[Id];
+                layoutDoc.x = 2 * (i % Math.floor(this.props.Document.numCols as number / 2));
+                layoutDoc.y = 2 * Math.floor(i / Math.floor(this.props.Document.numCols as number / 2));
                 layoutDoc.w = 2;
                 layoutDoc.h = 2;
 
@@ -52,7 +54,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             }
 
         }
-
     }
 
     /**
@@ -63,8 +64,17 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     private lookupIndividualTransform = (doc: Doc) => {
 
-        const yTranslation = (this.props.Document.rowHeight as number) * (doc.y as number) + 10 * (doc.y as number);
-        return this.props.ScreenToLocalTransform().translate(-this.props.PanelWidth() / (this.props.Document.numCols as number) * (doc.x as number), -yTranslation);
+        const yTranslation = document.getElementById(doc.i as string)?.getBoundingClientRect().top;
+        const xTranslation = document.getElementById(doc.i as string)?.getBoundingClientRect().left;// - 250;
+
+        //console.log(xTranslation);
+
+        if (xTranslation === undefined || yTranslation === undefined) {
+            return Transform.Identity();
+        }
+
+        return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
+
     }
 
 
@@ -74,13 +84,27 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * Sets the width of the decorating box.
      * @param Doc doc
      */
-    @observable private width = (doc: Doc) => doc.w as number * this.props.PanelWidth() / (this.props.Document.numCols as number);
-
+    private width = (doc: Doc) => {
+        // const left = document.getElementById(doc.i as string)?.getBoundingClientRect().left;
+        // const right = document.getElementById(doc.i as string)?.getBoundingClientRect().right;
+        // //console.log(left - right);
+        // return Math.abs(right - left);
+        return doc.w as number * (this.props.PanelWidth() - (this.props.Document.numCols as number - 1) * 10) / (this.props.Document.numCols as number);
+    }
     /**
      * Sets the height of the decorating box.
      * @param doc `Doc`
      */
-    @observable private height = (doc: Doc) => doc.h as number * (this.props.Document.rowHeight as number);
+    private height = (doc: Doc) => {
+
+        // const top = document.getElementById(doc.i as string)?.getBoundingClientRect().top;
+        // const bottom = document.getElementById(doc.i as string)?.getBoundingClientRect().bottom;
+        // //console.log(Math.abs(top - bottom));
+        // return Math.abs(top - bottom);
+
+
+        return (doc.h as number) * (this.props.Document.rowHeight as number);
+    }
 
     addDocTab = (doc: Doc, where: string) => {
         if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) {
@@ -91,6 +115,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     }
 
     getDisplayDoc(layout: Doc, dxf: () => Transform, width: () => number, height: () => number) {
+        console.log(layout[Id]);
         return <ContentFittingDocumentView
             {...this.props}
             Document={layout}
@@ -109,9 +134,40 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             renderDepth={this.props.renderDepth + 1}
             parentActive={this.props.active}
             display={"contents"}
+            removeDocument={this.deleteInContext}
         />;
     }
 
+    @undoBatch
+    deleteInContext(doc: Doc | Doc[]): boolean {
+
+        if (!(this.props.Document.flexGrid as boolean)) {
+            this.props.removeDocument(doc);
+        }
+        else {
+            const docList: Doc[] = DocListCast(this.props.Document.gridLayouts);
+            const newDocList: Doc[] = [];
+            if (doc instanceof Doc) {
+                for (const savedDoc of docList) {
+                    if (savedDoc.i !== doc[Id]) {
+                        console.log("compare");
+                        console.log(savedDoc.i);
+                        console.log(doc[Id]);
+                        newDocList.push(savedDoc);
+                    }
+                }
+                this.props.Document.gridLayouts = new List<Doc>(newDocList);
+                this.props.removeDocument(doc);
+            }
+            // else {
+            //     console.log("doc is list");
+            //     this.props.removeDocument(doc);
+            // }
+        }
+        console.log("here???? in deletei n conte");
+        return true;
+    }
+
 
     /**
      * Saves the layouts received from the Grid to the Document.
@@ -120,29 +176,25 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     @undoBatch
     setLayout(layouts: Layout[]) {
 
-        console.log("setting layout in CollectionGridView");
-        console.log(layouts?.[0].w);
-        //this.props.Document.gridLayouts = new List<Doc>();
+        if (this.props.Document.flexGrid) {
 
-        const docList: Doc[] = [];
+            const docList: Doc[] = [];
+            for (const layout of layouts) {
 
-        for (const layout of layouts) {
-            const layoutDoc = new Doc();
-            layoutDoc.i = layout.i;
-            layoutDoc.x = layout.x;
-            layoutDoc.y = layout.y;
-            layoutDoc.w = layout.w;
-            layoutDoc.h = layout.h;
+                const layoutDoc = new Doc();
+                layoutDoc.i = layout.i;
+                layoutDoc.x = layout.x;
+                layoutDoc.y = layout.y;
+                layoutDoc.w = layout.w;
+                layoutDoc.h = layout.h;
 
-            docList.push(layoutDoc);
-        }
+                docList.push(layoutDoc);
+            }
 
-        this.props.Document.gridLayouts = new List<Doc>(docList);
+            this.props.Document.gridLayouts = new List<Doc>(docList);
+        }
     }
 
-    // _.reject() on item removal?
-
-
     /**
      * @returns a list of `ContentFittingDocumentView`s inside wrapper divs.
      * The key of the wrapper div must be the same as the `i` value of the corresponding layout.
@@ -165,12 +217,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
         for (let i = 0; i < childLayoutPairs.length; i++) {
             const { layout } = childLayoutPairs[i];
-            const dxf = () => this.lookupIndividualTransform(docList?.[i]);
-            const width = () => this.width(docList?.[i]);
-            const height = () => this.height(docList?.[i]);
+            const dxf = () => this.lookupIndividualTransform(docList[i]);
+            const width = () => this.width(docList[i]);
+            const height = () => this.height(docList[i]);
             collector.push(
                 <div className={"document-wrapper"}
                     key={docList?.[i].i as string}
+                    id={docList?.[i].i as string}
                 >
                     {this.getDisplayDoc(layout, dxf, width, height)}
                 </div>
@@ -187,10 +240,20 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     toLayoutList(docLayoutList: Doc[]): Layout[] {
 
         const layouts: Layout[] = [];
-        for (const layout of docLayoutList) {
-            layouts.push(
-                { i: layout.i as string, x: layout.x as number, y: layout.y as number, w: layout.w as number, h: layout.h as number }
-            );
+
+        if (this.props.Document.flexGrid) {
+            for (const layout of docLayoutList) {
+                layouts.push(
+                    { i: layout.i as string, x: layout.x as number, y: layout.y as number, w: layout.w as number, h: layout.h as number, static: !(this.props.Document.flexGrid as boolean) }
+                );
+            }
+        }
+        else {
+            for (let i = 0; i < docLayoutList.length; i++) {
+                layouts.push(
+                    { i: docLayoutList[i].i as string, x: 2 * (i % Math.floor(this.props.Document.numCols as number / 2)), y: 2 * Math.floor(i / Math.floor(this.props.Document.numCols as number / 2)), w: 2, h: 2, static: true }
+                );
+            }
         }
         return layouts;
     }
@@ -204,9 +267,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         if (this.childLayoutPairs.length > previousLength) {
             console.log("adding doc");
             const layoutDoc: Doc = new Doc();
-            layoutDoc.i = layoutDoc[Id];
-            layoutDoc.x = 2 * (previousLength % 5);
-            layoutDoc.y = 2 * Math.floor(previousLength / 5);
+            layoutDoc.i = this.childLayoutPairs[this.childLayoutPairs.length - 1].layout[Id];
+            layoutDoc.x = 2 * (previousLength % Math.floor(this.props.Document.numCols as number / 2));
+            layoutDoc.y = 2 * Math.floor(previousLength / Math.floor(this.props.Document.numCols as number / 2));
             layoutDoc.w = 2;
             layoutDoc.h = 2;
 
@@ -218,11 +281,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
         this.checkUpdate();
 
+        //console.log("here first?");
+
         const docList: Doc[] = DocListCast(this.props.Document.gridLayouts);
 
+        //console.log("doclist length:::" + docList.length);
         const contents: JSX.Element[] = this.contents;
         const layout: Layout[] = this.toLayoutList(docList);
 
+        // for (const doc of docList) {
+        //     console.log(doc.i);
+        // }
+
         // if (layout.length === 0) {
         //     console.log("layouts not loaded");
         // }
@@ -247,7 +317,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     layout={layout}
                     numCols={this.props.Document.numCols as number}
                     rowHeight={this.props.Document.rowHeight as number}
-                    setLayout={(layout: Layout[]) => this.setLayout(layout)}
+                    setLayout={this.setLayout}
+                    flex={this.props.Document.flexGrid as boolean}
                 />
             </div>
         );
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index a5f5c724a..49179aaa8 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -7,7 +7,6 @@ import "../../../../../node_modules/react-resizable/css/styles.css";
 
 import * as GridLayout from 'react-grid-layout';
 import { Layout } from 'react-grid-layout';
-import { CollectionGridView } from './CollectionGridView';
 export { Layout } from 'react-grid-layout';
 
 
@@ -18,6 +17,7 @@ interface GridProps {
     numCols: number;
     rowHeight: number;
     setLayout: Function;
+    flex: boolean;
 }
 
 /**
@@ -26,13 +26,20 @@ interface GridProps {
 @observer
 export default class Grid extends React.Component<GridProps> {
 
+    constructor(props: Readonly<GridProps>) {
+        super(props);
+
+        this.onLayoutChange = this.onLayoutChange.bind(this);
+    }
     /**
      * If there has been a change in layout, calls a method in CollectionGridView to set the layouts on the Document.
      * @param layout `Layout[]`
      */
     onLayoutChange(layout: Layout[]) {
-        console.log("setting in grid component" + layout[0].w);
+        console.log("setting in grid component" + layout[0]?.w);
+        // if (this.props.flex) {
         this.props.setLayout(layout);
+        // }
     }
 
     render() {
@@ -46,7 +53,7 @@ export default class Grid extends React.Component<GridProps> {
                 compactType={null}
                 isDroppable={true}
                 margin={[10, 10]}
-                onLayoutChange={layout => this.onLayoutChange(layout)}
+                onLayoutChange={this.onLayoutChange}
             >
                 {this.props.nodeList}
             </GridLayout >
-- 
cgit v1.2.3-70-g09d2


From fb23850659dd6cc0b75d208168e25033096e07df Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 27 May 2020 20:11:06 +0530
Subject: changes

---
 .../views/collections/CollectionViewChromes.tsx    |  4 +--
 .../collectionGrid/CollectionGridView.scss         | 19 ++++-------
 .../collectionGrid/CollectionGridView.tsx          | 39 +++++++++++++---------
 .../views/collections/collectionGrid/Grid.tsx      |  1 +
 4 files changed, 33 insertions(+), 30 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 7e86995ac..2bffbdf7d 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -557,9 +557,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     </span>
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} />
                 </span>
-                <span>
+                <span className={"search-icon"}>
                     <span className="icon-background">
-                        <FontAwesomeIcon icon="arrows-alt" size="1x" />
+                        <FontAwesomeIcon icon="arrow-up" size="1x" />
                     </span>
                     <input type="checkbox" onChange={this.onCheck} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
                     <label>Flexible Grid</label>
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index 8f12c1a24..4ad3d7015 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -1,14 +1,9 @@
-.collectionGridView_contents {
-    display: flex;
-    overflow: hidden;
-    width: 100%;
-    height: 100%;
-    flex-direction: column;
+// .react-grid-layout.layout {
+    //     // max-height: 100%;// min-height: 100%;
+    //     overflow-y: auto;
+    // }
 
-    .document-wrapper {
-        display: flex;
-        flex-direction: column;
-        width: 100%;
-        height: 100%;
-    }
+.collectionView {
+    background-color: white;
+    overflow-y: scroll;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 468665ee5..a887cf98b 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -14,6 +14,7 @@ import { returnZero } from '../../../../Utils';
 import Grid, { Layout } from "./Grid";
 import { Id } from '../../../../fields/FieldSymbols';
 import { observer } from 'mobx-react';
+import "./CollectionGridView.scss";
 
 type GridSchema = makeInterface<[typeof documentSchema]>;
 const GridSchema = makeInterface(documentSchema);
@@ -64,16 +65,24 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     private lookupIndividualTransform = (doc: Doc) => {
 
-        const yTranslation = document.getElementById(doc.i as string)?.getBoundingClientRect().top;
-        const xTranslation = document.getElementById(doc.i as string)?.getBoundingClientRect().left;// - 250;
+        // const yTranslation = document.getElementById(doc.i as string)?.getBoundingClientRect().top;
+        // const xTranslation = document.getElementById(doc.i as string)?.getBoundingClientRect().left;// - 250;
 
         //console.log(xTranslation);
 
+        //console.log(`width: ${doc.w} height: ${doc.h} x: ${doc.x} y:${doc.y}`);
+
+        const xTranslation = doc.x as number * this.props.PanelWidth() / (this.props.Document.numCols as number) + 10;
+        const yTranslation = doc.y as number * (this.props.Document.rowHeight as number + 10) + 10;
+
         if (xTranslation === undefined || yTranslation === undefined) {
+            console.log("undefined babey");
             return Transform.Identity();
         }
 
-        return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
+        console.log(`xtrans: ${xTranslation}  ytrans:${yTranslation}`);
+
+        return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);//.translate(-NumCast(this.props.Document._xMargin), -NumCast(this.props.Document._yMargin));
 
     }
 
@@ -85,25 +94,23 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * @param Doc doc
      */
     private width = (doc: Doc) => {
-        // const left = document.getElementById(doc.i as string)?.getBoundingClientRect().left;
-        // const right = document.getElementById(doc.i as string)?.getBoundingClientRect().right;
-        // //console.log(left - right);
-        // return Math.abs(right - left);
-        return doc.w as number * (this.props.PanelWidth() - (this.props.Document.numCols as number - 1) * 10) / (this.props.Document.numCols as number);
+
+        // return document.getElementById(doc.i as string)?.getBoundingClientRect().width;
+        const xTranslation = doc.w as number * (this.props.PanelWidth() - 10 * (this.props.Document.numCols as number + 1)) / (this.props.Document.numCols as number);
+        return (this.props.PanelWidth() - 10 * (this.props.Document.numCols as number + 1)) / (this.props.Document.numCols as number) *
+            (this.props.Document.flexGrid as boolean ? doc.w as number : 2) + 10 * (doc.w as number - 1);// doc.w or 2
     }
     /**
      * Sets the height of the decorating box.
      * @param doc `Doc`
      */
     private height = (doc: Doc) => {
+        //console.log(document.getElementById(doc.i as string)?.getBoundingClientRect());
 
-        // const top = document.getElementById(doc.i as string)?.getBoundingClientRect().top;
-        // const bottom = document.getElementById(doc.i as string)?.getBoundingClientRect().bottom;
-        // //console.log(Math.abs(top - bottom));
-        // return Math.abs(top - bottom);
-
-
-        return (doc.h as number) * (this.props.Document.rowHeight as number);
+        // return document.getElementById(doc.i as string)?.getBoundingClientRect().height;
+        return this.props.Document.rowHeight as number *
+            (this.props.Document.flexGrid as boolean ? doc.h as number : 2) +
+            10 * (doc.h as number - 1);// + 10;
     }
 
     addDocTab = (doc: Doc, where: string) => {
@@ -303,7 +310,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
 
         return (
-            <div className="collectionGridView_contents"
+            <div className="collectionGridView-contents"
                 style={{
                     marginLeft: NumCast(this.props.Document._xMargin), marginRight: NumCast(this.props.Document._xMargin),
                     marginTop: NumCast(this.props.Document._yMargin), marginBottom: NumCast(this.props.Document._yMargin)
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 49179aaa8..9520532b8 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -54,6 +54,7 @@ export default class Grid extends React.Component<GridProps> {
                 isDroppable={true}
                 margin={[10, 10]}
                 onLayoutChange={this.onLayoutChange}
+                preventCollision={true}
             >
                 {this.props.nodeList}
             </GridLayout >
-- 
cgit v1.2.3-70-g09d2


From 85553878a01877efb9e9d3b748064db66a6d8e30 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 1 Jun 2020 10:06:31 +0530
Subject: added grid ref and fixed css

---
 .../views/collections/CollectionViewChromes.scss   | 23 ++++++++++--
 .../views/collections/CollectionViewChromes.tsx    | 41 +++++++++++----------
 .../collectionGrid/CollectionGridView.scss         | 43 +++++++++++++---------
 .../collectionGrid/CollectionGridView.tsx          | 37 ++++++++++++-------
 .../views/collections/collectionGrid/Grid.tsx      |  9 +++--
 5 files changed, 95 insertions(+), 58 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 9795a3a22..910c14060 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -164,13 +164,31 @@
             }
         }
 
-
         .collectionStackingViewChrome-cont,
         .collectionTreeViewChrome-cont {
             display: flex;
             justify-content: space-between;
         }
 
+        .collectionGridViewChrome-cont {
+            display: flex;
+            margin-left: 10;
+
+            .grid-control {
+                align-self: center;
+                width: 30%;
+
+                .grid-icon {
+                    margin-right: 5px;
+                }
+            }
+
+            .collectionGridViewChrome-entryBox {
+                width: 50%;
+            }
+        }
+
+
         .collectionStackingViewChrome-sort,
         .collectionTreeViewChrome-sort {
             display: flex;
@@ -238,9 +256,6 @@
             cursor: text;
         }
 
-        .collectionGridViewChrome-entryBox {
-            width: 50%;
-        }
     }
 }
 
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 2bffbdf7d..9423e417d 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -15,8 +15,6 @@ import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
 import { CollectionViewType } from "./CollectionView";
 import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
-import { CollectionGridView } from "./collectionGrid/CollectionGridView";
-import HeightLabel from "./collectionMulticolumn/MultirowHeightLabel";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -516,10 +514,10 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     /**
      * Sets the value of `numCols` on the grid's Document to the value entered.
      */
-    @action
+    @undoBatch
     onNumColsEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
         if (e.key === "Enter" || e.key === "Tab") {
-            if (this.props.CollectionView.props.Document.numCols as number !== e.currentTarget.valueAsNumber) {
+            if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.numCols as number !== e.currentTarget.valueAsNumber) {
                 this.props.CollectionView.props.Document.numCols = e.currentTarget.valueAsNumber;
                 //this.props.CollectionView.forceUpdate(); // to be used if CollectionGridView is not an observer
             }
@@ -530,39 +528,44 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     /**
      * Sets the value of `rowHeight` on the grid's Document to the value entered.
      */
-    @action
+    @undoBatch
     onRowHeightEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
         if (e.key === "Enter" || e.key === "Tab") {
-            if (this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) {
+            if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) {
                 this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber;
-                //this.props.CollectionView.forceUpdate();
             }
         }
     }
 
-    onCheck = (event: React.ChangeEvent<HTMLInputElement>) => this.props.CollectionView.props.Document.flexGrid = event.target.checked;
+    /**
+     * Sets whether the grid is flexible or not on the grid's Document.
+     */
+    @undoBatch
+    toggleFlex = () => {
+        this.props.CollectionView.props.Document.flexGrid = !this.props.CollectionView.props.Document.flexGrid;
+    }
 
     render() {
         return (
-            <div className="collectionTreeViewChrome-cont">
-                <span className={"search-icon"}>
-                    <span className="icon-background">
+            <div className="collectionGridViewChrome-cont">
+                <span className={"grid-control"}>
+                    <span className="grid-icon">
                         <FontAwesomeIcon icon="columns" size="1x" />
                     </span>
-                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.numCols as string} onKeyDown={this.onNumColsEnter} autoFocus />
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.numCols as string} onKeyDown={this.onNumColsEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => e.currentTarget.focus()} />
                 </span>
-                <span className={"search-icon"}>
-                    <span className="icon-background">
+                <span className={"grid-control"}>
+                    <span className="grid-icon">
                         <FontAwesomeIcon icon="text-height" size="1x" />
                     </span>
-                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} />
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => e.currentTarget.focus()} />
                 </span>
-                <span className={"search-icon"}>
-                    <span className="icon-background">
+                <span className={"grid-control"}>
+                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
+                    <span className="grid-icon">
                         <FontAwesomeIcon icon="arrow-up" size="1x" />
                     </span>
-                    <input type="checkbox" onChange={this.onCheck} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
-                    <label>Flexible Grid</label>
+                    <label>Flexible</label>
                 </span>
             </div>
         );
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index b88721b4d..49d463441 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -1,14 +1,4 @@
-// .react-grid-layout.layout {
-//     // max-height: 100%;// min-height: 100%;
-//     overflow-y: auto;
-// }
-
-// .collectionView {//     background-color: white;
-//     overflow-y: scroll;
-// }
-
-
-.collectionGridView_contents {
+.collectionGridView-contents {
     display: flex;
     overflow: hidden;
     width: 100%;
@@ -16,13 +6,32 @@
     flex-direction: column;
 }
 
-.collectionGridView_contents .document-wrapper {
-    display: flex;
-    flex-direction: column;
-    width: 100%;
+.collectionGridView-contents .collectionGridView-gridContainer {
     height: 100%;
+    overflow-y: auto;
+    background-color: white;
+}
+
+.documentDecorations-container .documentDecorations-resizer {
+    pointer-events: none;
+
+}
+
+#documentDecorations-bottomRightResizer,
+#documentDecorations-bottomLeftResizer,
+#documentDecorations-topRightResizer,
+#documentDecorations-topLeftResizer {
+    visibility: collapse;
+}
+
+/* Chrome, Safari, Edge, Opera */
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+    -webkit-appearance: none;
+    margin: 0;
 }
 
-.react-grid-layout.layout {
-    height: 100%
+/* Firefox */
+input[type=number] {
+    -moz-appearance: textfield;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 111ce4beb..5eeaa9b0d 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -1,4 +1,4 @@
-import { computed, observable } from 'mobx';
+import { computed, observable, action } from 'mobx';
 import * as React from "react";
 import { Doc, DocListCast } from '../../../../fields/Doc';
 import { documentSchema } from '../../../../fields/documentSchemas';
@@ -23,6 +23,8 @@ const GridSchema = makeInterface(documentSchema);
 
 @observer
 export class CollectionGridView extends CollectionSubView(GridSchema) {
+    private containerRef: React.RefObject<HTMLDivElement>;
+    @observable private _scroll: number = 0;
 
     constructor(props: Readonly<SubCollectionViewProps>) {
         super(props);
@@ -33,6 +35,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
         this.setLayout = this.setLayout.bind(this);
         this.deleteInContext = this.deleteInContext.bind(this);
+
+        this.containerRef = React.createRef();
     }
 
     componentDidMount() {
@@ -66,7 +70,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * documents before the target. 
      */
     private lookupIndividualTransform = (doc: Doc) => {
-        const yTranslation = this.rowHeightPlusGap * NumCast(doc.y) + 10;
+        const yTranslation = this.rowHeightPlusGap * NumCast(doc.y) + 10 - this._scroll;
+        console.log("CollectionGridView -> privatelookupIndividualTransform -> this.containerRef.current!.scrollTop", this.containerRef.current!.scrollTop)
         const xTranslation = this.colWidthPlusGap * NumCast(doc.x) + 10;
         return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
     }
@@ -113,7 +118,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             onClick={this.onChildClickHandler}
             renderDepth={this.props.renderDepth + 1}
             parentActive={this.props.active}
-            display={"contents"}
+            display={"contents"} // this causes an issue- this is the reason the decorations box is weird with images and web boxes
             removeDocument={this.deleteInContext}
         />;
     }
@@ -291,17 +296,21 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                 ref={this.createDashEventsTarget}
                 onPointerDown={e => { ((e.target as any)?.className.includes("react-resizable-handle")) && e.stopPropagation(); }} // the grid doesn't stopPropagation when its widgets are hit, so we need to otherwise the outer documents will respond
             >
-                DIV HERE with ref to access scroll of and adjust in getting position
-                <Grid
-                    width={this.props.PanelWidth()}
-                    nodeList={contents}
-                    layout={layout}
-                    numCols={this.props.Document.numCols as number}
-                    rowHeight={this.props.Document.rowHeight as number}
-                    setLayout={this.setLayout}
-                    flex={this.props.Document.flexGrid as boolean}
-                    scale={this.props.ScreenToLocalTransform().Scale}
-                />
+                <div className="collectionGridView-gridContainer"
+                    ref={this.containerRef}
+                    onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
+                >
+                    <Grid
+                        width={this.props.PanelWidth()}
+                        nodeList={contents}
+                        layout={layout}
+                        numCols={this.props.Document.numCols as number}
+                        rowHeight={this.props.Document.rowHeight as number}
+                        setLayout={this.setLayout}
+                        flex={this.props.Document.flexGrid as boolean}
+                        scale={this.props.ScreenToLocalTransform().Scale}
+                    />
+                </div>
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 673f670a6..be6c4343a 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -26,9 +26,11 @@ interface GridProps {
  */
 @observer
 export default class Grid extends React.Component<GridProps> {
+    gridRef: React.RefObject<HTMLDivElement>;
 
     constructor(props: Readonly<GridProps>) {
         super(props);
+        this.gridRef = React.createRef();
 
         this.onLayoutChange = this.onLayoutChange.bind(this);
     }
@@ -50,13 +52,12 @@ export default class Grid extends React.Component<GridProps> {
                 width={this.props.width}
                 compactType={null}
                 isDroppable={true}
-                useCSSTransforms={true}
+                // useCSSTransforms={true}
                 margin={[10, 10]}
                 onLayoutChange={this.onLayoutChange}
                 preventCollision={false} // change this to true later
-                transformScale={0.8} // 1.2/scale
-                style={{ height: "100%", overflowY: "scroll" }}
-            // draggableHandle={".documentDecorations-resizer"}
+                // transformScale={2} // 1.2/scale
+                onDrop={({ x, y, e }) => { console.log("Grid -> render -> x, y, e", x, y, e) }}
             >
                 {this.props.nodeList}
             </GridLayout >
-- 
cgit v1.2.3-70-g09d2


From eafb8ddc3bf65c828e7fc15fd9df1e64fa7a27f8 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 1 Jun 2020 20:45:42 +0530
Subject: jsonified doc layout list

---
 .../views/collections/CollectionViewChromes.tsx    |   1 -
 .../collectionGrid/CollectionGridView.tsx          | 140 ++++++++++-----------
 .../views/collections/collectionGrid/Grid.tsx      |   8 +-
 3 files changed, 73 insertions(+), 76 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 9b8a24d4a..3d712e4f5 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -598,7 +598,6 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     /**
      * Sets whether the grid is flexible or not on the grid's Document.
      */
-    @undoBatch
     toggleFlex = () => {
         this.props.CollectionView.props.Document.flexGrid = !this.props.CollectionView.props.Document.flexGrid;
     }
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 0583caa55..63a679f7e 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -27,53 +27,65 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     @observable private _scroll: number = 0;
     private changeListenerDisposer: Opt<Lambda>;
 
+    // private undoChangeListenerDisposer: Opt<Lambda>;
+
+    // @observable private _layouts: Layout[] = [];
+
     constructor(props: Readonly<SubCollectionViewProps>) {
         super(props);
 
         this.props.Document.numCols = NumCast(this.props.Document.numCols, 10);
         this.props.Document.rowHeight = NumCast(this.props.Document.rowHeight, 100);
-        this.props.Document.flexGrid = (this.props.Document.flexGrid !== undefined) ? this.props.Document.flexGrid : true;
+        this.props.Document.flexGrid = BoolCast(this.props.Document.flexGrid, true);
 
         this.setLayout = this.setLayout.bind(this);
-        this.deleteInContext = this.deleteInContext.bind(this);
 
         this.containerRef = React.createRef();
     }
 
     componentDidMount() {
-        if (!this.props.Document.gridLayouts) {
-            this.props.Document.gridLayouts = new List<Doc>();
-        }
+
+        // this.undoChangeListenerDisposer = computed(() => this.props.Document.gridLayoutString).observe(({ newValue }) => {
+        //     action(() => this._layouts = JSON.parse(newValue as string))();
+        // });
+
         this.changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => {
-            const gridLayouts = DocListCast(this.props.Document.gridLayouts);
 
             if (!oldValue || newValue.length > oldValue.length) {
+                const layouts: Layout[] = this.parsedLayoutList;
                 // for each document that was added, add a corresponding grid layout document
                 newValue.forEach(({ layout }, i) => {
                     const targetId = layout[Id];
-                    if (!gridLayouts.find((gridLayout: Doc) => StrCast(gridLayout.i) === targetId)) {
-                        const layoutDoc: Doc = new Doc();
-                        layoutDoc.i = targetId;
-                        layoutDoc.w = layoutDoc.h = 2;
-                        this.findNextLayout(layoutDoc, i);
-                        Doc.AddDocToList(this.props.Document, "gridLayouts", layoutDoc);
+                    if (!layouts.find((gridLayout: Layout) => gridLayout.i === targetId)) {
+                        layouts.push({
+                            i: targetId,
+                            w: 2,
+                            h: 2,
+                            x: 2 * (i % Math.floor(this.props.Document.numCols as number / 2)),
+                            y: 2 * Math.floor(i / Math.floor(this.props.Document.numCols as number / 2))
+                        });
                     }
                 });
+                this.props.Document.gridLayoutString = JSON.stringify(layouts);
             } else {
+                const layouts: Layout[] = this.parsedLayoutList;
                 // for each document that was removed, remove its corresponding grid layout document
                 oldValue.forEach(({ layout }) => {
                     const targetId = layout[Id];
                     if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) {
-                        const gridLayoutDoc = gridLayouts.find((gridLayout: Doc) => StrCast(gridLayout.i) === targetId);
-                        gridLayoutDoc && Doc.RemoveDocFromList(this.props.Document, "gridLayouts", gridLayoutDoc);
+                        const index = layouts.findIndex((gridLayout: Layout) => gridLayout.i === targetId);
+                        index !== -1 && action(() => layouts.splice(index, 1))();
                     }
                 });
+                this.props.Document.gridLayoutString = JSON.stringify(layouts);
             }
+
         }, true);
     }
 
     componentWillUnmount() {
         this.changeListenerDisposer && this.changeListenerDisposer();
+        this.undoChangeListenerDisposer && this.undoChangeListenerDisposer();
     }
 
     /**
@@ -89,8 +101,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * as big as the ratio height of the document you're trying to insert.  
      */
     private findNextLayout(layoutDoc: Doc, previousLength: number) {
-        layoutDoc.x = 2 * (previousLength % 5); // does this assume that there are 5 columns?
-        layoutDoc.y = 2 * Math.floor(previousLength / 5);
+        layoutDoc.x = 2 * (previousLength % Math.floor(this.props.Document.numCols as number / 2));
+        layoutDoc.y = 2 * Math.floor(previousLength / Math.floor(this.props.Document.numCols as number / 2));
     }
 
     /**
@@ -99,9 +111,12 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * the sum of all the resolved column widths of the
      * documents before the target. 
      */
-    private lookupIndividualTransform = (doc: Doc) => {
-        const yTranslation = this.rowHeightPlusGap * NumCast(doc.y) + 10 - this._scroll;
-        const xTranslation = this.colWidthPlusGap * NumCast(doc.x) + 10;
+    private lookupIndividualTransform = (layout: Layout) => {
+
+        const index = this.childLayoutPairs.findIndex(({ layout: layoutDoc }) => layoutDoc[Id] === layout.i);
+        const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : 2 * Math.floor(index / Math.floor(this.props.Document.numCols as number / 2))) * this.rowHeightPlusGap + 10 - this._scroll;
+        const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : 2 * (index % Math.floor(this.props.Document.numCols as number / 2))) * this.colWidthPlusGap + 10;
+
         return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
     }
 
@@ -110,17 +125,20 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
     @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
 
+    @computed get parsedLayoutList() { return this.props.Document.gridLayoutString ? JSON.parse(this.props.Document.gridLayoutString as string) : []; }
+    @undoBatch @action set unStringifiedLayoutList(layouts: Layout[]) { this.props.Document.gridLayoutString = JSON.stringify(layouts); }
+
     /**
      * Sets the width of the decorating box.
      * @param Doc doc
      */
-    @observable private width = (doc: Doc) => NumCast(doc.w) * this.colWidthPlusGap - 10;
+    @observable private width = (layout: Layout) => (this.props.Document.flexGrid ? layout.w : 2) * this.colWidthPlusGap - 10;
 
     /**
      * Sets the height of the decorating box.
      * @param doc `Doc`
      */
-    @observable private height = (doc: Doc) => NumCast(doc.h) * this.rowHeightPlusGap - 10;
+    @observable private height = (layout: Layout) => (this.props.Document.flexGrid ? layout.h : 2) * this.rowHeightPlusGap - 10;
 
     addDocTab = (doc: Doc, where: string) => {
         if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) {
@@ -148,60 +166,33 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             renderDepth={this.props.renderDepth + 1}
             parentActive={this.props.active}
             display={"contents"} // this causes an issue- this is the reason the decorations box is weird with images and web boxes
-            removeDocument={this.deleteInContext}
         />;
     }
 
-    @undoBatch
-    deleteInContext(doc: Doc | Doc[]): boolean {
-
-        if (!(this.props.Document.flexGrid as boolean)) {
-            this.props.removeDocument(doc);
-        }
-        else {
-            const docList: Doc[] = DocListCast(this.props.Document.gridLayouts);
-            const newDocList: Doc[] = [];
-            if (doc instanceof Doc) {
-                for (const savedDoc of docList) {
-                    if (savedDoc.i !== doc[Id]) {
-                        console.log("compare");
-                        console.log(savedDoc.i);
-                        console.log(doc[Id]);
-                        newDocList.push(savedDoc);
-                    }
-                }
-                this.props.Document.gridLayouts = new List<Doc>(newDocList);
-                this.props.removeDocument(doc);
-            }
-            // else {
-            //     console.log("doc is list");
-            //     this.props.removeDocument(doc);
-            // }
-        }
-        console.log("here???? in deletei n conte");
-        return true;
-    }
-
-
     /**
      * Saves the layouts received from the Grid to the Document.
      * @param layouts `Layout[]`
      */
     @undoBatch
-    setLayout(layouts: Layout[]) {
+    @action
+    setLayout(layoutArray: Layout[]) {
         // for every child in the collection, check to see if there's a corresponding grid layout document and
         // updated layout object. If both exist, which they should, update the grid layout document from the updated object 
+        const layouts: Layout[] = this.parsedLayoutList;
         this.childLayoutPairs.forEach(({ layout: doc }) => {
             let update: Opt<Layout>;
             const targetId = doc[Id];
-            const gridLayout = DocListCast(this.props.Document.gridLayouts).find(gridLayout => StrCast(gridLayout.i) === targetId);
-            if (gridLayout && (update = layouts.find(layout => layout.i === targetId))) {
+            const gridLayout = layouts.find(gridLayout => gridLayout.i === targetId);
+            // const gridLayout = DocListCast(this.props.Document.gridLayouts).find(gridLayout => StrCast(gridLayout.i) === targetId);
+            if (this.props.Document.flexGrid && gridLayout && (update = layoutArray.find(layout => layout.i === targetId))) {
                 gridLayout.x = update.x;
                 gridLayout.y = update.y;
                 gridLayout.w = update.w;
                 gridLayout.h = update.h;
             }
         });
+
+        this.props.Document.gridLayoutString = JSON.stringify(layouts);
     }
 
     /**
@@ -212,20 +203,20 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     private get contents(): JSX.Element[] {
         const { childLayoutPairs } = this;
         const collector: JSX.Element[] = [];
-        const docList: Doc[] = DocListCast(this.props.Document.gridLayouts);
-        if (!docList.length || docList.length !== childLayoutPairs.length) {
+        const layouts: Layout[] = this.parsedLayoutList;
+        if (!layouts || !layouts.length || layouts.length !== childLayoutPairs.length) {
             return [];
         }
 
         for (let i = 0; i < childLayoutPairs.length; i++) {
             const { layout } = childLayoutPairs[i];
-            const gridLayout = docList[i];
+            const gridLayout = layouts[i];
             const dxf = () => this.lookupIndividualTransform(gridLayout);
             const width = () => this.width(gridLayout);
             const height = () => this.height(gridLayout);
             collector.push(
                 <div className={"document-wrapper"}
-                    key={gridLayout.i as string}
+                    key={gridLayout.i}
                 >
                     {this.getDisplayDoc(layout, dxf, width, height)}
                 </div>
@@ -239,20 +230,21 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * @returns a list of Layouts from a list of Docs
      * @param docLayoutList `Doc[]`
      */
-    toLayoutList(docLayoutList: Doc[]): Layout[] {
-
+    get layoutList(): Layout[] {
+        const layouts: Layout[] = this.parsedLayoutList;
         if (this.props.Document.flexGrid) {
-            return docLayoutList.map(({ i, x, y, w, h }) => ({
-                i: i as string,
-                x: x as number,
-                y: y as number,
-                w: w as number,
-                h: h as number
+            return layouts.map(({ i, x, y, w, h }) => ({
+                i: i,
+                x: x,
+                y: y,
+                w: w,
+                h: h,
+                static: false
             }));
         }
         else {
-            return docLayoutList.map(({ i }, index) => ({
-                i: i as string,
+            return layouts.map(({ i }, index) => ({
+                i: i,
                 x: 2 * (index % Math.floor(this.props.Document.numCols as number / 2)),
                 y: 2 * Math.floor(index / Math.floor(this.props.Document.numCols as number / 2)),
                 w: 2,
@@ -271,9 +263,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * the setLayout event, which makes these unintended changes permanent by writing them to the likely now resolved documents.
      */
     render() {
-        const layoutDocList: Doc[] = DocListCast(this.props.Document.gridLayouts);
         const childDocumentViews: JSX.Element[] = this.contents;
-        if (!(childDocumentViews.length && layoutDocList.length)) {
+        const layouts: Layout[] = this.parsedLayoutList;
+        if (!childDocumentViews.length || !layouts.length) {
             return null;
         }
         return (
@@ -299,16 +291,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     ref={this.containerRef}
                     onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
                 >
+                    {/* {console.log(this.toLayoutList(layoutDocList))} */}
                     <Grid
                         width={this.props.PanelWidth()}
                         nodeList={childDocumentViews}
-                        layout={this.toLayoutList(layoutDocList)}
+                        layout={this.layoutList}
                         childrenDraggable={this.props.isSelected() ? true : false}
                         numCols={this.props.Document.numCols as number}
                         rowHeight={this.props.Document.rowHeight as number}
                         setLayout={this.setLayout}
                         //setLayout={(layout: Layout[]) => this.setLayout(layout)}
                         transformScale={this.props.ScreenToLocalTransform().Scale}
+                    // flex={this.props.Document.flexGrid as boolean}
                     />
                 </div>
             </div>
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 0e9e8bbca..8f9bc9f46 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -19,6 +19,7 @@ interface GridProps {
     setLayout: Function;
     transformScale: number;
     childrenDraggable: boolean;
+    // flex: boolean;
 }
 
 /**
@@ -49,12 +50,15 @@ export default class Grid extends React.Component<GridProps> {
                 width={this.props.width}
                 compactType={null}
                 isDroppable={true}
+                // isDraggable={this.props.flex}
+                // isResizable={this.props.flex}
                 // isDraggable={this.props.childrenDraggable}
-                // useCSSTransforms={true}
+                useCSSTransforms={true}
                 margin={[10, 10]}
                 onLayoutChange={this.onLayoutChange}
                 preventCollision={false} // change this to true later
-            // transformScale={2} // 1.2/scale
+                // transformScale={2} // 1.2/scale
+                style={{ zIndex: 5 }}
             >
                 {this.props.nodeList}
             </GridLayout >
-- 
cgit v1.2.3-70-g09d2


From 4cdd53c1208cd17593e0ecdb34e89265760a6512 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Thu, 4 Jun 2020 12:46:51 +0530
Subject: added numcols buttons to chrome + fixed some chrome css + added
 rowheight slider + rowheight slider css + fixed bug on document delete in
 freeform and reenter grid

---
 package-lock.json                                  | 84 +++++++++++++---------
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../views/collections/CollectionViewChromes.scss   |  7 ++
 .../views/collections/CollectionViewChromes.tsx    | 52 +++++++++++---
 .../collectionGrid/CollectionGridView.scss         | 47 ++++++++++--
 .../collectionGrid/CollectionGridView.tsx          | 72 +++++++++----------
 .../views/collections/collectionGrid/Grid.tsx      |  9 ++-
 7 files changed, 180 insertions(+), 93 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index adf71ee58..14b279ef6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2836,7 +2836,8 @@
                         },
                         "ansi-regex": {
                             "version": "2.1.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "aproba": {
                             "version": "1.2.0",
@@ -2854,11 +2855,13 @@
                         },
                         "balanced-match": {
                             "version": "1.0.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "brace-expansion": {
                             "version": "1.1.11",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "balanced-match": "^1.0.0",
                                 "concat-map": "0.0.1"
@@ -2871,15 +2874,18 @@
                         },
                         "code-point-at": {
                             "version": "1.1.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "concat-map": {
                             "version": "0.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "console-control-strings": {
                             "version": "1.1.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "core-util-is": {
                             "version": "1.0.2",
@@ -2982,7 +2988,8 @@
                         },
                         "inherits": {
                             "version": "2.0.4",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "ini": {
                             "version": "1.3.5",
@@ -2992,6 +2999,7 @@
                         "is-fullwidth-code-point": {
                             "version": "1.0.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "number-is-nan": "^1.0.0"
                             }
@@ -3004,17 +3012,20 @@
                         "minimatch": {
                             "version": "3.0.4",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "brace-expansion": "^1.1.7"
                             }
                         },
                         "minimist": {
                             "version": "1.2.5",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "safe-buffer": "^5.1.2",
                                 "yallist": "^3.0.0"
@@ -3031,6 +3042,7 @@
                         "mkdirp": {
                             "version": "0.5.3",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "minimist": "^1.2.5"
                             }
@@ -3086,7 +3098,8 @@
                         },
                         "npm-normalize-package-bin": {
                             "version": "1.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "npm-packlist": {
                             "version": "1.4.8",
@@ -3111,7 +3124,8 @@
                         },
                         "number-is-nan": {
                             "version": "1.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "object-assign": {
                             "version": "4.1.1",
@@ -3121,6 +3135,7 @@
                         "once": {
                             "version": "1.4.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "wrappy": "1"
                             }
@@ -3189,7 +3204,8 @@
                         },
                         "safe-buffer": {
                             "version": "5.1.2",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "safer-buffer": {
                             "version": "2.1.2",
@@ -3219,6 +3235,7 @@
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "code-point-at": "^1.0.0",
                                 "is-fullwidth-code-point": "^1.0.0",
@@ -3236,6 +3253,7 @@
                         "strip-ansi": {
                             "version": "3.0.1",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "ansi-regex": "^2.0.0"
                             }
@@ -3274,11 +3292,13 @@
                         },
                         "wrappy": {
                             "version": "1.0.2",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "yallist": {
                             "version": "3.1.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         }
                     }
                 }
@@ -9500,7 +9520,7 @@
                 },
                 "chownr": {
                     "version": "1.1.4",
-                    "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
                 },
                 "ci-info": {
@@ -9806,7 +9826,7 @@
                 },
                 "deep-extend": {
                     "version": "0.6.0",
-                    "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
                 },
                 "defaults": {
@@ -10305,7 +10325,7 @@
                 },
                 "glob": {
                     "version": "7.1.6",
-                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+                    "resolved": false,
                     "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
                     "requires": {
                         "fs.realpath": "^1.0.0",
@@ -10393,7 +10413,7 @@
                 },
                 "hosted-git-info": {
                     "version": "2.8.8",
-                    "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
                 },
                 "http-cache-semantics": {
@@ -10529,7 +10549,7 @@
                 },
                 "is-ci": {
                     "version": "1.2.1",
-                    "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
                     "requires": {
                         "ci-info": "^1.5.0"
@@ -10605,7 +10625,7 @@
                 },
                 "is-retry-allowed": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
                 },
                 "is-stream": {
@@ -11114,7 +11134,7 @@
                 },
                 "mkdirp": {
                     "version": "0.5.4",
-                    "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
                     "requires": {
                         "minimist": "^1.2.5"
@@ -11122,7 +11142,7 @@
                     "dependencies": {
                         "minimist": {
                             "version": "1.2.5",
-                            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+                            "resolved": false,
                             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
                         }
                     }
@@ -11174,7 +11194,7 @@
                 },
                 "node-gyp": {
                     "version": "5.1.0",
-                    "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==",
                     "requires": {
                         "env-paths": "^2.2.0",
@@ -11288,7 +11308,7 @@
                 },
                 "npm-packlist": {
                     "version": "1.4.8",
-                    "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
                     "requires": {
                         "ignore-walk": "^3.0.1",
@@ -11308,7 +11328,7 @@
                 },
                 "npm-profile": {
                     "version": "4.0.4",
-                    "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-4.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==",
                     "requires": {
                         "aproba": "^1.1.2 || 2",
@@ -11318,7 +11338,7 @@
                 },
                 "npm-registry-fetch": {
                     "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==",
                     "requires": {
                         "JSONStream": "^1.3.4",
@@ -11753,7 +11773,7 @@
                 },
                 "rc": {
                     "version": "1.2.8",
-                    "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
                     "requires": {
                         "deep-extend": "^0.6.0",
@@ -11764,7 +11784,7 @@
                     "dependencies": {
                         "minimist": {
                             "version": "1.2.5",
-                            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+                            "resolved": false,
                             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
                         }
                     }
@@ -11823,7 +11843,7 @@
                 },
                 "readable-stream": {
                     "version": "3.6.0",
-                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
                     "requires": {
                         "inherits": "^2.0.3",
@@ -11844,7 +11864,7 @@
                 },
                 "registry-auth-token": {
                     "version": "3.4.0",
-                    "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
                     "requires": {
                         "rc": "^1.1.6",
@@ -11908,7 +11928,7 @@
                 },
                 "rimraf": {
                     "version": "2.7.1",
-                    "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
                         "glob": "^7.1.3"
@@ -12207,7 +12227,7 @@
                 },
                 "string_decoder": {
                     "version": "1.3.0",
-                    "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
                     "requires": {
                         "safe-buffer": "~5.2.0"
@@ -12215,7 +12235,7 @@
                     "dependencies": {
                         "safe-buffer": {
                             "version": "5.2.0",
-                            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
                         }
                     }
@@ -12527,7 +12547,7 @@
                 },
                 "widest-line": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
                     "requires": {
                         "string-width": "^2.1.1"
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index bcb190de4..df84cab56 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -232,7 +232,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
         subItems.push({ description: "Carousel", event: () => func(CollectionViewType.Carousel), icon: "columns" });
         subItems.push({ description: "Pivot/Time", event: () => func(CollectionViewType.Time), icon: "columns" });
         subItems.push({ description: "Map", event: () => func(CollectionViewType.Map), icon: "globe-americas" });
-        subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "border-all" });
+        subItems.push({ description: "Grid", event: () => func(CollectionViewType.Grid), icon: "th-list" });
         if (addExtras && this.props.Document._viewType === CollectionViewType.Freeform) {
             subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
         }
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 42ec35853..f6027471b 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -181,9 +181,16 @@
             .grid-control {
                 align-self: center;
                 width: 30%;
+                display: flex;
+                flex-direction: row;
 
                 .grid-icon {
                     margin-right: 5px;
+                    align-self: center;
+                }
+
+                .flexLabel {
+                    margin-bottom: 0;
                 }
             }
 
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 3d712e4f5..5a76a4605 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -93,7 +93,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                 this.props.collapse?.(true);
                 break;
         }
-    })
+    });
 
     @undoBatch
     viewChanged = (e: React.ChangeEvent) => {
@@ -569,6 +569,9 @@ export class CollectionTreeViewChrome extends React.Component<CollectionViewChro
 @observer
 export class CollectionGridViewChrome extends React.Component<CollectionViewChromeProps> {
 
+    private clicked: boolean = false;
+    private entered: boolean = false;
+
     /**
      * Sets the value of `numCols` on the grid's Document to the value entered.
      */
@@ -577,7 +580,6 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         if (e.key === "Enter" || e.key === "Tab") {
             if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.numCols as number !== e.currentTarget.valueAsNumber) {
                 this.props.CollectionView.props.Document.numCols = e.currentTarget.valueAsNumber;
-                //this.props.CollectionView.forceUpdate(); // to be used if CollectionGridView is not an observer
             }
 
         }
@@ -602,27 +604,59 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.props.CollectionView.props.Document.flexGrid = !this.props.CollectionView.props.Document.flexGrid;
     }
 
+    onIncrementButtonClick = () => {
+        this.clicked = true;
+        this.entered && (this.props.CollectionView.props.Document.numCols as number)--;
+        undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)++)();
+        this.entered = false;
+    }
+
+    onDecrementButtonClick = () => {
+        this.clicked = true;
+        this.entered && (this.props.CollectionView.props.Document.numCols as number)++;
+        undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)--)();
+        this.entered = false;
+    }
+
+    incrementValue = () => {
+        this.entered = true;
+        if (!this.clicked) {
+            (this.props.CollectionView.props.Document.numCols as number)++;
+        }
+        this.clicked = false;
+    }
+
+    decrementValue = () => {
+        this.entered = true;
+        if (!this.clicked) {
+            (this.props.CollectionView.props.Document.numCols as number)--;
+        }
+        this.clicked = false;
+    }
+
     render() {
         return (
-            <div className="collectionGridViewChrome-cont">
-                <span className={"grid-control"}>
+            <div className="collectionGridViewChrome-cont" >
+                <span className="grid-control">
                     <span className="grid-icon">
                         <FontAwesomeIcon icon="columns" size="1x" />
                     </span>
-                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.numCols as string} onKeyDown={this.onNumColsEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => e.currentTarget.focus()} />
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.numCols as string} onKeyDown={this.onNumColsEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
+                    <input className="columnButton" onClick={this.onIncrementButtonClick} onMouseEnter={this.incrementValue} onMouseLeave={this.decrementValue} type="button" value="↑" />
+                    <input className="columnButton" style={{ marginRight: 5 }} onClick={this.onDecrementButtonClick} onMouseEnter={this.decrementValue} onMouseLeave={this.incrementValue} type="button" value="↓" />
                 </span>
-                <span className={"grid-control"}>
+                <span className="grid-control">
                     <span className="grid-icon">
                         <FontAwesomeIcon icon="text-height" size="1x" />
                     </span>
-                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => e.currentTarget.focus()} />
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                 </span>
-                <span className={"grid-control"}>
+                <span className="grid-control">
                     <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
                     <span className="grid-icon">
                         <FontAwesomeIcon icon="arrow-up" size="1x" />
                     </span>
-                    <label>Flexible</label>
+                    <label className="flexLabel">Flexible</label>
                 </span>
             </div>
         );
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index 94b0d958c..e06e8dc90 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -9,6 +9,43 @@
         height: 100%;
         overflow-y: auto;
         background-color: white;
+        overflow-x: hidden;
+
+        display: flex;
+        flex-direction: row;
+
+        .rowHeightSlider {
+
+            -webkit-appearance: none;
+            appearance: none;
+            width: 100%;
+            height: 15px;
+            background: #d3d3d3;
+            // border-radius: 5px;
+
+            position: absolute;
+            height: 3;
+            left: 5;
+            top: 40;
+            transform-origin: left;
+            transform: rotate(90deg);
+            outline: none;
+            opacity: 0.7;
+        }
+
+        .rowHeightSlider:hover {
+            opacity: 1;
+        }
+
+        .rowHeightSlider::-webkit-slider-thumb {
+            -webkit-appearance: none;
+            appearance: none;
+            width: 10px;
+            height: 10px;
+            border-radius: 50%;
+            background: darkgrey;
+            opacity: 1;
+        }
     }
 
     .collectionGridView-addDocumentButton {
@@ -17,7 +54,8 @@
         margin: auto;
         width: 90%;
         cursor: text;
-
+        min-height: 30px;
+        max-height: 30px;
         font-size: 75%;
         letter-spacing: 2px;
 
@@ -31,15 +69,14 @@
 
         .editableView-container-editing,
         .editableView-container-editing-oneLine {
-            min-height: 20px;
             display: flex;
             align-items: center;
             flex-direction: row;
-            height: auto;
+            height: 20px;
 
+            width: 100%;
             color: grey;
             padding: 10px;
-            width: 100%;
 
             span::before,
             span::after {
@@ -67,8 +104,6 @@
                 align-items: center;
             }
         }
-
-
     }
 
 }
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index c56d6ee53..68612c9dc 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -3,7 +3,7 @@ import * as React from "react";
 import { Doc, Opt } from '../../../../fields/Doc';
 import { documentSchema } from '../../../../fields/documentSchemas';
 import { makeInterface } from '../../../../fields/Schema';
-import { BoolCast, NumCast, ScriptCast } from '../../../../fields/Types';
+import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
 import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
@@ -15,9 +15,9 @@ import Grid, { Layout } from "./Grid";
 import { Id } from '../../../../fields/FieldSymbols';
 import { observer } from 'mobx-react';
 import { SnappingManager } from '../../../util/SnappingManager';
-import "./CollectionGridView.scss";
 import { Docs } from '../../../documents/Documents';
 import { EditableView, EditableProps } from '../../EditableView';
+import "./CollectionGridView.scss";
 
 
 type GridSchema = makeInterface<[typeof documentSchema]>;
@@ -37,28 +37,38 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         this.props.Document.flexGrid = BoolCast(this.props.Document.flexGrid, true);
 
         this.setLayout = this.setLayout.bind(this);
-        // this.addTextDoc = this.addTextDoc.bind(this);
+        this.onSliderChange = this.onSliderChange.bind(this);
 
         this.containerRef = React.createRef();
     }
 
     componentDidMount() {
-
         this.changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => {
 
             const layouts: Layout[] = this.parsedLayoutList;
+
+            // if grid view has been opened and then exited and a document has been deleted
+            // this deletes the layout of that document from the layouts list
+            if (!oldValue) {
+                layouts.forEach(({ i }, index) => {
+                    const targetId = i;
+                    if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) {
+                        layouts.splice(index, 1);
+                    }
+                });
+            }
+
             if (!oldValue || newValue.length > oldValue.length) {
                 // for each document that was added, add a corresponding grid layout document
                 newValue.forEach(({ layout }, i) => {
                     const targetId = layout[Id];
                     if (!layouts.find((gridLayout: Layout) => gridLayout.i === targetId)) {
-                        console.log("pushing")
                         layouts.push({
                             i: targetId,
                             w: 2,
                             h: 2,
-                            x: 2 * (i % Math.floor(this.props.Document.numCols as number / 2)),
-                            y: 2 * Math.floor(i / Math.floor(this.props.Document.numCols as number / 2))
+                            x: 2 * (i % Math.floor(NumCast(this.props.Document.numCols) / 2)),
+                            y: 2 * Math.floor(i / Math.floor(NumCast(this.props.Document.numCols) / 2))
                         });
                     }
                 });
@@ -72,9 +82,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     }
                 });
             }
-
             this.unStringifiedLayoutList = layouts;
-            // this.props.Document.gridLayoutString = JSON.stringify(layouts);
         }, true);
     }
 
@@ -82,23 +90,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         this.changeListenerDisposer && this.changeListenerDisposer();
     }
 
-    /**
-     * Establishes the x and y properties of the @param layoutDoc, currently
-     * using the @param previousLength for the computations.
-     * 
-     * However, this could also be more of a first fit algorithm, iterating through
-     * this.toLayoutList(DocListCast(this.props.Document.gridLayouts)) and finding the
-     * first gap in the layout structure that suits the width and height. It would be
-     * easiest to see that a column is free (for a given row, if two documents' x are separated
-     * by a value greater than the ratio width of the document you're trying to insert),
-     * but you would then have to ensure that the next row at that column has a y at least
-     * as big as the ratio height of the document you're trying to insert.  
-     */
-    private findNextLayout(layoutDoc: Doc, previousLength: number) {
-        layoutDoc.x = 2 * (previousLength % Math.floor(this.props.Document.numCols as number / 2));
-        layoutDoc.y = 2 * Math.floor(previousLength / Math.floor(this.props.Document.numCols as number / 2));
-    }
-
     /**
      * @returns the transform that will correctly place
      * the document decorations box, shifted to the right by
@@ -108,8 +99,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     private lookupIndividualTransform = (layout: Layout) => {
 
         const index = this.childLayoutPairs.findIndex(({ layout: layoutDoc }) => layoutDoc[Id] === layout.i);
-        const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : 2 * Math.floor(index / Math.floor(this.props.Document.numCols as number / 2))) * this.rowHeightPlusGap + 10 - this._scroll;
-        const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : 2 * (index % Math.floor(this.props.Document.numCols as number / 2))) * this.colWidthPlusGap + 10;
+        const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2))) * this.rowHeightPlusGap + 10 - this._scroll + 30; // 30 is the height of the add text doc bar
+        const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2))) * this.colWidthPlusGap + 10;
 
         return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
     }
@@ -119,7 +110,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
     @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
 
-    get parsedLayoutList() { return this.props.Document.gridLayoutString ? JSON.parse(this.props.Document.gridLayoutString as string) : []; }
+    get parsedLayoutList() { return this.props.Document.gridLayoutString ? JSON.parse(StrCast(this.props.Document.gridLayoutString)) : []; }
     set unStringifiedLayoutList(layouts: Layout[]) { this.props.Document.gridLayoutString = JSON.stringify(layouts); }
 
 
@@ -177,7 +168,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             let update: Opt<Layout>;
             const targetId = doc[Id];
             const gridLayout = layouts.find(gridLayout => gridLayout.i === targetId);
-            // const gridLayout = DocListCast(this.props.Document.gridLayouts).find(gridLayout => StrCast(gridLayout.i) === targetId);
             if (this.props.Document.flexGrid && gridLayout && (update = layoutArray.find(layout => layout.i === targetId))) {
                 gridLayout.x = update.x;
                 gridLayout.y = update.y;
@@ -186,7 +176,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             }
         });
 
-        // this.props.Document.gridLayoutString = JSON.stringify(layouts);
         this.unStringifiedLayoutList = layouts;
     }
 
@@ -210,7 +199,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             const width = () => this.width(gridLayout);
             const height = () => this.height(gridLayout);
             collector.push(
-                <div className={this.props.Document.flexGrid ? "document-wrapper" : "document-wrapper static"}
+                <div className={this.props.Document.flexGrid && (this.props.isSelected() ? true : false) ? "document-wrapper" : "document-wrapper static"}
                     key={gridLayout.i}
                 >
                     {this.getDisplayDoc(layout, dxf, width, height)}
@@ -231,14 +220,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         return this.props.Document.flexGrid ?
             layouts : layouts.map(({ i }, index) => ({
                 i: i,
-                x: 2 * (index % Math.floor(this.props.Document.numCols as number / 2)),
-                y: 2 * Math.floor(index / Math.floor(this.props.Document.numCols as number / 2)),
+                x: 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2)),
+                y: 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2)),
                 w: 2,
                 h: 2,
                 static: true
             }));
     }
 
+    onSliderChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+        this.props.Document.rowHeight = event.currentTarget.valueAsNumber;
+    }
+
     @undoBatch @action addTextDocument = (value: string) => this.props.addDocument(Docs.Create.TextDocument(value, { title: value }));
 
     /**
@@ -254,14 +247,13 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         const newEditableViewProps: EditableProps = {
             GetValue: () => "",
             SetValue: this.addTextDocument,
-            contents: "+ NEW",
+            contents: "+ ADD TEXT DOCUMENT AT END",
         };
 
         const childDocumentViews: JSX.Element[] = this.contents;
         const chromeStatus = this.props.Document._chromeStatus;
         const showChrome = (chromeStatus !== 'view-mode' && chromeStatus !== 'disabled');
 
-
         return (
             <div className="collectionGridView-contents"
                 style={{
@@ -290,18 +282,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     ref={this.containerRef}
                     onScroll={action((e: React.UIEvent<HTMLDivElement>) => this._scroll = e.currentTarget.scrollTop)}
                 >
+                    <input className="rowHeightSlider" type="range" defaultValue={NumCast(this.props.Document.rowHeight)} onChange={this.onSliderChange} style={{ width: this.props.PanelHeight() - 40 }} min={1} max={this.props.PanelHeight() - 40} onPointerEnter={e => e.currentTarget.focus()} />
                     <Grid
                         width={this.props.PanelWidth()}
                         nodeList={childDocumentViews.length ? childDocumentViews : null}
                         layout={childDocumentViews.length ? this.layoutList : undefined}
                         childrenDraggable={this.props.isSelected() ? true : false}
-                        numCols={this.props.Document.numCols as number}
-                        rowHeight={this.props.Document.rowHeight as number}
+                        numCols={NumCast(this.props.Document.numCols)}
+                        rowHeight={NumCast(this.props.Document.rowHeight)}
                         setLayout={this.setLayout}
-                        //setLayout={(layout: Layout[]) => this.setLayout(layout)}
                         transformScale={this.props.ScreenToLocalTransform().Scale}
-                    // flex={this.props.Document.flexGrid as boolean}
                     />
+
                 </div>
             </div >
         );
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index cae06c4e7..29bafda9b 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -36,7 +36,6 @@ export default class Grid extends React.Component<GridProps> {
      * @param layout `Layout[]`
      */
     onLayoutChange(layout: Layout[]) {
-        console.log("layout changed");
         this.props.setLayout(layout);
     }
 
@@ -50,12 +49,12 @@ export default class Grid extends React.Component<GridProps> {
                 width={this.props.width}
                 compactType={null}
                 isDroppable={true}
-                // isDraggable={this.props.childrenDraggable}
+                isDraggable={this.props.childrenDraggable}
+                isResizable={this.props.childrenDraggable}
                 useCSSTransforms={true}
-                margin={[10, 10]}
                 onLayoutChange={this.onLayoutChange}
-                preventCollision={false} // change this to true later
-                // transformScale={2} // 1.2/scale
+                preventCollision={true}
+                transformScale={this.props.transformScale}
                 style={{ zIndex: 5 }}
             >
                 {this.props.nodeList}
-- 
cgit v1.2.3-70-g09d2


From e30e5e4139be5312c46868f17de4dee5d516fd23 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 6 Jun 2020 14:30:48 +0530
Subject: added choice to compact, prevent collisions + fixed document
 repositioning on reducing columns + removed row height input

---
 package-lock.json                                  | 101 +++++++++++++++++++++
 package.json                                       |   3 +-
 .../views/collections/CollectionViewChromes.scss   |   1 +
 .../views/collections/CollectionViewChromes.tsx    |  56 ++++++++----
 .../collectionGrid/CollectionGridView.scss         |   8 ++
 .../collectionGrid/CollectionGridView.tsx          |  35 +++++--
 .../views/collections/collectionGrid/Grid.tsx      |   8 +-
 7 files changed, 185 insertions(+), 27 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 14b279ef6..d1db185a3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3532,6 +3532,11 @@
                 "delayed-stream": "~1.0.0"
             }
         },
+        "command-exists": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.6.tgz",
+            "integrity": "sha512-Qst/zUUNmS/z3WziPxyqjrcz09pm+2Knbs5mAZL4VAE0sSrNY1/w8+/YxeHcoBTsO6iojA6BW7eFf27Eg2MRuw=="
+        },
         "command-line-usage": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
@@ -12948,6 +12953,11 @@
                 "os-tmpdir": "^1.0.0"
             }
         },
+        "p-debounce": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/p-debounce/-/p-debounce-1.0.0.tgz",
+            "integrity": "sha1-y38svu/YegnrqGHhErZ1J+Yh4v0="
+        },
         "p-defer": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@@ -15983,6 +15993,20 @@
                 "readable-stream": "^3.1.1"
             }
         },
+        "temp-dir": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
+            "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0="
+        },
+        "tempy": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.2.1.tgz",
+            "integrity": "sha512-LB83o9bfZGrntdqPuRdanIVCPReam9SOZKW0fOy5I9X3A854GGWi0tjCqoXEk84XIEYBc/x9Hq3EFop/H5wJaw==",
+            "requires": {
+                "temp-dir": "^1.0.0",
+                "unique-string": "^1.0.0"
+            }
+        },
         "term-size": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
@@ -16558,6 +16582,40 @@
             "resolved": "https://registry.npmjs.org/typescript-collections/-/typescript-collections-1.3.3.tgz",
             "integrity": "sha512-7sI4e/bZijOzyURng88oOFZCISQPTHozfE2sUu5AviFYk5QV7fYGb6YiDl+vKjF/pICA354JImBImL9XJWUvdQ=="
         },
+        "typescript-language-server": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/typescript-language-server/-/typescript-language-server-0.4.0.tgz",
+            "integrity": "sha512-K8jNOmDFn+QfrCh8ujby2pGDs5rpjYZQn+zvQnf42rxG4IHbfw5CHoMvbGkWPK/J5Gw8/l5K3i03kVZC2IBElg==",
+            "requires": {
+                "command-exists": "1.2.6",
+                "commander": "^2.11.0",
+                "fs-extra": "^7.0.0",
+                "p-debounce": "^1.0.0",
+                "tempy": "^0.2.1",
+                "vscode-languageserver": "^5.3.0-next",
+                "vscode-uri": "^1.0.5"
+            },
+            "dependencies": {
+                "fs-extra": {
+                    "version": "7.0.1",
+                    "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+                    "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+                    "requires": {
+                        "graceful-fs": "^4.1.2",
+                        "jsonfile": "^4.0.0",
+                        "universalify": "^0.1.0"
+                    }
+                },
+                "jsonfile": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+                    "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+                    "requires": {
+                        "graceful-fs": "^4.1.6"
+                    }
+                }
+            }
+        },
         "typical": {
             "version": "2.6.1",
             "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
@@ -16712,6 +16770,11 @@
                 "crypto-random-string": "^1.0.0"
             }
         },
+        "universalify": {
+            "version": "0.1.2",
+            "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+            "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+        },
         "unpack-string": {
             "version": "0.0.2",
             "resolved": "https://registry.npmjs.org/unpack-string/-/unpack-string-0.0.2.tgz",
@@ -16954,6 +17017,44 @@
             "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
             "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
         },
+        "vscode-jsonrpc": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-5.0.1.tgz",
+            "integrity": "sha512-JvONPptw3GAQGXlVV2utDcHx0BiY34FupW/kI6mZ5x06ER5DdPG/tXWMVHjTNULF5uKPOUUD0SaXg5QaubJL0A=="
+        },
+        "vscode-languageserver": {
+            "version": "5.3.0-next.10",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.3.0-next.10.tgz",
+            "integrity": "sha512-QL7Fe1FT6PdLtVzwJeZ78pTic4eZbzLRy7yAQgPb9xalqqgZESR0+yDZPwJrM3E7PzOmwHBceYcJR54eQZ7Kng==",
+            "requires": {
+                "vscode-languageserver-protocol": "^3.15.0-next.8",
+                "vscode-textbuffer": "^1.0.0"
+            }
+        },
+        "vscode-languageserver-protocol": {
+            "version": "3.15.3",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.15.3.tgz",
+            "integrity": "sha512-zrMuwHOAQRhjDSnflWdJG+O2ztMWss8GqUUB8dXLR/FPenwkiBNkMIJJYfSN6sgskvsF0rHAoBowNQfbyZnnvw==",
+            "requires": {
+                "vscode-jsonrpc": "^5.0.1",
+                "vscode-languageserver-types": "3.15.1"
+            }
+        },
+        "vscode-languageserver-types": {
+            "version": "3.15.1",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
+            "integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
+        },
+        "vscode-textbuffer": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/vscode-textbuffer/-/vscode-textbuffer-1.0.0.tgz",
+            "integrity": "sha512-zPaHo4urgpwsm+PrJWfNakolRpryNja18SUip/qIIsfhuEqEIPEXMxHOlFPjvDC4JgTaimkncNW7UMXRJTY6ow=="
+        },
+        "vscode-uri": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
+            "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ=="
+        },
         "vue-template-compiler": {
             "version": "2.6.11",
             "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz",
diff --git a/package.json b/package.json
index 74b7bf9d1..a8ff42c91 100644
--- a/package.json
+++ b/package.json
@@ -206,10 +206,10 @@
         "react-compound-slider": "^2.5.0",
         "react-dom": "^16.12.0",
         "react-grid-layout": "^0.18.3",
-        "react-resizable": "^1.10.1",
         "react-image-lightbox-with-rotate": "^5.1.1",
         "react-jsx-parser": "^1.21.0",
         "react-measure": "^2.2.4",
+        "react-resizable": "^1.10.1",
         "react-table": "^6.11.5",
         "readline": "^1.3.0",
         "request": "^2.88.0",
@@ -223,6 +223,7 @@
         "solr-node": "^1.2.1",
         "standard-http-error": "^2.0.1",
         "typescript-collections": "^1.3.3",
+        "typescript-language-server": "^0.4.0",
         "url-loader": "^1.1.2",
         "uuid": "^3.4.0",
         "valid-url": "^1.0.9",
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index f6027471b..398b02d3f 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -183,6 +183,7 @@
                 width: 30%;
                 display: flex;
                 flex-direction: row;
+                margin-right: 5px;
 
                 .grid-icon {
                     margin-right: 5px;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 5a76a4605..95774adca 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -571,6 +571,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
 
     private clicked: boolean = false;
     private entered: boolean = false;
+    private decrementLimitReached: boolean = false;
 
     /**
      * Sets the value of `numCols` on the grid's Document to the value entered.
@@ -588,14 +589,14 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     /**
      * Sets the value of `rowHeight` on the grid's Document to the value entered.
      */
-    @undoBatch
-    onRowHeightEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
-        if (e.key === "Enter" || e.key === "Tab") {
-            if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) {
-                this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber;
-            }
-        }
-    }
+    // @undoBatch
+    // onRowHeightEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
+    //     if (e.key === "Enter" || e.key === "Tab") {
+    //         if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.rowHeight as number !== e.currentTarget.valueAsNumber) {
+    //             this.props.CollectionView.props.Document.rowHeight = e.currentTarget.valueAsNumber;
+    //         }
+    //     }
+    // }
 
     /**
      * Sets whether the grid is flexible or not on the grid's Document.
@@ -613,27 +614,44 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
 
     onDecrementButtonClick = () => {
         this.clicked = true;
-        this.entered && (this.props.CollectionView.props.Document.numCols as number)++;
-        undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)--)();
+        if (!this.decrementLimitReached) {
+            this.entered && (this.props.CollectionView.props.Document.numCols as number)++;
+            undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)--)();
+        }
         this.entered = false;
     }
 
     incrementValue = () => {
         this.entered = true;
-        if (!this.clicked) {
+        if (!this.clicked && !this.decrementLimitReached) {
             (this.props.CollectionView.props.Document.numCols as number)++;
         }
+        this.decrementLimitReached = false;
         this.clicked = false;
     }
 
     decrementValue = () => {
         this.entered = true;
         if (!this.clicked) {
-            (this.props.CollectionView.props.Document.numCols as number)--;
+            if (this.props.CollectionView.props.Document.numCols as number !== 1) {
+                (this.props.CollectionView.props.Document.numCols as number)--;
+            }
+            else {
+                this.decrementLimitReached = true;
+            }
         }
+
         this.clicked = false;
     }
 
+    toggleCollisions = () => {
+        this.props.CollectionView.props.Document.preventCollision = !this.props.CollectionView.props.Document.preventCollision;
+    }
+
+    changeCompactType = () => {
+        this.props.CollectionView.props.Document.compactType = this.props.CollectionView.props.Document.compactType === "vertical" ? "horizontal" : this.props.CollectionView.props.Document.compactType === "horizontal" ? "null" : "vertical";
+    }
+
     render() {
         return (
             <div className="collectionGridViewChrome-cont" >
@@ -645,17 +663,23 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <input className="columnButton" onClick={this.onIncrementButtonClick} onMouseEnter={this.incrementValue} onMouseLeave={this.decrementValue} type="button" value="↑" />
                     <input className="columnButton" style={{ marginRight: 5 }} onClick={this.onDecrementButtonClick} onMouseEnter={this.decrementValue} onMouseLeave={this.incrementValue} type="button" value="↓" />
                 </span>
-                <span className="grid-control">
+                {/* <span className="grid-control">
                     <span className="grid-icon">
                         <FontAwesomeIcon icon="text-height" size="1x" />
                     </span>
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
+                </span> */}
+                <span className="grid-control" style={{ width: "20%" }}>
+                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
+                    <label className="flexLabel">Collisions </label>
                 </span>
+
+                <span className="grid-control">
+                    <input style={{ marginRight: 5 }} type="button" onClick={this.changeCompactType} value={`Compact: ${this.props.CollectionView.props.Document.compactType}`} />
+                </span>
+
                 <span className="grid-control">
                     <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
-                    <span className="grid-icon">
-                        <FontAwesomeIcon icon="arrow-up" size="1x" />
-                    </span>
                     <label className="flexLabel">Flexible</label>
                 </span>
             </div>
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index e06e8dc90..578dae966 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -46,6 +46,14 @@
             background: darkgrey;
             opacity: 1;
         }
+
+        .rowHeightSlider::-moz-range-thumb {
+            width: 10px;
+            height: 10px;
+            border-radius: 50%;
+            background: darkgrey;
+            opacity: 1;
+        }
     }
 
     .collectionGridView-addDocumentButton {
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index dd4e28e33..e97cb9f0e 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -18,6 +18,7 @@ import { SnappingManager } from '../../../util/SnappingManager';
 import { Docs } from '../../../documents/Documents';
 import { EditableView, EditableProps } from '../../EditableView';
 import "./CollectionGridView.scss";
+import { ContextMenu } from '../../ContextMenu';
 
 
 type GridSchema = makeInterface<[typeof documentSchema]>;
@@ -29,6 +30,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     @observable private _scroll: number = 0;
     private changeListenerDisposer: Opt<Lambda>;
     private rowHeight: number = 0;
+    private sliderDragged: boolean = false;
 
     constructor(props: Readonly<SubCollectionViewProps>) {
         super(props);
@@ -37,6 +39,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         this.props.Document.rowHeight = NumCast(this.props.Document.rowHeight, 100);
         this.props.Document.flexGrid = BoolCast(this.props.Document.flexGrid, true);
 
+        this.props.Document.compactType = StrCast(this.props.Document.compactType, "vertical");
+        this.props.Document.preventCollision = BoolCast(this.props.Document.preventCollision, false);
+
         this.setLayout = this.setLayout.bind(this);
         this.onSliderChange = this.onSliderChange.bind(this);
         // this.deletePlaceholder = this.deletePlaceholder.bind(this);
@@ -44,6 +49,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     }
 
     componentDidMount() {
+
         this.changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => {
 
             const layouts: Layout[] = this.parsedLayoutList;
@@ -61,6 +67,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
             if (!oldValue || newValue.length > oldValue.length) {
                 // for each document that was added, add a corresponding grid layout document
+
                 newValue.forEach(({ layout }, i) => {
                     const targetId = layout[Id];
                     if (!layouts.find((gridLayout: Layout) => gridLayout.i === targetId)) {
@@ -89,7 +96,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
     componentWillUnmount() {
         this.changeListenerDisposer && this.changeListenerDisposer();
-        console.log("unmounted")
     }
 
     // deletePlaceholder(placeholder: Layout, e: MouseEvent) {
@@ -222,9 +228,10 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             collector.push(
                 <div className={this.props.Document.flexGrid && (this.props.isSelected() ? true : false) ? "document-wrapper" : "document-wrapper static"}
                     key={gridLayout.i}
+                // onContextMenu={() => ContextMenu.Instance.addItem({ description: "test", event: () => console.log("test"), icon: "rainbow" })}
                 >
                     {this.getDisplayDoc(layout, dxf, width, height)}
-                </div>
+                </div >
             );
         }
 
@@ -237,9 +244,17 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     get layoutList(): Layout[] {
         const layouts: Layout[] = this.parsedLayoutList;
+        this.unStringifiedLayoutList = layouts;
 
         return this.props.Document.flexGrid ?
-            layouts : layouts.map(({ i }, index) => ({
+            layouts.map(({ i, x, y, w, h }) => ({
+                i: i,
+                x: x + w > NumCast(this.props.Document.numCols) ? 0 : x,
+                y: y,
+                w: w,
+                h: h
+            }))
+            : layouts.map(({ i }, index) => ({
                 i: i,
                 x: 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2)),
                 y: 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2)),
@@ -250,7 +265,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     }
 
     onSliderChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+        NumCast(this.props.Document.rowHeight) !== event.currentTarget.valueAsNumber && (this.sliderDragged = true);
         this.props.Document.rowHeight = event.currentTarget.valueAsNumber;
+
     }
 
     onSliderDown = () => {
@@ -277,7 +294,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         const newEditableViewProps: EditableProps = {
             GetValue: () => "",
             SetValue: this.addTextDocument,
-            contents: "+ ADD TEXT DOCUMENT AT END",
+            contents: "+ ADD TEXT DOCUMENT",
         };
 
         const childDocumentViews: JSX.Element[] = this.contents;
@@ -287,10 +304,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         return (
             <div className="collectionGridView-contents"
                 style={{
-                    // marginLeft: NumCast(this.props.Document._xMargin), marginRight: NumCast(this.props.Document._xMargin),
-                    // marginTop: NumCast(this.props.Document._yMargin), marginBottom: NumCast(this.props.Document._yMargin),
                     pointerEvents: !this.props.isSelected() && this.props.renderDepth !== 0 && !this.props.ContainingCollectionView?._isChildActive && !SnappingManager.GetIsDragging() ? "none" : undefined
                 }}
+                // onContextMenu={() => ContextMenu.Instance.addItem({ description: "test", event: () => console.log("test"), icon: "rainbow" })}
                 ref={this.createDashEventsTarget}
                 onPointerDown={e => {
                     if (this.props.active(true)) {
@@ -301,7 +317,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     // is the following section needed? it prevents the slider from being easily used and I'm not sure what it's preventing
 
                     // if (this.props.isSelected(true)) {
-                    // !((e.target as any)?.className.includes("react-resizable-handle")) && e.preventDefault();
+                    //     !((e.target as any)?.className.includes("react-resizable-handle")) && e.preventDefault();
                     // }
 
                 }} // the grid doesn't stopPropagation when its widgets are hit, so we need to otherwise the outer documents will respond
@@ -316,7 +332,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     onScroll={action(e => this._scroll = e.currentTarget.scrollTop)}
                     onWheel={e => e.stopPropagation()}
                 >
-                    <input className="rowHeightSlider" type="range" value={NumCast(this.props.Document.rowHeight)} onPointerDown={this.onSliderDown} onPointerUp={this.onSliderUp} onChange={this.onSliderChange} style={{ width: this.props.PanelHeight() - 40 }} min={1} max={this.props.PanelHeight() - 40} onPointerEnter={e => e.currentTarget.focus()} />
+                    <input className="rowHeightSlider" type="range" value={NumCast(this.props.Document.rowHeight)} onPointerDown={this.onSliderDown} onPointerUp={this.onSliderUp} onChange={this.onSliderChange} style={{ width: this.props.PanelHeight() - 40 }} min={1} max={this.props.PanelHeight() - 40} onClick={() => !this.sliderDragged && console.log("clicking") && (this.sliderDragged = false)} />
                     <Grid
                         width={this.props.PanelWidth()}
                         nodeList={childDocumentViews.length ? childDocumentViews : null}
@@ -326,6 +342,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                         rowHeight={NumCast(this.props.Document.rowHeight)}
                         setLayout={this.setLayout}
                         transformScale={this.props.ScreenToLocalTransform().Scale}
+                        compactType={StrCast(this.props.Document.compactType)}
+                        preventCollision={BoolCast(this.props.Document.preventCollision)}
+
                     // deletePlaceholder={this.deletePlaceholder}
                     />
 
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index df550e3c2..5779bf463 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -20,6 +20,8 @@ interface GridProps {
     transformScale: number;
     childrenDraggable: boolean;
     // deletePlaceholder: Function;
+    preventCollision: boolean;
+    compactType: string;
 }
 
 /**
@@ -57,19 +59,21 @@ export default class Grid extends React.Component<GridProps> {
     render() {
         console.log(this.props.transformScale);
 
+        const compactType = this.props.compactType === "vertical" || this.props.compactType === "horizontal" ? this.props.compactType : null;
+
         return (
             <GridLayout className="layout"
                 layout={this.props.layout}
                 cols={this.props.numCols}
                 rowHeight={this.props.rowHeight}
                 width={this.props.width}
-                compactType={null}
+                compactType={compactType}
                 isDroppable={true}
                 isDraggable={this.props.childrenDraggable}
                 isResizable={this.props.childrenDraggable}
                 useCSSTransforms={true}
                 onLayoutChange={this.onLayoutChange}
-                preventCollision={true}
+                preventCollision={this.props.preventCollision}
                 transformScale={this.props.transformScale} // still doesn't work :(
                 style={{ zIndex: 5 }}
             >
-- 
cgit v1.2.3-70-g09d2


From bb283aa88662b98078ccaabe9369ce56129883c1 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 8 Jun 2020 19:23:51 +0530
Subject: changed compact type to dropdown menu

---
 .../views/collections/CollectionViewChromes.scss   | 15 +++++++++++++++
 .../views/collections/CollectionViewChromes.tsx    | 22 ++++++++++++++++------
 2 files changed, 31 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 398b02d3f..bfa20f42a 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -178,6 +178,21 @@
             display: flex;
             margin-left: 10;
 
+            .collectionGridViewChrome-viewPicker {
+                font-size: 75%;
+                //text-transform: uppercase;
+                //letter-spacing: 2px;
+                background: rgb(238, 238, 238);
+                color: grey;
+                outline-color: black;
+                border: none;
+                //padding: 12px 10px 11px 10px;
+            }
+
+            .collectionGridViewChrome-viewPicker:active {
+                outline-color: black;
+            }
+
             .grid-control {
                 align-self: center;
                 width: 30%;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 95774adca..6fb517940 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -648,8 +648,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.props.CollectionView.props.Document.preventCollision = !this.props.CollectionView.props.Document.preventCollision;
     }
 
-    changeCompactType = () => {
-        this.props.CollectionView.props.Document.compactType = this.props.CollectionView.props.Document.compactType === "vertical" ? "horizontal" : this.props.CollectionView.props.Document.compactType === "horizontal" ? "null" : "vertical";
+    changeCompactType = (e: React.ChangeEvent<HTMLSelectElement>) => {
+        this.props.CollectionView.props.Document.compactType = e.target.selectedOptions[0].value;
     }
 
     render() {
@@ -671,12 +671,22 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                 </span> */}
                 <span className="grid-control" style={{ width: "20%" }}>
                     <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
-                    <label className="flexLabel">Collisions </label>
+                    <label className="flexLabel">Collisions</label>
                 </span>
 
-                <span className="grid-control">
-                    <input style={{ marginRight: 5 }} type="button" onClick={this.changeCompactType} value={`Compact: ${this.props.CollectionView.props.Document.compactType}`} />
-                </span>
+                <select className="collectionGridViewChrome-viewPicker"
+                    style={{ marginRight: 5 }}
+                    onPointerDown={stopPropagation}
+                    onChange={this.changeCompactType}
+                >
+                    {["vertical", "horizontal", "null"].map(type =>
+                        <option className="collectionGridViewChrome-viewOption"
+                            onPointerDown={stopPropagation}
+                            value={type}>
+                            {"Compact: " + type}
+                        </option>
+                    )}
+                </select>
 
                 <span className="grid-control">
                     <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
-- 
cgit v1.2.3-70-g09d2


From 403993e0b91fc1be71f6ddef42e1141367ecb715 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 8 Jun 2020 23:03:05 +0530
Subject: cleanup + comments + changed compact type selector from button to
 dropdown menu

---
 .../views/collections/CollectionViewChromes.tsx    | 23 ++++++++++--
 .../collectionGrid/CollectionGridView.tsx          | 42 +++-------------------
 .../views/collections/collectionGrid/Grid.tsx      | 34 ++----------------
 3 files changed, 28 insertions(+), 71 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 6fb517940..c824c2f33 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -605,6 +605,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.props.CollectionView.props.Document.flexGrid = !this.props.CollectionView.props.Document.flexGrid;
     }
 
+    /**
+     * Increments the value of numCols on button click
+     */
     onIncrementButtonClick = () => {
         this.clicked = true;
         this.entered && (this.props.CollectionView.props.Document.numCols as number)--;
@@ -612,6 +615,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.entered = false;
     }
 
+    /**
+     * Decrements the value of numCols on button click
+     */
     onDecrementButtonClick = () => {
         this.clicked = true;
         if (!this.decrementLimitReached) {
@@ -621,6 +627,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.entered = false;
     }
 
+    /**
+     * Increments the value of numCols on button hover
+     */
     incrementValue = () => {
         this.entered = true;
         if (!this.clicked && !this.decrementLimitReached) {
@@ -630,6 +639,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.clicked = false;
     }
 
+    /**
+     * Decrements the value of numCols on button hover
+     */
     decrementValue = () => {
         this.entered = true;
         if (!this.clicked) {
@@ -644,10 +656,16 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.clicked = false;
     }
 
+    /**
+     * Toggles the value of preventCollision
+     */
     toggleCollisions = () => {
         this.props.CollectionView.props.Document.preventCollision = !this.props.CollectionView.props.Document.preventCollision;
     }
 
+    /**
+     * Changes the value of the compactType
+     */
     changeCompactType = (e: React.ChangeEvent<HTMLSelectElement>) => {
         this.props.CollectionView.props.Document.compactType = e.target.selectedOptions[0].value;
     }
@@ -670,7 +688,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                 </span> */}
                 <span className="grid-control" style={{ width: "20%" }}>
-                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
+                    <input type="checkbox" onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
                     <label className="flexLabel">Collisions</label>
                 </span>
 
@@ -678,7 +696,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     style={{ marginRight: 5 }}
                     onPointerDown={stopPropagation}
                     onChange={this.changeCompactType}
-                >
+                    value={StrCast(this.props.CollectionView.props.Document.compactType)}>
+                    >
                     {["vertical", "horizontal", "null"].map(type =>
                         <option className="collectionGridViewChrome-viewOption"
                             onPointerDown={stopPropagation}
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index b87bfd0e2..eab3fd79e 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -10,7 +10,7 @@ import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentVi
 import { CollectionSubView } from '../CollectionSubView';
 import { SubCollectionViewProps } from '../CollectionSubView';
 import { List } from '../../../../fields/List';
-import { returnZero } from '../../../../Utils';
+import { returnZero, returnFalse } from '../../../../Utils';
 import Grid, { Layout } from "./Grid";
 import { Id } from '../../../../fields/FieldSymbols';
 import { observer } from 'mobx-react';
@@ -104,25 +104,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         this.changeListenerDisposer && this.changeListenerDisposer();
     }
 
-    // deletePlaceholder(placeholder: Layout, e: MouseEvent) {
-
-    //     const { left, right, top, bottom } = this.containerRef.current!.getBoundingClientRect();
-    //     if (e.clientX > right || e.clientX < left || e.clientY < top || e.clientY > bottom) {
-    //         const layouts: Layout[] = this.parsedLayoutList;
-    //         const index = layouts.findIndex((gridLayout: Layout) => gridLayout.i === placeholder.i);
-    //         index !== -1 && layouts.splice(index, 1);
-
-    //         const i = this.childLayoutPairs.findIndex(({ layout }) => placeholder.i === layout.i);
-    //         i !== -1 && this.childLayoutPairs.splice(i, 1);
-
-    //         console.log("deleting");
-
-    //         this.unStringifiedLayoutList = layouts;
-    //     }
-
-    // }
-
-
     /**
      * @returns the transform that will correctly place the document decorations box. 
      */
@@ -140,8 +121,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     @computed get colWidthPlusGap() { return (this.props.PanelWidth() - 10) / NumCast(this.props.Document.numCols); }
     @computed get rowHeightPlusGap() { return NumCast(this.props.Document.rowHeight) + 10; }
 
-    @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
-
     /**
      * @returns the layout list converted from JSON
      */
@@ -165,14 +144,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     @observable private height = (layout: Layout) => (this.props.Document.flexGrid ? layout.h : 2) * this.rowHeightPlusGap - 10;
 
-    addDocTab = (doc: Doc, where: string) => {
-        if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) {
-            this.dataDoc[this.props.fieldKey] = new List<Doc>([doc]);
-            return true;
-        }
-        return this.props.addDocTab(doc, where);
-    }
-
     contextMenuItems = (layoutDoc: Doc) => {
         const layouts: Layout[] = this.parsedLayoutList;
         const freezeScript = ScriptField.MakeFunction(
@@ -184,7 +155,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         // const layouts: Layout[] = this.parsedLayoutList;
 
         // const layoutToChange = layouts.find(({ i }) => i === layoutDoc[Id]);
-        // layoutToChange!.static = true;
+        // layoutToChange!.static = !layoutToChange!.static;
 
         // this.unStringifiedLayoutList = layouts;
 
@@ -206,13 +177,12 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             DataDoc={layout.resolvedDataDoc as Doc}
             NativeHeight={returnZero}
             NativeWidth={returnZero}
-            addDocTab={this.addDocTab}
+            addDocTab={returnFalse}
             backgroundColor={this.props.backgroundColor}
             ContainingCollectionDoc={this.props.Document}
             PanelWidth={width}
             PanelHeight={height}
             ScreenToLocalTransform={dxf}
-            onClick={this.onChildClickHandler}
             renderDepth={this.props.renderDepth + 1}
             parentActive={this.props.active}
             display={"contents"}
@@ -227,8 +197,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     @undoBatch
     @action
     setLayout(layoutArray: Layout[]) {
-        // for every child in the collection, check to see if there's a corresponding grid layout document and
-        // updated layout object. If both exist, which they should, update the grid layout document from the updated object 
+        // for every child in the collection, check to see if there's a corresponding grid layout object and
+        // updated layout object. If both exist, which they should, update the grid layout object from the updated object 
         const layouts: Layout[] = this.parsedLayoutList;
         this.childLayoutPairs.forEach(({ layout: doc }) => {
             let update: Opt<Layout>;
@@ -392,8 +362,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                         transformScale={this.props.ScreenToLocalTransform().Scale}
                         compactType={StrCast(this.props.Document.compactType)}
                         preventCollision={BoolCast(this.props.Document.preventCollision)}
-
-                    // deletePlaceholder={this.deletePlaceholder}
                     />
 
                 </div>
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 5779bf463..058002722 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -16,10 +16,9 @@ interface GridProps {
     layout: Layout[] | undefined;
     numCols: number;
     rowHeight: number;
-    setLayout: Function;
+    setLayout: (layout: Layout[]) => void;
     transformScale: number;
     childrenDraggable: boolean;
-    // deletePlaceholder: Function;
     preventCollision: boolean;
     compactType: string;
 }
@@ -30,37 +29,8 @@ interface GridProps {
 @observer
 export default class Grid extends React.Component<GridProps> {
 
-    // private dragging: boolean = false;
-
-    constructor(props: Readonly<GridProps>) {
-        super(props);
-        this.onLayoutChange = this.onLayoutChange.bind(this);
-        // this.onDrag = this.onDrag.bind(this);
-    }
-    /**
-     * If there has been a change in layout, calls a method in CollectionGridView to set the layouts on the Document.
-     * @param layout `Layout[]`
-     */
-    onLayoutChange(layout: Layout[]) {
-        this.props.setLayout(layout);
-    }
-
-    // onDrag(layout: Layout[],
-    //     oldItem: Layout,
-    //     newItem: Layout,
-    //     placeholder: Layout,
-    //     event: MouseEvent,
-    //     element: HTMLElement) {
-    //     this.props.deletePlaceholder(placeholder, event);
-    //     console.log("Grid -> event", event.clientX)
-
-    // }
-
     render() {
-        console.log(this.props.transformScale);
-
         const compactType = this.props.compactType === "vertical" || this.props.compactType === "horizontal" ? this.props.compactType : null;
-
         return (
             <GridLayout className="layout"
                 layout={this.props.layout}
@@ -72,7 +42,7 @@ export default class Grid extends React.Component<GridProps> {
                 isDraggable={this.props.childrenDraggable}
                 isResizable={this.props.childrenDraggable}
                 useCSSTransforms={true}
-                onLayoutChange={this.onLayoutChange}
+                onLayoutChange={this.props.setLayout}
                 preventCollision={this.props.preventCollision}
                 transformScale={this.props.transformScale} // still doesn't work :(
                 style={{ zIndex: 5 }}
-- 
cgit v1.2.3-70-g09d2


From ca2757e137e287f3d6d711c97e2b8a212dd28021 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 10 Jun 2020 13:41:28 +0530
Subject: added reset button + resizable handle css + fixed rendering bug

---
 package-lock.json                                  |  90 +++++++++-------
 .../views/collections/CollectionViewChromes.tsx    |   5 +-
 .../collectionGrid/CollectionGridView.scss         |  14 ++-
 .../collectionGrid/CollectionGridView.tsx          | 115 +++++++++++++++------
 .../views/collections/collectionGrid/Grid.tsx      |   5 +-
 5 files changed, 157 insertions(+), 72 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index 48847f1fb..131a154c7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2836,7 +2836,8 @@
                         },
                         "ansi-regex": {
                             "version": "2.1.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "aproba": {
                             "version": "1.2.0",
@@ -2854,11 +2855,13 @@
                         },
                         "balanced-match": {
                             "version": "1.0.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "brace-expansion": {
                             "version": "1.1.11",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "balanced-match": "^1.0.0",
                                 "concat-map": "0.0.1"
@@ -2871,15 +2874,18 @@
                         },
                         "code-point-at": {
                             "version": "1.1.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "concat-map": {
                             "version": "0.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "console-control-strings": {
                             "version": "1.1.0",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "core-util-is": {
                             "version": "1.0.2",
@@ -2982,7 +2988,8 @@
                         },
                         "inherits": {
                             "version": "2.0.4",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "ini": {
                             "version": "1.3.5",
@@ -2992,6 +2999,7 @@
                         "is-fullwidth-code-point": {
                             "version": "1.0.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "number-is-nan": "^1.0.0"
                             }
@@ -3004,17 +3012,20 @@
                         "minimatch": {
                             "version": "3.0.4",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "brace-expansion": "^1.1.7"
                             }
                         },
                         "minimist": {
                             "version": "1.2.5",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "safe-buffer": "^5.1.2",
                                 "yallist": "^3.0.0"
@@ -3031,6 +3042,7 @@
                         "mkdirp": {
                             "version": "0.5.3",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "minimist": "^1.2.5"
                             }
@@ -3086,7 +3098,8 @@
                         },
                         "npm-normalize-package-bin": {
                             "version": "1.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "npm-packlist": {
                             "version": "1.4.8",
@@ -3111,7 +3124,8 @@
                         },
                         "number-is-nan": {
                             "version": "1.0.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "object-assign": {
                             "version": "4.1.1",
@@ -3121,6 +3135,7 @@
                         "once": {
                             "version": "1.4.0",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "wrappy": "1"
                             }
@@ -3189,7 +3204,8 @@
                         },
                         "safe-buffer": {
                             "version": "5.1.2",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "safer-buffer": {
                             "version": "2.1.2",
@@ -3219,6 +3235,7 @@
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "code-point-at": "^1.0.0",
                                 "is-fullwidth-code-point": "^1.0.0",
@@ -3236,6 +3253,7 @@
                         "strip-ansi": {
                             "version": "3.0.1",
                             "bundled": true,
+                            "optional": true,
                             "requires": {
                                 "ansi-regex": "^2.0.0"
                             }
@@ -3274,11 +3292,13 @@
                         },
                         "wrappy": {
                             "version": "1.0.2",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         },
                         "yallist": {
                             "version": "3.1.1",
-                            "bundled": true
+                            "bundled": true,
+                            "optional": true
                         }
                     }
                 }
@@ -9505,7 +9525,7 @@
                 },
                 "chownr": {
                     "version": "1.1.4",
-                    "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
                 },
                 "ci-info": {
@@ -9811,7 +9831,7 @@
                 },
                 "deep-extend": {
                     "version": "0.6.0",
-                    "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
                 },
                 "defaults": {
@@ -10310,7 +10330,7 @@
                 },
                 "glob": {
                     "version": "7.1.6",
-                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+                    "resolved": false,
                     "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
                     "requires": {
                         "fs.realpath": "^1.0.0",
@@ -10398,7 +10418,7 @@
                 },
                 "hosted-git-info": {
                     "version": "2.8.8",
-                    "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
                 },
                 "http-cache-semantics": {
@@ -10534,7 +10554,7 @@
                 },
                 "is-ci": {
                     "version": "1.2.1",
-                    "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
                     "requires": {
                         "ci-info": "^1.5.0"
@@ -10610,7 +10630,7 @@
                 },
                 "is-retry-allowed": {
                     "version": "1.2.0",
-                    "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
                 },
                 "is-stream": {
@@ -11119,7 +11139,7 @@
                 },
                 "mkdirp": {
                     "version": "0.5.4",
-                    "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
                     "requires": {
                         "minimist": "^1.2.5"
@@ -11127,7 +11147,7 @@
                     "dependencies": {
                         "minimist": {
                             "version": "1.2.5",
-                            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+                            "resolved": false,
                             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
                         }
                     }
@@ -11179,7 +11199,7 @@
                 },
                 "node-gyp": {
                     "version": "5.1.0",
-                    "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==",
                     "requires": {
                         "env-paths": "^2.2.0",
@@ -11293,7 +11313,7 @@
                 },
                 "npm-packlist": {
                     "version": "1.4.8",
-                    "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
                     "requires": {
                         "ignore-walk": "^3.0.1",
@@ -11313,7 +11333,7 @@
                 },
                 "npm-profile": {
                     "version": "4.0.4",
-                    "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-4.0.4.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==",
                     "requires": {
                         "aproba": "^1.1.2 || 2",
@@ -11323,7 +11343,7 @@
                 },
                 "npm-registry-fetch": {
                     "version": "4.0.3",
-                    "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz",
+                    "resolved": false,
                     "integrity": "sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==",
                     "requires": {
                         "JSONStream": "^1.3.4",
@@ -11758,7 +11778,7 @@
                 },
                 "rc": {
                     "version": "1.2.8",
-                    "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+                    "resolved": false,
                     "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
                     "requires": {
                         "deep-extend": "^0.6.0",
@@ -11769,7 +11789,7 @@
                     "dependencies": {
                         "minimist": {
                             "version": "1.2.5",
-                            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+                            "resolved": false,
                             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
                         }
                     }
@@ -11828,7 +11848,7 @@
                 },
                 "readable-stream": {
                     "version": "3.6.0",
-                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
                     "requires": {
                         "inherits": "^2.0.3",
@@ -11849,7 +11869,7 @@
                 },
                 "registry-auth-token": {
                     "version": "3.4.0",
-                    "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
                     "requires": {
                         "rc": "^1.1.6",
@@ -11913,7 +11933,7 @@
                 },
                 "rimraf": {
                     "version": "2.7.1",
-                    "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
                         "glob": "^7.1.3"
@@ -12212,7 +12232,7 @@
                 },
                 "string_decoder": {
                     "version": "1.3.0",
-                    "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+                    "resolved": false,
                     "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
                     "requires": {
                         "safe-buffer": "~5.2.0"
@@ -12220,7 +12240,7 @@
                     "dependencies": {
                         "safe-buffer": {
                             "version": "5.2.0",
-                            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+                            "resolved": false,
                             "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
                         }
                     }
@@ -12532,7 +12552,7 @@
                 },
                 "widest-line": {
                     "version": "2.0.1",
-                    "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
+                    "resolved": false,
                     "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
                     "requires": {
                         "string-width": "^2.1.1"
@@ -14071,9 +14091,9 @@
             }
         },
         "react-draggable": {
-            "version": "4.3.1",
-            "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.3.1.tgz",
-            "integrity": "sha512-m8QeV+eIi7LhD5mXoLqDzLbokc6Ncwa0T34fF6uJzWSs4vc4fdZI/XGqHYoEn91T8S6qO+BSXslONh7Jz9VPQQ==",
+            "version": "4.4.3",
+            "resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.3.tgz",
+            "integrity": "sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w==",
             "requires": {
                 "classnames": "^2.2.5",
                 "prop-types": "^15.6.0"
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index c824c2f33..7654c9d9e 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -688,7 +688,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                 </span> */}
                 <span className="grid-control" style={{ width: "20%" }}>
-                    <input type="checkbox" onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
+                    <input type="checkbox" style={{ marginRight: 5 }} onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
                     <label className="flexLabel">Collisions</label>
                 </span>
 
@@ -711,6 +711,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
                     <label className="flexLabel">Flexible</label>
                 </span>
+
+                <button onClick={() => this.props.CollectionView.props.Document.resetLayout = true}>Reset</button>
+
             </div>
         );
     }
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index 578dae966..8b19542f7 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -14,14 +14,22 @@
         display: flex;
         flex-direction: row;
 
-        .rowHeightSlider {
+        .react-grid-item>.react-resizable-handle {
+            z-index: 4; // doesn't work on prezi otherwise
+        }
+
+        .react-grid-item>.react-resizable-handle::after {
+            // grey so it can be seen on the audiobox
+            border-right: 2px solid slategrey;
+            border-bottom: 2px solid slategrey;
+        }
 
+        .rowHeightSlider {
             -webkit-appearance: none;
             appearance: none;
             width: 100%;
             height: 15px;
             background: #d3d3d3;
-            // border-radius: 5px;
 
             position: absolute;
             height: 3;
@@ -116,7 +124,6 @@
 
 }
 
-
 // .documentDecorations-container .documentDecorations-resizer {
 //     pointer-events: none;
 // }
@@ -128,7 +135,6 @@
 //     visibility: collapse;
 // }
 
-// .collectionGridView-contents
 
 /* Chrome, Safari, Edge, Opera */
 input::-webkit-outer-spin-button,
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index eab3fd79e..01ad44a2d 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -1,15 +1,14 @@
-import { computed, observable, Lambda, action } from 'mobx';
+import { computed, observable, Lambda, action, autorun } from 'mobx';
 import * as React from "react";
 import { Doc, Opt } from '../../../../fields/Doc';
 import { documentSchema } from '../../../../fields/documentSchemas';
 import { makeInterface } from '../../../../fields/Schema';
-import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { BoolCast, NumCast, StrCast, ScriptCast } from '../../../../fields/Types';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
 import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
 import { CollectionSubView } from '../CollectionSubView';
 import { SubCollectionViewProps } from '../CollectionSubView';
-import { List } from '../../../../fields/List';
 import { returnZero, returnFalse } from '../../../../Utils';
 import Grid, { Layout } from "./Grid";
 import { Id } from '../../../../fields/FieldSymbols';
@@ -29,8 +28,10 @@ const GridSchema = makeInterface(documentSchema);
 export class CollectionGridView extends CollectionSubView(GridSchema) {
     private containerRef: React.RefObject<HTMLDivElement>;
     @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll
-    private changeListenerDisposer: Opt<Lambda>;
-    private rowHeight: number = 0;
+    private changeListenerDisposer: Opt<Lambda>; // listens for changes in this.childLayoutPairs
+    private rowHeight: number = 0; // temporary store of row height to make change undoable
+    private mounted: boolean = false; // hack to fix the issue of not rerendering when mounting
+    private resetListenerDisposer: Opt<Lambda>; // listens for when the reset button is clicked
 
     constructor(props: Readonly<SubCollectionViewProps>) {
         super(props);
@@ -38,7 +39,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         this.props.Document.numCols = NumCast(this.props.Document.numCols, 10);
         this.props.Document.rowHeight = NumCast(this.props.Document.rowHeight, 100);
 
-        // determines whether the grid is static/flexible i.e. can nodes be moved around and resized or not
+        // determines whether the grid is static/flexible i.e. whether can nodes be moved around and resized or not
         this.props.Document.flexGrid = BoolCast(this.props.Document.flexGrid, true);
 
         // determines whether nodes should remain in position, be bound to the top, or to the left
@@ -49,12 +50,15 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
         this.setLayout = this.setLayout.bind(this);
         this.onSliderChange = this.onSliderChange.bind(this);
-        // this.deletePlaceholder = this.deletePlaceholder.bind(this);
+
         this.containerRef = React.createRef();
     }
 
     componentDidMount() {
 
+        console.log("mounting");
+        this.mounted = true;
+
         this.changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => {
 
             const layouts: Layout[] = this.parsedLayoutList;
@@ -71,7 +75,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             }
 
             if (!oldValue || newValue.length > oldValue.length) {
-                // for each document that was added, add a corresponding grid layout document
+                // for each document that was added, add a corresponding grid layout object
 
                 newValue.forEach(({ layout }, i) => {
                     const targetId = layout[Id];
@@ -87,7 +91,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                     }
                 });
             } else {
-                // for each document that was removed, remove its corresponding grid layout document
+                // for each document that was removed, remove its corresponding grid layout object
                 oldValue.forEach(({ layout }) => {
                     const targetId = layout[Id];
                     if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) {
@@ -98,10 +102,34 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             }
             this.unStringifiedLayoutList = layouts;
         }, true);
+
+        // updates the layouts if the reset button has been clicked
+        this.resetListenerDisposer = autorun(() => {
+            if (this.props.Document.resetLayout) {
+                if (this.props.Document.flexGrid) {
+                    console.log("Resetting layout");
+                    const layouts: Layout[] = this.parsedLayoutList;
+
+                    this.setLayout(
+                        layouts.map(({ i }, index) => ({
+                            i: i,
+                            x: 2 * (index % Math.floor(NumCast(this.props.Document.numCols) / 2)),
+                            y: 2 * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / 2)),
+                            w: 2,
+                            h: 2,
+                        })));
+                }
+
+                this.props.Document.resetLayout = false;
+            }
+        });
     }
 
     componentWillUnmount() {
+        console.clear();
+        this.mounted = false;
         this.changeListenerDisposer && this.changeListenerDisposer();
+        this.resetListenerDisposer?.();
     }
 
     /**
@@ -109,6 +137,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     private lookupIndividualTransform = (layout: Layout) => {
 
+        console.log("lookup");
+
         const index = this.childLayoutPairs.findIndex(({ layout: layoutDoc }) => layoutDoc[Id] === layout.i);
 
         // translations depend on whether the grid is flexible or static
@@ -117,6 +147,8 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
         return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
     }
+    // is this needed? it seems to never be called
+    @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
 
     @computed get colWidthPlusGap() { return (this.props.PanelWidth() - 10) / NumCast(this.props.Document.numCols); }
     @computed get rowHeightPlusGap() { return NumCast(this.props.Document.rowHeight) + 10; }
@@ -124,12 +156,26 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     /**
      * @returns the layout list converted from JSON
      */
-    get parsedLayoutList() { return this.props.Document.gridLayoutString ? JSON.parse(StrCast(this.props.Document.gridLayoutString)) : []; }
+    get parsedLayoutList() {
+        console.log("parsedlayoutlist");
+        return this.props.Document.gridLayoutString ? JSON.parse(StrCast(this.props.Document.gridLayoutString)) : [];
+    }
 
     /**
      * Stores the layout list on the Document as JSON
      */
-    set unStringifiedLayoutList(layouts: Layout[]) { this.props.Document.gridLayoutString = JSON.stringify(layouts); }
+    set unStringifiedLayoutList(layouts: Layout[]) {
+
+        // sometimes there are issues with rendering when you switch from a different view
+        // where the nodes are all squeezed together on the left hand side of the screen
+        // until you click on the screen or close the chrome or interact with it in some way
+        // this seems to fix that though it isn't very elegant
+
+        console.log("setting unstringified")
+        this.mounted && (this.props.Document.gridLayoutString = "");
+        this.props.Document.gridLayoutString = JSON.stringify(layouts);
+        this.mounted = false;
+    }
 
 
     /**
@@ -183,6 +229,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             PanelWidth={width}
             PanelHeight={height}
             ScreenToLocalTransform={dxf}
+            onClick={this.onChildClickHandler}
             renderDepth={this.props.renderDepth + 1}
             parentActive={this.props.active}
             display={"contents"}
@@ -199,20 +246,25 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     setLayout(layoutArray: Layout[]) {
         // for every child in the collection, check to see if there's a corresponding grid layout object and
         // updated layout object. If both exist, which they should, update the grid layout object from the updated object 
-        const layouts: Layout[] = this.parsedLayoutList;
-        this.childLayoutPairs.forEach(({ layout: doc }) => {
-            let update: Opt<Layout>;
-            const targetId = doc[Id];
-            const gridLayout = layouts.find(gridLayout => gridLayout.i === targetId);
-            if (this.props.Document.flexGrid && gridLayout && (update = layoutArray.find(layout => layout.i === targetId))) {
-                gridLayout.x = update.x;
-                gridLayout.y = update.y;
-                gridLayout.w = update.w;
-                gridLayout.h = update.h;
-            }
-        });
 
-        this.unStringifiedLayoutList = layouts;
+        console.log("settinglayout");
+
+        if (this.props.Document.flexGrid) {
+            const layouts: Layout[] = this.parsedLayoutList;
+            this.childLayoutPairs.forEach(({ layout: doc }) => {
+                let update: Opt<Layout>;
+                const targetId = doc[Id];
+                const gridLayout = layouts.find(gridLayout => gridLayout.i === targetId);
+                if (gridLayout && (update = layoutArray.find(layout => layout.i === targetId))) {
+                    gridLayout.x = update.x;
+                    gridLayout.y = update.y;
+                    gridLayout.w = update.w;
+                    gridLayout.h = update.h;
+                }
+            });
+
+            this.unStringifiedLayoutList = layouts;
+        }
     }
 
     /**
@@ -221,6 +273,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     @computed
     private get contents(): JSX.Element[] {
+
+        console.log("getting contents");
+
         const { childLayoutPairs } = this;
         const collector: JSX.Element[] = [];
         const layouts: Layout[] = this.parsedLayoutList;
@@ -251,17 +306,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * @returns a list of `Layout` objects with attributes depending on whether the grid is flexible or static
      */
     get layoutList(): Layout[] {
+
+        console.log("getting layoutlist");
         const layouts: Layout[] = this.parsedLayoutList;
-        // this.unStringifiedLayoutList = layouts;
 
         return this.props.Document.flexGrid ?
-            layouts.map(({ i, x, y, w, h, static: stat }) => ({
+            layouts.map(({ i, x, y, w, h, static: staticVal }) => ({
                 i: i,
                 x: x + w > NumCast(this.props.Document.numCols) ? 0 : x, // handles wrapping around of nodes when numCols decreases
                 y: y,
-                w: w,
+                w: w > NumCast(this.props.Document.numCols) ? NumCast(this.props.Document.numCols) : w, // reduces width if greater than numCols
                 h: h,
-                static: stat
+                static: staticVal // only needed if we implement freeze in place
             }))
             : layouts.map(({ i }, index) => ({
                 i: i,
@@ -277,9 +333,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * Handles the change in the value of the rowHeight slider.
      */
     onSliderChange = (event: React.ChangeEvent<HTMLInputElement>) => {
-        NumCast(this.props.Document.rowHeight) !== event.currentTarget.valueAsNumber;
         this.props.Document.rowHeight = event.currentTarget.valueAsNumber;
-
     }
 
     /**
@@ -305,6 +359,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
 
     render() {
 
+        console.log("and render");
         // for the add text document EditableView
         const newEditableViewProps: EditableProps = {
             GetValue: () => "",
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 058002722..9192a38d7 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -30,6 +30,7 @@ interface GridProps {
 export default class Grid extends React.Component<GridProps> {
 
     render() {
+        console.log(this.props.transformScale);
         const compactType = this.props.compactType === "vertical" || this.props.compactType === "horizontal" ? this.props.compactType : null;
         return (
             <GridLayout className="layout"
@@ -44,11 +45,11 @@ export default class Grid extends React.Component<GridProps> {
                 useCSSTransforms={true}
                 onLayoutChange={this.props.setLayout}
                 preventCollision={this.props.preventCollision}
-                transformScale={this.props.transformScale} // still doesn't work :(
+                transformScale={1 / this.props.transformScale} // still doesn't work :(
                 style={{ zIndex: 5 }}
             >
                 {this.props.nodeList}
-            </GridLayout >
+            </GridLayout>
         );
     }
 }
-- 
cgit v1.2.3-70-g09d2


From fd000c9de458737ea48b319c159c6824148640d0 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Thu, 11 Jun 2020 16:39:52 +0530
Subject: resizing chrome text on panelwidth decrease

---
 .../views/collections/CollectionViewChromes.scss   |  1 -
 .../views/collections/CollectionViewChromes.tsx    | 37 ++++++++++++++++------
 2 files changed, 28 insertions(+), 10 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index bfa20f42a..f85cbfee2 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -195,7 +195,6 @@
 
             .grid-control {
                 align-self: center;
-                width: 30%;
                 display: flex;
                 flex-direction: row;
                 margin-right: 5px;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 7654c9d9e..63080d2e6 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -1,8 +1,8 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, runInAction } from "mobx";
+import { action, computed, observable, runInAction, autorun, Lambda } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc, DocListCast, HeightSym } from "../../../fields/Doc";
+import { Doc, DocListCast, HeightSym, Opt } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
 import { List } from "../../../fields/List";
 import { listSpec } from "../../../fields/Schema";
@@ -572,6 +572,22 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     private clicked: boolean = false;
     private entered: boolean = false;
     private decrementLimitReached: boolean = false;
+    @observable private resize = false;
+    private resizeListenerDisposer: Opt<Lambda>;
+
+    componentDidMount() {
+
+        runInAction(() => this.resize = this.props.CollectionView.props.PanelWidth() < 700);
+
+        // listener to reduce text on chrome resize (panel resize)
+        this.resizeListenerDisposer = computed(() => this.props.CollectionView.props.PanelWidth()).observe(({ newValue }) => {
+            runInAction(() => this.resize = newValue < 700);
+        });
+    }
+
+    componentWillUnmount() {
+        this.resizeListenerDisposer?.();
+    }
 
     /**
      * Sets the value of `numCols` on the grid's Document to the value entered.
@@ -673,7 +689,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     render() {
         return (
             <div className="collectionGridViewChrome-cont" >
-                <span className="grid-control">
+                <span className="grid-control" style={{ width: this.resize ? "25%" : "30%" }}>
                     <span className="grid-icon">
                         <FontAwesomeIcon icon="columns" size="1x" />
                     </span>
@@ -687,9 +703,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     </span>
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                 </span> */}
-                <span className="grid-control" style={{ width: "20%" }}>
+                <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
                     <input type="checkbox" style={{ marginRight: 5 }} onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
-                    <label className="flexLabel">Collisions</label>
+                    <label className="flexLabel">{this.resize ? "Coll" : "Collisions"}</label>
                 </span>
 
                 <select className="collectionGridViewChrome-viewPicker"
@@ -702,17 +718,20 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                         <option className="collectionGridViewChrome-viewOption"
                             onPointerDown={stopPropagation}
                             value={type}>
-                            {"Compact: " + type}
+                            {this.resize ? type[0].toUpperCase() + type.substring(1) : "Compact: " + type}
                         </option>
                     )}
                 </select>
 
-                <span className="grid-control">
+                <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
                     <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
-                    <label className="flexLabel">Flexible</label>
+                    <label className="flexLabel">{this.resize ? "Flex" : "Flexible"}</label>
                 </span>
 
-                <button onClick={() => this.props.CollectionView.props.Document.resetLayout = true}>Reset</button>
+                <button onClick={() => this.props.CollectionView.props.Document.resetLayout = true}>
+                    {!this.resize ? "Reset" :
+                        <FontAwesomeIcon icon="redo-alt" size="1x" />}
+                </button>
 
             </div>
         );
-- 
cgit v1.2.3-70-g09d2


From af374bfbf3a218528bca426911f4de83e3466872 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Thu, 11 Jun 2020 22:25:13 -0400
Subject: code cleanup for CollectionGridView.  added double click to create
 text.

---
 package-lock.json                                  |  84 ++---
 src/client/views/collections/CollectionView.tsx    |  32 --
 .../views/collections/CollectionViewChromes.tsx    |  39 +-
 .../collectionGrid/CollectionGridView.scss         |   6 +-
 .../collectionGrid/CollectionGridView.tsx          | 407 ++++++++-------------
 .../views/collections/collectionGrid/Grid.tsx      |   2 -
 6 files changed, 207 insertions(+), 363 deletions(-)

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

diff --git a/package-lock.json b/package-lock.json
index e692b266d..457104c8e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2841,8 +2841,7 @@
                         },
                         "ansi-regex": {
                             "version": "2.1.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "aproba": {
                             "version": "1.2.0",
@@ -2860,13 +2859,11 @@
                         },
                         "balanced-match": {
                             "version": "1.0.0",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "brace-expansion": {
                             "version": "1.1.11",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "balanced-match": "^1.0.0",
                                 "concat-map": "0.0.1"
@@ -2879,18 +2876,15 @@
                         },
                         "code-point-at": {
                             "version": "1.1.0",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "concat-map": {
                             "version": "0.0.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "console-control-strings": {
                             "version": "1.1.0",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "core-util-is": {
                             "version": "1.0.2",
@@ -2993,8 +2987,7 @@
                         },
                         "inherits": {
                             "version": "2.0.4",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "ini": {
                             "version": "1.3.5",
@@ -3004,7 +2997,6 @@
                         "is-fullwidth-code-point": {
                             "version": "1.0.0",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "number-is-nan": "^1.0.0"
                             }
@@ -3017,20 +3009,17 @@
                         "minimatch": {
                             "version": "3.0.4",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "brace-expansion": "^1.1.7"
                             }
                         },
                         "minimist": {
                             "version": "1.2.5",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "minipass": {
                             "version": "2.9.0",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "safe-buffer": "^5.1.2",
                                 "yallist": "^3.0.0"
@@ -3047,7 +3036,6 @@
                         "mkdirp": {
                             "version": "0.5.3",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "minimist": "^1.2.5"
                             }
@@ -3103,8 +3091,7 @@
                         },
                         "npm-normalize-package-bin": {
                             "version": "1.0.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "npm-packlist": {
                             "version": "1.4.8",
@@ -3129,8 +3116,7 @@
                         },
                         "number-is-nan": {
                             "version": "1.0.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "object-assign": {
                             "version": "4.1.1",
@@ -3140,7 +3126,6 @@
                         "once": {
                             "version": "1.4.0",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "wrappy": "1"
                             }
@@ -3209,8 +3194,7 @@
                         },
                         "safe-buffer": {
                             "version": "5.1.2",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "safer-buffer": {
                             "version": "2.1.2",
@@ -3240,7 +3224,6 @@
                         "string-width": {
                             "version": "1.0.2",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "code-point-at": "^1.0.0",
                                 "is-fullwidth-code-point": "^1.0.0",
@@ -3258,7 +3241,6 @@
                         "strip-ansi": {
                             "version": "3.0.1",
                             "bundled": true,
-                            "optional": true,
                             "requires": {
                                 "ansi-regex": "^2.0.0"
                             }
@@ -3297,13 +3279,11 @@
                         },
                         "wrappy": {
                             "version": "1.0.2",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         },
                         "yallist": {
                             "version": "3.1.1",
-                            "bundled": true,
-                            "optional": true
+                            "bundled": true
                         }
                     }
                 }
@@ -9535,7 +9515,7 @@
                 },
                 "chownr": {
                     "version": "1.1.4",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
                     "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
                 },
                 "ci-info": {
@@ -9841,7 +9821,7 @@
                 },
                 "deep-extend": {
                     "version": "0.6.0",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
                     "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
                 },
                 "defaults": {
@@ -10340,7 +10320,7 @@
                 },
                 "glob": {
                     "version": "7.1.6",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
                     "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
                     "requires": {
                         "fs.realpath": "^1.0.0",
@@ -10428,7 +10408,7 @@
                 },
                 "hosted-git-info": {
                     "version": "2.8.8",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
                     "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
                 },
                 "http-cache-semantics": {
@@ -10564,7 +10544,7 @@
                 },
                 "is-ci": {
                     "version": "1.2.1",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
                     "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
                     "requires": {
                         "ci-info": "^1.5.0"
@@ -10640,7 +10620,7 @@
                 },
                 "is-retry-allowed": {
                     "version": "1.2.0",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
                     "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg=="
                 },
                 "is-stream": {
@@ -11149,7 +11129,7 @@
                 },
                 "mkdirp": {
                     "version": "0.5.4",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
                     "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
                     "requires": {
                         "minimist": "^1.2.5"
@@ -11157,7 +11137,7 @@
                     "dependencies": {
                         "minimist": {
                             "version": "1.2.5",
-                            "resolved": false,
+                            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
                             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
                         }
                     }
@@ -11209,7 +11189,7 @@
                 },
                 "node-gyp": {
                     "version": "5.1.0",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-5.1.0.tgz",
                     "integrity": "sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==",
                     "requires": {
                         "env-paths": "^2.2.0",
@@ -11323,7 +11303,7 @@
                 },
                 "npm-packlist": {
                     "version": "1.4.8",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
                     "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
                     "requires": {
                         "ignore-walk": "^3.0.1",
@@ -11343,7 +11323,7 @@
                 },
                 "npm-profile": {
                     "version": "4.0.4",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-4.0.4.tgz",
                     "integrity": "sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==",
                     "requires": {
                         "aproba": "^1.1.2 || 2",
@@ -11353,7 +11333,7 @@
                 },
                 "npm-registry-fetch": {
                     "version": "4.0.3",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz",
                     "integrity": "sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==",
                     "requires": {
                         "JSONStream": "^1.3.4",
@@ -11788,7 +11768,7 @@
                 },
                 "rc": {
                     "version": "1.2.8",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
                     "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
                     "requires": {
                         "deep-extend": "^0.6.0",
@@ -11799,7 +11779,7 @@
                     "dependencies": {
                         "minimist": {
                             "version": "1.2.5",
-                            "resolved": false,
+                            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
                             "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
                         }
                     }
@@ -11858,7 +11838,7 @@
                 },
                 "readable-stream": {
                     "version": "3.6.0",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
                     "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
                     "requires": {
                         "inherits": "^2.0.3",
@@ -11879,7 +11859,7 @@
                 },
                 "registry-auth-token": {
                     "version": "3.4.0",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
                     "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==",
                     "requires": {
                         "rc": "^1.1.6",
@@ -11943,7 +11923,7 @@
                 },
                 "rimraf": {
                     "version": "2.7.1",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
                     "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
                     "requires": {
                         "glob": "^7.1.3"
@@ -12242,7 +12222,7 @@
                 },
                 "string_decoder": {
                     "version": "1.3.0",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
                     "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
                     "requires": {
                         "safe-buffer": "~5.2.0"
@@ -12250,7 +12230,7 @@
                     "dependencies": {
                         "safe-buffer": {
                             "version": "5.2.0",
-                            "resolved": false,
+                            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
                             "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
                         }
                     }
@@ -12562,7 +12542,7 @@
                 },
                 "widest-line": {
                     "version": "2.0.1",
-                    "resolved": false,
+                    "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
                     "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
                     "requires": {
                         "string-width": "^2.1.1"
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 524997d20..215b5bce8 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -244,38 +244,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
 
     onContextMenu = (e: React.MouseEvent): void => {
         if (!e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
-            const existingVm = ContextMenu.Instance.findByDescription("View Modes...");
-            const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
-            subItems.push({ description: "Freeform", event: () => { this.props.Document._viewType = CollectionViewType.Freeform; }, icon: "signature" });
-            if (CollectionView._safeMode) {
-                ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => this.props.Document._viewType = CollectionViewType.Invalid, icon: "project-diagram" });
-            }
-            subItems.push({ description: "Schema", event: () => this.props.Document._viewType = CollectionViewType.Schema, icon: "th-list" });
-            subItems.push({ description: "Treeview", event: () => this.props.Document._viewType = CollectionViewType.Tree, icon: "tree" });
-            subItems.push({ description: "Stacking", event: () => this.props.Document._viewType = CollectionViewType.Stacking, icon: "ellipsis-v" });
-            subItems.push({
-                description: "Stacking (AutoHeight)", event: () => {
-                    this.props.Document._viewType = CollectionViewType.Stacking;
-                    this.props.Document._autoHeight = true;
-                }, icon: "ellipsis-v"
-            });
-            subItems.push({ description: "Staff", event: () => this.props.Document._viewType = CollectionViewType.Staff, icon: "music" });
-            subItems.push({ description: "Multicolumn", event: () => this.props.Document._viewType = CollectionViewType.Multicolumn, icon: "columns" });
-            subItems.push({ description: "Multirow", event: () => this.props.Document._viewType = CollectionViewType.Multirow, icon: "columns" });
-            subItems.push({ description: "Masonry", event: () => this.props.Document._viewType = CollectionViewType.Masonry, icon: "columns" });
-            subItems.push({ description: "Carousel", event: () => this.props.Document._viewType = CollectionViewType.Carousel, icon: "columns" });
-            subItems.push({ description: "Pivot/Time", event: () => this.props.Document._viewType = CollectionViewType.Time, icon: "columns" });
-            subItems.push({ description: "Map", event: () => this.props.Document._viewType = CollectionViewType.Map, icon: "globe-americas" });
-            subItems.push({ description: "Grid", event: () => this.props.Document._viewType = CollectionViewType.Grid, icon: "th-list" });
-            switch (this.props.Document._viewType) {
-                case CollectionViewType.Freeform: {
-                    subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
-                    break;
-                }
-            }
-            subItems.push({ description: "lightbox", event: action(() => this._isLightboxOpen = true), icon: "eye" });
-            !existingVm && ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems, icon: "eye" });
-
             this.setupViewTypes("Add a Perspective...", vtype => {
                 const newRendition = Doc.MakeAlias(this.props.Document);
                 newRendition._viewType = vtype;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 63080d2e6..53bff0fe5 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -16,6 +16,7 @@ import { CollectionViewType } from "./CollectionView";
 import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
+import { undo } from "prosemirror-history";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -589,14 +590,16 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
         this.resizeListenerDisposer?.();
     }
 
+    get numCols() { return NumCast(this.props.CollectionView.props.Document.gridNumCols, 10); }
+
     /**
      * Sets the value of `numCols` on the grid's Document to the value entered.
      */
     @undoBatch
     onNumColsEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
         if (e.key === "Enter" || e.key === "Tab") {
-            if (e.currentTarget.valueAsNumber > 0 && this.props.CollectionView.props.Document.numCols as number !== e.currentTarget.valueAsNumber) {
-                this.props.CollectionView.props.Document.numCols = e.currentTarget.valueAsNumber;
+            if (e.currentTarget.valueAsNumber > 0) {
+                this.props.CollectionView.props.Document.gridNumCols = e.currentTarget.valueAsNumber;
             }
 
         }
@@ -617,8 +620,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     /**
      * Sets whether the grid is flexible or not on the grid's Document.
      */
+    @undoBatch
     toggleFlex = () => {
-        this.props.CollectionView.props.Document.flexGrid = !this.props.CollectionView.props.Document.flexGrid;
+        this.props.CollectionView.props.Document.gridFlex = !this.props.CollectionView.props.Document.gridFlex;
     }
 
     /**
@@ -626,8 +630,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
      */
     onIncrementButtonClick = () => {
         this.clicked = true;
-        this.entered && (this.props.CollectionView.props.Document.numCols as number)--;
-        undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)++)();
+        this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)--;
+        undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1)();
         this.entered = false;
     }
 
@@ -637,8 +641,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     onDecrementButtonClick = () => {
         this.clicked = true;
         if (!this.decrementLimitReached) {
-            this.entered && (this.props.CollectionView.props.Document.numCols as number)++;
-            undoBatch(() => (this.props.CollectionView.props.Document.numCols as number)--)();
+            this.entered && (this.props.CollectionView.props.Document.gridNumCols as number)++;
+            undoBatch(() => this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1)();
         }
         this.entered = false;
     }
@@ -649,7 +653,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     incrementValue = () => {
         this.entered = true;
         if (!this.clicked && !this.decrementLimitReached) {
-            (this.props.CollectionView.props.Document.numCols as number)++;
+            this.props.CollectionView.props.Document.gridNumCols = this.numCols + 1;
         }
         this.decrementLimitReached = false;
         this.clicked = false;
@@ -661,8 +665,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     decrementValue = () => {
         this.entered = true;
         if (!this.clicked) {
-            if (this.props.CollectionView.props.Document.numCols as number !== 1) {
-                (this.props.CollectionView.props.Document.numCols as number)--;
+            if (this.numCols !== 1) {
+                this.props.CollectionView.props.Document.gridNumCols = this.numCols - 1;
             }
             else {
                 this.decrementLimitReached = true;
@@ -676,14 +680,15 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
      * Toggles the value of preventCollision
      */
     toggleCollisions = () => {
-        this.props.CollectionView.props.Document.preventCollision = !this.props.CollectionView.props.Document.preventCollision;
+        this.props.CollectionView.props.Document.gridPreventCollision = !this.props.CollectionView.props.Document.gridPreventCollision;
     }
 
     /**
      * Changes the value of the compactType
      */
+    @undoBatch
     changeCompactType = (e: React.ChangeEvent<HTMLSelectElement>) => {
-        this.props.CollectionView.props.Document.compactType = e.target.selectedOptions[0].value;
+        this.props.CollectionView.props.Document.gridCompaction = e.target.selectedOptions[0].value;
     }
 
     render() {
@@ -693,7 +698,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <span className="grid-icon">
                         <FontAwesomeIcon icon="columns" size="1x" />
                     </span>
-                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.numCols as string} onKeyDown={this.onNumColsEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
+                    <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.numCols.toString()} onKeyDown={this.onNumColsEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                     <input className="columnButton" onClick={this.onIncrementButtonClick} onMouseEnter={this.incrementValue} onMouseLeave={this.decrementValue} type="button" value="↑" />
                     <input className="columnButton" style={{ marginRight: 5 }} onClick={this.onDecrementButtonClick} onMouseEnter={this.decrementValue} onMouseLeave={this.incrementValue} type="button" value="↓" />
                 </span>
@@ -704,7 +709,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                 </span> */}
                 <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
-                    <input type="checkbox" style={{ marginRight: 5 }} onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.preventCollision} />
+                    <input type="checkbox" style={{ marginRight: 5 }} onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.gridPreventCollision} />
                     <label className="flexLabel">{this.resize ? "Coll" : "Collisions"}</label>
                 </span>
 
@@ -712,7 +717,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     style={{ marginRight: 5 }}
                     onPointerDown={stopPropagation}
                     onChange={this.changeCompactType}
-                    value={StrCast(this.props.CollectionView.props.Document.compactType)}>
+                    value={StrCast(this.props.CollectionView.props.Document.gridCompaction)}>
                     >
                     {["vertical", "horizontal", "null"].map(type =>
                         <option className="collectionGridViewChrome-viewOption"
@@ -724,11 +729,11 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                 </select>
 
                 <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
-                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={this.props.CollectionView.props.Document.flexGrid as boolean} />
+                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={BoolCast(this.props.CollectionView.props.Document.gridFlex)} />
                     <label className="flexLabel">{this.resize ? "Flex" : "Flexible"}</label>
                 </span>
 
-                <button onClick={() => this.props.CollectionView.props.Document.resetLayout = true}>
+                <button onClick={() => this.props.CollectionView.props.Document.gridResetLayout = true}>
                     {!this.resize ? "Reset" :
                         <FontAwesomeIcon icon="redo-alt" size="1x" />}
                 </button>
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.scss b/src/client/views/collections/collectionGrid/CollectionGridView.scss
index de7d62475..9c2d5cbff 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.scss
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.scss
@@ -21,6 +21,10 @@
             max-width: 100%;
         }
 
+        .react-grid-layout {
+            width : 100%;
+        }
+
         .react-grid-item>.react-resizable-handle {
             z-index: 4; // doesn't work on prezi otherwise
         }
@@ -41,7 +45,7 @@
             position: absolute;
             height: 3;
             left: 5;
-            top: 40;
+            top: 30;
             transform-origin: left;
             transform: rotate(90deg);
             outline: none;
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index a820b7e0e..2e1f7a0db 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -1,85 +1,61 @@
-import { computed, observable, Lambda, action, reaction } from 'mobx';
+import { action, computed, Lambda, observable, reaction } from 'mobx';
+import { observer } from 'mobx-react';
 import * as React from "react";
 import { Doc, Opt } from '../../../../fields/Doc';
 import { documentSchema } from '../../../../fields/documentSchemas';
+import { Id } from '../../../../fields/FieldSymbols';
 import { makeInterface } from '../../../../fields/Schema';
-import { BoolCast, NumCast, StrCast, ScriptCast } from '../../../../fields/Types';
+import { BoolCast, NumCast, ScriptCast, StrCast } from '../../../../fields/Types';
+import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils';
+import { Docs } from '../../../documents/Documents';
+import { DragManager } from '../../../util/DragManager';
+import { SnappingManager } from '../../../util/SnappingManager';
 import { Transform } from '../../../util/Transform';
 import { undoBatch } from '../../../util/UndoManager';
+import { ContextMenu } from '../../ContextMenu';
+import { ContextMenuProps } from '../../ContextMenuItem';
 import { ContentFittingDocumentView } from '../../nodes/ContentFittingDocumentView';
+import { FormattedTextBox } from '../../nodes/formattedText/FormattedTextBox';
 import { CollectionSubView } from '../CollectionSubView';
-import { SubCollectionViewProps } from '../CollectionSubView';
-import { returnZero } from '../../../../Utils';
-import Grid, { Layout } from "./Grid";
-import { Id } from '../../../../fields/FieldSymbols';
-import { observer } from 'mobx-react';
-import { SnappingManager } from '../../../util/SnappingManager';
-import { Docs } from '../../../documents/Documents';
-import { EditableView, EditableProps } from '../../EditableView';
 import "./CollectionGridView.scss";
-import { ContextMenu } from '../../ContextMenu';
-import { List } from '../../../../fields/List';
-import { ContextMenuProps } from '../../ContextMenuItem';
-
+import Grid, { Layout } from "./Grid";
 
 type GridSchema = makeInterface<[typeof documentSchema]>;
 const GridSchema = makeInterface(documentSchema);
 
 @observer
 export class CollectionGridView extends CollectionSubView(GridSchema) {
-    private containerRef: React.RefObject<HTMLDivElement>;
+    private _containerRef: React.RefObject<HTMLDivElement> = React.createRef();
+    private _changeListenerDisposer: Opt<Lambda>; // listens for changes in this.childLayoutPairs
+    private _resetListenerDisposer: Opt<Lambda>; // listens for when the reset button is clicked
+    @observable private _rowHeight: Opt<number>; // temporary store of row height to make change undoable
     @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll
-    private changeListenerDisposer: Opt<Lambda>; // listens for changes in this.childLayoutPairs
-    private rowHeight: number = 0; // temporary store of row height to make change undoable
-    private mounted: boolean = false; // hack to fix the issue of not rerendering when mounting
-    private resetListenerDisposer: Opt<Lambda>; // listens for when the reset button is clicked
-
-    constructor(props: Readonly<SubCollectionViewProps>) {
-        super(props);
-
-        this.props.Document.numCols = NumCast(this.props.Document.numCols, 10);
-        this.props.Document.rowHeight = NumCast(this.props.Document.rowHeight, 100);
-
-        // determines whether the grid is static/flexible i.e. whether can nodes be moved around and resized or not
-        this.props.Document.flexGrid = BoolCast(this.props.Document.flexGrid, true);
 
-        // determines whether nodes should remain in position, be bound to the top, or to the left
-        this.props.Document.compactType = StrCast(this.props.Document.compactType, "vertical");
-
-        // determines whether nodes should move out of the way (i.e. collide) when other nodes are dragged over them
-        this.props.Document.preventCollision = BoolCast(this.props.Document.preventCollision, false);
+    @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
 
-        // sets the default width and height of the grid nodes 
-        this.props.Document.defaultW = NumCast(this.props.Document.defaultW, 2);
-        this.props.Document.defaultH = NumCast(this.props.Document.defaultH, 2);
+    @computed get numCols() { return NumCast(this.props.Document.gridNumCols, 10); }
+    @computed get rowHeight() { return this._rowHeight === undefined ? NumCast(this.props.Document.gridRowHeight, 100) : this._rowHeight; }
+    // sets the default width and height of the grid nodes 
+    @computed get defaultW() { return NumCast(this.props.Document.gridDefaultW, 2); }
+    @computed get defaultH() { return NumCast(this.props.Document.gridDefaultH, 2); }
 
-        // sets the margin between grid nodes
-        this.props.Document.margin = NumCast(this.props.Document.margin, 10);
+    @computed get colWidthPlusGap() { return (this.props.PanelWidth() - this.margin) / this.numCols; }
+    @computed get rowHeightPlusGap() { return this.rowHeight + this.margin; }
 
-        // sets the css display type of the ContentFittingDocumentView component
-        this.props.Document.display = StrCast(this.props.Document.display, "contents");
+    @computed get margin() { return NumCast(this.props.Document.margin, 10); }  // sets the margin between grid nodes
 
-        this.setLayout = this.setLayout.bind(this);
-        this.onSliderChange = this.onSliderChange.bind(this);
-        this.onContextMenu = this.onContextMenu.bind(this);
-
-        this.containerRef = React.createRef();
-    }
+    @computed get flexGrid() { return BoolCast(this.props.Document.gridFlex, true); } // is grid static/flexible i.e. whether nodes be moved around and resized
 
     componentDidMount() {
-        this.mounted = true;
-
-        this.changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => {
-
-            const layouts: Layout[] = this.parsedLayoutList;
+        this._changeListenerDisposer = computed(() => this.childLayoutPairs).observe(({ oldValue, newValue }) => {
+            const layouts = this.parsedLayoutList;
 
             // if grid view has been opened and then exited and a document has been deleted
             // this deletes the layout of that document from the layouts list
 
             if (!oldValue && newValue.length) {
                 layouts.forEach(({ i }, index) => {
-                    const targetId = i;
-                    if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) {
+                    if (!newValue.find(({ layout: preserved }) => preserved[Id] === i)) {
                         layouts.splice(index, 1);
                     }
                 });
@@ -88,120 +64,84 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             if (!oldValue || newValue.length > oldValue.length) {
                 // for each document that was added, add a corresponding grid layout object
                 newValue.forEach(({ layout }, i) => {
-                    const targetId = layout[Id];
-                    if (!layouts.find((gridLayout: Layout) => gridLayout.i === targetId)) {
-                        layouts.push({
-                            i: targetId,
-                            w: this.defaultW,
-                            h: this.defaultH,
-                            x: this.defaultW * (i % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW)),
-                            y: this.defaultH * Math.floor(i / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH)),
-                            static: !this.props.Document.flexGrid
-                        });
+                    if (!layouts.find(gridLayout => gridLayout.i === layout[Id])) {
+                        this.addLayoutItem(layouts, this.makeLayoutItem(layout, this.unflexedPosition(i), !this.flexGrid))
                     }
-                });
+                })
             } else {
                 // for each document that was removed, remove its corresponding grid layout object
                 oldValue.forEach(({ layout }) => {
-                    const targetId = layout[Id];
-                    if (!newValue.find(({ layout: preserved }) => preserved[Id] === targetId)) {
-                        const index = layouts.findIndex((gridLayout: Layout) => gridLayout.i === targetId);
+                    if (!newValue.find(({ layout: preserved }) => preserved[Id] === layout[Id])) {
+                        const index = layouts.findIndex((gridLayout: Layout) => gridLayout.i === layout[Id]);
                         index !== -1 && layouts.splice(index, 1);
                     }
                 });
             }
-            this.unStringifiedLayoutList = layouts;
+            this.setLayoutList(layouts);
         }, true);
 
         // updates the layouts if the reset button has been clicked
-        this.resetListenerDisposer = reaction(() => this.props.Document.resetLayout, () => {
-            if (this.props.Document.flexGrid) {
-                const layouts: Layout[] = this.parsedLayoutList;
-                this.setLayout(
-                    layouts.map(({ i }, index) => ({
-                        i: i,
-                        x: this.defaultW * (index % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW)),
-                        y: this.defaultH * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH)),
-                        w: this.defaultW,
-                        h: this.defaultH,
-                    })));
+        this._resetListenerDisposer = reaction(() => this.props.Document.gridResetLayout, (reset) => {
+            if (reset && this.flexGrid) {
+                this.setLayout(this.childLayoutPairs.map((pair, index) => this.makeLayoutItem(pair.layout, this.unflexedPosition(index))));
             }
-            this.props.Document.resetLayout = false;
+            this.props.Document.gridResetLayout = false;
         });
     }
 
     componentWillUnmount() {
-        this.mounted = false;
-        this.changeListenerDisposer && this.changeListenerDisposer();
-        this.resetListenerDisposer?.();
+        this._changeListenerDisposer?.();
+        this._resetListenerDisposer?.();
     }
 
-    /**
-     * @returns the transform that will correctly place the document decorations box. 
-     */
-    private lookupIndividualTransform = (layout: Layout) => {
-        const index = this.childLayoutPairs.findIndex(({ layout: layoutDoc }) => layoutDoc[Id] === layout.i);
-
-        // translations depend on whether the grid is flexible or static
-        const xTranslation = (this.props.Document.flexGrid ? NumCast(layout.x) : this.defaultW * (index % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW))) * this.colWidthPlusGap + this.margin;
-        const yTranslation = (this.props.Document.flexGrid ? NumCast(layout.y) : this.defaultH * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH))) * this.rowHeightPlusGap + this.margin - this._scroll + 30; // 30 is the height of the add text doc bar
-
-        return this.props.ScreenToLocalTransform().translate(-xTranslation, -yTranslation);
+    unflexedPosition(index: number) {
+        return {
+            x: (index % Math.floor(this.numCols / this.defaultW)) * this.defaultW,
+            y: Math.floor(index / Math.floor(this.numCols / this.defaultH)) * this.defaultH
+        };
     }
 
-    @computed get onChildClickHandler() { return ScriptCast(this.Document.onChildClick); }
+    screenToCell(sx: number, sy: number) {
+        const pt = this.props.ScreenToLocalTransform().transformPoint(sx, sy);
+        const x = Math.floor(pt[0] / this.colWidthPlusGap);
+        const y = Math.floor((pt[1] + this._scroll) / this.rowHeight);
+        return { x, y };
+    }
 
-    addDocTab = (doc: Doc, where: string) => {
-        if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) {
-            this.dataDoc[this.props.fieldKey] = new List<Doc>([doc]);
-            return true;
-        }
-        return this.props.addDocTab(doc, where);
+    makeLayoutItem = (doc: Doc, pos: { x: number, y: number }, Static: boolean = false, w: number = this.defaultW, h: number = this.defaultH) => {
+        return ({ i: doc[Id], w, h, x: pos.x, y: pos.y, static: Static });
     }
 
-    @computed get colWidthPlusGap() { return (this.props.PanelWidth() - this.margin) / NumCast(this.props.Document.numCols); }
-    @computed get rowHeightPlusGap() { return NumCast(this.props.Document.rowHeight) + this.margin; }
+    addLayoutItem = (layouts: Layout[], layout: Layout) => {
+        const f = layouts.findIndex(l => l.i === layout.i);
+        f !== -1 && layouts.splice(f, 1);
+        layouts.push(layout);
+        return layouts;
+    }
+    /**
+     * @returns the transform that will correctly place the document decorations box. 
+     */
+    private lookupIndividualTransform = (layout: Layout) => {
+        const xypos = this.flexGrid ? layout : this.unflexedPosition(this.layoutList.findIndex(l => l.i === layout.i));
+        const pos = { x: xypos.x * this.colWidthPlusGap + this.margin, y: xypos.y * this.rowHeightPlusGap + this.margin - this._scroll };
 
-    @computed get margin() { return NumCast(this.props.Document.margin); }
-    @computed get defaultW() { return NumCast(this.props.Document.defaultW); }
-    @computed get defaultH() { return NumCast(this.props.Document.defaultH); }
+        return this.props.ScreenToLocalTransform().translate(-pos.x, -pos.y);
+    }
 
     /**
      * @returns the layout list converted from JSON
      */
     get parsedLayoutList() {
-        return this.props.Document.gridLayoutString ? JSON.parse(StrCast(this.props.Document.gridLayoutString)) : [];
+        return (this.props.Document.gridLayoutString ? JSON.parse(StrCast(this.props.Document.gridLayoutString)) : []) as Layout[];
     }
 
     /**
      * Stores the layout list on the Document as JSON
      */
-    set unStringifiedLayoutList(layouts: Layout[]) {
-
-        // sometimes there are issues with rendering when you switch from a different view
-        // where the nodes are all squeezed together on the left hand side of the screen
-        // until you click on the screen or close the chrome or interact with it in some way
-        // the component doesn't rerender when the component mounts
-        // this seems to fix that though it isn't very elegant
-
-        this.mounted && (this.props.Document.gridLayoutString = "");
+    setLayoutList(layouts: Layout[]) {
         this.props.Document.gridLayoutString = JSON.stringify(layouts);
-        this.mounted = false;
     }
 
-
-    /**
-     * Sets the width of the decorating box.
-     * @param layout 
-     */
-    @observable private width = (layout: Layout) => (this.props.Document.flexGrid ? layout.w : this.defaultW) * this.colWidthPlusGap - this.margin;
-
-    /**
-     * Sets the height of the decorating box.
-     * @param layout
-     */
-    @observable private height = (layout: Layout) => (this.props.Document.flexGrid ? layout.h : this.defaultH) * this.rowHeightPlusGap - this.margin;
-
     /**
      * 
      * @param layout 
@@ -217,7 +157,6 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             DataDoc={layout.resolvedDataDoc as Doc}
             NativeHeight={returnZero}
             NativeWidth={returnZero}
-            addDocTab={this.addDocTab}
             backgroundColor={this.props.backgroundColor}
             ContainingCollectionDoc={this.props.Document}
             PanelWidth={width}
@@ -226,7 +165,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
             onClick={this.onChildClickHandler}
             renderDepth={this.props.renderDepth + 1}
             parentActive={this.props.active}
-            display={StrCast(this.props.Document.display)}
+            display={StrCast(this.props.Document.display, "contents")} // sets the css display type of the ContentFittingDocumentView component
         />;
     }
 
@@ -234,27 +173,18 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * Saves the layouts received from the Grid to the Document.
      * @param layouts `Layout[]`
      */
-    @undoBatch
     @action
-    setLayout(layoutArray: Layout[]) {
+    setLayout = (layoutArray: Layout[]) => {
         // for every child in the collection, check to see if there's a corresponding grid layout object and
         // updated layout object. If both exist, which they should, update the grid layout object from the updated object 
-
-        if (this.props.Document.flexGrid) {
-            const layouts: Layout[] = this.parsedLayoutList;
+        if (this.flexGrid) {
+            const layouts = this.parsedLayoutList;
             this.childLayoutPairs.forEach(({ layout: doc }) => {
-                let update: Opt<Layout>;
-                const targetId = doc[Id];
-                const gridLayout = layouts.find(gridLayout => gridLayout.i === targetId);
-                if (gridLayout && (update = layoutArray.find(layout => layout.i === targetId))) {
-                    gridLayout.x = update.x;
-                    gridLayout.y = update.y;
-                    gridLayout.w = update.w;
-                    gridLayout.h = update.h;
-                }
+                let gridLayout = layouts.find(gridLayout => gridLayout.i === doc[Id]);
+                gridLayout && Object.assign(gridLayout, layoutArray.find(layout => layout.i === doc[Id]) || gridLayout);
             });
 
-            this.unStringifiedLayoutList = layouts;
+            this.setLayoutList(layouts);
         }
     }
 
@@ -264,27 +194,22 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      */
     @computed
     private get contents(): JSX.Element[] {
-
-        const { childLayoutPairs } = this;
         const collector: JSX.Element[] = [];
-        const layouts: Layout[] = this.parsedLayoutList;
-        if (!layouts.length || layouts.length !== childLayoutPairs.length) {
-            return [];
-        }
-
-        for (let i = 0; i < childLayoutPairs.length; i++) {
-            const { layout } = childLayoutPairs[i];
-            const gridLayout = layouts[i];
-            const dxf = () => this.lookupIndividualTransform(gridLayout);
-            const width = () => this.width(gridLayout);
-            const height = () => this.height(gridLayout);
-            collector.push(
-                <div className={this.props.Document.flexGrid && (this.props.isSelected() ? true : false) ? "document-wrapper" : "document-wrapper static"}
-                    key={gridLayout.i}
-                >
-                    {this.getDisplayDoc(layout, dxf, width, height)}
-                </div >
-            );
+        const layouts = this.parsedLayoutList;
+        if (layouts.length !== this.childLayoutPairs.length) {
+            setTimeout(action(() => this.props.Document.gridResetLayout = true), 0);
+        } else {
+            this.layoutList.forEach((l, i) => {
+                const child = this.childLayoutPairs.find(c => c.layout[Id] === l.i);
+                const dxf = () => this.lookupIndividualTransform(layouts[i]);
+                const width = () => (this.flexGrid ? layouts[i].w : this.defaultW) * this.colWidthPlusGap - this.margin;
+                const height = () => (this.flexGrid ? layouts[i].h : this.defaultH) * this.rowHeightPlusGap - this.margin;
+                child && collector.push(
+                    <div key={child.layout[Id]} className={"document-wrapper" + (this.flexGrid && this.props.isSelected() ? "" : " static")} >
+                        {this.getDisplayDoc(child.layout, dxf, width, height)}
+                    </div >
+                );
+            });
         }
         return collector;
     }
@@ -293,56 +218,42 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
      * @returns a list of `Layout` objects with attributes depending on whether the grid is flexible or static
      */
     get layoutList(): Layout[] {
-
-        const layouts: Layout[] = this.parsedLayoutList;
-
-        return this.props.Document.flexGrid ?
-            layouts.map(({ i, x, y, w, h }) => ({
-                i: i,
-                x: x + w > NumCast(this.props.Document.numCols) ? 0 : x, // handles wrapping around of nodes when numCols decreases
-                y: y,
-                w: w > NumCast(this.props.Document.numCols) ? NumCast(this.props.Document.numCols) : w, // reduces width if greater than numCols
-                h: h,
+        return this.flexGrid ?
+            this.parsedLayoutList.map(({ i, x, y, w, h }) => ({
+                i, y, h,
+                x: x + w > this.numCols ? 0 : x, // handles wrapping around of nodes when numCols decreases
+                w: Math.max(w, this.numCols), // reduces width if greater than numCols
                 static: BoolCast(this.childLayoutPairs.find(({ layout }) => layout[Id] === i)?.layout.lockedPosition, false) // checks if the lock position item has been selected in the context menu
-            }))
-            : layouts.map(({ i }, index) => ({
-                i: i,
-                x: this.defaultW * (index % Math.floor(NumCast(this.props.Document.numCols) / this.defaultW)),
-                y: this.defaultH * Math.floor(index / Math.floor(NumCast(this.props.Document.numCols) / this.defaultH)),
-                w: this.defaultW,
-                h: this.defaultH,
-                static: true
-            }));
+            })) :
+            this.parsedLayoutList.map((layout, index) => Object.assign(layout, this.unflexedPosition(index)));
     }
 
-    /**
-     * Handles the change in the value of the rowHeight slider.
-     */
-    onSliderChange = (event: React.ChangeEvent<HTMLInputElement>) => {
-        this.props.Document.rowHeight = event.currentTarget.valueAsNumber;
+    onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
+        const layouts = this.parsedLayoutList;
+        const dropped = de.complete.docDragData?.droppedDocuments;
+        if (dropped && super.onInternalDrop(e, de) && layouts.length !== this.childDocs.length) {
+            dropped.forEach(doc => this.addLayoutItem(layouts, this.makeLayoutItem(doc, this.screenToCell(de.x, de.y)))); // shouldn't place all docs in the same cell;
+            this.setLayoutList(layouts);
+            return true;
+        }
+        return false;
     }
 
     /**
-     * Saves the rowHeight in a temporary variable to make it undoable later.
+     * Handles the change in the value of the rowHeight slider.
      */
-    onSliderDown = () => {
-        this.rowHeight = NumCast(this.props.Document.rowHeight);
+    @action
+    onSliderChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+        this._rowHeight = event.currentTarget.valueAsNumber;
     }
-
-    /**
-     * Uses the stored rowHeight to make the rowHeight change undoable.
-     */
-    onSliderUp = () => {
-        const tempVal = this.props.Document.rowHeight;
-        this.props.Document.rowHeight = this.rowHeight;
-        undoBatch(() => this.props.Document.rowHeight = tempVal)();
+    @action
+    onSliderDown = (e: React.PointerEvent) => {
+        this._rowHeight = this.rowHeight; // uses _rowHeight during dragging and sets doc's rowHeight when finished so that operation is undoable
+        setupMoveUpEvents(this, e, returnFalse, action(() => {
+            undoBatch(() => this.props.Document.gridRowHeight = this._rowHeight)();
+            this._rowHeight = undefined;
+        }), emptyFunction, false, false);
     }
-
-    /**
-     * Creates a text document and adds it to the grid.
-     */
-    @undoBatch @action addTextDocument = (value: string) => this.props.addDocument(Docs.Create.TextDocument(value, { title: value }));
-
     /**
      * Adds the display option to change the css display attribute of the `ContentFittingDocumentView`s
      */
@@ -350,74 +261,52 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         const displayOptionsMenu: ContextMenuProps[] = [];
         displayOptionsMenu.push({ description: "Contents", event: () => this.props.Document.display = "contents", icon: "copy" });
         displayOptionsMenu.push({ description: "Undefined", event: () => this.props.Document.display = undefined, icon: "exclamation" });
-
         ContextMenu.Instance.addItem({ description: "Display", subitems: displayOptionsMenu, icon: "tv" });
     }
 
-    render() {
-
-        // for the add text document EditableView
-        const newEditableViewProps: EditableProps = {
-            GetValue: () => "",
-            SetValue: this.addTextDocument,
-            contents: "+ ADD TEXT DOCUMENT",
-        };
-
-        const childDocumentViews: JSX.Element[] = this.contents;
-        const chromeStatus = this.props.Document._chromeStatus;
-        const showChrome = (chromeStatus !== 'view-mode' && chromeStatus !== 'disabled');
+    onPointerDown = (e: React.PointerEvent) => {
+        this.props.isSelected(true) && setupMoveUpEvents(this, e, returnFalse, returnFalse, action((e: PointerEvent, doubleTap?: boolean) => {
+            if (doubleTap) {
+                const text = Docs.Create.TextDocument("", { _width: 150, _height: 50 });
+                FormattedTextBox.SelectOnLoad = text[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+                Doc.AddDocToList(this.props.Document, this.props.fieldKey, text);
+                this.setLayoutList(this.addLayoutItem(this.parsedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY))));
+            }
+        }), false);
+        e.stopPropagation();
+    }
 
+    render() {
         return (
-            <div className="collectionGridView-contents"
-                style={{
-                    pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined
-                }}
+            <div className="collectionGridView-contents" ref={this.createDashEventsTarget}
+                style={{ pointerEvents: !this.props.active() && !SnappingManager.GetIsDragging() ? "none" : undefined }}
                 onContextMenu={this.onContextMenu}
-                ref={this.createDashEventsTarget}
-                onPointerDown={e => {
-                    if (this.props.active(true)) {
-                        if (this.props.isSelected(true)) {
-                            e.stopPropagation();
-                        }
-                    }
-                    // is the following section needed? it prevents the slider from being easily used and I'm not sure what it's preventing
-
-                    // if (this.props.isSelected(true)) {
-                    //     !((e.target as any)?.className.includes("react-resizable-handle")) && e.preventDefault();
-                    // }
-
-                }} // the grid doesn't stopPropagation when its widgets are hit, so we need to otherwise the outer documents will respond
-            >
-                {showChrome ?
-                    <div className="collectionGridView-addDocumentButton">
-                        <EditableView {...newEditableViewProps} />
-                    </div> : null
-                }
-                <div className="collectionGridView-gridContainer"
-                    ref={this.containerRef}
+                onPointerDown={e => this.onPointerDown(e)} >
+                <div className="collectionGridView-gridContainer" ref={this._containerRef}
+                    onWheel={e => e.stopPropagation()}
                     onScroll={action(e => {
                         if (!this.props.isSelected()) e.currentTarget.scrollTop = this._scroll;
                         else this._scroll = e.currentTarget.scrollTop;
-                    })}
-                    onWheel={e => e.stopPropagation()}
-                >
-                    <input className="rowHeightSlider" type="range" value={NumCast(this.props.Document.rowHeight)} onPointerDown={this.onSliderDown} onPointerUp={this.onSliderUp} onChange={this.onSliderChange} style={{ width: this.props.PanelHeight() - 40 }} min={1} max={this.props.PanelHeight() - 40} />
+                    })} >
+                    <input className="rowHeightSlider" type="range"
+                        style={{ width: this.props.PanelHeight() - 30 }}
+                        min={1} value={this.rowHeight} max={this.props.PanelHeight() - 30}
+                        onPointerDown={this.onSliderDown} onChange={this.onSliderChange} />
                     <Grid
                         width={this.props.PanelWidth()}
-                        nodeList={childDocumentViews.length ? childDocumentViews : null}
-                        layout={childDocumentViews.length ? this.layoutList : undefined}
+                        nodeList={this.contents.length ? this.contents : null}
+                        layout={this.contents.length ? this.layoutList : undefined}
                         childrenDraggable={this.props.isSelected() ? true : false}
-                        numCols={NumCast(this.props.Document.numCols)}
-                        rowHeight={NumCast(this.props.Document.rowHeight)}
+                        numCols={this.numCols}
+                        rowHeight={this.rowHeight}
                         setLayout={this.setLayout}
                         transformScale={this.props.ScreenToLocalTransform().Scale}
-                        compactType={StrCast(this.props.Document.compactType)}
-                        preventCollision={BoolCast(this.props.Document.preventCollision)}
+                        compactType={StrCast(this.props.Document.gridCompaction, "vertical")} // determines whether nodes should remain in position, be bound to the top, or to the left
+                        preventCollision={BoolCast(this.props.Document.gridPreventCollision)}// determines whether nodes should move out of the way (i.e. collide) when other nodes are dragged over them
                         margin={this.margin}
                     />
-
                 </div>
             </div >
         );
     }
-}
+}
\ No newline at end of file
diff --git a/src/client/views/collections/collectionGrid/Grid.tsx b/src/client/views/collections/collectionGrid/Grid.tsx
index 6232fca7c..66edb99d9 100644
--- a/src/client/views/collections/collectionGrid/Grid.tsx
+++ b/src/client/views/collections/collectionGrid/Grid.tsx
@@ -1,7 +1,6 @@
 import * as React from 'react';
 import { observer } from "mobx-react";
 
-
 import "../../../../../node_modules/react-grid-layout/css/styles.css";
 import "../../../../../node_modules/react-resizable/css/styles.css";
 
@@ -29,7 +28,6 @@ interface GridProps {
  */
 @observer
 export default class Grid extends React.Component<GridProps> {
-
     render() {
         const compactType = this.props.compactType === "vertical" || this.props.compactType === "horizontal" ? this.props.compactType : null;
         return (
-- 
cgit v1.2.3-70-g09d2


From 747ae83d5b70b7e9b2d3755aa9e402dbf1c6ae5e Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Fri, 12 Jun 2020 18:31:49 +0530
Subject: fixed gridflex bugs

---
 src/client/views/collections/CollectionViewChromes.tsx            | 5 ++---
 .../views/collections/collectionGrid/CollectionGridView.tsx       | 8 +++++---
 2 files changed, 7 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 53bff0fe5..64a459aff 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -622,7 +622,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
      */
     @undoBatch
     toggleFlex = () => {
-        this.props.CollectionView.props.Document.gridFlex = !this.props.CollectionView.props.Document.gridFlex;
+        this.props.CollectionView.props.Document.gridFlex = !BoolCast(this.props.CollectionView.props.Document.gridFlex, true);
     }
 
     /**
@@ -718,7 +718,6 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     onPointerDown={stopPropagation}
                     onChange={this.changeCompactType}
                     value={StrCast(this.props.CollectionView.props.Document.gridCompaction)}>
-                    >
                     {["vertical", "horizontal", "null"].map(type =>
                         <option className="collectionGridViewChrome-viewOption"
                             onPointerDown={stopPropagation}
@@ -729,7 +728,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                 </select>
 
                 <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
-                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={BoolCast(this.props.CollectionView.props.Document.gridFlex)} />
+                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={BoolCast(this.props.CollectionView.props.Document.gridFlex, true)} />
                     <label className="flexLabel">{this.resize ? "Flex" : "Flexible"}</label>
                 </span>
 
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index ec142f7a5..87d7d945a 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -65,9 +65,9 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                 // for each document that was added, add a corresponding grid layout object
                 newValue.forEach(({ layout }, i) => {
                     if (!layouts.find(gridLayout => gridLayout.i === layout[Id])) {
-                        this.addLayoutItem(layouts, this.makeLayoutItem(layout, this.unflexedPosition(i), !this.flexGrid))
+                        this.addLayoutItem(layouts, this.makeLayoutItem(layout, this.unflexedPosition(i), !this.flexGrid));
                     }
-                })
+                });
             } else {
                 // for each document that was removed, remove its corresponding grid layout object
                 oldValue.forEach(({ layout }) => {
@@ -94,10 +94,12 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
         this._resetListenerDisposer?.();
     }
 
-    unflexedPosition(index: number) {
+    unflexedPosition(index: number): Omit<Layout, "i"> {
         return {
             x: (index % Math.floor(this.numCols / this.defaultW)) * this.defaultW,
             y: Math.floor(index / Math.floor(this.numCols / this.defaultH)) * this.defaultH,
+            w: this.defaultW,
+            h: this.defaultH,
             static: true
         };
     }
-- 
cgit v1.2.3-70-g09d2


From a16be30682d686e6588185a1104d268ae20c866d Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 12 Jun 2020 11:26:40 -0400
Subject: fixed bug with initial position of CollectionGrid items.  Added undo
 for changing GridView compaction

---
 .../views/collections/CollectionViewChromes.tsx    | 11 ++++----
 .../collectionGrid/CollectionGridView.tsx          | 29 +++++++++++++++-------
 2 files changed, 26 insertions(+), 14 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 64a459aff..459d98bb5 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -686,9 +686,9 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
     /**
      * Changes the value of the compactType
      */
-    @undoBatch
     changeCompactType = (e: React.ChangeEvent<HTMLSelectElement>) => {
-        this.props.CollectionView.props.Document.gridCompaction = e.target.selectedOptions[0].value;
+        // need to change startCompaction so that this operation will be undoable.
+        this.props.CollectionView.props.Document.gridStartCompaction = e.target.selectedOptions[0].value;
     }
 
     render() {
@@ -709,7 +709,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     <input className="collectionGridViewChrome-entryBox" type="number" placeholder={this.props.CollectionView.props.Document.rowHeight as string} onKeyDown={this.onRowHeightEnter} onClick={(e: React.MouseEvent<HTMLInputElement, MouseEvent>) => { e.stopPropagation(); e.preventDefault(); e.currentTarget.focus(); }} />
                 </span> */}
                 <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
-                    <input type="checkbox" style={{ marginRight: 5 }} onClick={this.toggleCollisions} defaultChecked={!this.props.CollectionView.props.Document.gridPreventCollision} />
+                    <input type="checkbox" style={{ marginRight: 5 }} onChange={this.toggleCollisions} checked={!this.props.CollectionView.props.Document.gridPreventCollision} />
                     <label className="flexLabel">{this.resize ? "Coll" : "Collisions"}</label>
                 </span>
 
@@ -717,7 +717,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     style={{ marginRight: 5 }}
                     onPointerDown={stopPropagation}
                     onChange={this.changeCompactType}
-                    value={StrCast(this.props.CollectionView.props.Document.gridCompaction)}>
+                    value={StrCast(this.props.CollectionView.props.Document.gridStartCompaction, StrCast(this.props.CollectionView.props.Document.gridCompaction))}>
                     {["vertical", "horizontal", "null"].map(type =>
                         <option className="collectionGridViewChrome-viewOption"
                             onPointerDown={stopPropagation}
@@ -728,7 +728,8 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                 </select>
 
                 <span className="grid-control" style={{ width: this.resize ? "12%" : "20%" }}>
-                    <input style={{ marginRight: 5 }} type="checkbox" onClick={this.toggleFlex} defaultChecked={BoolCast(this.props.CollectionView.props.Document.gridFlex, true)} />
+                    <input style={{ marginRight: 5 }} type="checkbox" onChange={this.toggleFlex}
+                        checked={BoolCast(this.props.CollectionView.props.Document.gridFlex, true)} />
                     <label className="flexLabel">{this.resize ? "Flex" : "Flexible"}</label>
                 </span>
 
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index aa343c68f..2b83eea86 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -45,6 +45,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     @computed get margin() { return NumCast(this.props.Document.margin, 10); }  // sets the margin between grid nodes
 
     @computed get flexGrid() { return BoolCast(this.props.Document.gridFlex, true); } // is grid static/flexible i.e. whether nodes be moved around and resized
+    @computed get compaction() { return StrCast(this.props.Document.gridStartCompaction, StrCast(this.props.Document.gridCompaction, "vertical")); } // is grid static/flexible i.e. whether nodes be moved around and resized
 
     componentDidMount() {
         this._changeListenerDisposer = reaction(() => this.childLayoutPairs, (pairs) => {
@@ -55,7 +56,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                 if (existing) newLayouts.push(existing);
                 else this.addLayoutItem(newLayouts, this.makeLayoutItem(pair.layout, this.unflexedPosition(i), !this.flexGrid));
             });
-            this.setLayoutList(newLayouts);
+            pairs?.length && this.setLayoutList(newLayouts);
         }, { fireImmediately: true });
 
         // updates the layouts if the reset button has been clicked
@@ -165,7 +166,15 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                 gridLayout && Object.assign(gridLayout, layoutArray.find(layout => layout.i === doc[Id]) || gridLayout);
             });
 
-            this.setLayoutList(savedLayouts);
+            if (this.props.Document.gridStartCompaction) {
+                undoBatch(() => {
+                    this.props.Document.gridCompaction = this.props.Document.gridStartCompaction;
+                    this.setLayoutList(savedLayouts);
+                })();
+                this.props.Document.gridStartCompaction = undefined;
+            } else {
+                undoBatch(() => this.setLayoutList(savedLayouts))();
+            }
         }
     }
 
@@ -247,14 +256,16 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     onPointerDown = (e: React.PointerEvent) => {
         if (this.props.isSelected(true)) {
             setupMoveUpEvents(this, e, returnFalse, returnFalse,
-                action((e: PointerEvent, doubleTap?: boolean) => {
+                (e: PointerEvent, doubleTap?: boolean) => {
                     if (doubleTap) {
-                        const text = Docs.Create.TextDocument("", { _width: 150, _height: 50 });
-                        FormattedTextBox.SelectOnLoad = text[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
-                        Doc.AddDocToList(this.props.Document, this.props.fieldKey, text);
-                        this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY))));
+                        undoBatch(action(() => {
+                            const text = Docs.Create.TextDocument("", { _width: 150, _height: 50 });
+                            FormattedTextBox.SelectOnLoad = text[Id];// track the new text box so we can give it a prop that tells it to focus itself when it's displayed
+                            Doc.AddDocToList(this.props.Document, this.props.fieldKey, text);
+                            this.setLayoutList(this.addLayoutItem(this.savedLayoutList, this.makeLayoutItem(text, this.screenToCell(e.clientX, e.clientY))));
+                        }))();
                     }
-                }),
+                },
                 false);
             e.stopPropagation();
         }
@@ -281,7 +292,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
                         rowHeight={this.rowHeight}
                         setLayout={this.setLayout}
                         transformScale={this.props.ScreenToLocalTransform().Scale}
-                        compactType={StrCast(this.props.Document.gridCompaction, "vertical")} // determines whether nodes should remain in position, be bound to the top, or to the left
+                        compactType={this.compaction} // determines whether nodes should remain in position, be bound to the top, or to the left
                         preventCollision={BoolCast(this.props.Document.gridPreventCollision)}// determines whether nodes should move out of the way (i.e. collide) when other nodes are dragged over them
                         margin={this.margin}
                     />
-- 
cgit v1.2.3-70-g09d2


From fe3251b3186d4bb17615ec0dbd5d9acdaa4528ce Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 12 Jun 2020 11:35:24 -0400
Subject: fixed double-click text creation in grid views.

---
 src/client/views/collections/CollectionViewChromes.tsx             | 2 +-
 src/client/views/collections/collectionGrid/CollectionGridView.tsx | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 459d98bb5..7179229f5 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -718,7 +718,7 @@ export class CollectionGridViewChrome extends React.Component<CollectionViewChro
                     onPointerDown={stopPropagation}
                     onChange={this.changeCompactType}
                     value={StrCast(this.props.CollectionView.props.Document.gridStartCompaction, StrCast(this.props.CollectionView.props.Document.gridCompaction))}>
-                    {["vertical", "horizontal", "null"].map(type =>
+                    {["vertical", "horizontal", "none"].map(type =>
                         <option className="collectionGridViewChrome-viewOption"
                             onPointerDown={stopPropagation}
                             value={type}>
diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
index 2b83eea86..96b1b5301 100644
--- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx
+++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx
@@ -254,7 +254,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) {
     }
 
     onPointerDown = (e: React.PointerEvent) => {
-        if (this.props.isSelected(true)) {
+        if (this.props.active(true)) {
             setupMoveUpEvents(this, e, returnFalse, returnFalse,
                 (e: PointerEvent, doubleTap?: boolean) => {
                     if (doubleTap) {
-- 
cgit v1.2.3-70-g09d2


From 5c3edf121012ce789cf51d057b18f46fbc9b2d62 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Fri, 12 Jun 2020 21:27:49 -0400
Subject: nothing really

---
 src/client/views/collections/CollectionViewChromes.tsx | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 7179229f5..dfc8e6754 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -1,8 +1,8 @@
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, observable, runInAction, autorun, Lambda } from "mobx";
+import { action, computed, observable, runInAction, Lambda } from "mobx";
 import { observer } from "mobx-react";
 import * as React from "react";
-import { Doc, DocListCast, HeightSym, Opt } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt } from "../../../fields/Doc";
 import { Id } from "../../../fields/FieldSymbols";
 import { List } from "../../../fields/List";
 import { listSpec } from "../../../fields/Schema";
@@ -16,8 +16,6 @@ import { CollectionViewType } from "./CollectionView";
 import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
 import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView";
-import { undo } from "prosemirror-history";
-const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
     CollectionView: CollectionView;
-- 
cgit v1.2.3-70-g09d2

