From 3b740e1c1ac74e7aac45c136ec9df1b37e2dbc16 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Tue, 23 Jul 2019 16:32:43 -0400
Subject: pretty ui for changing section fitler and added base for colletion
 chromes

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

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

diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
new file mode 100644
index 000000000..ca1480ff2
--- /dev/null
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -0,0 +1,152 @@
+import * as React from "react";
+import { CollectionView } from "./CollectionView";
+import "./CollectionViewChromes.scss";
+import { CollectionViewType } from "./CollectionBaseView";
+import { undoBatch } from "../../util/UndoManager";
+import { action, observable, runInAction, computed } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast } from "../../../new_fields/Doc";
+import { DocLike } from "../MetadataEntryMenu";
+const higflyout = require("@hig/flyout");
+export const Flyout = higflyout.default;
+import * as Autosuggest from 'react-autosuggest';
+import { EditableView } from "../EditableView";
+import { StrCast } from "../../../new_fields/Types";
+
+interface CollectionViewChromeProps {
+    CollectionView: CollectionView;
+}
+
+class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
+    @undoBatch
+    viewChanged = (e: React.ChangeEvent) => {
+        //@ts-ignore
+        switch (e.target.selectedOptions[0].value) {
+            case "freeform":
+                this.props.CollectionView.props.Document.viewType = CollectionViewType.Freeform;
+                break;
+            case "schema":
+                this.props.CollectionView.props.Document.viewType = CollectionViewType.Schema;
+                break;
+            case "treeview":
+                this.props.CollectionView.props.Document.viewType = CollectionViewType.Tree;
+                break;
+            case "stacking":
+                this.props.CollectionView.props.Document.viewType = CollectionViewType.Stacking;
+                break;
+            case "masonry":
+                this.props.CollectionView.props.Document.viewType = CollectionViewType.Masonry;
+                break;
+            default:
+                break;
+        }
+    }
+
+    render() {
+        return (
+            <div className="collectionViewBaseChrome">
+                <select onChange={this.viewChanged}>
+                    <option value="freeform" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Freeform}>Freeform View</option>
+                    <option value="schema" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Schema}>Schema View</option>
+                    <option value="treeview" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Tree}>Tree View</option>
+                    <option value="stacking" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Stacking}>Stacking View</option>
+                    <option value="masonry" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Masonry}>Masonry View</option>
+                </select>
+            </div>
+        )
+    }
+}
+
+@observer
+export class CollectionStackingViewChrome extends React.Component<CollectionViewChromeProps> {
+    @observable private _currentKey: string = "";
+    @observable private suggestions: string[] = [];
+
+    @computed get sectionFilter() { return StrCast(this.props.CollectionView.props.Document.sectionFilter); }
+
+    getKeySuggestions = async (value: string): Promise<string[]> => {
+        value = value.toLowerCase();
+        let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
+            = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
+        if (typeof docs === "function") {
+            docs = docs();
+        }
+        docs = await docs;
+        if (docs instanceof Doc) {
+            return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value));
+        } else {
+            const keys = new Set<string>();
+            docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
+            return Array.from(keys).filter(key => key.toLowerCase().startsWith(value));
+        }
+    }
+
+    @action
+    onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
+        this._currentKey = newValue;
+    }
+
+    getSuggestionValue = (suggestion: string) => suggestion;
+
+    renderSuggestion = (suggestion: string) => {
+        return <p>{suggestion}</p>;
+    }
+
+    onSuggestionFetch = async ({ value }: { value: string }) => {
+        const sugg = await this.getKeySuggestions(value);
+        runInAction(() => {
+            this.suggestions = sugg;
+        });
+    }
+
+    @action
+    onSuggestionClear = () => {
+        this.suggestions = [];
+    }
+
+    setValue = (value: string) => {
+        this.props.CollectionView.props.Document.sectionFilter = value;
+        return true;
+    }
+
+    @action resetValue = () => { this._currentKey = this.sectionFilter; }
+
+    render() {
+        return (
+            <div className="collectionStackingViewChrome">
+                <CollectionViewBaseChrome CollectionView={this.props.CollectionView} />
+                <div className="collectionStackingViewChrome-sectionFilter-cont">
+                    <div className="collectionStackingViewChrome-sectionFilter-label">
+                        Group items by:
+                    </div>
+                    <div className="collectionStackingViewChrome-sectionFilter">
+                        <EditableView
+                            GetValue={() => this.sectionFilter}
+                            autosuggestProps={
+                                {
+                                    resetValue: this.resetValue,
+                                    value: this._currentKey,
+                                    onChange: this.onKeyChange,
+                                    autosuggestProps: {
+                                        inputProps:
+                                        {
+                                            value: this._currentKey,
+                                            onChange: this.onKeyChange
+                                        },
+                                        getSuggestionValue: this.getSuggestionValue,
+                                        suggestions: this.suggestions,
+                                        alwaysRenderSuggestions: true,
+                                        renderSuggestion: this.renderSuggestion,
+                                        onSuggestionsFetchRequested: this.onSuggestionFetch,
+                                        onSuggestionsClearRequested: this.onSuggestionClear
+                                    }
+                                }}
+                            SetValue={this.setValue}
+                            contents={this.sectionFilter ? this.sectionFilter : "N/A"}
+                        />
+                    </div>
+                </div>
+            </div>
+        )
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 0ebcadb80a89e7fe4f8f2a8a47570b19fd2f8711 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Tue, 23 Jul 2019 17:05:07 -0400
Subject: i need a breakkk

---
 src/client/views/collections/CollectionViewChromes.tsx | 2 +-
 1 file changed, 1 insertion(+), 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 ca1480ff2..52fee26bf 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -109,7 +109,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
         return true;
     }
 
-    @action resetValue = () => { this._currentKey = this.sectionFilter; }
+    @action resetValue = () => { this._currentKey = this.sectionFilter; };
 
     render() {
         return (
-- 
cgit v1.2.3-70-g09d2


From 828fdd80ab8af26f6e2ef521e05a71e7e500bf8c Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Wed, 24 Jul 2019 17:18:15 -0400
Subject: view specsss

---
 package.json                                       |   1 +
 src/client/views/EditableView.tsx                  |   2 +-
 src/client/views/MainView.tsx                      |   4 +-
 .../views/collections/CollectionStackingView.tsx   |   9 +-
 .../CollectionStackingViewFieldColumn.tsx          |  44 +++-
 src/client/views/collections/CollectionSubView.tsx |  15 +-
 .../views/collections/CollectionViewChromes.scss   | 113 ++++++++-
 .../views/collections/CollectionViewChromes.tsx    | 261 ++++++++++++++++-----
 src/client/views/collections/KeyRestrictionRow.tsx |  45 ++++
 9 files changed, 428 insertions(+), 66 deletions(-)
 create mode 100644 src/client/views/collections/KeyRestrictionRow.tsx

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

diff --git a/package.json b/package.json
index 4a15cbb2f..37052fde3 100644
--- a/package.json
+++ b/package.json
@@ -136,6 +136,7 @@
         "image-size": "^0.7.4",
         "imagesloaded": "^4.1.4",
         "jquery-awesome-cursor": "^0.3.1",
+        "js-datepicker": "^4.6.6",
         "jsonwebtoken": "^8.5.0",
         "jsx-to-string": "^1.4.0",
         "lodash": "^4.17.11",
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index a5bb40243..bd00d47b9 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -116,7 +116,7 @@ export class EditableView extends React.Component<EditableProps> {
             return (
                 <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`}
                     style={{ display: this.props.display, height: "auto", maxHeight: `${this.props.height}` }}
-                    onClick={this.onClick} >
+                    onClick={this.onClick}>
                     <span style={{ fontStyle: this.props.fontStyle }}>{this.props.contents}</span>
                 </div>
             );
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 94a4835a1..69602deed 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -1,5 +1,5 @@
 import { IconName, library } from '@fortawesome/fontawesome-svg-core';
-import { faArrowDown, faCloudUploadAlt, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat } from '@fortawesome/free-solid-svg-icons';
+import { faArrowDown, faCaretUp, faLongArrowAltRight, faCloudUploadAlt, faArrowUp, faClone, faCheck, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faPortrait, faMusic, faObjectGroup, faPenNib, faRedoAlt, faTable, faThumbtack, faTree, faUndoAlt, faCat } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { action, computed, configure, observable, runInAction, reaction, trace } from 'mobx';
 import { observer } from 'mobx-react';
@@ -127,7 +127,9 @@ export class MainView extends React.Component {
         library.add(faCut);
         library.add(faCommentAlt);
         library.add(faThumbtack);
+        library.add(faLongArrowAltRight);
         library.add(faCheck);
+        library.add(faCaretUp);
         library.add(faArrowDown);
         library.add(faArrowUp);
         library.add(faCloudUploadAlt);
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e4e6f92e3..a78a47ffb 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -249,6 +249,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return false;
     }
 
+    sortFunc = (a: [SchemaHeaderField, Doc[]], b: [SchemaHeaderField, Doc[]]): 1 | -1 => {
+        let descending = BoolCast(this.props.Document.stackingHeadersSortDescending);
+        let firstEntry = descending ? b : a;
+        let secondEntry = descending ? a : b;
+        return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1;
+    }
+
     render() {
         let headings = Array.from(this.Sections.keys());
         let editableViewProps = {
@@ -264,7 +271,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                     ["width > height", this.filteredChildren.filter(f => f[WidthSym]() >= 1 + f[HeightSym]())],
                     ["width = height", this.filteredChildren.filter(f => Math.abs(f[WidthSym]() - f[HeightSym]()) < 1)],
                     ["height > width", this.filteredChildren.filter(f => f[WidthSym]() + 1 <= f[HeightSym]())]]. */}
-                {this.props.Document.sectionFilter ? Array.from(this.Sections.entries()).sort((a, b) => a[0].toString() > b[0].toString() ? 1 : -1).
+                {this.props.Document.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc).
                     map(section => this.section(section[0], section[1] as Doc[])) :
                     this.section(undefined, this.filteredChildren)}
                 {this.props.Document.sectionFilter ?
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index fe24c63c7..582adc418 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -16,6 +16,8 @@ import "./CollectionStackingView.scss";
 import { Docs } from "../../documents/Documents";
 import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { ScriptField } from "../../../new_fields/ScriptField";
+import { CompileScript } from "../../util/Scripting";
 
 
 interface CSVFieldColumnProps {
@@ -35,6 +37,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
 
     private _dropRef: HTMLDivElement | null = null;
     private dropDisposer?: DragManager.DragDropDisposer;
+    private _headerRef: React.RefObject<HTMLDivElement> = React.createRef();
 
     @observable _heading = this.props.headingObject ? this.props.headingObject.heading : this.props.heading;
 
@@ -182,6 +185,43 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         }
     }
 
+    startDrag = (e: PointerEvent) => {
+        let alias = Doc.MakeAlias(this.props.parent.props.Document);
+        let key = StrCast(this.props.parent.props.Document.sectionFilter);
+        let value = this.getValue(this._heading);
+        value = typeof value === "string" ? `"${value}"` : value;
+        let script = `return doc.${key} === ${value}`;
+        let compiled = CompileScript(script, { params: { doc: Doc.name } });
+        if (compiled.compiled) {
+            let scriptField = new ScriptField(compiled);
+            alias.viewSpecScript = scriptField;
+            let dragData = new DragManager.DocumentDragData([alias], [alias.proto]);
+            DragManager.StartDocumentDrag([this._headerRef.current!], dragData, e.clientX, e.clientY);
+        }
+
+        e.stopPropagation();
+        document.removeEventListener("pointermove", this.startDrag);
+        document.removeEventListener("pointerup", this.pointerUp);
+    }
+
+    pointerUp = (e: PointerEvent) => {
+        e.stopPropagation();
+        e.preventDefault();
+
+        document.removeEventListener("pointermove", this.startDrag);
+        document.removeEventListener("pointerup", this.pointerUp);
+    }
+
+    headerDown = (e: React.PointerEvent<HTMLDivElement>) => {
+        e.stopPropagation();
+        e.preventDefault();
+
+        document.removeEventListener("pointermove", this.startDrag);
+        document.addEventListener("pointermove", this.startDrag);
+        document.removeEventListener("pointerup", this.pointerUp);
+        document.addEventListener("pointerup", this.pointerUp);
+    }
+
     render() {
         let cols = this.props.cols();
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
@@ -199,11 +239,11 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             oneLine: true
         }
         let headingView = this.props.headingObject ?
-            <div key={heading} className="collectionStackingView-sectionHeader"
+            <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
                 style={{ width: (style.columnWidth) / (uniqueHeadings.length + 1) }}>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
                     Further, it does not have a color and cannot be deleted. */}
-                <div className="collectionStackingView-sectionHeader-subCont"
+                <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
                     title={evContents === `No ${key} value` ?
                         `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
                     style={{
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 2ddefb3c0..24c8adb35 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -21,6 +21,8 @@ import { CollectionView } from "./CollectionView";
 import React = require("react");
 import { MainView } from "../MainView";
 import { Utils } from "../../../Utils";
+import { ScriptField } from "../../../new_fields/ScriptField";
+import { CompileScript } from "../../util/Scripting";
 
 export interface CollectionViewProps extends FieldViewProps {
     addDocument: (document: Doc, allowDuplicates?: boolean) => boolean;
@@ -54,7 +56,18 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
             let self = this;
             //TODO tfs: This might not be what we want?
             //This linter error can't be fixed because of how js arguments work, so don't switch this to filter(FieldValue)
-            return DocListCast(this.extensionDoc[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey]);
+            let docs = DocListCast(this.extensionDoc[this.props.fieldExt ? this.props.fieldExt : this.props.fieldKey]);
+            let viewSpecScript = Cast(this.props.Document.viewSpecScript, ScriptField);
+            if (viewSpecScript) {
+                let script = viewSpecScript.script;
+                docs = docs.filter(d => {
+                    let res = script.run({ doc: d });
+                    if (res.success) {
+                        return res.result;
+                    }
+                });
+            }
+            return docs;
         }
         get childDocList() {
             //TODO tfs: This might not be what we want?
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index e5cb1b546..3103cd309 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -1,12 +1,120 @@
 @import "../globalCssVariables";
+@import '~js-datepicker/dist/datepicker.min.css';
+
+.collectionViewBaseChrome {
+    display: flex;
+
+    .collectionViewBaseChrome-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;
+    }
+
+    .collectionViewBaseChrome-viewPicker:active {
+        outline-color: black;
+    }
+
+    .collectionViewBaseChrome-collapse {
+        margin-right: 10px;
+        transition: all .5s;
+    }
+
+    .collectionViewBaseChrome-viewSpecs {
+        margin-left: 10px;
+        display: grid;
+
+        .collectionViewBaseChrome-viewSpecsInput {
+            padding: 12px 10px 11px 10px;
+            border: 0px;
+            color: grey;
+            text-align: center;
+            text-transform: uppercase;
+            letter-spacing: 2px;
+            outline-color: black;
+            font-size: 75%;
+            background: rgb(238, 238, 238);
+            height: 100%;
+            width: 150px;
+        }
+
+        .collectionViewBaseChrome-viewSpecsMenu {
+            overflow: hidden;
+            transition: height .5s, display .5s;
+            position: absolute;
+            top: 60px;
+            z-index: 100;
+            display: flex;
+            flex-direction: column;
+            background: rgb(238, 238, 238);
+            box-shadow: grey 2px 2px 4px;
+
+            .qs-datepicker {
+                left: unset;
+                right: 0;
+            }
+
+            .collectionViewBaseChrome-viewSpecsMenu-row {
+                display: grid;
+                grid-template-columns: 150px 200px 150px;
+                margin-top: 10px;
+                margin-right: 10px;
+
+                .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
+                .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
+                .collectionViewBaseChrome-viewSpecsMenu-rowRight {
+                    font-size: 75%;
+                    letter-spacing: 2px;
+                    color: grey;
+                    margin-left: 10px;
+                    padding: 5px;
+                    border: none;
+                    outline-color: black;
+                }
+            }
+
+            .collectionViewBaseChrome-viewSpecsMenu-lastRow {
+                display: grid;
+                grid-template-columns: 1fr 1fr;
+                grid-gap: 10px;
+                margin: 10px;
+            }
+        }
+    }
+}
 
 .collectionStackingViewChrome {
     display: grid;
-    grid-template-columns: 1fr 1fr;
+    grid-template-columns: 1fr auto;
     padding-bottom: 10px;
     border-bottom: .5px solid lightgrey;
     margin: 10px;
 
+    .collectionStackingViewChrome-cont {
+        display: flex;
+        justify-content: space-between;
+    }
+
+    .collectionStackingViewChrome-sort {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+
+        .collectionStackingViewChrome-sortIcon {
+            transition: transform .5s;
+            margin-left: 10px;
+        }
+    }
+
+    button:hover {
+        transform: scale(1);
+    }
+
+
     .collectionStackingViewChrome-sectionFilter-cont {
         justify-self: right;
         display: flex;
@@ -21,10 +129,9 @@
 
         .collectionStackingViewChrome-sectionFilter {
             color: white;
-            width: fit-content;
+            width: 100px;
             text-align: center;
             background: rgb(238, 238, 238);
-            height: 37px;
 
             .editable-view-input,
             input,
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 52fee26bf..2edac384d 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -3,55 +3,189 @@ import { CollectionView } from "./CollectionView";
 import "./CollectionViewChromes.scss";
 import { CollectionViewType } from "./CollectionBaseView";
 import { undoBatch } from "../../util/UndoManager";
-import { action, observable, runInAction, computed } from "mobx";
+import { action, observable, runInAction, computed, IObservable, IObservableValue } from "mobx";
 import { observer } from "mobx-react";
 import { Doc, DocListCast } from "../../../new_fields/Doc";
 import { DocLike } from "../MetadataEntryMenu";
-const higflyout = require("@hig/flyout");
-export const Flyout = higflyout.default;
 import * as Autosuggest from 'react-autosuggest';
 import { EditableView } from "../EditableView";
-import { StrCast } from "../../../new_fields/Types";
+import { StrCast, NumCast, BoolCast, Cast } from "../../../new_fields/Types";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { Utils } from "../../../Utils";
+import KeyRestrictionRow from "./KeyRestrictionRow";
+import { CompileScript } from "../../util/Scripting";
+import { ScriptField } from "../../../new_fields/ScriptField";
+const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
     CollectionView: CollectionView;
 }
 
+let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
+
+@observer
 class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
+    @observable private _viewSpecsOpen: boolean = false;
+    @observable private _dateWithinValue: string = "";
+    @observable private _dateValue: Date = new Date();
+    @observable private _keyRestrictions: [JSX.Element, string][] = [];
+    @computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
+
+    private _picker: any;
+    private _datePickerElGuid = Utils.GenerateGuid();
+
+    componentDidMount = () => {
+        this._picker = datepicker("#" + this._datePickerElGuid, {
+            disabler: (date: Date) => date > new Date(),
+            onSelect: (instance: any, date: Date) => runInAction(() => this._dateValue = date),
+            dateSelected: new Date()
+        });
+
+        runInAction(() => {
+            this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[0][1] = value)} />, ""]);
+            this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={false} script={(value: string) => runInAction(() => this._keyRestrictions[1][1] = value)} />, ""]);
+        });
+    }
+
     @undoBatch
     viewChanged = (e: React.ChangeEvent) => {
         //@ts-ignore
-        switch (e.target.selectedOptions[0].value) {
-            case "freeform":
-                this.props.CollectionView.props.Document.viewType = CollectionViewType.Freeform;
-                break;
-            case "schema":
-                this.props.CollectionView.props.Document.viewType = CollectionViewType.Schema;
-                break;
-            case "treeview":
-                this.props.CollectionView.props.Document.viewType = CollectionViewType.Tree;
-                break;
-            case "stacking":
-                this.props.CollectionView.props.Document.viewType = CollectionViewType.Stacking;
-                break;
-            case "masonry":
-                this.props.CollectionView.props.Document.viewType = CollectionViewType.Masonry;
-                break;
-            default:
-                break;
+        this.props.CollectionView.props.Document.viewType = parseInt(e.target.selectedOptions[0].value);
+    }
+
+    @action
+    openViewSpecs = (e: React.SyntheticEvent) => {
+        this._viewSpecsOpen = true;
+
+        //@ts-ignore
+        if (!e.target.classList[0].startsWith("qs")) {
+            this.closeDatePicker();
+        }
+
+        e.stopPropagation();
+        document.removeEventListener("pointerdown", this.closeViewSpecs);
+        document.addEventListener("pointerdown", this.closeViewSpecs);
+    }
+
+    @action closeViewSpecs = () => { this._viewSpecsOpen = false; document.removeEventListener("pointerdown", this.closeViewSpecs); };
+
+    @action
+    openDatePicker = (e: React.PointerEvent) => {
+        this.openViewSpecs(e);
+        if (this._picker) {
+            this._picker.alwaysShow = true;
+            this._picker.show();
+            // TODO: calendar is offset when zoomed in/out
+            // this._picker.calendar.style.position = "absolute";
+            // let transform = this.props.CollectionView.props.ScreenToLocalTransform();
+            // let x = parseInt(this._picker.calendar.style.left) / transform.Scale;
+            // let y = parseInt(this._picker.calendar.style.top) / transform.Scale;
+            // this._picker.calendar.style.left = x;
+            // this._picker.calendar.style.top = y;
+
+            e.stopPropagation();
         }
     }
 
+    @action
+    addKeyRestriction = (e: React.MouseEvent) => {
+        let index = this._keyRestrictions.length;
+        this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[index][1] = value)} />, ""]);
+
+        this.openViewSpecs(e);
+    }
+
+    @action
+    applyFilter = (e: React.MouseEvent) => {
+        this.openViewSpecs(e);
+
+        let keyRestrictionScript = `${this._keyRestrictions.map(i => i[1])
+            .reduce((acc: string, value: string, i: number) => value ? `${acc} && ${value}` : acc)}`;
+        let yearOffset = this._dateWithinValue[1] === 'y' ? 1 : 0;
+        let monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0;
+        let weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0;
+        let dayOffset = (this._dateWithinValue[1] === 'd' ? parseInt(this._dateWithinValue[0]) : 0) + weekOffset * 7;
+        let lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset);
+        let upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1);
+        let dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`;
+        let fullScript = `return ${dateRestrictionScript} && ${keyRestrictionScript}`;
+        let compiled = CompileScript(fullScript, { params: { doc: Doc.name } });
+        if (compiled.compiled) {
+            this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
+        }
+    }
+
+    @action
+    closeDatePicker = () => {
+        if (this._picker) {
+            this._picker.alwaysShow = false;
+            this._picker.hide();
+        }
+        document.removeEventListener("pointerdown", this.closeDatePicker);
+    }
+
     render() {
         return (
             <div className="collectionViewBaseChrome">
-                <select onChange={this.viewChanged}>
-                    <option value="freeform" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Freeform}>Freeform View</option>
-                    <option value="schema" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Schema}>Schema View</option>
-                    <option value="treeview" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Tree}>Tree View</option>
-                    <option value="stacking" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Stacking}>Stacking View</option>
-                    <option value="masonry" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Masonry}>Masonry View</option>
+                <button className="collectionViewBaseChrome-collapse" title="Collapse collection chrome">
+                    <FontAwesomeIcon icon="caret-up" size="2x" />
+                </button>
+                <select
+                    className="collectionViewBaseChrome-viewPicker"
+                    onPointerDown={stopPropagation}
+                    onChange={this.viewChanged}
+                    value={NumCast(this.props.CollectionView.props.Document.viewType)}>
+                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="1">Freeform View</option>
+                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
+                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
+                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
+                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View></option>
                 </select>
+                <div className="collectionViewBaseChrome-viewSpecs">
+                    <input className="collectionViewBaseChrome-viewSpecsInput"
+                        placeholder="Filter Documents"
+                        value={this.filterValue ? this.filterValue.script.originalScript : ""}
+                        onPointerDown={this.openViewSpecs} />
+                    <div className="collectionViewBaseChrome-viewSpecsMenu"
+                        onPointerDown={this.openViewSpecs}
+                        style={{
+                            height: this._viewSpecsOpen ? "fit-content" : "0px",
+                            overflow: this._viewSpecsOpen ? "initial" : "hidden"
+                        }}>
+                        {this._keyRestrictions.map(i => i[0])}
+                        <div className="collectionViewBaseChrome-viewSpecsMenu-row">
+                            <div className="collectionViewBaseChrome-viewSpecsMenu-rowLeft">
+                                CREATED WITHIN:
+                            </div>
+                            <select className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
+                                style={{ textTransform: "uppercase", textAlign: "center" }}
+                                value={this._dateWithinValue}
+                                onChange={(e) => runInAction(() => this._dateWithinValue = e.target.value)}>
+                                <option value="1d">1 day of</option>
+                                <option value="3d">3 days of</option>
+                                <option value="1w">1 week of</option>
+                                <option value="2w">2 weeks of</option>
+                                <option value="1m">1 month of</option>
+                                <option value="2m">2 months of</option>
+                                <option value="6m">6 months of</option>
+                                <option value="1y">1 year of</option>
+                            </select>
+                            <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
+                                id={this._datePickerElGuid}
+                                value={this._dateValue.toLocaleDateString()}
+                                onPointerDown={this.openDatePicker}
+                                placeholder="Value" />
+                        </div>
+                        <div className="collectionViewBaseChrome-viewSpecsMenu-lastRow">
+                            <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}>
+                                ADD KEY RESTRICTION
+                            </button>
+                            <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
+                                APPLY FILTER
+                            </button>
+                        </div>
+                    </div>
+                </div>
             </div>
         )
     }
@@ -62,6 +196,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
     @observable private _currentKey: string = "";
     @observable private suggestions: string[] = [];
 
+    @computed private get descending() { return BoolCast(this.props.CollectionView.props.Document.stackingHeadersSortDescending); }
     @computed get sectionFilter() { return StrCast(this.props.CollectionView.props.Document.sectionFilter); }
 
     getKeySuggestions = async (value: string): Promise<string[]> => {
@@ -109,41 +244,53 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
         return true;
     }
 
+    @action toggleSort = () => { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; }
     @action resetValue = () => { this._currentKey = this.sectionFilter; };
 
     render() {
         return (
             <div className="collectionStackingViewChrome">
                 <CollectionViewBaseChrome CollectionView={this.props.CollectionView} />
-                <div className="collectionStackingViewChrome-sectionFilter-cont">
-                    <div className="collectionStackingViewChrome-sectionFilter-label">
-                        Group items by:
-                    </div>
-                    <div className="collectionStackingViewChrome-sectionFilter">
-                        <EditableView
-                            GetValue={() => this.sectionFilter}
-                            autosuggestProps={
-                                {
-                                    resetValue: this.resetValue,
-                                    value: this._currentKey,
-                                    onChange: this.onKeyChange,
-                                    autosuggestProps: {
-                                        inputProps:
-                                        {
-                                            value: this._currentKey,
-                                            onChange: this.onKeyChange
-                                        },
-                                        getSuggestionValue: this.getSuggestionValue,
-                                        suggestions: this.suggestions,
-                                        alwaysRenderSuggestions: true,
-                                        renderSuggestion: this.renderSuggestion,
-                                        onSuggestionsFetchRequested: this.onSuggestionFetch,
-                                        onSuggestionsClearRequested: this.onSuggestionClear
-                                    }
-                                }}
-                            SetValue={this.setValue}
-                            contents={this.sectionFilter ? this.sectionFilter : "N/A"}
-                        />
+                <div className="collectionStackingViewChrome-cont">
+                    <button className="collectionStackingViewChrome-sort" onClick={this.toggleSort}>
+                        <div className="collectionStackingViewChrome-sortLabel">
+                            Sort
+                        </div>
+                        <div className="collectionStackingViewChrome-sortIcon" style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}>
+                            <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
+                        </div>
+                    </button>
+                    <div className="collectionStackingViewChrome-sectionFilter-cont">
+                        <div className="collectionStackingViewChrome-sectionFilter-label">
+                            Group items by:
+                        </div>
+                        <div className="collectionStackingViewChrome-sectionFilter">
+                            <EditableView
+                                GetValue={() => this.sectionFilter}
+                                autosuggestProps={
+                                    {
+                                        resetValue: this.resetValue,
+                                        value: this._currentKey,
+                                        onChange: this.onKeyChange,
+                                        autosuggestProps: {
+                                            inputProps:
+                                            {
+                                                value: this._currentKey,
+                                                onChange: this.onKeyChange
+                                            },
+                                            getSuggestionValue: this.getSuggestionValue,
+                                            suggestions: this.suggestions,
+                                            alwaysRenderSuggestions: true,
+                                            renderSuggestion: this.renderSuggestion,
+                                            onSuggestionsFetchRequested: this.onSuggestionFetch,
+                                            onSuggestionsClearRequested: this.onSuggestionClear
+                                        }
+                                    }}
+                                oneLine
+                                SetValue={this.setValue}
+                                contents={this.sectionFilter ? this.sectionFilter : "N/A"}
+                            />
+                        </div>
                     </div>
                 </div>
             </div>
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
new file mode 100644
index 000000000..8051a8359
--- /dev/null
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -0,0 +1,45 @@
+import * as React from "react";
+import { observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+
+interface IKeyRestrictionProps {
+    contains: boolean;
+    script: (value: string) => void;
+}
+
+@observer
+export default class KeyRestrictionRow extends React.Component<IKeyRestrictionProps> {
+    @observable private _key = "";
+    @observable private _value = "";
+    @observable private _contains = this.props.contains;
+
+    render() {
+        if (this._key && this._value) {
+            let parsedValue: string | number = `"${this._value}"`;
+            let parsed = parseInt(this._value);
+            if (!isNaN(parsed)) {
+                parsedValue = parsed;
+            }
+            let scriptText = `(doc.${this._key} ${this._contains ? "===" : "!=="} ${parsedValue})`;
+            this.props.script(scriptText);
+        }
+        return (
+            <div className="collectionViewBaseChrome-viewSpecsMenu-row">
+                <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
+                    value={this._key}
+                    onChange={(e) => runInAction(() => this._key = e.target.value)}
+                    placeholder="KEY" />
+                <button className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
+                    style={{ background: PastelSchemaPalette.get(this._contains ? "green" : "red") }}
+                    onClick={() => runInAction(() => this._contains = !this._contains)}>
+                    {this._contains ? "CONTAINS" : "DOES NOT CONTAIN"}
+                </button>
+                <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
+                    value={this._value}
+                    onChange={(e) => runInAction(() => this._value = e.target.value)}
+                    placeholder="VALUE" />
+            </div>
+        )
+    }
+}
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From ede0719d96cc2551490398caf3e1f41fe7992931 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Wed, 24 Jul 2019 22:27:37 -0400
Subject: view specs almost entirely done, refactored some chrome impl

---
 .../views/collections/CollectionStackingView.scss  |   1 +
 .../views/collections/CollectionStackingView.tsx   |   6 +-
 src/client/views/collections/CollectionSubView.tsx |   1 +
 src/client/views/collections/CollectionView.tsx    |  42 ++--
 .../views/collections/CollectionViewChromes.scss   | 156 +++++++--------
 .../views/collections/CollectionViewChromes.tsx    | 214 ++++++++++++---------
 6 files changed, 227 insertions(+), 193 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index e0ced8af4..f43340967 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -7,6 +7,7 @@
     display: flex;
     overflow-y: auto;
     flex-wrap: wrap;
+    transition: top .5s;
 
     .collectionStackingView-docView-container {
         width: 45%;
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index a78a47ffb..31ec80d76 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -8,7 +8,7 @@ import { BoolCast, NumCast, Cast, StrCast, FieldValue } from "../../../new_field
 import { emptyFunction, Utils } from "../../../Utils";
 import { CollectionSchemaPreview } from "./CollectionSchemaView";
 import "./CollectionStackingView.scss";
-import { CollectionSubView } from "./CollectionSubView";
+import { CollectionSubView, SubCollectionViewProps } from "./CollectionSubView";
 import { undoBatch } from "../../util/UndoManager";
 import { DragManager } from "../../util/DragManager";
 import { DocumentType } from "../../documents/Documents";
@@ -19,6 +19,7 @@ import { listSpec } from "../../../new_fields/Schema";
 import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { List } from "../../../new_fields/List";
 import { EditableView } from "../EditableView";
+import { CollectionViewProps } from "./CollectionBaseView";
 
 let valuesCreated = 1;
 
@@ -32,6 +33,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _columnStart: number = 0;
     @observable private cursor: CursorProperty = "grab";
     get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
+    get chromeCollapsed() { return this.props.chromeCollapsed; }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
@@ -265,7 +267,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         }
         // let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
         return (
-            <div className="collectionStackingView"
+            <div className="collectionStackingView" style={{ top: this.chromeCollapsed ? 0 : 100 }}
                 ref={this.createRef} onDrop={this.onDrop.bind(this)} onWheel={(e: React.WheelEvent) => e.stopPropagation()} >
                 {/* {sectionFilter as boolean ? [
                     ["width > height", this.filteredChildren.filter(f => f[WidthSym]() >= 1 + f[HeightSym]())],
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 24c8adb35..98447e824 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -30,6 +30,7 @@ export interface CollectionViewProps extends FieldViewProps {
     moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
     PanelWidth: () => number;
     PanelHeight: () => number;
+    chromeCollapsed: boolean;
 }
 
 export interface SubCollectionViewProps extends CollectionViewProps {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index ba9780c24..e2f652908 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -17,7 +17,8 @@ import { CollectionStackingView } from './CollectionStackingView';
 import { CollectionTreeView } from "./CollectionTreeView";
 import { StrCast, PromiseValue } from '../../../new_fields/Types';
 import { DocumentType } from '../../documents/Documents';
-import { CollectionStackingViewChrome } from './CollectionViewChromes';
+import { CollectionStackingViewChrome, CollectionViewBaseChrome } from './CollectionViewChromes';
+import { observable } from 'mobx';
 export const COLLECTION_BORDER_WIDTH = 2;
 
 library.add(faTh);
@@ -32,40 +33,39 @@ library.add(faImage);
 
 @observer
 export class CollectionView extends React.Component<FieldViewProps> {
+    @observable private _collapsed = false;
+
     public static LayoutString(fieldStr: string = "data", fieldExt: string = "") { return FieldView.LayoutString(CollectionView, fieldStr, fieldExt); }
 
     private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
         let props = { ...this.props, ...renderProps };
         switch (this.isAnnotationOverlay ? CollectionViewType.Freeform : type) {
-            case CollectionViewType.Schema: return (<CollectionSchemaView key="collview" {...props} CollectionView={this} />);
-            case CollectionViewType.Docking: return (<CollectionDockingView key="collview" {...props} CollectionView={this} />);
-            case CollectionViewType.Tree: return (<CollectionTreeView key="collview" {...props} CollectionView={this} />);
-            case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView key="collview" {...props} CollectionView={this} />); }
-            case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView key="collview" {...props} CollectionView={this} />); }
+            case CollectionViewType.Schema: return (<CollectionSchemaView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
+            case CollectionViewType.Docking: return (<CollectionDockingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
+            case CollectionViewType.Tree: return (<CollectionTreeView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
+            case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
+            case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
             case CollectionViewType.Freeform:
             default:
-                return (<CollectionFreeFormView key="collview" {...props} CollectionView={this} />);
+                return (<CollectionFreeFormView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
         }
         return (null);
     }
 
-    private Chrome = (type: CollectionViewType) => {
-        if (this.isAnnotationOverlay || this.props.Document === CurrentUserUtils.UserDocument.sidebar) {
-            return (null);
-        }
-
-        switch (type) {
-            case CollectionViewType.Stacking: return (<CollectionStackingViewChrome key="collchrome" CollectionView={this} />);
-            default:
-                return null;
-        }
+    private collapse = (value: boolean) => {
+        this._collapsed = value;
     }
 
     private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
-        return [
-            this.Chrome(type),
-            this.SubViewHelper(type, renderProps)
-        ]
+        if (this.isAnnotationOverlay || this.props.Document === CurrentUserUtils.UserDocument.sidebar) {
+            return [(null), this.SubViewHelper(type, renderProps)];
+        }
+        else {
+            return [
+                (<CollectionViewBaseChrome CollectionView={this} type={type} collapse={this.collapse} />),
+                this.SubViewHelper(type, renderProps)
+            ];
+        }
     }
 
     get isAnnotationOverlay() { return this.props.fieldExt ? true : false; }
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 3103cd309..d37228bde 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -1,98 +1,104 @@
 @import "../globalCssVariables";
 @import '~js-datepicker/dist/datepicker.min.css';
 
-.collectionViewBaseChrome {
-    display: flex;
-
-    .collectionViewBaseChrome-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;
-    }
-
-    .collectionViewBaseChrome-viewPicker:active {
-        outline-color: black;
-    }
-
-    .collectionViewBaseChrome-collapse {
-        margin-right: 10px;
-        transition: all .5s;
-    }
+.collectionViewChrome {
+    display: grid;
+    grid-template-columns: 1fr auto;
+    padding-bottom: 10px;
+    border-bottom: .5px solid lightgrey;
+    margin: 10px;
+    position: relative;
+    z-index: 9001;
+    transition: top .5s;
 
-    .collectionViewBaseChrome-viewSpecs {
-        margin-left: 10px;
-        display: grid;
+    .collectionViewBaseChrome {
+        display: flex;
 
-        .collectionViewBaseChrome-viewSpecsInput {
-            padding: 12px 10px 11px 10px;
-            border: 0px;
-            color: grey;
-            text-align: center;
+        .collectionViewBaseChrome-viewPicker {
+            font-size: 75%;
             text-transform: uppercase;
             letter-spacing: 2px;
-            outline-color: black;
-            font-size: 75%;
             background: rgb(238, 238, 238);
-            height: 100%;
-            width: 150px;
+            color: grey;
+            outline-color: black;
+            border: none;
+            padding: 12px 10px 11px 10px;
+            margin-left: 50px;
         }
 
-        .collectionViewBaseChrome-viewSpecsMenu {
-            overflow: hidden;
-            transition: height .5s, display .5s;
+        .collectionViewBaseChrome-viewPicker:active {
+            outline-color: black;
+        }
+
+        .collectionViewBaseChrome-collapse {
+            transition: all .5s;
             position: absolute;
-            top: 60px;
-            z-index: 100;
-            display: flex;
-            flex-direction: column;
-            background: rgb(238, 238, 238);
-            box-shadow: grey 2px 2px 4px;
+            width: 40px;
+        }
+
+        .collectionViewBaseChrome-viewSpecs {
+            margin-left: 10px;
+            display: grid;
 
-            .qs-datepicker {
-                left: unset;
-                right: 0;
+            .collectionViewBaseChrome-viewSpecsInput {
+                padding: 12px 10px 11px 10px;
+                border: 0px;
+                color: grey;
+                text-align: center;
+                text-transform: uppercase;
+                letter-spacing: 2px;
+                outline-color: black;
+                font-size: 75%;
+                background: rgb(238, 238, 238);
+                height: 100%;
+                width: 150px;
             }
 
-            .collectionViewBaseChrome-viewSpecsMenu-row {
-                display: grid;
-                grid-template-columns: 150px 200px 150px;
-                margin-top: 10px;
-                margin-right: 10px;
-
-                .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
-                .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
-                .collectionViewBaseChrome-viewSpecsMenu-rowRight {
-                    font-size: 75%;
-                    letter-spacing: 2px;
-                    color: grey;
-                    margin-left: 10px;
-                    padding: 5px;
-                    border: none;
-                    outline-color: black;
+            .collectionViewBaseChrome-viewSpecsMenu {
+                overflow: hidden;
+                transition: height .5s, display .5s;
+                position: absolute;
+                top: 60px;
+                z-index: 100;
+                display: flex;
+                flex-direction: column;
+                background: rgb(238, 238, 238);
+                box-shadow: grey 2px 2px 4px;
+
+                .qs-datepicker {
+                    left: unset;
+                    right: 0;
+                }
+
+                .collectionViewBaseChrome-viewSpecsMenu-row {
+                    display: grid;
+                    grid-template-columns: 150px 200px 150px;
+                    margin-top: 10px;
+                    margin-right: 10px;
+
+                    .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
+                    .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
+                    .collectionViewBaseChrome-viewSpecsMenu-rowRight {
+                        font-size: 75%;
+                        letter-spacing: 2px;
+                        color: grey;
+                        margin-left: 10px;
+                        padding: 5px;
+                        border: none;
+                        outline-color: black;
+                    }
                 }
-            }
 
-            .collectionViewBaseChrome-viewSpecsMenu-lastRow {
-                display: grid;
-                grid-template-columns: 1fr 1fr;
-                grid-gap: 10px;
-                margin: 10px;
+                .collectionViewBaseChrome-viewSpecsMenu-lastRow {
+                    display: grid;
+                    grid-template-columns: 1fr 1fr;
+                    grid-gap: 10px;
+                    margin: 10px;
+                }
             }
         }
     }
-}
 
-.collectionStackingViewChrome {
-    display: grid;
-    grid-template-columns: 1fr auto;
-    padding-bottom: 10px;
-    border-bottom: .5px solid lightgrey;
-    margin: 10px;
 
     .collectionStackingViewChrome-cont {
         display: flex;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 2edac384d..24d13d5cb 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -19,16 +19,19 @@ const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
     CollectionView: CollectionView;
+    type: CollectionViewType;
+    collapse?: (value: boolean) => any;
 }
 
 let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
 
 @observer
-class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
+export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
     @observable private _viewSpecsOpen: boolean = false;
     @observable private _dateWithinValue: string = "";
     @observable private _dateValue: Date = new Date();
     @observable private _keyRestrictions: [JSX.Element, string][] = [];
+    @observable private _collapsed: boolean = false;
     @computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
 
     private _picker: any;
@@ -124,68 +127,92 @@ class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps
         document.removeEventListener("pointerdown", this.closeDatePicker);
     }
 
+    @action
+    toggleCollapse = () => {
+        this._collapsed = !this._collapsed;
+        this.props.collapse(this._collapsed);
+    }
+
+    subChrome = () => {
+
+        switch (this.props.type) {
+            case CollectionViewType.Stacking: return (
+                <CollectionStackingViewChrome
+                    key="collchrome"
+                    CollectionView={this.props.CollectionView}
+                    type={this.props.type} />);
+            default:
+                return null;
+        }
+    }
+
     render() {
         return (
-            <div className="collectionViewBaseChrome">
-                <button className="collectionViewBaseChrome-collapse" title="Collapse collection chrome">
-                    <FontAwesomeIcon icon="caret-up" size="2x" />
-                </button>
-                <select
-                    className="collectionViewBaseChrome-viewPicker"
-                    onPointerDown={stopPropagation}
-                    onChange={this.viewChanged}
-                    value={NumCast(this.props.CollectionView.props.Document.viewType)}>
-                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="1">Freeform View</option>
-                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
-                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
-                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
-                    <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View></option>
-                </select>
-                <div className="collectionViewBaseChrome-viewSpecs">
-                    <input className="collectionViewBaseChrome-viewSpecsInput"
-                        placeholder="Filter Documents"
-                        value={this.filterValue ? this.filterValue.script.originalScript : ""}
-                        onPointerDown={this.openViewSpecs} />
-                    <div className="collectionViewBaseChrome-viewSpecsMenu"
-                        onPointerDown={this.openViewSpecs}
-                        style={{
-                            height: this._viewSpecsOpen ? "fit-content" : "0px",
-                            overflow: this._viewSpecsOpen ? "initial" : "hidden"
-                        }}>
-                        {this._keyRestrictions.map(i => i[0])}
-                        <div className="collectionViewBaseChrome-viewSpecsMenu-row">
-                            <div className="collectionViewBaseChrome-viewSpecsMenu-rowLeft">
-                                CREATED WITHIN:
+            <div className="collectionViewChrome" style={{ top: this._collapsed ? -100 : 0 }}>
+                <div className="collectionViewBaseChrome">
+                    <button className="collectionViewBaseChrome-collapse"
+                        style={{ top: this._collapsed ? 80 : 0, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
+                        title="Collapse collection chrome" onClick={this.toggleCollapse}>
+                        <FontAwesomeIcon icon="caret-up" size="2x" />
+                    </button>
+                    <select
+                        className="collectionViewBaseChrome-viewPicker"
+                        onPointerDown={stopPropagation}
+                        onChange={this.viewChanged}
+                        value={NumCast(this.props.CollectionView.props.Document.viewType)}>
+                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="1">Freeform View</option>
+                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
+                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
+                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
+                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View></option>
+                    </select>
+                    <div className="collectionViewBaseChrome-viewSpecs">
+                        <input className="collectionViewBaseChrome-viewSpecsInput"
+                            placeholder="Filter Documents"
+                            value={this.filterValue ? this.filterValue.script.originalScript : ""}
+                            onPointerDown={this.openViewSpecs} />
+                        <div className="collectionViewBaseChrome-viewSpecsMenu"
+                            onPointerDown={this.openViewSpecs}
+                            style={{
+                                height: this._viewSpecsOpen ? "fit-content" : "0px",
+                                overflow: this._viewSpecsOpen ? "initial" : "hidden"
+                            }}>
+                            {this._keyRestrictions.map(i => i[0])}
+                            <div className="collectionViewBaseChrome-viewSpecsMenu-row">
+                                <div className="collectionViewBaseChrome-viewSpecsMenu-rowLeft">
+                                    CREATED WITHIN:
                             </div>
-                            <select className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
-                                style={{ textTransform: "uppercase", textAlign: "center" }}
-                                value={this._dateWithinValue}
-                                onChange={(e) => runInAction(() => this._dateWithinValue = e.target.value)}>
-                                <option value="1d">1 day of</option>
-                                <option value="3d">3 days of</option>
-                                <option value="1w">1 week of</option>
-                                <option value="2w">2 weeks of</option>
-                                <option value="1m">1 month of</option>
-                                <option value="2m">2 months of</option>
-                                <option value="6m">6 months of</option>
-                                <option value="1y">1 year of</option>
-                            </select>
-                            <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
-                                id={this._datePickerElGuid}
-                                value={this._dateValue.toLocaleDateString()}
-                                onPointerDown={this.openDatePicker}
-                                placeholder="Value" />
-                        </div>
-                        <div className="collectionViewBaseChrome-viewSpecsMenu-lastRow">
-                            <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}>
-                                ADD KEY RESTRICTION
+                                <select className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
+                                    style={{ textTransform: "uppercase", textAlign: "center" }}
+                                    value={this._dateWithinValue}
+                                    onChange={(e) => runInAction(() => this._dateWithinValue = e.target.value)}>
+                                    <option value="1d">1 day of</option>
+                                    <option value="3d">3 days of</option>
+                                    <option value="1w">1 week of</option>
+                                    <option value="2w">2 weeks of</option>
+                                    <option value="1m">1 month of</option>
+                                    <option value="2m">2 months of</option>
+                                    <option value="6m">6 months of</option>
+                                    <option value="1y">1 year of</option>
+                                </select>
+                                <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
+                                    id={this._datePickerElGuid}
+                                    value={this._dateValue.toLocaleDateString()}
+                                    onPointerDown={this.openDatePicker}
+                                    placeholder="Value" />
+                            </div>
+                            <div className="collectionViewBaseChrome-viewSpecsMenu-lastRow">
+                                <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}>
+                                    ADD KEY RESTRICTION
                             </button>
-                            <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
-                                APPLY FILTER
+                                <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
+                                    APPLY FILTER
                             </button>
+                            </div>
                         </div>
                     </div>
                 </div>
+                {this.subChrome()}
             </div>
         )
     }
@@ -249,48 +276,45 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
 
     render() {
         return (
-            <div className="collectionStackingViewChrome">
-                <CollectionViewBaseChrome CollectionView={this.props.CollectionView} />
-                <div className="collectionStackingViewChrome-cont">
-                    <button className="collectionStackingViewChrome-sort" onClick={this.toggleSort}>
-                        <div className="collectionStackingViewChrome-sortLabel">
-                            Sort
-                        </div>
-                        <div className="collectionStackingViewChrome-sortIcon" style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}>
-                            <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
+            <div className="collectionStackingViewChrome-cont">
+                <button className="collectionStackingViewChrome-sort" onClick={this.toggleSort}>
+                    <div className="collectionStackingViewChrome-sortLabel">
+                        Sort
                         </div>
-                    </button>
-                    <div className="collectionStackingViewChrome-sectionFilter-cont">
-                        <div className="collectionStackingViewChrome-sectionFilter-label">
-                            Group items by:
-                        </div>
-                        <div className="collectionStackingViewChrome-sectionFilter">
-                            <EditableView
-                                GetValue={() => this.sectionFilter}
-                                autosuggestProps={
-                                    {
-                                        resetValue: this.resetValue,
-                                        value: this._currentKey,
-                                        onChange: this.onKeyChange,
-                                        autosuggestProps: {
-                                            inputProps:
-                                            {
-                                                value: this._currentKey,
-                                                onChange: this.onKeyChange
-                                            },
-                                            getSuggestionValue: this.getSuggestionValue,
-                                            suggestions: this.suggestions,
-                                            alwaysRenderSuggestions: true,
-                                            renderSuggestion: this.renderSuggestion,
-                                            onSuggestionsFetchRequested: this.onSuggestionFetch,
-                                            onSuggestionsClearRequested: this.onSuggestionClear
-                                        }
-                                    }}
-                                oneLine
-                                SetValue={this.setValue}
-                                contents={this.sectionFilter ? this.sectionFilter : "N/A"}
-                            />
+                    <div className="collectionStackingViewChrome-sortIcon" style={{ transform: `rotate(${this.descending ? "180" : "0"}deg)` }}>
+                        <FontAwesomeIcon icon="caret-up" size="2x" color="white" />
+                    </div>
+                </button>
+                <div className="collectionStackingViewChrome-sectionFilter-cont">
+                    <div className="collectionStackingViewChrome-sectionFilter-label">
+                        Group items by:
                         </div>
+                    <div className="collectionStackingViewChrome-sectionFilter">
+                        <EditableView
+                            GetValue={() => this.sectionFilter}
+                            autosuggestProps={
+                                {
+                                    resetValue: this.resetValue,
+                                    value: this._currentKey,
+                                    onChange: this.onKeyChange,
+                                    autosuggestProps: {
+                                        inputProps:
+                                        {
+                                            value: this._currentKey,
+                                            onChange: this.onKeyChange
+                                        },
+                                        getSuggestionValue: this.getSuggestionValue,
+                                        suggestions: this.suggestions,
+                                        alwaysRenderSuggestions: true,
+                                        renderSuggestion: this.renderSuggestion,
+                                        onSuggestionsFetchRequested: this.onSuggestionFetch,
+                                        onSuggestionsClearRequested: this.onSuggestionClear
+                                    }
+                                }}
+                            oneLine
+                            SetValue={this.setValue}
+                            contents={this.sectionFilter ? this.sectionFilter : "N/A"}
+                        />
                     </div>
                 </div>
             </div>
-- 
cgit v1.2.3-70-g09d2


From f8f3ee8df596758ca6f5f7e735fb1296a676f5b6 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Wed, 24 Jul 2019 22:31:45 -0400
Subject: merge

---
 .../views/collections/CollectionSchemaMovableTableHOC.tsx | 15 ++++++++++-----
 src/client/views/collections/CollectionSchemaView.scss    |  9 +++++++++
 src/client/views/collections/CollectionViewChromes.tsx    |  6 +++---
 3 files changed, 22 insertions(+), 8 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 6d388bb40..290958cd0 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -8,7 +8,11 @@ import { SelectionManager } from "../../util/SelectionManager";
 import { Cast, FieldValue, StrCast } from "../../../new_fields/Types";
 import { ContextMenu } from "../ContextMenu";
 import { action } from "mobx";
+import { library } from '@fortawesome/fontawesome-svg-core';
+import { faGripVertical } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 
+library.add(faGripVertical);
 
 export interface MovableColumnProps {
     columnRenderer: TableCellRenderer;
@@ -198,11 +202,12 @@ export class MovableRow extends React.Component<MovableRowProps> {
         return (
             <div className={className} ref={this.createRowDropTarget} onContextMenu={this.onRowContextMenu}>
                 <div className="collectionSchema-row-wrapper" ref={this._header} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave}>
-                    <div className="row-dragger" ref={reference} onPointerDown={onItemDown}>
-                        <ReactTableDefaults.TrComponent>
-                            {children}
-                        </ReactTableDefaults.TrComponent>
-                    </div>
+                    <ReactTableDefaults.TrComponent>
+                        <div className="row-dragger" ref={reference} onPointerDown={onItemDown}>
+                            <FontAwesomeIcon icon={"grip-vertical"} size="sm" />
+                        </div>
+                        {children}
+                    </ReactTableDefaults.TrComponent>
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 3bc1bc060..22d8a5cb6 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -70,6 +70,9 @@
     }
 
     .rt-thead {
+        width: calc(100% - 30px);
+        margin-left: 30px;
+
         &.-header {
             // background: $intermediate-color;
             // color: $light-color;
@@ -77,6 +80,8 @@
             height: 30px;
             // border: 1px solid $intermediate-color;
             box-shadow: none;
+            // width: calc(100% - 30px);
+            // margin-right: -30px;
         }
 
         .rt-resizable-header {
@@ -298,6 +303,10 @@ button.add-column {
 
     .row-dragger {
         // height: $MAX_ROW_HEIGHT;
+        width: 30px;
+        height: 100%;
+        padding: 10px;
+        color: gray;
     }
 
     .collectionSchema-row-wrapper {
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 52fee26bf..03676fe86 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -53,7 +53,7 @@ class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps
                     <option value="masonry" selected={this.props.CollectionView.props.Document.viewType === CollectionViewType.Masonry}>Masonry View</option>
                 </select>
             </div>
-        )
+        );
     }
 }
 
@@ -147,6 +147,6 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
                     </div>
                 </div>
             </div>
-        )
+        );
     }
-}
\ No newline at end of file
+}
-- 
cgit v1.2.3-70-g09d2


From db560a8c43f77b9342e55a48dd96f695813b32ef Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Thu, 25 Jul 2019 12:53:09 -0400
Subject: oof a lot of stuff here

---
 .../views/collections/CollectionSchemaView.scss    |   1 +
 .../views/collections/CollectionSchemaView.tsx     |   2 +
 .../views/collections/CollectionStackingView.tsx   |   5 +-
 .../views/collections/CollectionTreeView.scss      |  27 ++-
 .../views/collections/CollectionTreeView.tsx       |   2 +
 src/client/views/collections/CollectionView.tsx    |  18 +-
 .../views/collections/CollectionViewChromes.scss   | 258 +++++++++++----------
 .../views/collections/CollectionViewChromes.tsx    | 137 ++++++-----
 .../authentication/models/current_user_utils.ts    |   4 +
 9 files changed, 251 insertions(+), 203 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 186e006f3..1e6d1fe99 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -12,6 +12,7 @@
     width: 100%;
     height: 100%;
     overflow: hidden;
+    transition: top 0.5s;
 
     .collectionSchemaView-cellContents {
         height: $MAX_ROW_HEIGHT;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 2cf50e551..bdcedea10 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -69,6 +69,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @observable _newKeyName: string = "";
     @observable previewScript: string = "";
 
+    @computed get chromeCollapsed() { return this.props.chromeCollapsed; }
     @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); }
     @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; }
     @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); }
@@ -390,6 +391,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     render() {
         return (
             <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} onWheel={this.onWheel}
+                style={{ top: this.chromeCollapsed ? 0 : "unset" }}
                 onDrop={(e: React.DragEvent) => this.onDrop(e, {})} onContextMenu={this.onContextMenu} ref={this.createTarget}>
                 {this.reactTable}
                 {this.dividerDragger}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 31ec80d76..b5c0fb3d6 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -21,8 +21,6 @@ import { List } from "../../../new_fields/List";
 import { EditableView } from "../EditableView";
 import { CollectionViewProps } from "./CollectionBaseView";
 
-let valuesCreated = 1;
-
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _masonryGridRef: HTMLDivElement | null = null;
@@ -33,7 +31,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _columnStart: number = 0;
     @observable private cursor: CursorProperty = "grab";
     get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
-    get chromeCollapsed() { return this.props.chromeCollapsed; }
+    @computed get chromeCollapsed() { return this.props.chromeCollapsed; }
     @computed get xMargin() { return NumCast(this.props.Document.xMargin, 2 * this.gridGap); }
     @computed get yMargin() { return NumCast(this.props.Document.yMargin, 2 * this.gridGap); }
     @computed get gridGap() { return NumCast(this.props.Document.gridGap, 10); }
@@ -84,7 +82,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
             () => StrCast(this.props.Document.sectionFilter),
             () => {
                 this.props.Document.sectionHeaders = new List();
-                valuesCreated = 1;
             }
         )
     }
diff --git a/src/client/views/collections/CollectionTreeView.scss b/src/client/views/collections/CollectionTreeView.scss
index 5205f4313..db3652ff6 100644
--- a/src/client/views/collections/CollectionTreeView.scss
+++ b/src/client/views/collections/CollectionTreeView.scss
@@ -31,6 +31,7 @@
         margin-top: 4px;
         transform: scale(1.3, 1.3);
     }
+
     .editableView-container {
         font-weight: bold;
     }
@@ -43,18 +44,20 @@
         display: inline;
     }
 
-    .editableView-input, .editableView-container-editing {
+    .editableView-input,
+    .editableView-container-editing {
         display: block;
         text-overflow: ellipsis;
         font-size: 24px;
         white-space: nowrap;
     }
 }
+
 .collectionTreeView-keyHeader {
     font-style: italic;
     font-size: 8pt;
     margin-left: 3px;
-    display:none;
+    display: none;
     background: lightgray;
 }
 
@@ -72,28 +75,31 @@
     // width:100%;//width: max-content;
 
 }
+
 .treeViewItem-openRight {
     display: none;
 }
 
 .treeViewItem-border {
-    display:inherit;
+    display: inherit;
     border-left: dashed 1px #00000042;
 }
 
 .treeViewItem-header:hover {
     .collectionTreeView-keyHeader {
-        display:inherit;
+        display: inherit;
     }
+
     .treeViewItem-openRight {
         display: inline-block;
-        height:13px;
-        margin-top:2px;
+        height: 13px;
+        margin-top: 2px;
         margin-left: 5px;
+
         // display: inline;
         svg {
-            display:block;
-            padding:0px;
+            display: block;
+            padding: 0px;
             margin: 0px;
         }
     }
@@ -101,14 +107,17 @@
 
 .treeViewItem-header {
     border: transparent 1px solid;
-    display:flex;
+    display: flex;
 }
+
 .treeViewItem-header-above {
     border-top: black 1px solid;
 }
+
 .treeViewItem-header-below {
     border-bottom: black 1px solid;
 }
+
 .treeViewItem-header-inside {
     border: black 1px solid;
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index d05cc375e..cbf32c667 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -456,6 +456,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
     private treedropDisposer?: DragManager.DragDropDisposer;
     private _mainEle?: HTMLDivElement;
 
+    @computed get chromeCollapsed() { return this.props.chromeCollapsed; }
+
     protected createTreeDropTarget = (ele: HTMLDivElement) => {
         this.treedropDisposer && this.treedropDisposer();
         if (this._mainEle = ele) {
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index e2f652908..1c6dd661d 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -18,7 +18,7 @@ import { CollectionTreeView } from "./CollectionTreeView";
 import { StrCast, PromiseValue } from '../../../new_fields/Types';
 import { DocumentType } from '../../documents/Documents';
 import { CollectionStackingViewChrome, CollectionViewBaseChrome } from './CollectionViewChromes';
-import { observable } from 'mobx';
+import { observable, action, runInAction } from 'mobx';
 export const COLLECTION_BORDER_WIDTH = 2;
 
 library.add(faTh);
@@ -37,11 +37,20 @@ export class CollectionView extends React.Component<FieldViewProps> {
 
     public static LayoutString(fieldStr: string = "data", fieldExt: string = "") { return FieldView.LayoutString(CollectionView, fieldStr, fieldExt); }
 
+    componentDidMount = () => {
+        // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
+        let chromeStatus = this.props.Document.chromeStatus;
+        if (chromeStatus && (chromeStatus === "disabled" || chromeStatus === "collapsed")) {
+            runInAction(() => this._collapsed = true);
+        }
+    }
+
     private SubViewHelper = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
         let props = { ...this.props, ...renderProps };
         switch (this.isAnnotationOverlay ? CollectionViewType.Freeform : type) {
             case CollectionViewType.Schema: return (<CollectionSchemaView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
-            case CollectionViewType.Docking: return (<CollectionDockingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
+            // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip
+            case CollectionViewType.Docking: return (<CollectionDockingView chromeCollapsed={true} key="collview" {...props} CollectionView={this} />);
             case CollectionViewType.Tree: return (<CollectionTreeView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />);
             case CollectionViewType.Stacking: { this.props.Document.singleColumn = true; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
             case CollectionViewType.Masonry: { this.props.Document.singleColumn = false; return (<CollectionStackingView chromeCollapsed={this._collapsed} key="collview" {...props} CollectionView={this} />); }
@@ -52,12 +61,15 @@ export class CollectionView extends React.Component<FieldViewProps> {
         return (null);
     }
 
+    @action
     private collapse = (value: boolean) => {
         this._collapsed = value;
+        this.props.Document.chromeStatus = value ? "collapsed" : "visible";
     }
 
     private SubView = (type: CollectionViewType, renderProps: CollectionRenderProps) => {
-        if (this.isAnnotationOverlay || this.props.Document === CurrentUserUtils.UserDocument.sidebar) {
+        // currently cant think of a reason for collection docking view to have a chrome. mind may change if we ever have nested docking views -syip
+        if (this.isAnnotationOverlay || this.props.Document.chromeStatus === "disabled" || type === CollectionViewType.Docking) {
             return [(null), this.SubViewHelper(type, renderProps)];
         }
         else {
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index d37228bde..0faca0607 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -1,167 +1,171 @@
 @import "../globalCssVariables";
 @import '~js-datepicker/dist/datepicker.min.css';
 
-.collectionViewChrome {
-    display: grid;
-    grid-template-columns: 1fr auto;
-    padding-bottom: 10px;
-    border-bottom: .5px solid lightgrey;
-    margin: 10px;
+.collectionViewChrome-cont {
     position: relative;
     z-index: 9001;
     transition: top .5s;
+    background: rgb(238, 238, 238);
+    padding: 10px;
 
-    .collectionViewBaseChrome {
-        display: flex;
+    .collectionViewChrome {
+        display: grid;
+        grid-template-columns: 1fr auto;
+        padding-bottom: 10px;
+        border-bottom: .5px solid lightgrey;
 
-        .collectionViewBaseChrome-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;
-            margin-left: 50px;
-        }
-
-        .collectionViewBaseChrome-viewPicker:active {
-            outline-color: black;
-        }
-
-        .collectionViewBaseChrome-collapse {
-            transition: all .5s;
-            position: absolute;
-            width: 40px;
-        }
-
-        .collectionViewBaseChrome-viewSpecs {
-            margin-left: 10px;
-            display: grid;
+        .collectionViewBaseChrome {
+            display: flex;
 
-            .collectionViewBaseChrome-viewSpecsInput {
-                padding: 12px 10px 11px 10px;
-                border: 0px;
-                color: grey;
-                text-align: center;
+            .collectionViewBaseChrome-viewPicker {
+                font-size: 75%;
                 text-transform: uppercase;
                 letter-spacing: 2px;
-                outline-color: black;
-                font-size: 75%;
                 background: rgb(238, 238, 238);
-                height: 100%;
-                width: 150px;
+                color: grey;
+                outline-color: black;
+                border: none;
+                padding: 12px 10px 11px 10px;
+                margin-left: 50px;
+            }
+
+            .collectionViewBaseChrome-viewPicker:active {
+                outline-color: black;
             }
 
-            .collectionViewBaseChrome-viewSpecsMenu {
-                overflow: hidden;
-                transition: height .5s, display .5s;
+            .collectionViewBaseChrome-collapse {
+                transition: all .5s;
                 position: absolute;
-                top: 60px;
-                z-index: 100;
-                display: flex;
-                flex-direction: column;
-                background: rgb(238, 238, 238);
-                box-shadow: grey 2px 2px 4px;
+                width: 40px;
+            }
 
-                .qs-datepicker {
-                    left: unset;
-                    right: 0;
+            .collectionViewBaseChrome-viewSpecs {
+                margin-left: 10px;
+                display: grid;
+
+                .collectionViewBaseChrome-viewSpecsInput {
+                    padding: 12px 10px 11px 10px;
+                    border: 0px;
+                    color: grey;
+                    text-align: center;
+                    text-transform: uppercase;
+                    letter-spacing: 2px;
+                    outline-color: black;
+                    font-size: 75%;
+                    background: rgb(238, 238, 238);
+                    height: 100%;
+                    width: 150px;
                 }
 
-                .collectionViewBaseChrome-viewSpecsMenu-row {
-                    display: grid;
-                    grid-template-columns: 150px 200px 150px;
-                    margin-top: 10px;
-                    margin-right: 10px;
-
-                    .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
-                    .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
-                    .collectionViewBaseChrome-viewSpecsMenu-rowRight {
-                        font-size: 75%;
-                        letter-spacing: 2px;
-                        color: grey;
-                        margin-left: 10px;
-                        padding: 5px;
-                        border: none;
-                        outline-color: black;
+                .collectionViewBaseChrome-viewSpecsMenu {
+                    overflow: hidden;
+                    transition: height .5s, display .5s;
+                    position: absolute;
+                    top: 60px;
+                    z-index: 100;
+                    display: flex;
+                    flex-direction: column;
+                    background: rgb(238, 238, 238);
+                    box-shadow: grey 2px 2px 4px;
+
+                    .qs-datepicker {
+                        left: unset;
+                        right: 0;
                     }
-                }
 
-                .collectionViewBaseChrome-viewSpecsMenu-lastRow {
-                    display: grid;
-                    grid-template-columns: 1fr 1fr;
-                    grid-gap: 10px;
-                    margin: 10px;
+                    .collectionViewBaseChrome-viewSpecsMenu-row {
+                        display: grid;
+                        grid-template-columns: 150px 200px 150px;
+                        margin-top: 10px;
+                        margin-right: 10px;
+
+                        .collectionViewBaseChrome-viewSpecsMenu-rowLeft,
+                        .collectionViewBaseChrome-viewSpecsMenu-rowMiddle,
+                        .collectionViewBaseChrome-viewSpecsMenu-rowRight {
+                            font-size: 75%;
+                            letter-spacing: 2px;
+                            color: grey;
+                            margin-left: 10px;
+                            padding: 5px;
+                            border: none;
+                            outline-color: black;
+                        }
+                    }
+
+                    .collectionViewBaseChrome-viewSpecsMenu-lastRow {
+                        display: grid;
+                        grid-template-columns: 1fr 1fr;
+                        grid-gap: 10px;
+                        margin: 10px;
+                    }
                 }
             }
         }
-    }
 
 
-    .collectionStackingViewChrome-cont {
-        display: flex;
-        justify-content: space-between;
-    }
+        .collectionStackingViewChrome-cont {
+            display: flex;
+            justify-content: space-between;
+        }
 
-    .collectionStackingViewChrome-sort {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
+        .collectionStackingViewChrome-sort {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
 
-        .collectionStackingViewChrome-sortIcon {
-            transition: transform .5s;
-            margin-left: 10px;
+            .collectionStackingViewChrome-sortIcon {
+                transition: transform .5s;
+                margin-left: 10px;
+            }
         }
-    }
-
-    button:hover {
-        transform: scale(1);
-    }
 
+        button:hover {
+            transform: scale(1);
+        }
 
-    .collectionStackingViewChrome-sectionFilter-cont {
-        justify-self: right;
-        display: flex;
-        font-size: 75%;
-        text-transform: uppercase;
-        letter-spacing: 2px;
 
-        .collectionStackingViewChrome-sectionFilter-label {
-            vertical-align: center;
-            padding: 10px;
-        }
+        .collectionStackingViewChrome-sectionFilter-cont {
+            justify-self: right;
+            display: flex;
+            font-size: 75%;
+            text-transform: uppercase;
+            letter-spacing: 2px;
 
-        .collectionStackingViewChrome-sectionFilter {
-            color: white;
-            width: 100px;
-            text-align: center;
-            background: rgb(238, 238, 238);
+            .collectionStackingViewChrome-sectionFilter-label {
+                vertical-align: center;
+                padding: 10px;
+            }
 
-            .editable-view-input,
-            input,
-            .editableView-container-editing-oneLine,
-            .editableView-container-editing {
-                padding: 12px 10px 11px 10px;
-                border: 0px;
-                color: grey;
+            .collectionStackingViewChrome-sectionFilter {
+                color: white;
+                width: 100px;
                 text-align: center;
-                text-transform: uppercase;
-                letter-spacing: 2px;
-                outline-color: black;
-                height: 100%;
-            }
+                background: rgb(238, 238, 238);
 
-            .react-autosuggest__container {
-                margin: 0;
-                color: grey;
-                padding: 0px;
+                .editable-view-input,
+                input,
+                .editableView-container-editing-oneLine,
+                .editableView-container-editing {
+                    padding: 12px 10px 11px 10px;
+                    border: 0px;
+                    color: grey;
+                    text-align: center;
+                    text-transform: uppercase;
+                    letter-spacing: 2px;
+                    outline-color: black;
+                    height: 100%;
+                }
+
+                .react-autosuggest__container {
+                    margin: 0;
+                    color: grey;
+                    padding: 0px;
+                }
             }
         }
-    }
 
-    .collectionStackingViewChrome-sectionFilter:hover {
-        cursor: text;
+        .collectionStackingViewChrome-sectionFilter:hover {
+            cursor: text;
+        }
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 24d13d5cb..4129781f7 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -47,6 +47,20 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         runInAction(() => {
             this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[0][1] = value)} />, ""]);
             this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={false} script={(value: string) => runInAction(() => this._keyRestrictions[1][1] = value)} />, ""]);
+
+            // chrome status is one of disabled, collapsed, or visible. this determines initial state from document
+            let chromeStatus = this.props.CollectionView.props.Document.chromeStatus;
+            if (chromeStatus) {
+                if (chromeStatus === "disabled") {
+                    throw new Error("how did you get here, if chrome status is 'disabled' on a collection, a chrome shouldn't even be instantiated!");
+                }
+                else if (chromeStatus === "collapsed") {
+                    this._collapsed = true;
+                    if (this.props.collapse) {
+                        this.props.collapse(true);
+                    }
+                }
+            }
         });
     }
 
@@ -130,11 +144,12 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     @action
     toggleCollapse = () => {
         this._collapsed = !this._collapsed;
-        this.props.collapse(this._collapsed);
+        if (this.props.collapse) {
+            this.props.collapse(this._collapsed);
+        }
     }
 
     subChrome = () => {
-
         switch (this.props.type) {
             case CollectionViewType.Stacking: return (
                 <CollectionStackingViewChrome
@@ -148,71 +163,73 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     render() {
         return (
-            <div className="collectionViewChrome" style={{ top: this._collapsed ? -100 : 0 }}>
-                <div className="collectionViewBaseChrome">
-                    <button className="collectionViewBaseChrome-collapse"
-                        style={{ top: this._collapsed ? 80 : 0, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
-                        title="Collapse collection chrome" onClick={this.toggleCollapse}>
-                        <FontAwesomeIcon icon="caret-up" size="2x" />
-                    </button>
-                    <select
-                        className="collectionViewBaseChrome-viewPicker"
-                        onPointerDown={stopPropagation}
-                        onChange={this.viewChanged}
-                        value={NumCast(this.props.CollectionView.props.Document.viewType)}>
-                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="1">Freeform View</option>
-                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
-                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
-                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
-                        <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View></option>
-                    </select>
-                    <div className="collectionViewBaseChrome-viewSpecs">
-                        <input className="collectionViewBaseChrome-viewSpecsInput"
-                            placeholder="Filter Documents"
-                            value={this.filterValue ? this.filterValue.script.originalScript : ""}
-                            onPointerDown={this.openViewSpecs} />
-                        <div className="collectionViewBaseChrome-viewSpecsMenu"
-                            onPointerDown={this.openViewSpecs}
-                            style={{
-                                height: this._viewSpecsOpen ? "fit-content" : "0px",
-                                overflow: this._viewSpecsOpen ? "initial" : "hidden"
-                            }}>
-                            {this._keyRestrictions.map(i => i[0])}
-                            <div className="collectionViewBaseChrome-viewSpecsMenu-row">
-                                <div className="collectionViewBaseChrome-viewSpecsMenu-rowLeft">
-                                    CREATED WITHIN:
-                            </div>
-                                <select className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
-                                    style={{ textTransform: "uppercase", textAlign: "center" }}
-                                    value={this._dateWithinValue}
-                                    onChange={(e) => runInAction(() => this._dateWithinValue = e.target.value)}>
-                                    <option value="1d">1 day of</option>
-                                    <option value="3d">3 days of</option>
-                                    <option value="1w">1 week of</option>
-                                    <option value="2w">2 weeks of</option>
-                                    <option value="1m">1 month of</option>
-                                    <option value="2m">2 months of</option>
-                                    <option value="6m">6 months of</option>
-                                    <option value="1y">1 year of</option>
-                                </select>
-                                <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
-                                    id={this._datePickerElGuid}
-                                    value={this._dateValue.toLocaleDateString()}
-                                    onPointerDown={this.openDatePicker}
-                                    placeholder="Value" />
+            <div className="collectionViewChrome-cont" style={{ top: this._collapsed ? -100 : 0 }}>
+                <div className="collectionViewChrome">
+                    <div className="collectionViewBaseChrome">
+                        <button className="collectionViewBaseChrome-collapse"
+                            style={{ top: this._collapsed ? 90 : 10, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
+                            title="Collapse collection chrome" onClick={this.toggleCollapse}>
+                            <FontAwesomeIcon icon="caret-up" size="2x" />
+                        </button>
+                        <select
+                            className="collectionViewBaseChrome-viewPicker"
+                            onPointerDown={stopPropagation}
+                            onChange={this.viewChanged}
+                            value={NumCast(this.props.CollectionView.props.Document.viewType)}>
+                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="1">Freeform View</option>
+                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
+                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
+                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
+                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View></option>
+                        </select>
+                        <div className="collectionViewBaseChrome-viewSpecs">
+                            <input className="collectionViewBaseChrome-viewSpecsInput"
+                                placeholder="Filter Documents"
+                                value={this.filterValue ? this.filterValue.script.originalScript : ""}
+                                onPointerDown={this.openViewSpecs} />
+                            <div className="collectionViewBaseChrome-viewSpecsMenu"
+                                onPointerDown={this.openViewSpecs}
+                                style={{
+                                    height: this._viewSpecsOpen ? "fit-content" : "0px",
+                                    overflow: this._viewSpecsOpen ? "initial" : "hidden"
+                                }}>
+                                {this._keyRestrictions.map(i => i[0])}
+                                <div className="collectionViewBaseChrome-viewSpecsMenu-row">
+                                    <div className="collectionViewBaseChrome-viewSpecsMenu-rowLeft">
+                                        CREATED WITHIN:
                             </div>
-                            <div className="collectionViewBaseChrome-viewSpecsMenu-lastRow">
-                                <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}>
-                                    ADD KEY RESTRICTION
+                                    <select className="collectionViewBaseChrome-viewSpecsMenu-rowMiddle"
+                                        style={{ textTransform: "uppercase", textAlign: "center" }}
+                                        value={this._dateWithinValue}
+                                        onChange={(e) => runInAction(() => this._dateWithinValue = e.target.value)}>
+                                        <option value="1d">1 day of</option>
+                                        <option value="3d">3 days of</option>
+                                        <option value="1w">1 week of</option>
+                                        <option value="2w">2 weeks of</option>
+                                        <option value="1m">1 month of</option>
+                                        <option value="2m">2 months of</option>
+                                        <option value="6m">6 months of</option>
+                                        <option value="1y">1 year of</option>
+                                    </select>
+                                    <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
+                                        id={this._datePickerElGuid}
+                                        value={this._dateValue.toLocaleDateString()}
+                                        onPointerDown={this.openDatePicker}
+                                        placeholder="Value" />
+                                </div>
+                                <div className="collectionViewBaseChrome-viewSpecsMenu-lastRow">
+                                    <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.addKeyRestriction}>
+                                        ADD KEY RESTRICTION
                             </button>
-                                <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
-                                    APPLY FILTER
+                                    <button className="collectonViewBaseChrome-viewSpecsMenu-lastRowButton" onClick={this.applyFilter}>
+                                        APPLY FILTER
                             </button>
+                                </div>
                             </div>
                         </div>
                     </div>
+                    {this.subChrome()}
                 </div>
-                {this.subChrome()}
             </div>
         )
     }
diff --git a/src/server/authentication/models/current_user_utils.ts b/src/server/authentication/models/current_user_utils.ts
index 1c52a3f11..41eb1aa0c 100644
--- a/src/server/authentication/models/current_user_utils.ts
+++ b/src/server/authentication/models/current_user_utils.ts
@@ -50,6 +50,7 @@ export class CurrentUserUtils {
         if (doc.workspaces === undefined) {
             const workspaces = Docs.Create.TreeDocument([], { title: "Workspaces", height: 100 });
             workspaces.excludeFromLibrary = true;
+            workspaces.chromeStatus = "disabled";
             workspaces.workspaceLibrary = true;
             workspaces.boxShadow = "0 0";
             doc.workspaces = workspaces;
@@ -57,6 +58,7 @@ export class CurrentUserUtils {
         if (doc.recentlyClosed === undefined) {
             const recentlyClosed = Docs.Create.TreeDocument([], { title: "Recently Closed", height: 75 });
             recentlyClosed.excludeFromLibrary = true;
+            recentlyClosed.chromeStatus = "disabled";
             recentlyClosed.boxShadow = "0 0";
             doc.recentlyClosed = recentlyClosed;
         }
@@ -65,11 +67,13 @@ export class CurrentUserUtils {
             sidebar.excludeFromLibrary = true;
             sidebar.gridGap = 5;
             sidebar.xMargin = 5;
+            sidebar.chromeStatus = "disabled";
             sidebar.yMargin = 5;
             Doc.GetProto(sidebar).backgroundColor = "#aca3a6";
             sidebar.boxShadow = "1 1 3";
             doc.sidebar = sidebar;
         }
+        doc.chromeStatus = "disabled";
         StrCast(doc.title).indexOf("@") !== -1 && (doc.title = StrCast(doc.title).split("@")[0] + "'s Library");
 
     }
-- 
cgit v1.2.3-70-g09d2


From 0baefb4e0b133df60f42d894733113c961740af3 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Thu, 25 Jul 2019 19:30:44 -0400
Subject: almost done

---
 .../views/collections/CollectionStackingView.scss  | 42 ++++++++++++----------
 .../views/collections/CollectionStackingView.tsx   |  8 ++---
 .../CollectionStackingViewFieldColumn.tsx          | 26 ++++++++------
 .../views/collections/CollectionViewChromes.scss   |  5 +--
 .../views/collections/CollectionViewChromes.tsx    |  6 ++--
 5 files changed, 48 insertions(+), 39 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index f43340967..9dbe4ccb8 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -96,7 +96,6 @@
             outline: none;
             border: 0px;
             color: $light-color;
-            text-transform: uppercase;
             letter-spacing: 2px;
             font-size: 75%;
             transition: transform 0.2s;
@@ -118,9 +117,7 @@
                 padding: 12px 10px 11px 10px;
                 border: 0px;
                 color: grey;
-                // font-size: 75%;
                 text-align: center;
-                text-transform: uppercase;
                 letter-spacing: 2px;
                 outline-color: black;
             }
@@ -142,15 +139,6 @@
         width: 90%;
         color: lightgrey;
         overflow: ellipses;
-    }
-
-    .collectionStackingView-addGroupButton {
-        background: rgb(238, 238, 238);
-        font-size: 75%;
-        text-align: center;
-        text-transform: uppercase;
-        letter-spacing: 2px;
-        height: fit-content;
 
         .editableView-container-editing-oneLine,
         .editableView-container-editing {
@@ -165,14 +153,32 @@
         }
 
         .editableView-input {
-            padding: 12px 10px 11px 10px;
-            border: 0px;
-            color: grey;
-            // font-size: 75%;
-            text-align: center;
-            text-transform: uppercase;
+            outline-color: black;
             letter-spacing: 2px;
+            color: grey;
+            border: 0px;
+            padding: 12px 10px 11px 10px;
+        }
+    }
+
+    .collectionStackingView-addDocumentButton {
+        font-size: 75%;
+        letter-spacing: 2px;
+
+        .editableView-input {
             outline-color: black;
+            letter-spacing: 2px;
+            color: grey;
+            border: 0px;
+            padding: 12px 10px 11px 10px;
         }
     }
+
+    .collectionStackingView-addGroupButton {
+        background: rgb(238, 238, 238);
+        font-size: 75%;
+        text-align: center;
+        letter-spacing: 2px;
+        height: fit-content;
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index b5c0fb3d6..7c93201fe 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -47,7 +47,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         let fields = new Map<SchemaHeaderField, Doc[]>(sectionHeaders.map(sh => [sh, []]));
         if (sectionFilter) {
             this.filteredChildren.map(d => {
-                let sectionValue = (d[sectionFilter] ? d[sectionFilter] : `No ${sectionFilter} value`) as object;
+                let sectionValue = (d[sectionFilter] ? d[sectionFilter] : `NO ${sectionFilter.toUpperCase()} VALUE`) as object;
                 // the next five lines ensures that floating point rounding errors don't create more than one section -syip
                 let parsed = parseInt(sectionValue.toString());
                 let castedSectionValue: any = sectionValue;
@@ -56,12 +56,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                 }
 
                 // look for if header exists already
-                let existingHeader = sectionHeaders!.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `No ${sectionFilter} value`));
+                let existingHeader = sectionHeaders!.find(sh => sh.heading === (castedSectionValue ? castedSectionValue.toString() : `NO ${sectionFilter.toUpperCase()} VALUE`));
                 if (existingHeader) {
                     fields.get(existingHeader)!.push(d);
                 }
                 else {
-                    let newSchemaHeader = new SchemaHeaderField(castedSectionValue ? castedSectionValue.toString() : `No ${sectionFilter} value`);
+                    let newSchemaHeader = new SchemaHeaderField(castedSectionValue ? castedSectionValue.toString() : `NO ${sectionFilter.toUpperCase()} VALUE`);
                     fields.set(newSchemaHeader, [d]);
                     sectionHeaders!.push(newSchemaHeader);
                 }
@@ -260,7 +260,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         let editableViewProps = {
             GetValue: () => "",
             SetValue: this.addGroup,
-            contents: "+ Add a Group"
+            contents: "+ ADD A GROUP"
         }
         // let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
         return (
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 582adc418..ea2a302ff 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -18,6 +18,7 @@ import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { ScriptField } from "../../../new_fields/ScriptField";
 import { CompileScript } from "../../util/Scripting";
+import { RichTextField } from "../../../new_fields/RichTextField";
 
 
 interface CSVFieldColumnProps {
@@ -168,11 +169,11 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
     }
 
     @action
-    addDocument = () => {
+    addDocument = (value: string, shiftDown?: boolean) => {
         let key = StrCast(this.props.parent.props.Document.sectionFilter);
-        let newDoc = Docs.Create.TextDocument({ height: 18, title: "new text document" });
+        let newDoc = Docs.Create.TextDocument({ height: 18, width: 200, title: value });
         newDoc[key] = this.getValue(this.props.heading);
-        this.props.parent.props.addDocument(newDoc);
+        return this.props.parent.props.addDocument(newDoc);
     }
 
     @action
@@ -231,29 +232,34 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
         let style = this.props.parent;
         let singleColumn = style.singleColumn;
         let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
-        let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `No ${key} value`;
-        let editableViewProps = {
+        let evContents = heading ? heading : this.props.type && this.props.type === "number" ? "0" : `NO ${key.toUpperCase()} VALUE`;
+        let headerEditableViewProps = {
             GetValue: () => evContents,
             SetValue: this.headingChanged,
             contents: evContents,
             oneLine: true
         }
+        let newEditableViewProps = {
+            GetValue: () => "",
+            SetValue: this.addDocument,
+            contents: "+ NEW"
+        }
         let headingView = this.props.headingObject ?
             <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
                 style={{ width: (style.columnWidth) / (uniqueHeadings.length + 1) }}>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
                     Further, it does not have a color and cannot be deleted. */}
                 <div className="collectionStackingView-sectionHeader-subCont" onPointerDown={this.headerDown}
-                    title={evContents === `No ${key} value` ?
+                    title={evContents === `NO ${key.toUpperCase()} VALUE` ?
                         `Documents that don't have a ${key} value will go here. This column cannot be removed.` : ""}
                     style={{
                         width: "100%",
-                        background: this.props.headingObject && evContents !== `No ${key} value` ?
+                        background: this.props.headingObject && evContents !== `NO ${key.toUpperCase()} VALUE` ?
                             this.props.headingObject.color : "lightgrey",
                         color: "grey"
                     }}>
-                    <EditableView {...editableViewProps} />
-                    {evContents === `No ${key} value` ?
+                    <EditableView {...headerEditableViewProps} />
+                    {evContents === `NO ${key.toUpperCase()} VALUE` ?
                         (null) :
                         <button className="collectionStackingView-sectionDelete" onClick={this.deleteColumn}>
                             <FontAwesomeIcon icon="trash" />
@@ -282,7 +288,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                 </div>
                 <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
                     style={{ width: style.columnWidth / (uniqueHeadings.length + 1) }}>
-                    <button style={{ width: "100%" }} onClick={this.addDocument}>+ New</button>
+                    <EditableView {...newEditableViewProps} />
                 </div>
             </div>
         );
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 0faca0607..6525f3b07 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -5,7 +5,7 @@
     position: relative;
     z-index: 9001;
     transition: top .5s;
-    background: rgb(238, 238, 238);
+    background: lightslategray;
     padding: 10px;
 
     .collectionViewChrome {
@@ -48,7 +48,6 @@
                     border: 0px;
                     color: grey;
                     text-align: center;
-                    text-transform: uppercase;
                     letter-spacing: 2px;
                     outline-color: black;
                     font-size: 75%;
@@ -128,7 +127,6 @@
             justify-self: right;
             display: flex;
             font-size: 75%;
-            text-transform: uppercase;
             letter-spacing: 2px;
 
             .collectionStackingViewChrome-sectionFilter-label {
@@ -150,7 +148,6 @@
                     border: 0px;
                     color: grey;
                     text-align: center;
-                    text-transform: uppercase;
                     letter-spacing: 2px;
                     outline-color: black;
                     height: 100%;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 4129781f7..78ceaad86 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -180,11 +180,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="2">Schema View</option>
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="4">Tree View</option>
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
-                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View></option>
+                            <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View</option>
                         </select>
                         <div className="collectionViewBaseChrome-viewSpecs">
                             <input className="collectionViewBaseChrome-viewSpecsInput"
-                                placeholder="Filter Documents"
+                                placeholder="FILTER DOCUMENTS"
                                 value={this.filterValue ? this.filterValue.script.originalScript : ""}
                                 onPointerDown={this.openViewSpecs} />
                             <div className="collectionViewBaseChrome-viewSpecsMenu"
@@ -304,7 +304,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
                 </button>
                 <div className="collectionStackingViewChrome-sectionFilter-cont">
                     <div className="collectionStackingViewChrome-sectionFilter-label">
-                        Group items by:
+                        GROUP ITEMS BY:
                         </div>
                     <div className="collectionStackingViewChrome-sectionFilter">
                         <EditableView
-- 
cgit v1.2.3-70-g09d2


From a53d76d28750b03744727f2646313bccb120dbcb Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Fri, 26 Jul 2019 19:13:39 -0400
Subject: moved schema toolbar into collection chrome

---
 .../views/collections/CollectionViewChromes.tsx     | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 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 1ad9e47ce..de1d01ef0 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -16,6 +16,7 @@ import KeyRestrictionRow from "./KeyRestrictionRow";
 import { CompileScript } from "../../util/Scripting";
 import { ScriptField } from "../../../new_fields/ScriptField";
 import { CollectionSchemaView } from "./CollectionSchemaView";
+import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -346,16 +347,26 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
     }
 }
 
-interface SchemaChromeProps extends CollectionViewChromeProps {
-    toolbar: JSX.Element;
-}
 
 @observer
-export class CollectionSchemaViewChrome extends React.Component<SchemaChromeProps> {
+export class CollectionSchemaViewChrome extends React.Component<CollectionViewChromeProps> {
+
+    togglePreview = () => {
+        let dividerWidth = 4;
+        let borderWidth = Number(COLLECTION_BORDER_WIDTH);
+        let panelWidth = this.props.CollectionView.props.PanelWidth();
+        let previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
+        let tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth;
+        this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
+
+    }
+
+
     render() {
+        let previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
         return (
             <div className="collectionStackingViewChrome-cont">
-                {this.props.toolbar}
+                <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={previewWidth !== 0} onChange={this.togglePreview} />Show Preview</div>
             </div>
         );
     }
-- 
cgit v1.2.3-70-g09d2


From 73fcf938eb817ae9b4dfdcefd5f04502079c153e Mon Sep 17 00:00:00 2001
From: Tyler Schicke <tyler_schicke@brown.edu>
Date: Sat, 27 Jul 2019 18:38:09 -0400
Subject: Fixed linter errors

---
 src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 6 +++---
 src/client/views/collections/CollectionViewChromes.tsx             | 2 +-
 src/client/views/collections/KeyRestrictionRow.tsx                 | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 1a5d203f9..cf6079196 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -74,7 +74,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             let layoutDoc = Doc.expandTemplateLayout(d, parent.props.DataDoc);
             let headings = this.props.headings();
             let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
-            let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d)
+            let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d);
             let width = () => (d.nativeWidth && !BoolCast(d.ignoreAspect) ? Math.min(pair.layout[WidthSym](), parent.columnWidth) : parent.columnWidth) / (uniqueHeadings.length + 1);
             let height = () => parent.getDocHeight(pair.layout);
             if (parent.singleColumn) {
@@ -243,12 +243,12 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             SetValue: this.headingChanged,
             contents: evContents,
             oneLine: true
-        }
+        };
         let newEditableViewProps = {
             GetValue: () => "",
             SetValue: this.addDocument,
             contents: "+ NEW"
-        }
+        };
         let headingView = this.props.headingObject ?
             <div key={heading} className="collectionStackingView-sectionHeader" ref={this._headerRef}
                 style={{ width: (style.columnWidth) / (uniqueHeadings.length + 1) }}>
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index de1d01ef0..bf643347f 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -296,7 +296,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
         return true;
     }
 
-    @action toggleSort = () => { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; }
+    @action toggleSort = () => { this.props.CollectionView.props.Document.stackingHeadersSortDescending = !this.props.CollectionView.props.Document.stackingHeadersSortDescending; };
     @action resetValue = () => { this._currentKey = this.sectionFilter; };
 
     render() {
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 8051a8359..f292557b5 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -40,6 +40,6 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
                     onChange={(e) => runInAction(() => this._value = e.target.value)}
                     placeholder="VALUE" />
             </div>
-        )
+        );
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 31fafa54bd85cb292a5facd12d7c8f0ed13d1ea9 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Sat, 27 Jul 2019 19:24:54 -0400
Subject: small timeout thing

---
 src/client/views/collections/CollectionViewChromes.tsx | 4 ++--
 1 file 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 bf643347f..044d5336a 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -40,11 +40,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
     private _datePickerElGuid = Utils.GenerateGuid();
 
     componentDidMount = () => {
-        this._picker = datepicker("#" + this._datePickerElGuid, {
+        setTimeout(() => this._picker = datepicker("#" + this._datePickerElGuid, {
             disabler: (date: Date) => date > new Date(),
             onSelect: (instance: any, date: Date) => runInAction(() => this._dateValue = date),
             dateSelected: new Date()
-        });
+        }), 1000);
 
         runInAction(() => {
             this._keyRestrictions.push([<KeyRestrictionRow key={Utils.GenerateGuid()} contains={true} script={(value: string) => runInAction(() => this._keyRestrictions[0][1] = value)} />, ""]);
-- 
cgit v1.2.3-70-g09d2


From 22955412de5b0c5634343cfc45bbe09a91bbbdde Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Sun, 28 Jul 2019 18:20:44 -0400
Subject: improvements to view specs box

---
 .../views/collections/CollectionViewChromes.tsx    | 27 +++++++++++++++++-----
 src/client/views/collections/KeyRestrictionRow.tsx |  3 +++
 2 files changed, 24 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 044d5336a..9c751c4df 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -31,7 +31,7 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation();
 export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> {
     @observable private _viewSpecsOpen: boolean = false;
     @observable private _dateWithinValue: string = "";
-    @observable private _dateValue: Date = new Date();
+    @observable private _dateValue: Date | string = "";
     @observable private _keyRestrictions: [JSX.Element, string][] = [];
     @observable private _collapsed: boolean = false;
     @computed private get filterValue() { return Cast(this.props.CollectionView.props.Document.viewSpecScript, ScriptField); }
@@ -124,10 +124,24 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
         let monthOffset = this._dateWithinValue[1] === 'm' ? parseInt(this._dateWithinValue[0]) : 0;
         let weekOffset = this._dateWithinValue[1] === 'w' ? parseInt(this._dateWithinValue[0]) : 0;
         let dayOffset = (this._dateWithinValue[1] === 'd' ? parseInt(this._dateWithinValue[0]) : 0) + weekOffset * 7;
-        let lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset);
-        let upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1);
-        let dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`;
-        let fullScript = `return ${dateRestrictionScript} && ${keyRestrictionScript}`;
+        let dateRestrictionScript = "";
+        if (this._dateValue instanceof Date) {
+            let lowerBound = new Date(this._dateValue.getFullYear() - yearOffset, this._dateValue.getMonth() - monthOffset, this._dateValue.getDate() - dayOffset);
+            let upperBound = new Date(this._dateValue.getFullYear() + yearOffset, this._dateValue.getMonth() + monthOffset, this._dateValue.getDate() + dayOffset + 1);
+            dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`;
+        }
+        else {
+            let createdDate = new Date(this._dateValue);
+            if (!isNaN(createdDate.getTime())) {
+                let lowerBound = new Date(createdDate.getFullYear() - yearOffset, createdDate.getMonth() - monthOffset, createdDate.getDate() - dayOffset);
+                let upperBound = new Date(createdDate.getFullYear() + yearOffset, createdDate.getMonth() + monthOffset, createdDate.getDate() + dayOffset + 1);
+                dateRestrictionScript = `((doc.creationDate as any).date >= ${lowerBound.valueOf()} && (doc.creationDate as any).date <= ${upperBound.valueOf()})`;
+            }
+        }
+        let fullScript = dateRestrictionScript.length || keyRestrictionScript.length ? dateRestrictionScript.length ?
+            `return ${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} ${keyRestrictionScript}` :
+            `return ${keyRestrictionScript} ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
+            "return true";
         let compiled = CompileScript(fullScript, { params: { doc: Doc.name } });
         if (compiled.compiled) {
             this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
@@ -221,7 +235,8 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                                     </select>
                                     <input className="collectionViewBaseChrome-viewSpecsMenu-rowRight"
                                         id={this._datePickerElGuid}
-                                        value={this._dateValue.toLocaleDateString()}
+                                        value={this._dateValue instanceof Date ? this._dateValue.toLocaleDateString() : this._dateValue}
+                                        onChange={(e) => runInAction(() => this._dateValue = e.target.value)}
                                         onPointerDown={this.openDatePicker}
                                         placeholder="Value" />
                                 </div>
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 4f3d82114..9c3c9c07c 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -26,6 +26,9 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
             let scriptText = `${this._contains ? "" : "!"}((doc.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))`;
             this.props.script(scriptText);
         }
+        else {
+            this.props.script("");
+        }
         return (
             <div className="collectionViewBaseChrome-viewSpecsMenu-row">
                 <input className="collectionViewBaseChrome-viewSpecsMenu-rowLeft"
-- 
cgit v1.2.3-70-g09d2


From 39a6c99d8466bf64b01edb285d776f3db7bf9eb8 Mon Sep 17 00:00:00 2001
From: Fawn <fangrui_tong@brown.edu>
Date: Mon, 29 Jul 2019 11:51:17 -0400
Subject: fixed schema view vertical overflow scrolling + collection chrome
 collapsing

---
 src/client/views/collections/CollectionSchemaView.scss  | 3 ++-
 src/client/views/collections/CollectionSchemaView.tsx   | 4 ++--
 src/client/views/collections/CollectionViewChromes.scss | 2 +-
 src/client/views/collections/CollectionViewChromes.tsx  | 4 ++--
 4 files changed, 7 insertions(+), 6 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 3c3708a30..c1f53f159 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -8,7 +8,8 @@
     box-sizing: border-box;
     // position: absolute;
     width: 100%;
-    height: calc(100% - 70px);
+    transition: height .5s;
+    height: 100%;
     // overflow: hidden;
     // overflow-x: scroll;
     // border: none;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 7bd0b5965..7463429e0 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -237,8 +237,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
         // if (SelectionManager.SelectedDocuments().length > 0) console.log(StrCast(SelectionManager.SelectedDocuments()[0].Document.title));
         // if (DocumentManager.Instance.getDocumentView(this.props.Document)) console.log(StrCast(this.props.Document.title), SelectionManager.IsSelected(DocumentManager.Instance.getDocumentView(this.props.Document)!))
         return (
-            <div className="collectionSchemaView-container" onPointerDown={this.onPointerDown} onWheel={this.onWheel}
-                onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createTarget}>
+            <div className="collectionSchemaView-container" style={{ height: this.chromeCollapsed ? "100%" : "calc(100% - 70px" }}
+                onPointerDown={this.onPointerDown} onWheel={this.onWheel} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createTarget}>
                 {this.schemaTable}
                 {this.dividerDragger}
                 {!this.previewWidth() ? (null) : this.previewPanel}
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 6525f3b07..f9f3ce473 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -4,7 +4,7 @@
 .collectionViewChrome-cont {
     position: relative;
     z-index: 9001;
-    transition: top .5s;
+    transition: margin-top .5s;
     background: lightslategray;
     padding: 10px;
 
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 9c751c4df..2bffe3cc0 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -185,11 +185,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     render() {
         return (
-            <div className="collectionViewChrome-cont" style={{ top: this._collapsed ? -100 : 0 }}>
+            <div className="collectionViewChrome-cont" style={{ marginTop: this._collapsed ? -70 : 0, height: 70 }}>
                 <div className="collectionViewChrome">
                     <div className="collectionViewBaseChrome">
                         <button className="collectionViewBaseChrome-collapse"
-                            style={{ top: this._collapsed ? 90 : 10, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
+                            style={{ marginTop: this._collapsed ? 60 : 0, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
                             title="Collapse collection chrome" onClick={this.toggleCollapse}>
                             <FontAwesomeIcon icon="caret-up" size="2x" />
                         </button>
-- 
cgit v1.2.3-70-g09d2


From 1190dc51c66cb48d48c16988f14100fd9a7004e2 Mon Sep 17 00:00:00 2001
From: fawn <fangrui_tong@brown.edu>
Date: Mon, 29 Jul 2019 17:34:57 -0400
Subject: color + type on schemaheaderfields fixed and schemas can toggle
 textwrapping

---
 .../views/collections/CollectionSchemaCells.tsx    |   4 +-
 .../views/collections/CollectionSchemaHeaders.tsx  |  82 +++++-----
 .../views/collections/CollectionSchemaView.scss    |  13 +-
 .../views/collections/CollectionSchemaView.tsx     | 175 ++++++++++-----------
 .../views/collections/CollectionViewChromes.tsx    |  33 ++++
 .../collections/collectionFreeForm/MarqueeView.tsx |   2 +-
 src/new_fields/SchemaHeaderField.ts                |  11 +-
 7 files changed, 183 insertions(+), 137 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index e06a5c66b..17dfd317d 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -108,7 +108,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
                 this._document[fieldKey] = de.data.draggedDocuments[0];
             }
             else {
-                let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "f1efeb")], de.data.draggedDocuments, {});
+                let coll = Docs.Create.SchemaDocument([new SchemaHeaderField("title", "#f1efeb")], de.data.draggedDocuments, {});
                 this._document[fieldKey] = coll;
             }
             e.stopPropagation();
@@ -284,7 +284,7 @@ export class CollectionSchemaCheckboxCell extends CollectionSchemaCell {
         this._isChecked = e.target.checked;
         let script = CompileScript(e.target.checked.toString(), { requiredType: "boolean", addReturn: true, params: { this: Doc.name } });
         if (script.compiled) {
-            this.applyToDoc(this._document, script.run);
+            this.applyToDoc(this._document, this.props.row, this.props.col, script.run);
         }
     }
 
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 387107c55..088ad7ecd 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -23,23 +23,25 @@ export interface HeaderProps {
     onSelect: (oldKey: string, newKey: string, addnew: boolean) => void;
     setIsEditing: (isEditing: boolean) => void;
     deleteColumn: (column: string) => void;
-    setColumnType: (key: string, type: ColumnType) => void;
+    setColumnType: (column: SchemaHeaderField, type: ColumnType) => void;
     setColumnSort: (key: string, desc: boolean) => void;
     removeColumnSort: (key: string) => void;
+    setColumnColor: (column: SchemaHeaderField, color: string) => void;
+
 }
 
 export class CollectionSchemaHeader extends React.Component<HeaderProps> {
     render() {
         let icon: IconProp = this.props.keyType === ColumnType.Number ? "hashtag" : this.props.keyType === ColumnType.String ? "font" :
             this.props.keyType === ColumnType.Boolean ? "check-square" : this.props.keyType === ColumnType.Doc ? "file" : "align-justify";
-
         return (
             <div className="collectionSchemaView-header" style={{ background: this.props.keyValue.color }}>
                 <CollectionSchemaColumnMenu
-                    keyValue={this.props.keyValue.heading}
+                    columnField={this.props.keyValue}
+                    // keyValue={this.props.keyValue.heading}
                     possibleKeys={this.props.possibleKeys}
                     existingKeys={this.props.existingKeys}
-                    keyType={this.props.keyType}
+                    // keyType={this.props.keyType}
                     typeConst={this.props.typeConst}
                     menuButtonContent={<div><FontAwesomeIcon icon={icon} size="sm" />{this.props.keyValue.heading}</div>}
                     addNew={false}
@@ -50,6 +52,7 @@ export class CollectionSchemaHeader extends React.Component<HeaderProps> {
                     setColumnType={this.props.setColumnType}
                     setColumnSort={this.props.setColumnSort}
                     removeColumnSort={this.props.removeColumnSort}
+                    setColumnColor={this.props.setColumnColor}
                 />
             </div>
         );
@@ -73,10 +76,11 @@ export class CollectionSchemaAddColumnHeader extends React.Component<AddColumnHe
 
 
 export interface ColumnMenuProps {
-    keyValue: string;
+    columnField: SchemaHeaderField;
+    // keyValue: string;
     possibleKeys: string[];
     existingKeys: string[];
-    keyType: ColumnType;
+    // keyType: ColumnType;
     typeConst: boolean;
     menuButtonContent: JSX.Element;
     addNew: boolean;
@@ -84,10 +88,11 @@ export interface ColumnMenuProps {
     setIsEditing: (isEditing: boolean) => void;
     deleteColumn: (column: string) => void;
     onlyShowOptions: boolean;
-    setColumnType: (key: string, type: ColumnType) => void;
+    setColumnType: (column: SchemaHeaderField, type: ColumnType) => void;
     setColumnSort: (key: string, desc: boolean) => void;
     removeColumnSort: (key: string) => void;
     anchorPoint?: any;
+    setColumnColor: (column: SchemaHeaderField, color: string) => void;
 }
 @observer
 export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps> {
@@ -110,16 +115,21 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
         }
     }
 
+    setNewColor = (color: string): void => {
+        this.changeColumnType(ColumnType.Any);
+        console.log("change color", this.props.columnField.heading);
+        this.props.setColumnColor(this.props.columnField, color);
+    }
+
     @action
     toggleIsOpen = (): void => {
         this._isOpen = !this._isOpen;
         this.props.setIsEditing(this._isOpen);
     }
 
-    setColumnType = (oldKey: string, newKey: string, addnew: boolean) => {
-        let typeStr = newKey as keyof typeof ColumnType;
-        let type = ColumnType[typeStr];
-        this.props.setColumnType(this.props.keyValue, type);
+    changeColumnType = (type: ColumnType): void => {
+        console.log("change type", this.props.columnField.heading);
+        // this.props.setColumnType(this.props.columnField, type);
     }
 
     @action
@@ -129,33 +139,29 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
         }
     }
 
-    changeColumnColor = (color: string): void => {
-
-    }
-
     renderTypes = () => {
         if (this.props.typeConst) return <></>;
         return (
             <div className="collectionSchema-headerMenu-group">
                 <label>Column type:</label>
                 <div className="columnMenu-types">
-                    <button title="Any" className={this.props.keyType === ColumnType.Any ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Any)}>
+                    <button title="Any" className={this.props.columnField.type === ColumnType.Any ? "active" : ""} onClick={() => this.changeColumnType(ColumnType.Any)}>
                         <FontAwesomeIcon icon={"align-justify"} size="sm" />
                     </button>
-                    <button title="Number" className={this.props.keyType === ColumnType.Number ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Number)}>
+                    <button title="Number" className={this.props.columnField.type === ColumnType.Number ? "active" : ""} onClick={() => this.changeColumnType(ColumnType.Number)}>
                         <FontAwesomeIcon icon={"hashtag"} size="sm" />
                     </button>
-                    <button title="String" className={this.props.keyType === ColumnType.String ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.String)}>
+                    <button title="String" className={this.props.columnField.type === ColumnType.String ? "active" : ""} onClick={() => this.changeColumnType(ColumnType.String)}>
                         <FontAwesomeIcon icon={"font"} size="sm" />
                     </button>
-                    <button title="Checkbox" className={this.props.keyType === ColumnType.Boolean ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Boolean)}>
+                    <button title="Checkbox" className={this.props.columnField.type === ColumnType.Boolean ? "active" : ""} onClick={() => this.changeColumnType(ColumnType.Boolean)}>
                         <FontAwesomeIcon icon={"check-square"} size="sm" />
                     </button>
-                    <button title="Document" className={this.props.keyType === ColumnType.Doc ? "active" : ""} onClick={() => this.props.setColumnType(this.props.keyValue, ColumnType.Doc)}>
+                    <button title="Document" className={this.props.columnField.type === ColumnType.Doc ? "active" : ""} onClick={() => this.changeColumnType(ColumnType.Doc)}>
                         <FontAwesomeIcon icon={"file"} size="sm" />
                     </button>
                 </div>
-            </div>
+            </div >
         );
     }
 
@@ -164,9 +170,9 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
             <div className="collectionSchema-headerMenu-group">
                 <label>Sort by:</label>
                 <div className="columnMenu-sort">
-                    <div className="columnMenu-option" onClick={() => this.props.setColumnSort(this.props.keyValue, false)}>Sort ascending</div>
-                    <div className="columnMenu-option" onClick={() => this.props.setColumnSort(this.props.keyValue, true)}>Sort descending</div>
-                    <div className="columnMenu-option" onClick={() => this.props.removeColumnSort(this.props.keyValue)}>Clear sorting</div>
+                    <div className="columnMenu-option" onClick={() => this.props.setColumnSort(this.props.columnField.heading, false)}>Sort ascending</div>
+                    <div className="columnMenu-option" onClick={() => this.props.setColumnSort(this.props.columnField.heading, true)}>Sort descending</div>
+                    <div className="columnMenu-option" onClick={() => this.props.removeColumnSort(this.props.columnField.heading)}>Clear sorting</div>
                 </div>
             </div>
         );
@@ -177,29 +183,29 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
             <div className="collectionSchema-headerMenu-group">
                 <label>Color:</label>
                 <div className="columnMenu-colors">
-                    <input type="radio" name="column-color" id="pink" value="#FFB4E8" onClick={() => this.changeColumnColor("#FFB4E8")} />
+                    <input type="radio" name="column-color" id="pink" value="#FFB4E8" onClick={() => this.setNewColor("#FFB4E8")} />
                     <label htmlFor="pink">
                         <div className="columnMenu-colorPicker" style={{ backgroundColor: "#FFB4E8" }}></div>
                     </label>
-                    <input type="radio" name="column-color" id="purple" value="#b28dff" onClick={() => this.changeColumnColor("#b28dff")} />
+                    <input type="radio" name="column-color" id="purple" value="#b28dff" onClick={() => this.setNewColor("#b28dff")} />
                     <label htmlFor="purple">
-                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#FFB4E8" }}></div>
+                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#b28dff" }}></div>
                     </label>
-                    <input type="radio" name="column-color" id="blue" value="#afcbff" onClick={() => this.changeColumnColor("#afcbff")} />
+                    <input type="radio" name="column-color" id="blue" value="#afcbff" onClick={() => this.setNewColor("#afcbff")} />
                     <label htmlFor="blue">
-                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#FFB4E8" }}></div>
+                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#afcbff" }}></div>
                     </label>
-                    <input type="radio" name="column-color" id="yellow" value="#f3ffe3" onClick={() => this.changeColumnColor("#f3ffe3")} />
+                    <input type="radio" name="column-color" id="yellow" value="#fff5ba" onClick={() => this.setNewColor("#fff5ba")} />
                     <label htmlFor="yellow">
-                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#FFB4E8" }}></div>
+                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#fff5ba" }}></div>
                     </label>
-                    <input type="radio" name="column-color" id="red" value="#ffc9de" onClick={() => this.changeColumnColor("#ffc9de")} />
+                    <input type="radio" name="column-color" id="red" value="#ffabab" onClick={() => this.setNewColor("#ffabab")} />
                     <label htmlFor="red">
-                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#FFB4E8" }}></div>
+                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#ffabab" }}></div>
                     </label>
-                    <input type="radio" name="column=color" id="none" value="#f1efeb" onClick={() => this.changeColumnColor("#f1efeb")} />
+                    <input type="radio" name="column=color" id="none" value="#f1efeb" onClick={() => this.setNewColor("#f1efeb")} />
                     <label htmlFor="none">
-                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#FFB4E8" }}></div>
+                        <div className="columnMenu-colorPicker" style={{ backgroundColor: "#f1efeb" }}></div>
                     </label>
                 </div>
             </div>
@@ -212,7 +218,7 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
                 <label>Key:</label>
                 <div className="collectionSchema-headerMenu-group">
                     <KeysDropdown
-                        keyValue={this.props.keyValue}
+                        keyValue={this.props.columnField.heading}
                         possibleKeys={this.props.possibleKeys}
                         existingKeys={this.props.existingKeys}
                         canAddNew={true}
@@ -225,9 +231,9 @@ export class CollectionSchemaColumnMenu extends React.Component<ColumnMenuProps>
                     <>
                         {this.renderTypes()}
                         {this.renderSorting()}
-                        {this.renderColors()}
+                        {/* {this.renderColors()} */}
                         <div className="collectionSchema-headerMenu-group">
-                            <button onClick={() => this.props.deleteColumn(this.props.keyValue)}>Delete Column</button>
+                            <button onClick={() => this.props.deleteColumn(this.props.columnField.heading)}>Delete Column</button>
                         </div>
                     </>
                 }
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 749b9a364..487907c1c 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -167,8 +167,8 @@
         padding: 0;
         font-size: 13px;
         text-align: center;
-        
         // white-space: normal;
+        white-space: nowrap;
 
         .imageBox-cont {
             position: relative;
@@ -318,15 +318,19 @@ button.add-column {
     }
 
     .columnMenu-colors {
-
+        display: flex;
+        justify-content: space-between;
+        flex-wrap: wrap;
 
         input[type="radio"] {
             display: none;
         }
 
         .columnMenu-colorPicker {
+            cursor: pointer;
             width: 20px;
             height: 20px;
+            border-radius: 10px;
         }
     }
 }
@@ -335,13 +339,16 @@ button.add-column {
     // height: $MAX_ROW_HEIGHT;
     height: 100%;
     background-color: white;
+    // white-space: nowrap;
 
     &.row-focused .rt-tr {
         background-color: rgb(255, 246, 246);//$light-color-secondary;
     }
 
     &.row-wrapped {
-        white-space: normal;
+        .rt-td {
+            white-space: normal;
+        }
     }
 
     .row-dragger {
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index ece638ec7..2ce6f1be3 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -280,16 +280,20 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     @observable _focusedCell: { row: number, col: number } = { row: 0, col: 0 };
     @observable _sortedColumns: Map<string, { id: string, desc: boolean }> = new Map();
     @observable _openCollections: Array<string> = [];
-    @observable _textWrappedRows: Array<string> = [];
+    // @observable _textWrappedRows: Array<string> = [];
     @observable private _node: HTMLDivElement | null = null;
 
     @computed get previewWidth() { return () => NumCast(this.props.Document.schemaPreviewWidth); }
     @computed get previewHeight() { return () => this.props.PanelHeight() - 2 * this.borderWidth; }
     @computed get tableWidth() { return this.props.PanelWidth() - 2 * this.borderWidth - this.DIVIDER_WIDTH - this.previewWidth(); }
+
     @computed get columns() {
-        console.log("columns");
         return Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField), []);
     }
+    set columns(columns: SchemaHeaderField[]) {
+        this.props.Document.schemaColumns = new List<SchemaHeaderField>(columns);
+    }
+
     @computed get childDocs() {
         if (this.props.childDocs) return this.props.childDocs;
 
@@ -300,7 +304,14 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
         doc[this.props.fieldKey] = new List<Doc>(docs);
     }
-    set columns(columns: SchemaHeaderField[]) { this.props.Document.schemaColumns = new List<SchemaHeaderField>(columns); }
+
+    @computed get textWrappedRows() {
+        return Cast(this.props.Document.textwrappedSchemaRows, listSpec("string"), []);
+    }
+    set textWrappedRows(textWrappedRows: string[]) {
+        this.props.Document.textwrappedSchemaRows = new List<string>(textWrappedRows);
+    }
+
     @computed get borderWidth() { return Number(COLLECTION_BORDER_WIDTH); }
     @computed get tableColumns(): Column<Doc>[] {
         let possibleKeys = this.documentKeys.filter(key => this.columns.findIndex(existingKey => existingKey.heading.toUpperCase() === key.toUpperCase()) === -1);
@@ -345,6 +356,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 setColumnType={this.setColumnType}
                 setColumnSort={this.setColumnSort}
                 removeColumnSort={this.removeColumnSort}
+                setColumnColor={this.setColumnColor}
             />;
 
             return {
@@ -399,19 +411,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         return columns;
     }
 
-    // onHeaderDrag = (columnName: string) => {
-    //     let schemaDoc = Cast(this.props.Document.schemaDoc, Doc);
-    //     if (schemaDoc instanceof Doc) {
-    //         let columnDocs = DocListCast(schemaDoc.data);
-    //         if (columnDocs) {
-    //             let ddoc = columnDocs.find(doc => doc.title === columnName);
-    //             if (ddoc) {
-    //                 return ddoc;
-    //             }
-    //         }
-    //     }
-    //     return this.props.Document;  
-    // }
     constructor(props: SchemaTableProps) {
         super(props);
         // convert old schema columns (list of strings) into new schema columns (list of schema header fields)
@@ -436,8 +435,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     tableRemoveDoc = (document: Doc): boolean => {
-        // let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
-        // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []);
+
         let children = this.childDocs;
         if (children.indexOf(document) !== -1) {
             children.splice(children.indexOf(document), 1);
@@ -456,11 +454,10 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             ScreenToLocalTransform: this.props.ScreenToLocalTransform,
             addDoc: this.tableAddDoc,
             removeDoc: this.tableRemoveDoc,
-            // removeDoc: this.props.deleteDocument,
             rowInfo,
             rowFocused: !this._headerIsEditing && rowInfo.index === this._focusedCell.row && this.props.isFocused(this.props.Document),
-            textWrapRow: this.textWrapRow,
-            rowWrapped: this._textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1
+            textWrapRow: this.toggleTextWrapRow,
+            rowWrapped: this.textWrappedRows.findIndex(id => rowInfo.original[Id] === id) > -1
         };
     }
 
@@ -471,9 +468,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         let row = rowInfo.index;
         //@ts-ignore
         let col = this.columns.map(c => c.heading).indexOf(column!.id);
-        // let col = column ? this.columns.indexOf(column!) : -1;
         let isFocused = this._focusedCell.row === row && this._focusedCell.col === col && this.props.isFocused(this.props.Document);
-        // let column = this.columns.indexOf(column.id!);
         return {
             style: {
                 border: !this._headerIsEditing && isFocused ? "2px solid rgb(255, 160, 160)" : "1px solid #f1efeb"
@@ -481,19 +476,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         };
     }
 
-    // private createTarget = (ele: HTMLDivElement) => {
-    //     this._mainCont = ele;
-    //     this.props.CreateDropTarget(ele);
-    // }
-
-    // detectClick = (e: PointerEvent): void => {
-    //     if (this._node && this._node.contains(e.target as Node)) {
-    //     } else {
-    //         this._isOpen = false;
-    //         this.props.setIsEditing(false);
-    //     }
-    // }
-
     @action
     onExpandCollection = (collection: Doc): void => {
         this._openCollections.push(collection[Id]);
@@ -533,8 +515,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
             let direction = e.key === "Tab" ? "tab" : e.which === 39 ? "right" : e.which === 37 ? "left" : e.which === 38 ? "up" : e.which === 40 ? "down" : "";
             this.changeFocusedCellByDirection(direction);
 
-            // let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
-            // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []);
             let children = this.childDocs;
             const pdoc = FieldValue(children[this._focusedCell.row]);
             pdoc && this.props.setPreviewDoc(pdoc);
@@ -543,8 +523,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
     @action
     changeFocusedCellByDirection = (direction: string): void => {
-        // let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
-        // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []);
         let children = this.childDocs;
         switch (direction) {
             case "tab":
@@ -569,81 +547,74 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 this._focusedCell = { row: this._focusedCell.row + 1 === children.length ? this._focusedCell.row : this._focusedCell.row + 1, col: this._focusedCell.col };
                 break;
         }
-        // const pdoc = FieldValue(children[this._focusedCell.row]);
-        // pdoc && this.props.setPreviewDoc(pdoc);
     }
 
     @action
     changeFocusedCellByIndex = (row: number, col: number): void => {
-        // let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
-        // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []);
-
         this._focusedCell = { row: row, col: col };
         this.props.setFocused(this.props.Document);
-
-        // const fdoc = FieldValue(children[this._focusedCell.row]);
-        // fdoc && this.props.setPreviewDoc(fdoc);
     }
 
     createRow = () => {
-        // let doc = this.props.dataDoc ? this.props.dataDoc : this.props.Document;
-        // let children = Cast(doc[this.props.fieldKey], listSpec(Doc), []);
         let children = this.childDocs;
 
         let newDoc = Docs.Create.TextDocument({ width: 100, height: 30 });
         let proto = Doc.GetProto(newDoc);
         proto.title = "";
         children.push(newDoc);
+
         this.childDocs = children;
     }
 
     @action
     createColumn = () => {
         let index = 0;
-        let found = this.columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
+        let columns = this.columns;
+        let found = columns.findIndex(col => col.heading.toUpperCase() === "New field".toUpperCase()) > -1;
         if (!found) {
-            console.log("create column found");
-            this.columns.push(new SchemaHeaderField("New field", "#f1efeb"));
+            columns.push(new SchemaHeaderField("New field", "#f1efeb"));
+            this.columns = columns;
             return;
         }
         while (found) {
             index++;
-            found = this.columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
+            found = columns.findIndex(col => col.heading.toUpperCase() === ("New field (" + index + ")").toUpperCase()) > -1;
         }
-        console.log("create column new");
-        this.columns.push(new SchemaHeaderField("New field (" + index + ")", "#f1efeb"));
+        columns.push(new SchemaHeaderField("New field (" + index + ")", "#f1efeb"));
+        this.columns = columns;
     }
 
     @action
     deleteColumn = (key: string) => {
-        console.log("deleting columnnn");
-        let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
-        if (list === undefined) {
-            console.log("delete column");
-            this.props.Document.schemaColumns = list = new List<SchemaHeaderField>([]);
+        let columns = this.columns;
+        // let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
+        if (columns === undefined) {
+            this.columns = new List<SchemaHeaderField>([]);
         } else {
-            const index = list.map(c => c.heading).indexOf(key);
+            const index = columns.map(c => c.heading).indexOf(key);
             if (index > -1) {
-                list.splice(index, 1);
+                columns.splice(index, 1);
+                this.columns = columns;
             }
         }
     }
 
     @action
     changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
-        console.log("changingin columnsdfhs");
-        let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
-        if (list === undefined) {
-            console.log("change columns new");
-            this.props.Document.schemaColumns = list = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "#f1efeb")]);
+        // let list = Cast(this.props.Document.schemaColumns, listSpec(SchemaHeaderField));
+        let columns = this.columns;
+        if (columns === undefined) {
+            // console.log("change columns new");
+            this.columns = new List<SchemaHeaderField>([new SchemaHeaderField(newKey, "f1efeb")]);
         } else {
-            console.log("change column");
             if (addNew) {
-                this.columns.push(new SchemaHeaderField(newKey, "#f1efeb"));
+                columns.push(new SchemaHeaderField(newKey, "f1efeb"));
+                this.columns = columns;
             } else {
-                const index = list.map(c => c.heading).indexOf(oldKey);
+                const index = columns.map(c => c.heading).indexOf(oldKey);
                 if (index > -1) {
-                    list[index] = new SchemaHeaderField(newKey, "#f1efeb");
+                    columns[index] = new SchemaHeaderField(newKey, columns[index].color);
+                    this.columns = columns;
                 }
             }
         }
@@ -667,16 +638,39 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         return NumCast(typesDoc[column.heading]);
     }
 
-    setColumnType = (key: string, type: ColumnType): void => {
-        if (columnTypes.get(key)) return;
-        const typesDoc = FieldValue(Cast(this.props.Document.schemaColumnTypes, Doc));
-        if (!typesDoc) {
-            let newTypesDoc = new Doc();
-            newTypesDoc[key] = type;
-            this.props.Document.schemaColumnTypes = newTypesDoc;
-            return;
-        } else {
-            typesDoc[key] = type;
+    setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
+        if (columnTypes.get(columnField.heading)) return;
+
+        let columns = this.columns;
+        let index = columns.indexOf(columnField);
+        if (index > -1) {
+            // let column = columns[index];
+            columnField.type = NumCast(type);
+            columns[index] = columnField;
+            this.columns = columns;
+        }
+
+        // const typesDoc = FieldValue(Cast(this.props.Document.schemaColumnTypes, Doc));
+        // if (!typesDoc) {
+        //     let newTypesDoc = new Doc();
+        //     newTypesDoc[key] = type;
+        //     this.props.Document.schemaColumnTypes = newTypesDoc;
+        //     return;
+        // } else {
+        //     typesDoc[key] = type;
+        // }
+    }
+
+    setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
+        // console.log("setting color", key);
+        let columns = this.columns;
+        let index = columns.indexOf(columnField);
+        if (index > -1) {
+            // let column = columns[index];
+            columnField.color = color;
+            columns[index] = columnField;
+            this.columns = columns;
+            console.log(columnField, this.columns[index]);
         }
     }
 
@@ -694,7 +688,8 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         if (oldIndex === newIndex) return;
 
         columns.splice(newIndex, 0, columns.splice(oldIndex, 1)[0]);
-        this.setColumns(columns);
+        this.columns = columns;
+        // this.setColumns(columns);
     }
 
     @action
@@ -725,14 +720,18 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     }
 
     @action
-    textWrapRow = (doc: Doc): void => {
-        let index = this._textWrappedRows.findIndex(id => doc[Id] === id);
+    toggleTextWrapRow = (doc: Doc): void => {
+        let textWrapped = this.textWrappedRows;
+        let index = textWrapped.findIndex(id => doc[Id] === id);
+        console.log("toggle text wrap", index);
+
         if (index > -1) {
-            this._textWrappedRows.splice(index, 1);
+            textWrapped.splice(index, 1);
         } else {
-            this._textWrappedRows.push(doc[Id]);
+            textWrapped.push(doc[Id]);
         }
 
+        this.textWrappedRows = textWrapped;
     }
 
     @computed
@@ -748,7 +747,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         let expanded = {};
         //@ts-ignore
         expandedRowsList.forEach(row => expanded[row] = true);
-        console.log(...[...this._textWrappedRows]); // TODO: get component to rerender on text wrap change without needign to console.log :((((
+        console.log("text wrapped rows", ...[...this.textWrappedRows]); // TODO: get component to rerender on text wrap change without needign to console.log :((((
 
         return <ReactTable
             style={{ position: "relative", float: "left", width: `calc(100% - ${previewWidth}px` }}
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 2bffe3cc0..8691bea8a 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -17,6 +17,9 @@ import { CompileScript } from "../../util/Scripting";
 import { ScriptField } from "../../../new_fields/ScriptField";
 import { CollectionSchemaView } from "./CollectionSchemaView";
 import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
+import { listSpec } from "../../../new_fields/Schema";
+import { List } from "../../../new_fields/List";
+import { Id } from "../../../new_fields/FieldSymbols";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -365,6 +368,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
 
 @observer
 export class CollectionSchemaViewChrome extends React.Component<CollectionViewChromeProps> {
+    // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
 
     togglePreview = () => {
         let dividerWidth = 4;
@@ -373,14 +377,43 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
         let previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
         let tableWidth = panelWidth - 2 * borderWidth - dividerWidth - previewWidth;
         this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
+    }
 
+    @action
+    toggleTextwrap = async () => {
+        console.log("toggle text wrap");
+        let textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
+        if (textwrappedRows.length) {
+            console.log("unwrap");
+            this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>([]);
+        } else {
+            console.log("wrap");
+            let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
+                = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
+            if (typeof docs === "function") {
+                docs = docs();
+            }
+            docs = await docs;
+            if (docs instanceof Doc) {
+                let allRows = [docs[Id]];
+                console.log(...[...allRows]);
+                this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
+            } else {
+                let allRows = docs.map(doc => doc[Id]);
+                console.log(...[...allRows]);
+                this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
+            }
+        }
     }
 
 
     render() {
         let previewWidth = NumCast(this.props.CollectionView.props.Document.schemaPreviewWidth);
+        let textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
+
         return (
             <div className="collectionStackingViewChrome-cont">
+                <div id=""><input type="checkbox" key={"Toggle textwrap"} checked={textWrapped} onChange={this.toggleTextwrap} />Textwrap</div>
                 <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={previewWidth !== 0} onChange={this.togglePreview} />Show Preview</div>
             </div>
         );
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 7decadbe9..476a0f957 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -135,7 +135,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
                 doc.width = 200;
                 docList.push(doc);
             }
-            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
+            let newCol = Docs.Create.SchemaDocument([...(groupAttr ? [new SchemaHeaderField("_group", "#f1efeb")] : []), ...columns.filter(c => c).map(c => new SchemaHeaderField(c, "#f1efeb"))], docList, { x: x, y: y, title: "droppedTable", width: 300, height: 100 });
 
             this.props.addDocument(newCol, false);
         }
diff --git a/src/new_fields/SchemaHeaderField.ts b/src/new_fields/SchemaHeaderField.ts
index 475296d5c..9f716bf9f 100644
--- a/src/new_fields/SchemaHeaderField.ts
+++ b/src/new_fields/SchemaHeaderField.ts
@@ -6,7 +6,7 @@ import { scriptingGlobal, Scripting } from "../client/util/Scripting";
 import { ColumnType } from "../client/views/collections/CollectionSchemaView";
 
 export const PastelSchemaPalette = new Map<string, string>([
-    ["pink1", "#FFB4E8"],
+    // ["pink1", "#FFB4E8"],
     ["pink2", "#ff9cee"],
     ["pink3", "#ffccf9"],
     ["pink4", "#fcc2ff"],
@@ -32,7 +32,7 @@ export const PastelSchemaPalette = new Map<string, string>([
     ["yellow2", "#e7ffac"],
     ["yellow3", "#ffffd1"],
     ["yellow4", "#fff5ba"],
-    ["red1", "#ffc9de"],
+    // ["red1", "#ffc9de"],
     ["red2", "#ffabab"],
     ["red3", "#ffbebc"],
     ["red4", "#ffcbc1"],
@@ -45,15 +45,16 @@ export const RandomPastel = () => Array.from(PastelSchemaPalette.values())[Math.
 export class SchemaHeaderField extends ObjectField {
     @serializable(primitive())
     heading: string;
+    @serializable(primitive())
     color: string;
+    @serializable(primitive())
     type: number;
 
-    constructor(heading: string = "", color: string, type?: ColumnType) {
-        console.log("CREATING SCHEMA HEADER FIELD");
+    constructor(heading: string = "", color: string = RandomPastel(), type?: ColumnType) {
         super();
 
         this.heading = heading;
-        this.color = color === undefined ? "#000" : color;
+        this.color = color;
         if (type) {
             this.type = type;
         }
-- 
cgit v1.2.3-70-g09d2


From 6efe31636305bf5120d472f456b69d1b699b2ae8 Mon Sep 17 00:00:00 2001
From: fawn <fangrui_tong@brown.edu>
Date: Mon, 29 Jul 2019 22:48:31 -0400
Subject: styled toggle buttons on schema chrome

---
 .../views/collections/CollectionSchemaView.scss    |  3 +-
 .../views/collections/CollectionSchemaView.tsx     |  6 ---
 .../views/collections/CollectionViewChromes.scss   | 51 ++++++++++++++++++++++
 .../views/collections/CollectionViewChromes.tsx    | 29 ++++++++----
 4 files changed, 73 insertions(+), 16 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index dc6ca060d..e826ff63a 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -492,7 +492,8 @@ button.add-column {
 }
 
 .collectionSchemaView-table {
-    width: calc(100% - 7px);
+    // width: calc(100% - 7px);
+    width: 100%;
     height: 100%;
     // overflow-y: scroll;
     overflow: visible;
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 0f9c9ca51..26b19474a 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -122,7 +122,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @action
     onDividerMove = (e: PointerEvent): void => {
         let nativeWidth = this._mainCont!.getBoundingClientRect();
-        console.log("divider", nativeWidth.right - nativeWidth.left, this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0]);
         let minWidth = 40;
         let maxWidth = 1000;
         let movedWidth = this.props.ScreenToLocalTransform().transformDirection(nativeWidth.right - e.clientX, 0)[0];
@@ -240,8 +239,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     }
 
     render() {
-        // if (SelectionManager.SelectedDocuments().length > 0) console.log(StrCast(SelectionManager.SelectedDocuments()[0].Document.title));
-        // if (DocumentManager.Instance.getDocumentView(this.props.Document)) console.log(StrCast(this.props.Document.title), SelectionManager.IsSelected(DocumentManager.Instance.getDocumentView(this.props.Document)!))
         return (
             <div className="collectionSchemaView-container" style={{ height: this.chromeCollapsed ? "100%" : "calc(100% - 70px" }}>
                 <div className="collectionSchemaView-tableContainer" onPointerDown={this.onPointerDown} onWheel={this.onWheel} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createTarget}>
@@ -419,7 +416,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         // convert old schema columns (list of strings) into new schema columns (list of schema header fields)
         let oldSchemaColumns = Cast(this.props.Document.schemaColumns, listSpec("string"), []);
         if (oldSchemaColumns && oldSchemaColumns.length && typeof oldSchemaColumns[0] !== "object") {
-            console.log("REMAKING COLUMNs");
             let newSchemaColumns = oldSchemaColumns.map(i => typeof i === "string" ? new SchemaHeaderField(i, "#f1efeb") : i);
             this.props.Document.schemaColumns = new List<SchemaHeaderField>(newSchemaColumns);
         }
@@ -720,7 +716,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
     toggleTextWrapRow = (doc: Doc): void => {
         let textWrapped = this.textWrappedRows;
         let index = textWrapped.findIndex(id => doc[Id] === id);
-        console.log("toggle text wrap", index);
 
         if (index > -1) {
             textWrapped.splice(index, 1);
@@ -736,7 +731,6 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         let children = this.childDocs;
 
         let previewWidth = this.previewWidth(); // + 2 * this.borderWidth + this.DIVIDER_WIDTH + 1;
-        console.log(previewWidth);
         let hasCollectionChild = children.reduce((found, doc) => found || doc.type === "collection", false);
         let expandedRowsList = this._openCollections.map(col => children.findIndex(doc => doc[Id] === col).toString());
         let expanded = {};
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index f9f3ce473..933ba7411 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -165,4 +165,55 @@
             cursor: text;
         }
     }
+}
+
+.collectionSchemaViewChrome-cont {
+    display: flex;
+    font-size: 10.5px;
+
+    .collectionSchemaViewChrome-toggle {
+        display: flex;
+        margin-left: 10px;
+    }
+
+    .collectionSchemaViewChrome-label {
+        text-transform: uppercase;
+        letter-spacing: 2px;
+        margin-right: 5px;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+    }
+
+    .collectionSchemaViewChrome-toggler {
+        width: 100px;
+        height: 41px;
+        background-color: black;
+        position: relative;
+    }
+
+    .collectionSchemaViewChrome-togglerButton {
+        width: 47px;
+        height: 35px;
+        background-color: lightgray;
+        // position: absolute;
+        transition: all 0.5s ease;
+        // top: 3px;
+        margin-top: 3px;
+        color: gray;
+        letter-spacing: 2px;
+        text-transform: uppercase;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        text-align: center;
+
+        &.on {
+            margin-left: 3px;
+        }
+
+        &.off {
+            margin-left: 50px;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 8691bea8a..92afb3888 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -20,6 +20,7 @@ import { COLLECTION_BORDER_WIDTH } from "../globalCssVariables.scss";
 import { listSpec } from "../../../new_fields/Schema";
 import { List } from "../../../new_fields/List";
 import { Id } from "../../../new_fields/FieldSymbols";
+import { threadId } from "worker_threads";
 const datepicker = require('js-datepicker');
 
 interface CollectionViewChromeProps {
@@ -381,13 +382,10 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
 
     @action
     toggleTextwrap = async () => {
-        console.log("toggle text wrap");
         let textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
         if (textwrappedRows.length) {
-            console.log("unwrap");
             this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>([]);
         } else {
-            console.log("wrap");
             let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
                 = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
             if (typeof docs === "function") {
@@ -396,11 +394,9 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
             docs = await docs;
             if (docs instanceof Doc) {
                 let allRows = [docs[Id]];
-                console.log(...[...allRows]);
                 this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
             } else {
                 let allRows = docs.map(doc => doc[Id]);
-                console.log(...[...allRows]);
                 this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
             }
         }
@@ -412,10 +408,25 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
         let textWrapped = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
 
         return (
-            <div className="collectionStackingViewChrome-cont">
-                <div id=""><input type="checkbox" key={"Toggle textwrap"} checked={textWrapped} onChange={this.toggleTextwrap} />Textwrap</div>
-                <div id="preview-schema-checkbox-div"><input type="checkbox" key={"Show Preview"} checked={previewWidth !== 0} onChange={this.togglePreview} />Show Preview</div>
-            </div>
+            <div className="collectionSchemaViewChrome-cont">
+                <div className="collectionSchemaViewChrome-toggle">
+                    <div className="collectionSchemaViewChrome-label">Wrap Text: </div>
+                    <div className="collectionSchemaViewChrome-toggler" onClick={this.toggleTextwrap}>
+                        <div className={"collectionSchemaViewChrome-togglerButton" + (textWrapped ? " on" : " off")}>
+                            {textWrapped ? "on" : "off"}
+                        </div>
+                    </div>
+                </div>
+
+                <div className="collectionSchemaViewChrome-toggle">
+                    <div className="collectionSchemaViewChrome-label">Show Preview: </div>
+                    <div className="collectionSchemaViewChrome-toggler" onClick={this.togglePreview}>
+                        <div className={"collectionSchemaViewChrome-togglerButton" + (previewWidth !== 0 ? " on" : " off")}>
+                            {previewWidth !== 0 ? "on" : "off"}
+                        </div>
+                    </div>
+                </div>
+            </div >
         );
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 5b455e2aaf119c7db1fe9ef22d71a3accf55a8e2 Mon Sep 17 00:00:00 2001
From: bob <bcz@cs.brown.edu>
Date: Tue, 30 Jul 2019 10:27:42 -0400
Subject: tweaks.

---
 src/client/apis/youtube/YoutubeBox.tsx             | 22 +++++++++-------------
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../views/collections/CollectionViewChromes.tsx    |  1 +
 3 files changed, 11 insertions(+), 14 deletions(-)

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

diff --git a/src/client/apis/youtube/YoutubeBox.tsx b/src/client/apis/youtube/YoutubeBox.tsx
index 019d191bc..7f9a3ad70 100644
--- a/src/client/apis/youtube/YoutubeBox.tsx
+++ b/src/client/apis/youtube/YoutubeBox.tsx
@@ -1,20 +1,16 @@
-import "../../views/nodes/WebBox.scss";
-import React = require("react");
-import { FieldViewProps, FieldView } from "../../views/nodes/FieldView";
-import { HtmlField } from "../../../new_fields/HtmlField";
-import { WebField } from "../../../new_fields/URLField";
+import { action, observable, runInAction } from 'mobx';
 import { observer } from "mobx-react";
-import { computed, reaction, IReactionDisposer, observable, action, runInAction } from 'mobx';
-import { DocumentDecorations } from "../../views/DocumentDecorations";
-import { InkingControl } from "../../views/InkingControl";
+import { Doc, DocListCastAsync } from "../../../new_fields/Doc";
+import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
 import { Utils } from "../../../Utils";
 import { DocServer } from "../../DocServer";
-import { NumCast, Cast, StrCast } from "../../../new_fields/Types";
-import "./YoutubeBox.scss";
 import { Docs } from "../../documents/Documents";
-import { Doc, DocListCastAsync } from "../../../new_fields/Doc";
-import { listSpec } from "../../../new_fields/Schema";
-import { List } from "../../../new_fields/List";
+import { DocumentDecorations } from "../../views/DocumentDecorations";
+import { InkingControl } from "../../views/InkingControl";
+import { FieldView, FieldViewProps } from "../../views/nodes/FieldView";
+import "../../views/nodes/WebBox.scss";
+import "./YoutubeBox.scss";
+import React = require("react");
 
 interface VideoTemplate {
     thumbnailUrl: string;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index b7ac8768f..212cc5477 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -85,7 +85,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
         }
         else {
             return [
-                (<CollectionViewBaseChrome CollectionView={this} type={type} collapse={this.collapse} />),
+                (<CollectionViewBaseChrome CollectionView={this} key="chrome" type={type} collapse={this.collapse} />),
                 this.SubViewHelper(type, renderProps)
             ];
         }
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 2bffe3cc0..38aafd3cc 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -208,6 +208,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                             <input className="collectionViewBaseChrome-viewSpecsInput"
                                 placeholder="FILTER DOCUMENTS"
                                 value={this.filterValue ? this.filterValue.script.originalScript : ""}
+                                onChange={(e) => { }}
                                 onPointerDown={this.openViewSpecs} />
                             <div className="collectionViewBaseChrome-viewSpecsMenu"
                                 onPointerDown={this.openViewSpecs}
-- 
cgit v1.2.3-70-g09d2


From f03f94accabc2336d1c143fcb80bb0c3f5b70d99 Mon Sep 17 00:00:00 2001
From: kimdahey <claire_kim1@brown.edu>
Date: Tue, 30 Jul 2019 13:29:27 -0400
Subject: added toggle button

---
 package.json                                       |  2 +
 .../views/collections/CollectionStackingView.scss  | 53 +++++++++++++++++++++-
 .../views/collections/CollectionStackingView.tsx   | 21 ++++++++-
 .../CollectionStackingViewFieldColumn.tsx          |  8 ++--
 .../views/collections/CollectionViewChromes.tsx    |  4 +-
 5 files changed, 78 insertions(+), 10 deletions(-)

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

diff --git a/package.json b/package.json
index 37052fde3..ae3a9d964 100644
--- a/package.json
+++ b/package.json
@@ -91,6 +91,7 @@
         "@types/prosemirror-transform": "^1.1.0",
         "@types/prosemirror-view": "^1.3.1",
         "@types/pug": "^2.0.4",
+        "@types/rc-switch": "^1.8.0",
         "@types/react": "^16.8.7",
         "@types/react-autosuggest": "^9.3.9",
         "@types/react-color": "^2.14.1",
@@ -170,6 +171,7 @@
         "pug": "^2.0.3",
         "query-string": "^6.8.1",
         "raw-loader": "^1.0.0",
+        "rc-switch": "^1.9.0",
         "react": "^16.8.4",
         "react-anime": "^2.2.0",
         "react-autosuggest": "^9.4.3",
diff --git a/src/client/views/collections/CollectionStackingView.scss b/src/client/views/collections/CollectionStackingView.scss
index 0cb01dc9d..3fcec265f 100644
--- a/src/client/views/collections/CollectionStackingView.scss
+++ b/src/client/views/collections/CollectionStackingView.scss
@@ -79,8 +79,8 @@
 
     .collectionStackingView-sectionHeader {
         text-align: center;
-        margin-left: 5px;
-        margin-right: 5px;
+        margin-left: 2px;
+        margin-right: 2px;
         margin-top: 10px;
         overflow: hidden;
 
@@ -102,6 +102,7 @@
             font-size: 75%;
             transition: transform 0.2s;
             position: relative;
+            width: 98%;
 
             .editableView-container-editing-oneLine,
             .editableView-container-editing {
@@ -184,4 +185,52 @@
         letter-spacing: 2px;
         height: fit-content;
     }
+
+    .rc-switch {
+        position: absolute;
+        display: inline-block;
+        bottom: 15px;
+        right: 15px;
+        width: 125px;
+        height: 54px;
+        border-radius: 40px 40px;
+    }
+
+    .rc-switch:after {
+        position: absolute;
+        width: 36px;
+        height: 36px;
+        left: 7px;
+        top: 9px;
+        border-radius: 50% 50%;
+        background-color: #fff;
+        content: " ";
+        cursor: pointer;
+        box-shadow: 0 2px 5px rgba(0, 0, 0, 0.26);
+        -webkit-transform: scale(1);
+        transform: scale(1);
+        transition: left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
+        -webkit-animation-timing-function: cubic-bezier(0.35, 0, 0.25, 1);
+        animation-timing-function: cubic-bezier(0.35, 0, 0.25, 1);
+        -webkit-animation-duration: 0.3s;
+        animation-duration: 0.3s;
+    }
+
+    .rc-switch-checked:after {
+        left: 80px;
+    }
+
+    .rc-switch-inner {
+        color: #fff;
+        font-size: 22px;
+        position: absolute;
+        left: 50px;
+        top: 14px;
+    }
+
+    .rc-switch-checked .rc-switch-inner {
+        left: 17px;
+    }
+
+
 }
\ No newline at end of file
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index bcf3a85d7..c6e889bb5 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -20,6 +20,7 @@ import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeade
 import { List } from "../../../new_fields/List";
 import { EditableView } from "../EditableView";
 import { CollectionViewProps } from "./CollectionBaseView";
+import Switch from 'rc-switch';
 
 @observer
 export class CollectionStackingView extends CollectionSubView(doc => doc) {
@@ -29,6 +30,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
     _sectionFilterDisposer?: IReactionDisposer;
     _docXfs: any[] = [];
     _columnStart: number = 0;
+    _toggleTitle: string = "author mode";
     @observable private cursor: CursorProperty = "grab";
     get sectionHeaders() { return Cast(this.props.Document.sectionHeaders, listSpec(SchemaHeaderField)); }
     @computed get chromeCollapsed() { return this.props.chromeCollapsed; }
@@ -269,6 +271,14 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
         return firstEntry[0].heading > secondEntry[0].heading ? 1 : -1;
     }
 
+    onToggle = (checked: Boolean) => {
+        if (checked) {
+            this.props.CollectionView.props.Document.chromeStatus = 'collapsed';
+        } else {
+            this.props.CollectionView.props.Document.chromeStatus = 'view-mode';
+        }
+    }
+
     render() {
         let headings = Array.from(this.Sections.keys());
         let editableViewProps = {
@@ -289,11 +299,18 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
                 {this.props.Document.sectionFilter ? Array.from(this.Sections.entries()).sort(this.sortFunc).
                     map(section => this.section(section[0], section[1])) :
                     this.section(undefined, this.filteredChildren)}
-                {(this.props.Document.sectionFilter && this.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
+                {(this.props.Document.sectionFilter && this.props.CollectionView.props.Document.chromeStatus !== 'view-mode') ?
                     <div key={`${this.props.Document[Id]}-addGroup`} className="collectionStackingView-addGroupButton"
-                        style={{ width: (this.columnWidth / (headings.length + (this.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? 1 : 0))) - 10, marginTop: 10 }}>
+                        style={{ width: (this.columnWidth / (headings.length + (this.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0))) - 10, marginTop: 10 }}>
                         <EditableView {...editableViewProps} />
                     </div> : null}
+                {this.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? <Switch
+                    onChange={this.onToggle}
+                    onClick={this.onToggle}
+                    defaultChecked={this.props.CollectionView.props.Document.chromeStatus !== 'view-mode'}
+                    checkedChildren="edit"
+                    unCheckedChildren="view"
+                /> : null}
             </div>
         );
     }
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index d8bed7e88..4f7de0c24 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -242,7 +242,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                 style={{
                     width: (style.columnWidth) /
                         ((uniqueHeadings.length +
-                            (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? 1 : 0)) || 1)
+                            (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0)) || 1)
                 }}>
                 {/* the default bucket (no key value) has a tooltip that describes what it is.
                     Further, it does not have a color and cannot be deleted. */}
@@ -265,7 +265,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
             </div> : (null);
         for (let i = 0; i < cols; i++) templatecols += `${style.columnWidth}px `;
         return (
-            <div key={heading} style={{ width: `${100 / ((uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? 1 : 0)) || 1)}%`, background: this._background }}
+            <div key={heading} style={{ width: `${100 / ((uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0)) || 1)}%`, background: this._background }}
                 ref={this.createColumnDropRef} onPointerEnter={this.pointerEntered} onPointerLeave={this.pointerLeave}>
                 {headingView}
                 <div key={`${heading}-stack`} className={`collectionStackingView-masonry${singleColumn ? "Single" : "Grid"}`}
@@ -283,9 +283,9 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
                     {this.children(this.props.docList)}
                     {singleColumn ? (null) : this.props.parent.columnDragger}
                 </div>
-                {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled') ?
+                {(this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode') ?
                     <div key={`${heading}-add-document`} className="collectionStackingView-addDocumentButton"
-                        style={{ width: style.columnWidth / (uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'disabled' ? 1 : 0)) }}>
+                        style={{ width: style.columnWidth / (uniqueHeadings.length + (this.props.parent.props.CollectionView.props.Document.chromeStatus !== 'view-mode' ? 1 : 0)) }}>
                         <EditableView {...newEditableViewProps} />
                     </div> : null}
             </div>
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 2bffe3cc0..9c751c4df 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -185,11 +185,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     render() {
         return (
-            <div className="collectionViewChrome-cont" style={{ marginTop: this._collapsed ? -70 : 0, height: 70 }}>
+            <div className="collectionViewChrome-cont" style={{ top: this._collapsed ? -100 : 0 }}>
                 <div className="collectionViewChrome">
                     <div className="collectionViewBaseChrome">
                         <button className="collectionViewBaseChrome-collapse"
-                            style={{ marginTop: this._collapsed ? 60 : 0, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
+                            style={{ top: this._collapsed ? 90 : 10, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
                             title="Collapse collection chrome" onClick={this.toggleCollapse}>
                             <FontAwesomeIcon icon="caret-up" size="2x" />
                         </button>
-- 
cgit v1.2.3-70-g09d2


From 7c3b56a2e4552308014aa011493b33e3b054be94 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Tue, 30 Jul 2019 16:33:27 -0400
Subject: fixed some scripting stuff on view specs

---
 src/client/views/collections/CollectionSubView.tsx      | 3 +++
 src/client/views/collections/CollectionViewChromes.scss | 3 ++-
 src/client/views/collections/CollectionViewChromes.tsx  | 9 +++++++--
 src/client/views/collections/KeyRestrictionRow.tsx      | 6 +++++-
 4 files changed, 17 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index a15ed8f94..7386eaba6 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -66,6 +66,9 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
                     if (res.success) {
                         return res.result;
                     }
+                    else {
+                        console.log(res.error);
+                    }
                 });
             }
             return docs;
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 989315194..c062c3261 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -37,9 +37,10 @@
             }
 
             .collectionViewBaseChrome-collapse {
-                transition: all .5s;
+                transition: all .5s opacity 0.2s;
                 position: absolute;
                 width: 40px;
+                transform-origin: top left;
             }
 
             .collectionViewBaseChrome-viewSpecs {
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 2bffe3cc0..0827cfef9 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -142,7 +142,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
             `return ${dateRestrictionScript} ${keyRestrictionScript.length ? "&&" : ""} ${keyRestrictionScript}` :
             `return ${keyRestrictionScript} ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
             "return true";
-        let compiled = CompileScript(fullScript, { params: { doc: Doc.name } });
+        let compiled = CompileScript(fullScript, { params: { doc: Doc.name }, typecheck: false });
         if (compiled.compiled) {
             this.props.CollectionView.props.Document.viewSpecScript = new ScriptField(compiled);
         }
@@ -189,7 +189,12 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                 <div className="collectionViewChrome">
                     <div className="collectionViewBaseChrome">
                         <button className="collectionViewBaseChrome-collapse"
-                            style={{ marginTop: this._collapsed ? 60 : 0, transform: `rotate(${this._collapsed ? 180 : 0}deg)` }}
+                            style={{
+                                marginTop: this._collapsed ? 60 : 0,
+                                transform: `rotate(${this._collapsed ? 180 : 0}deg) scale(${this._collapsed ? 0.5 : 1}) translate(${this._collapsed ? "-100%, -100%" : "0, 0"})`,
+                                opacity: (this._collapsed && !this.props.CollectionView.props.isSelected()) ? 0 : 0.9,
+                                left: (this._collapsed ? 0 : "unset"),
+                            }}
                             title="Collapse collection chrome" onClick={this.toggleCollapse}>
                             <FontAwesomeIcon icon="caret-up" size="2x" />
                         </button>
diff --git a/src/client/views/collections/KeyRestrictionRow.tsx b/src/client/views/collections/KeyRestrictionRow.tsx
index 9baa250a6..1b59547d8 100644
--- a/src/client/views/collections/KeyRestrictionRow.tsx
+++ b/src/client/views/collections/KeyRestrictionRow.tsx
@@ -2,6 +2,7 @@ import * as React from "react";
 import { observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
 import { PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+import { Doc } from "../../../new_fields/Doc";
 
 interface IKeyRestrictionProps {
     contains: boolean;
@@ -23,7 +24,10 @@ export default class KeyRestrictionRow extends React.Component<IKeyRestrictionPr
                 parsedValue = parsed;
                 type = "number";
             }
-            let scriptText = `${this._contains ? "" : "!"}((doc.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))`;
+            let scriptText = `${this._contains ? "" : "!"}(((doc.${this._key} && (doc.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))) ||
+                ((doc.data_ext && doc.data_ext.${this._key}) && (doc.data_ext.${this._key} as ${type})${type === "string" ? ".includes" : "<="}(${parsedValue}))))`;
+            // let doc = new Doc();
+            // ((doc.data_ext && doc.data_ext!.text) && (doc.data_ext!.text as string).includes("hello"));
             this.props.script(scriptText);
         }
         else {
-- 
cgit v1.2.3-70-g09d2


From a5646ecb3eac0a6cf8cfa9a915ea56b399106ef4 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Tue, 30 Jul 2019 20:08:46 -0400
Subject: chrome collapse in right place again

---
 .../views/collections/CollectionViewChromes.scss      |  3 +--
 .../views/collections/CollectionViewChromes.tsx       |  4 ++--
 src/client/views/search/FilterBox.scss                | 19 ++++++++++---------
 3 files changed, 13 insertions(+), 13 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 e1a612643..0c2665b1c 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -7,8 +7,6 @@
     z-index: 9001;
     transition: top .5s;
     background: lightgrey;
-    transition: margin-top .5s;
-    background: lightgray;
     padding: 10px;
 
     .collectionViewChrome {
@@ -41,6 +39,7 @@
                 position: absolute;
                 width: 40px;
                 transform-origin: top left;
+                // margin-top: 10px;
             }
 
             .collectionViewBaseChrome-viewSpecs {
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index 3bf96bf60..bf1f35a92 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -189,12 +189,12 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
 
     render() {
         return (
-            <div className="collectionViewChrome-cont" style={{ top: this._collapsed ? -100 : 0 }}>
+            <div className="collectionViewChrome-cont" style={{ top: this._collapsed ? -70 : 0 }}>
                 <div className="collectionViewChrome">
                     <div className="collectionViewBaseChrome">
                         <button className="collectionViewBaseChrome-collapse"
                             style={{
-                                marginTop: this._collapsed ? 60 : 0,
+                                top: this._collapsed ? 70 : 10,
                                 transform: `rotate(${this._collapsed ? 180 : 0}deg) scale(${this._collapsed ? 0.5 : 1}) translate(${this._collapsed ? "-100%, -100%" : "0, 0"})`,
                                 opacity: (this._collapsed && !this.props.CollectionView.props.isSelected()) ? 0 : 0.9,
                                 left: (this._collapsed ? 0 : "unset"),
diff --git a/src/client/views/search/FilterBox.scss b/src/client/views/search/FilterBox.scss
index 799c72e65..ebb39460d 100644
--- a/src/client/views/search/FilterBox.scss
+++ b/src/client/views/search/FilterBox.scss
@@ -166,15 +166,16 @@
         align-items: center;
         justify-content: center;
 
-    .save-filter,
-    .reset-filter,
-    .all-filter {
-        background-color: gray;
-    }
+        .save-filter,
+        .reset-filter,
+        .all-filter {
+            background-color: gray;
+        }
 
-    .save-filter:hover,
-    .reset-filter:hover,
-    .all-filter:hover {
-        background-color: $darker-alt-accent;
+        .save-filter:hover,
+        .reset-filter:hover,
+        .all-filter:hover {
+            background-color: $darker-alt-accent;
+        }
     }
 }
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From a28a3b79f81e82e4b3368c0e87d3a56c694cc3b4 Mon Sep 17 00:00:00 2001
From: Sam Wilkins <abdullah_ahmed@brown.edu>
Date: Tue, 30 Jul 2019 21:24:45 -0400
Subject: added undo to schema

---
 src/client/views/collections/CollectionSchemaCells.tsx         |  2 ++
 src/client/views/collections/CollectionSchemaHeaders.tsx       |  2 ++
 .../views/collections/CollectionSchemaMovableTableHOC.tsx      |  2 ++
 src/client/views/collections/CollectionSchemaView.tsx          | 10 ++++++++++
 src/client/views/collections/CollectionViewChromes.tsx         |  2 ++
 5 files changed, 18 insertions(+)

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

diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 61f21006e..4ff65b277 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -26,6 +26,7 @@ import { faExpand } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
 import { KeyCodes } from "../../northstar/utils/KeyCodes";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faExpand);
 
@@ -96,6 +97,7 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         if (typeof field === "object" && doc) this.props.setPreviewDoc(doc);
     }
 
+    @undoBatch
     applyToDoc = (doc: Doc, row: number, col: number, run: (args?: { [name: string]: any }) => any) => {
         const res = run({ this: doc, $r: row, $c: col, $: (r: number = 0, c: number = 0) => this.props.getField(r + row, c + col) });
         if (!res.success) return false;
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index 4f0681f6c..dfd65770e 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -11,6 +11,7 @@ import { emptyFunction } from "../../../Utils";
 import { contains } from "typescript-collections/dist/lib/arrays";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
 import { SchemaHeaderField, RandomPastel, PastelSchemaPalette } from "../../../new_fields/SchemaHeaderField";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faFile, faSortAmountDown, faSortAmountUp, faTimes);
 
@@ -286,6 +287,7 @@ class KeysDropdown extends React.Component<KeysDropdownProps> {
         this.props.setIsEditing(false);
     }
 
+    @undoBatch
     @action
     onKeyDown = (e: React.KeyboardEvent): void => {
         if (e.key === "Enter") {
diff --git a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
index 5741c4191..ec40043cc 100644
--- a/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
+++ b/src/client/views/collections/CollectionSchemaMovableTableHOC.tsx
@@ -13,6 +13,7 @@ import { faGripVertical, faTrash } from '@fortawesome/free-solid-svg-icons';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { DocumentManager } from "../../util/DocumentManager";
 import { PastelSchemaPalette, SchemaHeaderField } from "../../../new_fields/SchemaHeaderField";
+import { undoBatch } from "../../util/UndoManager";
 
 library.add(faGripVertical, faTrash);
 
@@ -196,6 +197,7 @@ export class MovableRow extends React.Component<MovableRowProps> {
         ContextMenu.Instance.addItem({ description: description, event: () => this.props.textWrapRow(this.props.rowInfo.original), icon: "file-pdf" });
     }
 
+    @undoBatch
     @action
     move: DragManager.MoveFunction = (doc: Doc, target: Doc, addDoc) => {
         let targetView = DocumentManager.Instance.getDocumentView(target);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 26b9de3e7..4d6bf437f 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -176,6 +176,8 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             />
         </div>;
     }
+
+    @undoBatch
     @action
     setPreviewScript = (script: string) => {
         this.previewScript = script;
@@ -552,6 +554,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.props.setFocused(this.props.Document);
     }
 
+    @undoBatch
     createRow = () => {
         let children = this.childDocs;
 
@@ -563,6 +566,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.childDocs = children;
     }
 
+    @undoBatch
     @action
     createColumn = () => {
         let index = 0;
@@ -581,6 +585,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.columns = columns;
     }
 
+    @undoBatch
     @action
     deleteColumn = (key: string) => {
         let columns = this.columns;
@@ -595,6 +600,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         }
     }
 
+    @undoBatch
     @action
     changeColumns = (oldKey: string, newKey: string, addNew: boolean) => {
         let columns = this.columns;
@@ -634,6 +640,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         return NumCast(typesDoc[column.heading]);
     }
 
+    @undoBatch
     setColumnType = (columnField: SchemaHeaderField, type: ColumnType): void => {
         if (columnTypes.get(columnField.heading)) return;
 
@@ -656,6 +663,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         // }
     }
 
+    @undoBatch
     setColumnColor = (columnField: SchemaHeaderField, color: string): void => {
         let columns = this.columns;
         let index = columns.indexOf(columnField);
@@ -671,6 +679,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.columns = columns;
     }
 
+    @undoBatch
     reorderColumns = (toMove: SchemaHeaderField, relativeTo: SchemaHeaderField, before: boolean, columnsValues: SchemaHeaderField[]) => {
         let columns = [...columnsValues];
         let oldIndex = columns.indexOf(toMove);
@@ -683,6 +692,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
         this.columns = columns;
     }
 
+    @undoBatch
     @action
     setColumnSort = (columnField: SchemaHeaderField, descending: boolean | undefined) => {
         let columns = this.columns;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index bf1f35a92..ecf78b8c1 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -377,6 +377,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
 export class CollectionSchemaViewChrome extends React.Component<CollectionViewChromeProps> {
     // private _textwrapAllRows: boolean = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []).length > 0;
 
+    @undoBatch
     togglePreview = () => {
         let dividerWidth = 4;
         let borderWidth = Number(COLLECTION_BORDER_WIDTH);
@@ -386,6 +387,7 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
         this.props.CollectionView.props.Document.schemaPreviewWidth = previewWidth === 0 ? Math.min(tableWidth / 3, 200) : 0;
     }
 
+    @undoBatch
     @action
     toggleTextwrap = async () => {
         let textwrappedRows = Cast(this.props.CollectionView.props.Document.textwrappedSchemaRows, listSpec("string"), []);
-- 
cgit v1.2.3-70-g09d2


From f953ab92c8e0d4bf54f90a6b7f22a86cf5985c38 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Tue, 30 Jul 2019 22:39:52 -0400
Subject: removed chrome (scrollbar) of collectionChrome when collapsed.  fixed
 make background.

---
 src/client/views/collections/CollectionView.tsx          | 14 ++++++--------
 src/client/views/collections/CollectionViewChromes.scss  |  1 +
 src/client/views/collections/CollectionViewChromes.tsx   |  2 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx        |  6 +++++-
 .../views/collections/collectionFreeForm/MarqueeView.tsx | 16 +++++++++++++---
 src/client/views/nodes/DocumentView.tsx                  |  9 +++++----
 6 files changed, 31 insertions(+), 17 deletions(-)

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

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 376aaf53f..34adc5840 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -1,11 +1,13 @@
 import { library } from '@fortawesome/fontawesome-svg-core';
-import { faProjectDiagram, faSignature, faColumns, faSquare, faTh, faImage, faThList, faTree, faEllipsisV, faFingerprint, faLaptopCode } from '@fortawesome/free-solid-svg-icons';
+import { faEye } from '@fortawesome/free-regular-svg-icons';
+import { faColumns, faEllipsisV, faFingerprint, faImage, faProjectDiagram, faSignature, faSquare, faTh, faThList, faTree } from '@fortawesome/free-solid-svg-icons';
+import { action, IReactionDisposer, observable, reaction, runInAction } from 'mobx';
 import { observer } from "mobx-react";
 import * as React from 'react';
-import { Doc, DocListCast, WidthSym, HeightSym } from '../../../new_fields/Doc';
+import { Doc } from '../../../new_fields/Doc';
 import { Id } from '../../../new_fields/FieldSymbols';
+import { StrCast } from '../../../new_fields/Types';
 import { CurrentUserUtils } from '../../../server/authentication/models/current_user_utils';
-import { undoBatch } from '../../util/UndoManager';
 import { ContextMenu } from "../ContextMenu";
 import { ContextMenuProps } from '../ContextMenuItem';
 import { FieldView, FieldViewProps } from '../nodes/FieldView';
@@ -15,11 +17,7 @@ import { CollectionFreeFormView } from './collectionFreeForm/CollectionFreeFormV
 import { CollectionSchemaView } from "./CollectionSchemaView";
 import { CollectionStackingView } from './CollectionStackingView';
 import { CollectionTreeView } from "./CollectionTreeView";
-import { StrCast, PromiseValue } from '../../../new_fields/Types';
-import { DocumentType } from '../../documents/Documents';
-import { CollectionStackingViewChrome, CollectionViewBaseChrome } from './CollectionViewChromes';
-import { observable, action, runInAction, IReactionDisposer, reaction } from 'mobx';
-import { faEye } from '@fortawesome/free-regular-svg-icons';
+import { CollectionViewBaseChrome } from './CollectionViewChromes';
 export const COLLECTION_BORDER_WIDTH = 2;
 
 library.add(faTh);
diff --git a/src/client/views/collections/CollectionViewChromes.scss b/src/client/views/collections/CollectionViewChromes.scss
index 0c2665b1c..793cb7a8b 100644
--- a/src/client/views/collections/CollectionViewChromes.scss
+++ b/src/client/views/collections/CollectionViewChromes.scss
@@ -14,6 +14,7 @@
         grid-template-columns: 1fr auto;
         padding-bottom: 10px;
         border-bottom: .5px solid rgb(180, 180, 180);
+        overflow: hidden;
 
         .collectionViewBaseChrome {
             display: flex;
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index ecf78b8c1..1b2561953 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -213,7 +213,7 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="5">Stacking View</option>
                             <option className="collectionViewBaseChrome-viewOption" onPointerDown={stopPropagation} value="6">Masonry View</option>
                         </select>
-                        <div className="collectionViewBaseChrome-viewSpecs">
+                        <div className="collectionViewBaseChrome-viewSpecs" style={{ display: this._collapsed ? "none" : "grid" }}>
                             <input className="collectionViewBaseChrome-viewSpecsInput"
                                 placeholder="FILTER DOCUMENTS"
                                 value={this.filterValue ? this.filterValue.script.originalScript : ""}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index cbab14976..3cead34e6 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -310,7 +310,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
     onDragOver = (): void => {
     }
 
-    bringToFront = (doc: Doc) => {
+    bringToFront = (doc: Doc, sendToBack?: boolean) => {
+        if (sendToBack) {
+            doc.zIndex = 0;
+            return;
+        }
         const docs = this.childDocs;
         docs.slice().sort((doc1, doc2) => {
             if (doc1 === doc) return 1;
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 07d06d053..b9ee588dd 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -370,15 +370,25 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
         let selRect = this.Bounds;
         let selection: Doc[] = [];
         this.props.activeDocuments().filter(doc => !doc.isBackground).map(doc => {
-            var z = NumCast(doc.zoomBasis, 1);
             var x = NumCast(doc.x);
             var y = NumCast(doc.y);
-            var w = NumCast(doc.width) / z;
-            var h = NumCast(doc.height) / z;
+            var w = NumCast(doc.width);
+            var h = NumCast(doc.height);
             if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
                 selection.push(doc);
             }
         });
+        if (!selection.length) {
+            this.props.activeDocuments().map(doc => {
+                var x = NumCast(doc.x);
+                var y = NumCast(doc.y);
+                var w = NumCast(doc.width);
+                var h = NumCast(doc.height);
+                if (this.intersectRect({ left: x, top: y, width: w, height: h }, selRect)) {
+                    selection.push(doc);
+                }
+            });
+        }
         return selection;
     }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 51662274d..14f0b5a5a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -96,7 +96,7 @@ export interface DocumentViewProps {
     selectOnLoad: boolean;
     parentActive: () => boolean;
     whenActiveChanged: (isActive: boolean) => void;
-    bringToFront: (doc: Doc) => void;
+    bringToFront: (doc: Doc, sendToBack?: boolean) => void;
     addDocTab: (doc: Doc, dataDoc: Doc | undefined, where: string) => void;
     collapseToPoint?: (scrpt: number[], expandedDocs: Doc[] | undefined) => void;
     zoomToScale: (scale: number) => void;
@@ -529,7 +529,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @undoBatch
     @action
     makeBackground = (): void => {
-        this.props.Document.isBackground = true;
+        this.props.Document.isBackground = !this.props.Document.isBackground;
+        this.props.Document.isBackground && this.props.bringToFront(this.props.Document, true);
     }
 
     @undoBatch
@@ -568,7 +569,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
         cm.addItem({ description: "Transcribe Speech", event: this.listen, icon: "microphone" });
         let makes: ContextMenuProps[] = [];
-        makes.push({ description: "Make Background", event: this.makeBackground, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
+        makes.push({ description: this.props.Document.isBackground ? "Remove Background" : "Make Background", event: this.makeBackground, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
         makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });
         makes.push({
             description: "Make Portal", event: () => {
@@ -708,7 +709,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             <div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
                 ref={this._mainCont}
                 style={{
-                    pointerEvents: this.layoutDoc.isBackground ? "none" : "all",
+                    pointerEvents: this.layoutDoc.isBackground && !this.isSelected() ? "none" : "all",
                     color: foregroundColor,
                     outlineColor: "maroon",
                     outlineStyle: "dashed",
-- 
cgit v1.2.3-70-g09d2

