From 25ec1ef48c36ad91dccc408fa6075f0915c36118 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Tue, 21 Jul 2020 17:18:07 -0500
Subject: finished left side UI changes

---
 src/client/views/collections/CollectionView.tsx | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

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

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index c1da23470..21b0045d5 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -80,6 +80,7 @@ export interface CollectionViewCustomProps {
     childLayoutTemplate?: () => Opt<Doc>;  // specify a layout Doc template to use for children of the collection
     childLayoutString?: string;  // specify a layout string to use for children of the collection
     childOpacity?: () => number;
+    hideFilter?: true;
 }
 
 export interface CollectionRenderProps {
@@ -559,7 +560,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         Utils.CorsProxy(Cast(d.data, ImageField)!.url.href) : Cast(d.data, ImageField)!.url.href
                     :
                     ""))}
-            {(!this.props.isSelected() || this.props.Document.hideFilterView) && !this.props.Document.forceActive ? (null) :
+            {this.props.hideFilter || this.props.Document.hideFilterView || !this.props.isSelected() && !this.props.Document.forceActive ? (null) :
                 <div className="collectionView-filterDragger" title="library View Dragger" onPointerDown={this.onPointerDown}
                     style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
             }
-- 
cgit v1.2.3-70-g09d2


From 47214818a4a6f423ed65ab90d2a5876bde370dc8 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 22 Jul 2020 10:22:27 -0500
Subject: framework for properties panel

---
 src/client/views/MainView.scss                     |  5 ++-
 src/client/views/collections/CollectionView.scss   | 35 ++++++++++++++++
 src/client/views/collections/CollectionView.tsx    | 49 ++++++++++++++++++++--
 .../collectionFreeForm/PropertiesView.scss         | 32 ++++++++++++++
 .../collectionFreeForm/PropertiesView.tsx          | 38 +++++++++++++++++
 5 files changed, 154 insertions(+), 5 deletions(-)
 create mode 100644 src/client/views/collections/collectionFreeForm/PropertiesView.scss
 create mode 100644 src/client/views/collections/collectionFreeForm/PropertiesView.tsx

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

diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 9454b0c78..9c04458fe 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -142,7 +142,7 @@
             margin-left: -13px;
             border-radius: 8px;
             width: 65px;
-            position: absolute;
+            position: relative;
             text-align: center;
             font-size: 9.5px;
             margin-top: 4px;
@@ -290,7 +290,8 @@
         width: 10px;
         height: 10px;
         float: right;
-        margin-right: 1px;
+        margin-right: 3px;
+        padding-top: 19px;
     }
 
 }
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index b630f9cf8..585f6865e 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -24,6 +24,41 @@
         border-right: unset;
         z-index: 2;
     }
+
+    .collectionView-propertiesDragger {
+        background-color: rgb(140, 139, 139);
+        height: 55px;
+        width: 15.5px;
+        position: absolute;
+        top: 55%;
+        border: 1px black solid;
+        border-radius: 0;
+        border-top-left-radius: 10px;
+        border-bottom-left-radius: 10px;
+        border-right: unset;
+        z-index: 2;
+
+        .collectionView-propertiesDragger-icon {
+            width: 10px;
+            height: 10px;
+            float: left;
+            margin-left: 3px;
+            padding-top: 19px;
+        }
+    }
+
+    .collectionView-propertiesView {
+        display: flex;
+        flex-direction: column;
+        width: 200px;
+        height: 100%;
+        position: absolute;
+        right: 0;
+        top: 0;
+        border-left: solid 1px;
+        z-index: 10;
+    }
+
     .collectionTimeView-treeView {
         display: flex;
         flex-direction: column;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 8b09281d5..44d22dd5d 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -49,6 +49,7 @@ import { CollectionTreeView } from "./CollectionTreeView";
 import './CollectionView.scss';
 import CollectionMenu from './CollectionMenu';
 import { SharingPermissions } from '../../util/SharingManager';
+import { PropertiesView } from './collectionFreeForm/PropertiesView';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -367,9 +368,22 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
     get _facetWidth() { return NumCast(this.props.Document._facetWidth); }
     set _facetWidth(value) { this.props.Document._facetWidth = value; }
 
-    bodyPanelWidth = () => this.props.PanelWidth() - this.facetWidth();
+    get _propertiesWidth() { return NumCast(this.props.Document._propertiesWidth); }
+    set _propertiesWidth(value) { this.props.Document._propertiesWidth = value; }
+
+    bodyPanelWidth = () => this.props.PanelWidth() - this.propertiesWidth();
     facetWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._facetWidth));
 
+    propertiesWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._propertiesWidth));
+
+    @computed get propertiesIcon() {
+        if (this.propertiesWidth() < 10) {
+            return "chevron-left";
+        } else {
+            return "chevron-right";
+        }
+    }
+
     @computed get dataDoc() {
         return (this.props.DataDoc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) :
             this.props.Document.resolvedDataDoc ? this.props.Document : Doc.GetProto(this.props.Document)); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
@@ -489,6 +503,14 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             return false;
         }), returnFalse, action(() => this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
     }
+
+    onDown = (e: React.PointerEvent) => {
+        setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
+            this._propertiesWidth = this.props.PanelWidth() - Math.max(this.props.ScreenToLocalTransform().transformPoint(e.clientX, 0)[0], 0);
+            return false;
+        }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
+    }
+
     filterBackground = () => "rgba(105, 105, 105, 0.432)";
     get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves)
     @computed get scriptField() {
@@ -558,6 +580,18 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 </div>
             </div>;
     }
+
+    @computed get propertiesView() {
+        TraceMobx();
+        return !this._propertiesWidth || this.props.dontRegisterView ? (null) :
+            <div className="collectionView-propertiesView" style={{
+                width: `${this.propertiesWidth()}px`,
+                overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
+            }}>
+                <PropertiesView />
+            </div>;
+    }
+
     childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
     childLayoutString = this.props.childLayoutString || StrCast(this.props.Document.childLayoutString);
 
@@ -588,11 +622,20 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         Utils.CorsProxy(Cast(d.data, ImageField)!.url.href) : Cast(d.data, ImageField)!.url.href
                     :
                     ""))}
-            {this.props.hideFilter || this.props.Document.hideFilterView || !this.props.isSelected() && !this.props.Document.forceActive ? (null) :
+            {/* {this.props.hideFilter || this.props.Document.hideFilterView || !this.props.isSelected() && !this.props.Document.forceActive ? (null) :
                 <div className="collectionView-filterDragger" title="library View Dragger" onPointerDown={this.onPointerDown}
                     style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
             }
-            {this.facetWidth() < 10 ? (null) : this.filterView}
+            {this.facetWidth() < 10 ? (null) : this.filterView} */}
+
+            {this.props.hideFilter || this.props.Document.hideFilterView || !this.props.isSelected() && !this.props.Document.forceActive ? (null) :
+                <div className="collectionView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onDown}
+                    style={{ right: this.propertiesWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }}>
+                    <div className="collectionView-propertiesDragger-icon">
+                        <FontAwesomeIcon icon={this.propertiesIcon} color="white" size="sm" /> </div>
+                </div>
+            }
+            {this.propertiesWidth() < 10 ? (null) : this.propertiesView}
         </div>);
     }
 }
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
new file mode 100644
index 000000000..d4cc53bfa
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -0,0 +1,32 @@
+.propertiesView {
+
+    background-color: rgb(168, 168, 168);
+    height: 100%;
+    z-index: 1;
+
+    .propertiesView-title {
+        background-color: rgb(134, 134, 134);
+        border-top: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+
+    .propertiesView-name {
+        border-top: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+
+    .propertiesView-settings {
+        border-top: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+
+    .propertiesView-fields {
+        border-top: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+
+    .propertiesView-layout {
+        border-top: 1px solid black;
+        border-bottom: 1px solid black;
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
new file mode 100644
index 000000000..4306453ea
--- /dev/null
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -0,0 +1,38 @@
+import React = require("react");
+import { observer } from "mobx-react";
+import "./PropertiesView.scss";
+import { observable, action } from "mobx";
+import { Doc } from "../../../../fields/Doc";
+import { DocumentView } from "../../nodes/DocumentView";
+
+
+// interface PropertiesViewProps {
+//     document: Doc;
+//     dataDoc: Doc;
+//     docView: DocumentView;
+//     width: number;
+// }
+
+@observer
+export class PropertiesView extends React.Component<{}> {
+
+    render() {
+        return <div className="propertiesView" >
+            <div className="propertiesView-title">
+                Properties
+            </div>
+            <div className="propertiesView-name">
+                Properties
+            </div>
+            <div className="propertiesView-settings">
+                Settings
+            </div>
+            <div className="propertiesView-fields">
+                Fields
+            </div>
+            <div className="propertiesView-layout">
+                Layout
+            </div>
+        </div>;
+    }
+} 
\ No newline at end of file
-- 
cgit v1.2.3-70-g09d2


From 5b025537f60ef9222c0203db378c0298cd3dc86f Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 22 Jul 2020 12:57:05 -0500
Subject: adding fields to properties column

---
 src/client/util/CurrentUserUtils.ts                |  8 +--
 src/client/views/EditableView.tsx                  |  2 +-
 src/client/views/MainView.scss                     |  5 +-
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../collectionFreeForm/PropertiesView.scss         | 43 +++++++++++++---
 .../collectionFreeForm/PropertiesView.tsx          | 60 +++++++++++++++++-----
 6 files changed, 93 insertions(+), 27 deletions(-)

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

diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 088e20a3e..1dd25ae30 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -660,7 +660,7 @@ export class CurrentUserUtils {
 
         CurrentUserUtils.workspaceStack = new PrefetchProxy(Docs.Create.TreeDocument([workspaces], {
             title: " ", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
-            treeViewTruncateTitleWidth: 150, hideFilterView: true,
+            treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false,
             lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
         })) as any as Doc;
 
@@ -679,7 +679,7 @@ export class CurrentUserUtils {
 
         CurrentUserUtils.catalogStack = new PrefetchProxy(Docs.Create.TreeDocument([catalog], {
             title: " ", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
-            treeViewTruncateTitleWidth: 150, hideFilterView: true,
+            treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false,
             lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
         })) as any as Doc;
 
@@ -703,7 +703,7 @@ export class CurrentUserUtils {
 
         CurrentUserUtils.closedStack = new PrefetchProxy(Docs.Create.TreeDocument([recentlyClosed], {
             title: " ", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
-            treeViewTruncateTitleWidth: 150, hideFilterView: true,
+            treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false,
             lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
         })) as any as Doc;
 
@@ -718,7 +718,7 @@ export class CurrentUserUtils {
         if (doc["tabs-button-library"] === undefined) {
             const libraryStack = new PrefetchProxy(Docs.Create.TreeDocument([workspaces, documents, recentlyClosed, doc], {
                 title: "Library", _xMargin: 5, _yMargin: 5, _gridGap: 5, forceActive: true, childDropAction: "alias",
-                treeViewTruncateTitleWidth: 150, hideFilterView: true,
+                treeViewTruncateTitleWidth: 150, hideFilterView: true, treeViewPreventOpen: false,
                 lockedPosition: true, boxShadow: "0 0", dontRegisterChildViews: true, targetDropAction: "same"
             })) as any as Doc;
             doc["tabs-button-library"] = new PrefetchProxy(Docs.Create.ButtonDocument({
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 25a87ab56..259a803a2 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -192,7 +192,7 @@ export class EditableView extends React.Component<EditableProps> {
             return (this.props.contents instanceof ObjectField ? (null) :
                 <div className={`editableView-container-editing${this.props.oneLine ? "-oneLine" : ""}`}
                     ref={this._ref}
-                    style={{ display: this.props.display, minHeight: "20px", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }}
+                    style={{ display: this.props.display, minHeight: "17px", whiteSpace: "nowrap", height: `${this.props.height ? this.props.height : "auto"}`, maxHeight: `${this.props.maxHeight}` }}
                     onClick={this.onClick} placeholder={this.props.placeholder}>
                     <span style={{
                         fontStyle: this.props.fontStyle, fontSize: this.props.fontSize,
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 9c04458fe..55280b231 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -121,6 +121,9 @@
     padding: 20px;
     padding-right: 50px;
 
+    overflow-y: scroll;
+    overflow-x: hidden;
+
     .mainView-menuPanel-button {
         width: 45px;
         height: 45px;
@@ -174,7 +177,7 @@
         background-color: dimgray;
         border-radius: 100%;
         transform-origin: top left;
-        margin-bottom: 23px;
+        margin-bottom: 20px;
         margin-top: 5px;
 
         margin-right: 25px;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 44d22dd5d..616e7995d 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -588,7 +588,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 width: `${this.propertiesWidth()}px`,
                 overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
             }}>
-                <PropertiesView />
+                <PropertiesView document={this.dataDoc} />
             </div>;
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index d4cc53bfa..bb5b80abd 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -1,32 +1,59 @@
 .propertiesView {
 
-    background-color: rgb(168, 168, 168);
+    background-color: rgb(205, 205, 205);
     height: 100%;
     z-index: 1;
+    font-family: "Noto Sans";
+    cursor: auto;
+
+    //overflow-y: scroll;
 
     .propertiesView-title {
-        background-color: rgb(134, 134, 134);
-        border-top: 1px solid black;
-        border-bottom: 1px solid black;
+        background-color: rgb(159, 159, 159);
+        text-align: center;
+        font-size: 18px;
+        font-weight: bold;
+        padding-top: 12px;
+        padding-bottom: 12px;
     }
 
     .propertiesView-name {
-        border-top: 1px solid black;
         border-bottom: 1px solid black;
+        padding: 8.5px;
+        font-size: 12.5px;
     }
 
     .propertiesView-settings {
-        border-top: 1px solid black;
         border-bottom: 1px solid black;
+        padding: 8.5px;
+        font-size: 12.5px;
+        font-weight: bold;
     }
 
     .propertiesView-fields {
-        border-top: 1px solid black;
         border-bottom: 1px solid black;
+        padding: 8.5px;
+
+        .propertiesView-fields-title {
+            font-size: 12.5px;
+            font-weight: bold;
+            padding-bottom: 7px;
+        }
+
+        .propertiesView-fields-content {
+            font-size: 10px;
+            margin-left: 5px;
+
+            &:hover {
+                cursor: pointer;
+            }
+        }
     }
 
     .propertiesView-layout {
-        border-top: 1px solid black;
         border-bottom: 1px solid black;
+        padding: 8.5px;
+        font-size: 12.5px;
+        font-weight: bold;
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 4306453ea..bc78fccdf 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -1,20 +1,54 @@
 import React = require("react");
 import { observer } from "mobx-react";
 import "./PropertiesView.scss";
-import { observable, action } from "mobx";
-import { Doc } from "../../../../fields/Doc";
+import { observable, action, computed } from "mobx";
+import { Doc, Field, DocListCast } from "../../../../fields/Doc";
 import { DocumentView } from "../../nodes/DocumentView";
+import { ComputedField } from "../../../../fields/ScriptField";
+import { EditableView } from "../../EditableView";
+import { KeyValueBox } from "../../nodes/KeyValueBox";
+import { Cast } from "../../../../fields/Types";
+import { listSpec } from "../../../../fields/Schema";
 
 
-// interface PropertiesViewProps {
-//     document: Doc;
-//     dataDoc: Doc;
-//     docView: DocumentView;
-//     width: number;
-// }
+interface PropertiesViewProps {
+    document: Doc;
+    //dataDoc: Doc;
+    //docView: DocumentView;
+}
 
 @observer
-export class PropertiesView extends React.Component<{}> {
+export class PropertiesView extends React.Component<PropertiesViewProps> {
+
+    @computed get expandedField() {
+        const ids: { [key: string]: string } = {};
+        const doc = this.props.document;
+        doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
+
+        const rows: JSX.Element[] = [];
+        for (const key of Object.keys(ids).slice().sort()) {
+            const contents = doc[key];
+            let contentElement: (JSX.Element | null)[] | JSX.Element = [];
+            contentElement = <EditableView key="editableView"
+                contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
+                height={13}
+                fontSize={10}
+                GetValue={() => Field.toKeyValueString(doc, key)}
+                SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
+            />;
+
+            rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+                <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+                &nbsp;
+                {contentElement}
+            </div>);
+        }
+        return rows;
+    }
+
+    @computed get layoutPreview() {
+        return "layout";
+    }
 
     render() {
         return <div className="propertiesView" >
@@ -22,16 +56,18 @@ export class PropertiesView extends React.Component<{}> {
                 Properties
             </div>
             <div className="propertiesView-name">
-                Properties
+                Collection
             </div>
             <div className="propertiesView-settings">
                 Settings
             </div>
             <div className="propertiesView-fields">
-                Fields
+                <div className="propertiesView-fields-title"> Fields</div>
+                <div className="propertiesView-fields-content"> {this.expandedField} </div>
             </div>
             <div className="propertiesView-layout">
-                Layout
+                <div>Layout</div>
+                <div>{this.layoutPreview}</div>
             </div>
         </div>;
     }
-- 
cgit v1.2.3-70-g09d2


From a99cef9945c1c4f9e5ff07663fc6db5cda2dcd50 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 22 Jul 2020 16:27:27 -0500
Subject: added layout section

---
 src/client/views/collections/CollectionView.tsx    |  7 +-
 .../collectionFreeForm/PropertiesView.scss         | 15 +++-
 .../collectionFreeForm/PropertiesView.tsx          | 82 +++++++++++++++++++---
 3 files changed, 92 insertions(+), 12 deletions(-)

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

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 616e7995d..eec68f9fc 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -588,7 +588,12 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 width: `${this.propertiesWidth()}px`,
                 overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
             }}>
-                <PropertiesView document={this.dataDoc} />
+                <PropertiesView dataDoc={this.dataDoc} Document={this.props.Document}
+                    width={this._propertiesWidth}
+                    height={this.props.PanelHeight()}
+                    renderDepth={this.props.renderDepth}
+                    ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                />
             </div>;
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index bb5b80abd..e81b1eeb4 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -51,9 +51,18 @@
     }
 
     .propertiesView-layout {
-        border-bottom: 1px solid black;
         padding: 8.5px;
-        font-size: 12.5px;
-        font-weight: bold;
+
+        .propertiesView-layout-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding-bottom: 7px;
+        }
+
+        .propertiesView-layout-content {
+            margin-left: 5px;
+            overflow: hidden;
+        }
+
     }
 }
\ No newline at end of file
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index bc78fccdf..27b0dbd9e 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -2,27 +2,58 @@ import React = require("react");
 import { observer } from "mobx-react";
 import "./PropertiesView.scss";
 import { observable, action, computed } from "mobx";
-import { Doc, Field, DocListCast } from "../../../../fields/Doc";
+import { Doc, Field, DocListCast, WidthSym, HeightSym } from "../../../../fields/Doc";
 import { DocumentView } from "../../nodes/DocumentView";
 import { ComputedField } from "../../../../fields/ScriptField";
 import { EditableView } from "../../EditableView";
 import { KeyValueBox } from "../../nodes/KeyValueBox";
-import { Cast } from "../../../../fields/Types";
+import { Cast, StrCast, NumCast } from "../../../../fields/Types";
 import { listSpec } from "../../../../fields/Schema";
+import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentView";
+import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZero, returnEmptyFilter, Utils } from "../../../../Utils";
+import { Id } from "../../../../fields/FieldSymbols";
+import { Transform } from "../../../util/Transform";
 
 
 interface PropertiesViewProps {
-    document: Doc;
-    //dataDoc: Doc;
+    dataDoc: Doc;
+    Document: Doc;
+    width: number;
+    height: number;
+    renderDepth: number;
+    ScreenToLocalTransform: () => Transform;
     //docView: DocumentView;
 }
 
 @observer
 export class PropertiesView extends React.Component<PropertiesViewProps> {
 
+    @computed get MAX_EMBED_HEIGHT() { return 200; }
+
+    rtfWidth = () => Math.min(this.props.Document?.[WidthSym](), this.props.width - 20);
+    rtfHeight = () => this.rtfWidth() <= this.props.Document?.[WidthSym]() ? Math.min(this.props.Document?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+
+    docWidth = () => {
+        const layoutDoc = this.props.Document;
+        const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+        if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
+        return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+    }
+    docHeight = () => {
+        const layoutDoc = this.props.Document;
+        return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
+            const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+            if (aspect) return this.docWidth() * aspect;
+            return layoutDoc._fitWidth ? (!this.props.dataDoc._nativeHeight ? NumCast(this.props.height) :
+                Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+                    NumCast(this.props.height)))) :
+                NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
+        })()));
+    }
+
     @computed get expandedField() {
         const ids: { [key: string]: string } = {};
-        const doc = this.props.document;
+        const doc = this.props.dataDoc;
         doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
 
         const rows: JSX.Element[] = [];
@@ -47,7 +78,42 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     }
 
     @computed get layoutPreview() {
-        return "layout";
+        const layoutDoc = Doc.Layout(this.props.Document);
+        const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
+        const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
+        return <div style={{ display: "inline-block", height: panelHeight() }} key={this.props.dataDoc[Id]}>
+            <ContentFittingDocumentView
+                Document={layoutDoc}
+                DataDoc={this.props.dataDoc}
+                LibraryPath={emptyPath}
+                renderDepth={this.props.renderDepth + 1}
+                rootSelected={returnFalse}
+                treeViewDoc={undefined}
+                backgroundColor={() => "lightgrey"}
+                fitToBox={false}
+                FreezeDimensions={true}
+                NativeWidth={layoutDoc.type ===
+                    StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
+                NativeHeight={layoutDoc.type ===
+                    StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
+                PanelWidth={panelWidth}
+                PanelHeight={panelHeight}
+                focus={returnFalse}
+                ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                docFilters={returnEmptyFilter}
+                ContainingCollectionDoc={undefined}
+                ContainingCollectionView={undefined}
+                addDocument={returnFalse}
+                moveDocument={undefined}
+                removeDocument={returnFalse}
+                parentActive={() => false}
+                whenActiveChanged={emptyFunction}
+                addDocTab={returnFalse}
+                pinToPres={emptyFunction}
+                bringToFront={returnFalse}
+                ContentScaling={returnOne}
+            />
+        </div>;
     }
 
     render() {
@@ -66,8 +132,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 <div className="propertiesView-fields-content"> {this.expandedField} </div>
             </div>
             <div className="propertiesView-layout">
-                <div>Layout</div>
-                <div>{this.layoutPreview}</div>
+                <div className="propertiesView-layout-title" >Layout</div>
+                <div className="propertiesView-layout-content">{this.layoutPreview}</div>
             </div>
         </div>;
     }
-- 
cgit v1.2.3-70-g09d2


From 66bcfb6364ca5d8b4a0fd26139966ea9d6c12f87 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 22 Jul 2020 18:07:45 -0500
Subject: adding buttons

---
 src/client/views/PropertiesButtons.scss            | 105 ++++++++
 src/client/views/PropertiesButtons.tsx             | 296 +++++++++++++++++++++
 src/client/views/collections/CollectionView.tsx    |   2 +
 .../collectionFreeForm/PropertiesView.scss         |  12 +
 .../collectionFreeForm/PropertiesView.tsx          |   8 +-
 5 files changed, 421 insertions(+), 2 deletions(-)
 create mode 100644 src/client/views/PropertiesButtons.scss
 create mode 100644 src/client/views/PropertiesButtons.tsx

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

diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
new file mode 100644
index 000000000..8dd5cec03
--- /dev/null
+++ b/src/client/views/PropertiesButtons.scss
@@ -0,0 +1,105 @@
+@import "globalCssVariables";
+
+$linkGap : 3px;
+
+.propertiesButtons-linkFlyout {
+    grid-column: 2/4;
+}
+
+.propertiesButtons-linkButton-empty:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
+}
+
+.propertiesButtons-linkButton-nonempty:hover {
+    background: $main-accent;
+    transform: scale(1.05);
+    cursor: pointer;
+}
+
+.propertiesButtons-linkButton-empty,
+.propertiesButtons-linkButton-nonempty {
+    height: 20px;
+    width: 20px;
+    border-radius: 50%;
+    opacity: 0.9;
+    pointer-events: auto;
+    background-color: $dark-color;
+    color: $light-color;
+    text-transform: uppercase;
+    letter-spacing: 2px;
+    font-size: 75%;
+    transition: transform 0.2s;
+    text-align: center;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+
+    &:hover {
+        background: $main-accent;
+        transform: scale(1.05);
+        cursor: pointer;
+    }
+}
+
+.propertiesButtons {
+    margin-top: $linkGap;
+    grid-column: 1/4;
+    width: max-content;
+    height: auto;
+    display: flex;
+    flex-direction: row;
+}
+
+.propertiesButtons-button {
+    pointer-events: auto;
+    padding-right: 5px;
+    width: 25px;
+}
+
+.propertiesButtons-linker {
+    height: 20px;
+    width: 20px;
+    text-align: center;
+    border-radius: 50%;
+    pointer-events: auto;
+    color: $dark-color;
+    border: $dark-color 1px solid;
+    transition: 0.2s ease all;
+}
+
+.propertiesButtons-linker:hover {
+    cursor: pointer;
+    transform: scale(1.05);
+}
+
+
+@-moz-keyframes spin {
+    100% {
+        -moz-transform: rotate(360deg);
+    }
+}
+
+@-webkit-keyframes spin {
+    100% {
+        -webkit-transform: rotate(360deg);
+    }
+}
+
+@keyframes spin {
+    100% {
+        -webkit-transform: rotate(360deg);
+        transform: rotate(360deg);
+    }
+}
+
+@keyframes shadow-pulse {
+    0% {
+        box-shadow: 0 0 0 0px rgba(0, 0, 0, 0.8);
+    }
+
+    100% {
+        box-shadow: 0 0 0 10px rgba(0, 255, 0, 0);
+    }
+}
\ No newline at end of file
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
new file mode 100644
index 000000000..842d0320f
--- /dev/null
+++ b/src/client/views/PropertiesButtons.tsx
@@ -0,0 +1,296 @@
+import { IconProp, library } from '@fortawesome/fontawesome-svg-core';
+import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faCheckCircle, faCloudUploadAlt, faLink, faPhotoVideo, faShare, faStopCircle, faSyncAlt, faTag, faTimes } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { Doc, DocListCast } from "../../fields/Doc";
+import { RichTextField } from '../../fields/RichTextField';
+import { Cast, NumCast } from "../../fields/Types";
+import { emptyFunction, setupMoveUpEvents } from "../../Utils";
+import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
+import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
+import { Docs, DocUtils } from '../documents/Documents';
+import { DragManager } from '../util/DragManager';
+import { CollectionDockingView, DockedFrameRenderer } from './collections/CollectionDockingView';
+import { ParentDocSelector } from './collections/ParentDocumentSelector';
+import './collections/ParentDocumentSelector.scss';
+import './PropertiesButtons.scss';
+import { MetadataEntryMenu } from './MetadataEntryMenu';
+import { DocumentView } from './nodes/DocumentView';
+import { GoogleRef } from "./nodes/formattedText/FormattedTextBox";
+import { TemplateMenu } from "./TemplateMenu";
+import { Template, Templates } from "./Templates";
+import React = require("react");
+import { Tooltip } from '@material-ui/core';
+const higflyout = require("@hig/flyout");
+export const { anchorPoints } = higflyout;
+export const Flyout = higflyout.default;
+
+library.add(faLink);
+library.add(faTag);
+library.add(faTimes);
+library.add(faArrowAltCircleDown);
+library.add(faArrowAltCircleUp);
+library.add(faArrowAltCircleRight);
+library.add(faStopCircle);
+library.add(faCheckCircle);
+library.add(faCloudUploadAlt);
+library.add(faSyncAlt);
+library.add(faShare);
+library.add(faPhotoVideo);
+
+const cloud: IconProp = "cloud-upload-alt";
+const fetch: IconProp = "sync-alt";
+
+enum UtilityButtonState {
+    Default,
+    OpenRight,
+    OpenExternally
+}
+
+@observer
+export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
+    private _dragRef = React.createRef<HTMLDivElement>();
+    private _pullAnimating = false;
+    private _pushAnimating = false;
+    private _pullColorAnimating = false;
+
+    @observable private pushIcon: IconProp = "arrow-alt-circle-up";
+    @observable private pullIcon: IconProp = "arrow-alt-circle-down";
+    @observable private pullColor: string = "white";
+    @observable public isAnimatingFetch = false;
+    @observable public isAnimatingPulse = false;
+
+    @observable private openHover: UtilityButtonState = UtilityButtonState.Default;
+
+    @observable public static Instance: PropertiesButtons;
+    public static hasPushedHack = false;
+    public static hasPulledHack = false;
+
+    public startPullOutcome = action((success: boolean) => {
+        if (!this._pullAnimating) {
+            this._pullAnimating = true;
+            this.pullIcon = success ? "check-circle" : "stop-circle";
+            setTimeout(() => runInAction(() => {
+                this.pullIcon = "arrow-alt-circle-down";
+                this._pullAnimating = false;
+            }), 1000);
+        }
+    });
+
+    public startPushOutcome = action((success: boolean) => {
+        this.isAnimatingPulse = false;
+        if (!this._pushAnimating) {
+            this._pushAnimating = true;
+            this.pushIcon = success ? "check-circle" : "stop-circle";
+            setTimeout(() => runInAction(() => {
+                this.pushIcon = "arrow-alt-circle-up";
+                this._pushAnimating = false;
+            }), 1000);
+        }
+    });
+
+    public setPullState = action((unchanged: boolean) => {
+        this.isAnimatingFetch = false;
+        if (!this._pullColorAnimating) {
+            this._pullColorAnimating = true;
+            this.pullColor = unchanged ? "lawngreen" : "red";
+            setTimeout(this.clearPullColor, 1000);
+        }
+    });
+
+    private clearPullColor = action(() => {
+        this.pullColor = "white";
+        this._pullColorAnimating = false;
+    });
+
+    //get view0() { return this.props.views()?.[0]; }
+
+    @computed
+    get considerGoogleDocsPush() {
+        const targetDoc = this.props.doc;
+        const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
+        const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`${published ? "Push" : "Publish"} to Google Docs`}</div></>}>
+            <div
+                className="propertiesButtons-linker"
+                style={{ animation }}
+                onClick={async () => {
+                    await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
+                    !published && runInAction(() => this.isAnimatingPulse = true);
+                    PropertiesButtons.hasPushedHack = false;
+                    targetDoc[Pushes] = NumCast(targetDoc[Pushes]) + 1;
+                }}>
+                <FontAwesomeIcon className="documentdecorations-icon" icon={published ? (this.pushIcon as any) : cloud} size={published ? "sm" : "xs"} />
+            </div></Tooltip>;
+    }
+
+    @computed
+    get considerGoogleDocsPull() {
+        const targetDoc = this.props.doc;
+        const dataDoc = targetDoc && Doc.GetProto(targetDoc);
+        const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
+
+        const title = (() => {
+            switch (this.openHover) {
+                default:
+                case UtilityButtonState.Default: return `${!dataDoc?.unchanged ? "Pull from" : "Fetch"} Google Docs`;
+                case UtilityButtonState.OpenRight: return "Open in Right Split";
+                case UtilityButtonState.OpenExternally: return "Open in new Browser Tab";
+            }
+        })();
+
+        return !targetDoc || !dataDoc || !dataDoc[GoogleRef] ? (null) : <Tooltip
+            title={<><div className="dash-tooltip">{title}</div></>}>
+            <div className="propertiesButtons-linker"
+                style={{ backgroundColor: this.pullColor }}
+                onPointerEnter={action(e => {
+                    if (e.altKey) {
+                        this.openHover = UtilityButtonState.OpenExternally;
+                    } else if (e.shiftKey) {
+                        this.openHover = UtilityButtonState.OpenRight;
+                    }
+                })}
+                onPointerLeave={action(() => this.openHover = UtilityButtonState.Default)}
+                onClick={async e => {
+                    const googleDocUrl = `https://docs.google.com/document/d/${dataDoc[GoogleRef]}/edit`;
+                    if (e.shiftKey) {
+                        e.preventDefault();
+                        let googleDoc = await Cast(dataDoc.googleDoc, Doc);
+                        if (!googleDoc) {
+                            const options = { _width: 600, _nativeWidth: 960, _nativeHeight: 800, isAnnotating: false, UseCors: false };
+                            googleDoc = Docs.Create.WebDocument(googleDocUrl, options);
+                            dataDoc.googleDoc = googleDoc;
+                        }
+                        CollectionDockingView.AddRightSplit(googleDoc);
+                    } else if (e.altKey) {
+                        e.preventDefault();
+                        window.open(googleDocUrl);
+                    } else {
+                        this.clearPullColor();
+                        PropertiesButtons.hasPulledHack = false;
+                        targetDoc[Pulls] = NumCast(targetDoc[Pulls]) + 1;
+                        dataDoc.unchanged && runInAction(() => this.isAnimatingFetch = true);
+                    }
+                }}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm"
+                    style={{ WebkitAnimation: animation, MozAnimation: animation }}
+                    icon={(() => {
+                        switch (this.openHover) {
+                            default:
+                            case UtilityButtonState.Default: return dataDoc.unchanged === false ? (this.pullIcon as any) : fetch;
+                            case UtilityButtonState.OpenRight: return "arrow-alt-circle-right";
+                            case UtilityButtonState.OpenExternally: return "share";
+                        }
+                    })()}
+                />
+            </div></Tooltip>;
+    }
+    @computed
+    get pinButton() {
+        const targetDoc = this.props.doc;
+        const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
+        return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
+            <div className="propertiesButtons-linker"
+                style={{ backgroundColor: isPinned ? "black" : "white", color: isPinned ? "white" : "black" }}
+                onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
+                <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
+                />
+            </div></Tooltip>;
+    }
+
+    @computed
+    get metadataButton() {
+        //const view0 = this.view0;
+        return <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
+            <div className="propertiesButtons-linkFlyout">
+                <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+                    content={<MetadataEntryMenu docs={[this.props.doc]} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
+                    <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
+                        {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
+                    </div>
+                </Flyout>
+            </div></Tooltip>;
+    }
+
+    // @computed
+    // get contextButton() {
+    //     return <ParentDocSelector Document={this.Document} addDocTab={(doc, where) => {
+    //         where === "onRight" ? CollectionDockingView.AddRightSplit(doc) :
+    //                 this.props.doc.props.addDocTab(doc, "onRight");
+    //         return true;
+    //     }} />;
+    // }
+
+    @observable _aliasDown = false;
+    onAliasButtonDown = (e: React.PointerEvent): void => {
+        //setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction);
+
+    }
+
+    // onAliasButtonMoved = () => {
+    //     if (this._dragRef.current) {
+    //         const dragDocView = this.props.doc!;
+    //         if (dragDocView.props){
+    //             const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
+    //             const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
+    //             dragData.dropAction = "alias";
+    //             DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, {
+    //             offsetX: dragData.offset[0],
+    //             offsetY: dragData.offset[1],
+    //             hideSource: false
+    //         });
+    //         return true;
+    //         }
+
+    //     }
+    //     return false;
+    // }
+
+    // @computed
+    // get templateButton() {
+    //     //const view0 = this.view0;
+    //     const templates: Map<Template, boolean> = new Map();
+    //     //const views = this.props.views();
+    //     Array.from(Object.values(Templates.TemplateList)).map(template =>
+    //         templates.set(template, views.reduce((checked, doc) => checked || doc?.props.Document["_show" + template.Name] ? true : false, false as boolean)));
+    //     return !this.props.doc ? (null) :
+    //         <Tooltip title={<><div className="dash-tooltip">Tap: Customize layout.  Drag: Create alias</div></>}>
+    //             <div className="propertiesButtons-linkFlyout" ref={this._dragRef}>
+    //                 <Flyout anchorPoint={anchorPoints.LEFT_TOP} onOpen={action(() => this._aliasDown = true)} onClose={action(() => this._aliasDown = false)}
+    //                     content={!this._aliasDown ? (null) : <TemplateMenu docViews={views.filter(v => v).map(v => v as DocumentView)} templates={templates} />}>
+    //                     <div className={"propertiesButtons-linkButton-empty"} ref={this._dragRef} onPointerDown={this.onAliasButtonDown} >
+    //                         {<FontAwesomeIcon className="documentdecorations-icon" icon="edit" size="sm" />}
+    //                     </div>
+    //                 </Flyout>
+    //             </div></Tooltip>;
+    // }
+
+    render() {
+        if (!this.props.doc) return (null);
+
+        const isText = this.props.doc[Doc.LayoutFieldKey(this.props.doc)] instanceof RichTextField;
+        const considerPull = isText && this.considerGoogleDocsPull;
+        const considerPush = isText && this.considerGoogleDocsPush;
+        return <div className="propertiesButtons">
+            {/* <div className="propertiesButtons-button">
+                {this.templateButton}
+            </div> */}
+            <div className="propertiesButtons-button">
+                {this.metadataButton}
+            </div>
+            {/* <div className="propertiesButtons-button">
+                {this.contextButton}
+            </div> */}
+            <div className="propertiesButtons-button">
+                {this.pinButton}
+            </div>
+            <div className="propertiesButtons-button" style={{ display: !considerPush ? "none" : "" }}>
+                {this.considerGoogleDocsPush}
+            </div>
+            <div className="propertiesButtons-button" style={{ display: !considerPull ? "none" : "" }}>
+                {this.considerGoogleDocsPull}
+            </div>
+        </div>;
+    }
+}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index eec68f9fc..853321d3c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -50,6 +50,7 @@ import './CollectionView.scss';
 import CollectionMenu from './CollectionMenu';
 import { SharingPermissions } from '../../util/SharingManager';
 import { PropertiesView } from './collectionFreeForm/PropertiesView';
+import { DocumentView } from '../nodes/DocumentView';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -589,6 +590,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
             }}>
                 <PropertiesView dataDoc={this.dataDoc} Document={this.props.Document}
+                    docView={CollectionView as unknown as DocumentView}
                     width={this._propertiesWidth}
                     height={this.props.PanelHeight()}
                     renderDepth={this.props.renderDepth}
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index e81b1eeb4..98eae1ac7 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -28,6 +28,18 @@
         padding: 8.5px;
         font-size: 12.5px;
         font-weight: bold;
+
+        .propertiesView-settings-title {
+            font-weight: bold;
+            font-size: 12.5px;
+            padding-bottom: 7px;
+        }
+
+        .propertiesView-settings-content {
+            margin-left: 5px;
+            padding-bottom: 10px;
+        }
+
     }
 
     .propertiesView-fields {
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 27b0dbd9e..5242aa8fd 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -13,6 +13,7 @@ import { ContentFittingDocumentView } from "../../nodes/ContentFittingDocumentVi
 import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZero, returnEmptyFilter, Utils } from "../../../../Utils";
 import { Id } from "../../../../fields/FieldSymbols";
 import { Transform } from "../../../util/Transform";
+import { PropertiesButtons } from "../../PropertiesButtons";
 
 
 interface PropertiesViewProps {
@@ -22,7 +23,7 @@ interface PropertiesViewProps {
     height: number;
     renderDepth: number;
     ScreenToLocalTransform: () => Transform;
-    //docView: DocumentView;
+    docView: DocumentView;
 }
 
 @observer
@@ -125,7 +126,10 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 Collection
             </div>
             <div className="propertiesView-settings">
-                Settings
+                <div className="propertiesView-settings-title"> Settings</div>
+                <div className="propertiesView-settings-content">
+                    <PropertiesButtons doc={this.props.Document} />
+                </div>
             </div>
             <div className="propertiesView-fields">
                 <div className="propertiesView-fields-title"> Fields</div>
-- 
cgit v1.2.3-70-g09d2


From 831fbc76ec1c6e9829da547cdef791ac087677d9 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Thu, 23 Jul 2020 11:08:54 -0500
Subject: moved right panel into mainview

---
 src/client/util/SelectionManager.ts                |  24 +++
 src/client/views/MainView.scss                     |  38 ++++
 src/client/views/MainView.tsx                      |  65 ++++++-
 src/client/views/PropertiesButtons.tsx             |  39 +++--
 src/client/views/collections/CollectionView.scss   |  34 ----
 src/client/views/collections/CollectionView.tsx    |  49 +-----
 .../collectionFreeForm/PropertiesView.tsx          | 193 +++++++++++++--------
 7 files changed, 262 insertions(+), 180 deletions(-)

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

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 9a968aeda..6fb758eac 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -12,9 +12,14 @@ export namespace SelectionManager {
 
         @observable IsDragging: boolean = false;
         SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
+
+        @observable public lastSelection: DocumentView | undefined;
+
         @action
         SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
 
+            this.lastSelection = docView;
+
             // if doc is not in SelectedDocuments, add it
             if (!manager.SelectedDocuments.get(docView)) {
                 if (!ctrlPressed) {
@@ -33,6 +38,15 @@ export namespace SelectionManager {
         }
         @action
         DeselectDoc(docView: DocumentView): void {
+
+            if (this.lastSelection === docView) {
+                const list = Array.from(manager.SelectedDocuments.keys());
+                if (list.length > 0) {
+                    this.lastSelection = list[list.length - 1];
+                } else {
+                    this.lastSelection = undefined;
+                }
+            }
             if (manager.SelectedDocuments.get(docView)) {
                 manager.SelectedDocuments.delete(docView);
                 docView.props.whenActiveChanged(false);
@@ -41,10 +55,16 @@ export namespace SelectionManager {
         }
         @action
         DeselectAll(): void {
+            this.lastSelection = undefined;
             Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false));
             manager.SelectedDocuments.clear();
             Doc.UserDoc().activeSelection = new List<Doc>([]);
         }
+
+        @action
+        getLast(): DocumentView | undefined {
+            return this.lastSelection;
+        }
     }
 
     const manager = new Manager();
@@ -56,6 +76,10 @@ export namespace SelectionManager {
         manager.SelectDoc(docView, ctrlPressed);
     }
 
+    export function LastSelection(): DocumentView | undefined {
+        return manager.getLast();
+    }
+
     // computed functions, such as used in IsSelected generate errors if they're called outside of a
     // reaction context.  Specifying the context with 'outsideReaction' allows an efficiency feature
     // to avoid unnecessary mobx invalidations when running inside a reaction.
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 55280b231..f64129600 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -102,6 +102,44 @@
     user-select: none;
 }
 
+.mainView-propertiesDragger {
+    background-color: rgb(140, 139, 139);
+    height: 55px;
+    width: 15.5px;
+    position: absolute;
+    top: 55%;
+    border: 1px black solid;
+    border-radius: 0;
+    border-top-left-radius: 10px;
+    border-bottom-left-radius: 10px;
+    border-right: unset;
+    z-index: 2;
+
+    .mainView-propertiesDragger-icon {
+        width: 10px;
+        height: 10px;
+        float: left;
+        margin-left: 3px;
+        padding-top: 19px;
+    }
+
+    &:hover {
+        cursor: pointer;
+    }
+}
+
+.mainiView-propertiesView {
+    display: flex;
+    flex-direction: column;
+    width: 200px;
+    height: 100%;
+    position: absolute;
+    right: 0;
+    top: 0;
+    border-left: solid 1px;
+    z-index: 10;
+}
+
 .mainView-flyoutContainer {
     display: flex;
     flex-direction: column;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 766626a82..88f072493 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -21,10 +21,10 @@ import { Doc, DocListCast, Field, Opt } from '../../fields/Doc';
 import { Id } from '../../fields/FieldSymbols';
 import { List } from '../../fields/List';
 import { listSpec } from '../../fields/Schema';
-import { BoolCast, Cast, FieldValue, StrCast } from '../../fields/Types';
+import { BoolCast, Cast, FieldValue, StrCast, NumCast } from '../../fields/Types';
 import { TraceMobx } from '../../fields/util';
 import { CurrentUserUtils } from '../util/CurrentUserUtils';
-import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter } from '../../Utils';
+import { emptyFunction, emptyPath, returnFalse, returnOne, returnZero, returnTrue, Utils, returnEmptyFilter, setupMoveUpEvents } from '../../Utils';
 import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
 import { DocServer } from '../DocServer';
 import { Docs, DocumentOptions } from '../documents/Documents';
@@ -66,7 +66,9 @@ import { LinkDescriptionPopup } from './nodes/LinkDescriptionPopup';
 import FormatShapePane from "./collections/collectionFreeForm/FormatShapePane";
 import HypothesisAuthenticationManager from '../apis/HypothesisAuthenticationManager';
 import CollectionMenu from './collections/CollectionMenu';
-import { Tooltip } from '@material-ui/core';
+import { Tooltip, AccordionActions } from '@material-ui/core';
+import { PropertiesView } from './collections/collectionFreeForm/PropertiesView';
+import { SelectionManager } from '../util/SelectionManager';
 
 @observer
 export class MainView extends React.Component {
@@ -90,9 +92,24 @@ export class MainView extends React.Component {
 
     @observable public sidebarContent: any = this.userDoc?.["tabs-panelContainer"];
     @observable public panelContent: string = "none";
+    @observable public showProperties: boolean = false;
 
+    @computed get selectedDocumentView() { return SelectionManager.LastSelection(); }
+    @observable selectedDoc: Doc | undefined = this.selectedDocumentView?.props.Document;
+    @observable selectedDataDoc: Doc | undefined = this.selectedDocumentView?.props.DataDoc ? this.selectedDocumentView.props.DataDoc : this.selectedDoc;
     public isPointerDown = false;
 
+    @observable _propertiesWidth: number = 0;
+    propertiesWidth = () => Math.max(0, Math.min(this._panelWidth - 50, this._propertiesWidth));
+
+    @computed get propertiesIcon() {
+        if (this.propertiesWidth() < 10) {
+            return "chevron-left";
+        } else {
+            return "chevron-right";
+        }
+    }
+
     componentDidMount() {
         DocServer.setPlaygroundFields(["dataTransition", "_viewTransition", "_panX", "_panY", "_viewScale", "_viewType", "_chromeStatus"]); // can play with these fields on someone else's
 
@@ -216,7 +233,7 @@ export class MainView extends React.Component {
         const freeformOptions: DocumentOptions = {
             x: 0,
             y: 400,
-            _width: this._panelWidth * .7,
+            _width: this._panelWidth * .7 - this._propertiesWidth,
             _height: this._panelHeight,
             title: "Collection " + workspaceCount,
         };
@@ -282,10 +299,13 @@ export class MainView extends React.Component {
 
     @action
     onResize = (r: any) => {
-        this._panelWidth = r.offset.width;
+        this._panelWidth = r.offset.width - this._propertiesWidth;
         this._panelHeight = r.offset.height;
     }
-    getPWidth = () => this._panelWidth;
+
+    @action
+    getPWidth = () => this._panelWidth - this._propertiesWidth;
+
     getPHeight = () => this._panelHeight;
     getContentsHeight = () => this._panelHeight - this._buttonBarHeight;
 
@@ -329,7 +349,6 @@ export class MainView extends React.Component {
             NativeWidth={returnZero}
             PanelWidth={this.getPWidth}
             PanelHeight={this.getPHeight}
-            renderDepth={0}
             focus={emptyFunction}
             parentActive={returnTrue}
             whenActiveChanged={emptyFunction}
@@ -570,6 +589,30 @@ export class MainView extends React.Component {
         }
     }
 
+    @action
+    onDown = (e: React.PointerEvent) => {
+        setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
+            this._propertiesWidth = this._panelWidth - Math.max(Transform.Identity().transformPoint(e.clientX, 0)[0], 0);
+            return false;
+        }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this._panelWidth - 50, 200) : 0), false);
+    }
+
+    @computed get propertiesView() {
+        TraceMobx();
+        return this._propertiesWidth === 0 ? (null) :
+            <div className="mainView-propertiesView" style={{
+                width: `${this.propertiesWidth()}px`,
+                overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
+            }}>
+                <PropertiesView
+                    width={this._propertiesWidth}
+                    height={this._panelHeight}
+                    renderDepth={1}
+                    ScreenToLocalTransform={Transform.Identity}
+                />
+            </div>;
+    }
+
     @computed get mainContent() {
         const n = (RichTextMenu.Instance?.Pinned ? 1 : 0) + (CollectionMenu.Instance?.Pinned ? 1 : 0);
         const height = `calc(100% - ${n * Number(ANTIMODEMENU_HEIGHT.replace("px", ""))}px)`;
@@ -606,6 +649,14 @@ export class MainView extends React.Component {
                         </div>
                     </div>
                     {this.dockingContent}
+                    {this.showProperties ? (null) :
+                        <div className="mainView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onDown}
+                            style={{ right: this._propertiesWidth - 1, top: "45%" }}>
+                            <div className="mainView-propertiesDragger-icon">
+                                <FontAwesomeIcon icon={this.propertiesIcon} color="white" size="sm" /> </div>
+                        </div>
+                    }
+                    {this.propertiesWidth() < 10 ? (null) : this.propertiesView}
                 </div>
             </div>);
     }
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 842d0320f..1b06a41fa 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -22,6 +22,7 @@ import { TemplateMenu } from "./TemplateMenu";
 import { Template, Templates } from "./Templates";
 import React = require("react");
 import { Tooltip } from '@material-ui/core';
+import { SelectionManager } from '../util/SelectionManager';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -49,7 +50,7 @@ enum UtilityButtonState {
 }
 
 @observer
-export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
+export class PropertiesButtons extends React.Component<{}, {}> {
     private _dragRef = React.createRef<HTMLDivElement>();
     private _pullAnimating = false;
     private _pushAnimating = false;
@@ -67,6 +68,9 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
     public static hasPushedHack = false;
     public static hasPulledHack = false;
 
+    @observable selectedDocumentView: DocumentView | undefined = SelectionManager.LastSelection();
+    @observable selectedDoc: Doc | undefined = this.selectedDocumentView?.props.Document;
+
     public startPullOutcome = action((success: boolean) => {
         if (!this._pullAnimating) {
             this._pullAnimating = true;
@@ -108,7 +112,7 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
 
     @computed
     get considerGoogleDocsPush() {
-        const targetDoc = this.props.doc;
+        const targetDoc = this.selectedDoc;
         const published = targetDoc && Doc.GetProto(targetDoc)[GoogleRef] !== undefined;
         const animation = this.isAnimatingPulse ? "shadow-pulse 1s linear infinite" : "none";
         return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{`${published ? "Push" : "Publish"} to Google Docs`}</div></>}>
@@ -127,7 +131,7 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
 
     @computed
     get considerGoogleDocsPull() {
-        const targetDoc = this.props.doc;
+        const targetDoc = this.selectedDoc;
         const dataDoc = targetDoc && Doc.GetProto(targetDoc);
         const animation = this.isAnimatingFetch ? "spin 0.5s linear infinite" : "none";
 
@@ -188,7 +192,7 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
     }
     @computed
     get pinButton() {
-        const targetDoc = this.props.doc;
+        const targetDoc = this.selectedDoc;
         const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
         return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
             <div className="propertiesButtons-linker"
@@ -202,15 +206,20 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
     @computed
     get metadataButton() {
         //const view0 = this.view0;
-        return <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
-            <div className="propertiesButtons-linkFlyout">
-                <Flyout anchorPoint={anchorPoints.LEFT_TOP}
-                    content={<MetadataEntryMenu docs={[this.props.doc]} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
-                    <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
-                        {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
-                    </div>
-                </Flyout>
-            </div></Tooltip>;
+        if (this.selectedDoc) {
+            return <Tooltip title={<><div className="dash-tooltip">Show metadata panel</div></>}>
+                <div className="propertiesButtons-linkFlyout">
+                    <Flyout anchorPoint={anchorPoints.LEFT_TOP}
+                        content={<MetadataEntryMenu docs={[this.selectedDoc]} suggestWithFunction />  /* tfs: @bcz This might need to be the data document? */}>
+                        <div className={"propertiesButtons-linkButton-" + "empty"} onPointerDown={e => e.stopPropagation()} >
+                            {<FontAwesomeIcon className="documentdecorations-icon" icon="tag" size="sm" />}
+                        </div>
+                    </Flyout>
+                </div></Tooltip>;
+        } else {
+            return null;
+        }
+
     }
 
     // @computed
@@ -267,9 +276,9 @@ export class PropertiesButtons extends React.Component<{ doc: Doc }, {}> {
     // }
 
     render() {
-        if (!this.props.doc) return (null);
+        if (!this.selectedDoc) return (null);
 
-        const isText = this.props.doc[Doc.LayoutFieldKey(this.props.doc)] instanceof RichTextField;
+        const isText = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof RichTextField;
         const considerPull = isText && this.considerGoogleDocsPull;
         const considerPush = isText && this.considerGoogleDocsPush;
         return <div className="propertiesButtons">
diff --git a/src/client/views/collections/CollectionView.scss b/src/client/views/collections/CollectionView.scss
index 585f6865e..a5aef86de 100644
--- a/src/client/views/collections/CollectionView.scss
+++ b/src/client/views/collections/CollectionView.scss
@@ -25,40 +25,6 @@
         z-index: 2;
     }
 
-    .collectionView-propertiesDragger {
-        background-color: rgb(140, 139, 139);
-        height: 55px;
-        width: 15.5px;
-        position: absolute;
-        top: 55%;
-        border: 1px black solid;
-        border-radius: 0;
-        border-top-left-radius: 10px;
-        border-bottom-left-radius: 10px;
-        border-right: unset;
-        z-index: 2;
-
-        .collectionView-propertiesDragger-icon {
-            width: 10px;
-            height: 10px;
-            float: left;
-            margin-left: 3px;
-            padding-top: 19px;
-        }
-    }
-
-    .collectionView-propertiesView {
-        display: flex;
-        flex-direction: column;
-        width: 200px;
-        height: 100%;
-        position: absolute;
-        right: 0;
-        top: 0;
-        border-left: solid 1px;
-        z-index: 10;
-    }
-
     .collectionTimeView-treeView {
         display: flex;
         flex-direction: column;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 853321d3c..19a82a113 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -49,7 +49,6 @@ import { CollectionTreeView } from "./CollectionTreeView";
 import './CollectionView.scss';
 import CollectionMenu from './CollectionMenu';
 import { SharingPermissions } from '../../util/SharingManager';
-import { PropertiesView } from './collectionFreeForm/PropertiesView';
 import { DocumentView } from '../nodes/DocumentView';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
@@ -369,22 +368,9 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
     get _facetWidth() { return NumCast(this.props.Document._facetWidth); }
     set _facetWidth(value) { this.props.Document._facetWidth = value; }
 
-    get _propertiesWidth() { return NumCast(this.props.Document._propertiesWidth); }
-    set _propertiesWidth(value) { this.props.Document._propertiesWidth = value; }
-
-    bodyPanelWidth = () => this.props.PanelWidth() - this.propertiesWidth();
+    bodyPanelWidth = () => this.props.PanelWidth();
     facetWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._facetWidth));
 
-    propertiesWidth = () => Math.max(0, Math.min(this.props.PanelWidth() - 25, this._propertiesWidth));
-
-    @computed get propertiesIcon() {
-        if (this.propertiesWidth() < 10) {
-            return "chevron-left";
-        } else {
-            return "chevron-right";
-        }
-    }
-
     @computed get dataDoc() {
         return (this.props.DataDoc && this.props.Document.isTemplateForField ? Doc.GetProto(this.props.DataDoc) :
             this.props.Document.resolvedDataDoc ? this.props.Document : Doc.GetProto(this.props.Document)); // if the layout document has a resolvedDataDoc, then we don't want to get its parent which would be the unexpanded template
@@ -505,13 +491,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
         }), returnFalse, action(() => this._facetWidth = this.facetWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
     }
 
-    onDown = (e: React.PointerEvent) => {
-        setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
-            this._propertiesWidth = this.props.PanelWidth() - Math.max(this.props.ScreenToLocalTransform().transformPoint(e.clientX, 0)[0], 0);
-            return false;
-        }), returnFalse, action(() => this._propertiesWidth = this.propertiesWidth() < 15 ? Math.min(this.props.PanelWidth() - 25, 200) : 0), false);
-    }
-
     filterBackground = () => "rgba(105, 105, 105, 0.432)";
     get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; } // this makes the tree view collection ignore these filters (otherwise, the filters would filter themselves)
     @computed get scriptField() {
@@ -582,23 +561,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             </div>;
     }
 
-    @computed get propertiesView() {
-        TraceMobx();
-        return !this._propertiesWidth || this.props.dontRegisterView ? (null) :
-            <div className="collectionView-propertiesView" style={{
-                width: `${this.propertiesWidth()}px`,
-                overflow: this.propertiesWidth() < 15 ? "hidden" : undefined
-            }}>
-                <PropertiesView dataDoc={this.dataDoc} Document={this.props.Document}
-                    docView={CollectionView as unknown as DocumentView}
-                    width={this._propertiesWidth}
-                    height={this.props.PanelHeight()}
-                    renderDepth={this.props.renderDepth}
-                    ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                />
-            </div>;
-    }
-
     childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
     childLayoutString = this.props.childLayoutString || StrCast(this.props.Document.childLayoutString);
 
@@ -634,15 +596,6 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                     style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
             }
             {this.facetWidth() < 10 ? (null) : this.filterView} */}
-
-            {this.props.hideFilter || this.props.Document.hideFilterView || !this.props.isSelected() && !this.props.Document.forceActive ? (null) :
-                <div className="collectionView-propertiesDragger" title="Properties View Dragger" onPointerDown={this.onDown}
-                    style={{ right: this.propertiesWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }}>
-                    <div className="collectionView-propertiesDragger-icon">
-                        <FontAwesomeIcon icon={this.propertiesIcon} color="white" size="sm" /> </div>
-                </div>
-            }
-            {this.propertiesWidth() < 10 ? (null) : this.propertiesView}
         </div>);
     }
 }
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 5242aa8fd..5aa0066d2 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -14,121 +14,162 @@ import { returnFalse, returnOne, emptyFunction, emptyPath, returnTrue, returnZer
 import { Id } from "../../../../fields/FieldSymbols";
 import { Transform } from "../../../util/Transform";
 import { PropertiesButtons } from "../../PropertiesButtons";
+import { SelectionManager } from "../../../util/SelectionManager";
 
 
 interface PropertiesViewProps {
-    dataDoc: Doc;
-    Document: Doc;
     width: number;
     height: number;
     renderDepth: number;
     ScreenToLocalTransform: () => Transform;
-    docView: DocumentView;
 }
 
 @observer
 export class PropertiesView extends React.Component<PropertiesViewProps> {
 
     @computed get MAX_EMBED_HEIGHT() { return 200; }
+    @observable numSelected: number = SelectionManager.SelectedDocuments().length;
+    @computed get selectedDocumentView() { return SelectionManager.LastSelection(); }
+    @observable selectedDoc: Doc | undefined = this.selectedDocumentView?.props.Document;
+    @observable dataDoc: Doc | undefined = this.selectedDocumentView?.props.DataDoc ? this.selectedDocumentView.props.DataDoc : this.selectedDoc;
 
-    rtfWidth = () => Math.min(this.props.Document?.[WidthSym](), this.props.width - 20);
-    rtfHeight = () => this.rtfWidth() <= this.props.Document?.[WidthSym]() ? Math.min(this.props.Document?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+    @action
+    rtfWidth = () => {
+        if (this.selectedDoc) {
+            return Math.min(this.selectedDoc?.[WidthSym](), this.props.width - 20);
+        } else {
+            return 0;
+        }
+    }
+    @action
+    rtfHeight = () => {
+        if (this.selectedDoc) {
+            return this.rtfWidth() <= this.selectedDoc?.[WidthSym]() ? Math.min(this.selectedDoc?.[HeightSym](), this.MAX_EMBED_HEIGHT) : this.MAX_EMBED_HEIGHT;
+        } else {
+            return 0;
+        }
+    }
 
+    @action
     docWidth = () => {
-        const layoutDoc = this.props.Document;
-        const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
-        if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
-        return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+        if (this.selectedDoc) {
+            const layoutDoc = this.selectedDoc;
+            const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+            if (aspect) return Math.min(layoutDoc[WidthSym](), Math.min(this.MAX_EMBED_HEIGHT / aspect, this.props.width - 20));
+            return NumCast(layoutDoc._nativeWidth) ? Math.min(layoutDoc[WidthSym](), this.props.width - 20) : this.props.width - 20;
+        } else {
+            return 0;
+        }
     }
+
+    @action
     docHeight = () => {
-        const layoutDoc = this.props.Document;
-        return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
-            const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
-            if (aspect) return this.docWidth() * aspect;
-            return layoutDoc._fitWidth ? (!this.props.dataDoc._nativeHeight ? NumCast(this.props.height) :
-                Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
-                    NumCast(this.props.height)))) :
-                NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
-        })()));
+        if (this.selectedDoc && this.dataDoc) {
+            const layoutDoc = this.selectedDoc;
+            return Math.max(70, Math.min(this.MAX_EMBED_HEIGHT, (() => {
+                const aspect = NumCast(layoutDoc._nativeHeight, layoutDoc._fitWidth ? 0 : layoutDoc[HeightSym]()) / NumCast(layoutDoc._nativeWidth, layoutDoc._fitWidth ? 1 : layoutDoc[WidthSym]());
+                if (aspect) return this.docWidth() * aspect;
+                return layoutDoc._fitWidth ? (!this.dataDoc._nativeHeight ? NumCast(this.props.height) :
+                    Math.min(this.docWidth() * NumCast(layoutDoc.scrollHeight, NumCast(layoutDoc._nativeHeight)) / NumCast(layoutDoc._nativeWidth,
+                        NumCast(this.props.height)))) :
+                    NumCast(layoutDoc._height) ? NumCast(layoutDoc._height) : 50;
+            })()));
+        } else {
+            return 0;
+        }
     }
 
     @computed get expandedField() {
-        const ids: { [key: string]: string } = {};
-        const doc = this.props.dataDoc;
-        doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
+        if (this.dataDoc) {
+            const ids: { [key: string]: string } = {};
+            const doc = this.dataDoc;
+            doc && Object.keys(doc).forEach(key => !(key in ids) && doc[key] !== ComputedField.undefined && (ids[key] = key));
 
-        const rows: JSX.Element[] = [];
-        for (const key of Object.keys(ids).slice().sort()) {
-            const contents = doc[key];
-            let contentElement: (JSX.Element | null)[] | JSX.Element = [];
-            contentElement = <EditableView key="editableView"
-                contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
-                height={13}
-                fontSize={10}
-                GetValue={() => Field.toKeyValueString(doc, key)}
-                SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
-            />;
+            const rows: JSX.Element[] = [];
+            for (const key of Object.keys(ids).slice().sort()) {
+                const contents = doc[key];
+                let contentElement: (JSX.Element | null)[] | JSX.Element = [];
+                contentElement = <EditableView key="editableView"
+                    contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
+                    height={13}
+                    fontSize={10}
+                    GetValue={() => Field.toKeyValueString(doc, key)}
+                    SetValue={(value: string) => KeyValueBox.SetField(doc, key, value, true)}
+                />;
 
-            rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
-                <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
-                &nbsp;
-                {contentElement}
-            </div>);
+                rows.push(<div style={{ display: "flex", overflowY: "visible", marginBottom: "-1px" }} key={key}>
+                    <span style={{ fontWeight: "bold", whiteSpace: "nowrap" }}>{key + ":"}</span>
+                    &nbsp;
+                    {contentElement}
+                </div>);
+            }
+            return rows;
         }
-        return rows;
     }
 
     @computed get layoutPreview() {
-        const layoutDoc = Doc.Layout(this.props.Document);
-        const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
-        const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
-        return <div style={{ display: "inline-block", height: panelHeight() }} key={this.props.dataDoc[Id]}>
-            <ContentFittingDocumentView
-                Document={layoutDoc}
-                DataDoc={this.props.dataDoc}
-                LibraryPath={emptyPath}
-                renderDepth={this.props.renderDepth + 1}
-                rootSelected={returnFalse}
-                treeViewDoc={undefined}
-                backgroundColor={() => "lightgrey"}
-                fitToBox={false}
-                FreezeDimensions={true}
-                NativeWidth={layoutDoc.type ===
-                    StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
-                NativeHeight={layoutDoc.type ===
-                    StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
-                PanelWidth={panelWidth}
-                PanelHeight={panelHeight}
-                focus={returnFalse}
-                ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                docFilters={returnEmptyFilter}
-                ContainingCollectionDoc={undefined}
-                ContainingCollectionView={undefined}
-                addDocument={returnFalse}
-                moveDocument={undefined}
-                removeDocument={returnFalse}
-                parentActive={() => false}
-                whenActiveChanged={emptyFunction}
-                addDocTab={returnFalse}
-                pinToPres={emptyFunction}
-                bringToFront={returnFalse}
-                ContentScaling={returnOne}
-            />
-        </div>;
+        if (this.selectedDoc) {
+            const layoutDoc = Doc.Layout(this.selectedDoc);
+            const panelHeight = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : this.docHeight;
+            const panelWidth = StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : this.docWidth;
+            return <div style={{ display: "inline-block", height: panelHeight() }} key={this.selectedDoc[Id]}>
+                <ContentFittingDocumentView
+                    Document={layoutDoc}
+                    DataDoc={this.dataDoc}
+                    LibraryPath={emptyPath}
+                    renderDepth={this.props.renderDepth + 1}
+                    rootSelected={returnFalse}
+                    treeViewDoc={undefined}
+                    backgroundColor={() => "lightgrey"}
+                    fitToBox={false}
+                    FreezeDimensions={true}
+                    NativeWidth={layoutDoc.type ===
+                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfWidth : returnZero}
+                    NativeHeight={layoutDoc.type ===
+                        StrCast(Doc.LayoutField(layoutDoc)).includes("FormattedTextBox") ? this.rtfHeight : returnZero}
+                    PanelWidth={panelWidth}
+                    PanelHeight={panelHeight}
+                    focus={returnFalse}
+                    ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                    docFilters={returnEmptyFilter}
+                    ContainingCollectionDoc={undefined}
+                    ContainingCollectionView={undefined}
+                    addDocument={returnFalse}
+                    moveDocument={undefined}
+                    removeDocument={returnFalse}
+                    parentActive={() => false}
+                    whenActiveChanged={emptyFunction}
+                    addDocTab={returnFalse}
+                    pinToPres={emptyFunction}
+                    bringToFront={returnFalse}
+                    ContentScaling={returnOne}
+                />
+            </div>;
+        } else {
+            return null;
+        }
     }
 
     render() {
+
+        if (!this.selectedDocumentView || !this.selectedDoc || !this.dataDoc) {
+            return <div className="propertiesView" >
+                <div className="propertiesView-title">
+                    No Document Selected
+            </div> </div>;
+        }
+
         return <div className="propertiesView" >
             <div className="propertiesView-title">
                 Properties
             </div>
             <div className="propertiesView-name">
-                Collection
+                {this.dataDoc.title}
             </div>
             <div className="propertiesView-settings">
                 <div className="propertiesView-settings-title"> Settings</div>
                 <div className="propertiesView-settings-content">
-                    <PropertiesButtons doc={this.props.Document} />
+                    <PropertiesButtons />
                 </div>
             </div>
             <div className="propertiesView-fields">
-- 
cgit v1.2.3-70-g09d2


From 8f250a359e957b01e281cfad1bd92043a2f1b165 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Sat, 25 Jul 2020 10:49:33 -0500
Subject: merge fix

---
 src/client/views/collections/CollectionView.tsx | 2 +-
 src/client/views/nodes/DocumentView.tsx         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2ea391b19..2d360d13c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -48,7 +48,7 @@ import { CollectionTimeView } from './CollectionTimeView';
 import { CollectionTreeView } from "./CollectionTreeView";
 import './CollectionView.scss';
 import CollectionMenu from './CollectionMenu';
-import { SharingPermissions } from '../../util/SharingManager';
+//import SharingPermissions from '../../util/SharingManager';
 import { DocumentView } from '../nodes/DocumentView';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 85e8409d1..bb1c43e6b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1041,7 +1041,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     @computed get contents() {
         const pos = this.props.relative ? "relative " : "absolute";
         TraceMobx();
-        return (<div style={{ position: pos, width: "100%", height: "100%" }}>
+        return (<div style={{ width: "100%", height: "100%" }}>
             <DocumentContentsView key={1}
                 docFilters={this.props.docFilters}
                 ContainingCollectionView={this.props.ContainingCollectionView}
-- 
cgit v1.2.3-70-g09d2


From 4224ebd13aec9e01f1fe73c935c40adb089dbc69 Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Wed, 29 Jul 2020 23:11:35 -0500
Subject: sally UI changes

---
 src/client/views/ContextMenuItem.tsx               |   4 +-
 src/client/views/DocumentDecorations.tsx           |   4 +-
 src/client/views/MainView.scss                     |   9 +
 src/client/views/MainView.tsx                      | 251 +++++++++++----------
 src/client/views/PropertiesButtons.tsx             |  25 +-
 .../views/collections/CollectionSchemaView.tsx     |   2 +-
 src/client/views/collections/CollectionView.tsx    |   2 +-
 src/client/views/collections/SchemaTable.tsx       |   6 +-
 .../collectionFreeForm/CollectionFreeFormView.tsx  |   8 +-
 src/client/views/linking/LinkMenuItem.tsx          |   1 +
 src/client/views/nodes/DocumentView.tsx            |  17 +-
 11 files changed, 189 insertions(+), 140 deletions(-)

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

diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 81432968d..7e233ec04 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -80,7 +80,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
     render() {
         if ("event" in this.props) {
             return (
-                <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")} onClick={this.handleEvent}>
+                <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")} onPointerDown={this.handleEvent}>
                     {this.props.icon ? (
                         <span className="icon-background">
                             <FontAwesomeIcon icon={this.props.icon} size="sm" />
@@ -95,7 +95,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
             const where = !this.overItem ? "" : this._overPosY < window.innerHeight / 3 ? "flex-start" : this._overPosY > window.innerHeight * 2 / 3 ? "flex-end" : "center";
             const marginTop = !this.overItem ? "" : this._overPosY < window.innerHeight / 3 ? "20px" : this._overPosY > window.innerHeight * 2 / 3 ? "-20px" : "";
             const submenu = !this.overItem ? (null) :
-                <div className="contextMenu-subMenu-cont" style={{ marginLeft: "25%", left: "0px", marginTop }}>
+                <div className="contextMenu-subMenu-cont" style={{ marginLeft: "90%", left: "0px", marginTop }}>
                     {this._items.map(prop => <ContextMenuItem {...prop} key={prop.description} closeMenu={this.props.closeMenu} />)}
                 </div>;
             if (!("noexpand" in this.props)) {
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index ff91e401f..85dd40173 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -577,9 +577,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
                 </div>}
             </> :
             <>
-                {minimal ? (null) : <Tooltip title={<><div className="dash-tooltip">Show context menu</div></>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
+                {/* {minimal ? (null) : <Tooltip title={<><div className="dash-tooltip">Show context menu</div></>} placement="top"><div className="documentDecorations-contextMenu" key="menu" onPointerDown={this.onSettingsDown}>
                     <FontAwesomeIcon size="lg" icon="bars" />
-                </div></Tooltip>}
+                </div></Tooltip>} */}
                 <div className="documentDecorations-title" key="title" onPointerDown={this.onTitleDown} >
                     <span style={{ width: "100%", display: "inline-block", cursor: "move" }}>{`${this.selectionTitle}`}</span>
                 </div>
diff --git a/src/client/views/MainView.scss b/src/client/views/MainView.scss
index 8bf38ebe9..fe01c27a3 100644
--- a/src/client/views/MainView.scss
+++ b/src/client/views/MainView.scss
@@ -314,6 +314,15 @@
     display: flex;
     flex-direction: column;
     z-index: 2;
+
+    .mainView-libraryFlyout-close {
+        right: 6;
+        top: 5;
+        position: absolute;
+        margin-right: 6px;
+        z-index: 10;
+        margin-bottom: 10;
+    }
 }
 
 .mainView-expandFlyoutButton {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 5f7f7ca03..326082927 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -63,6 +63,8 @@ import { SelectionManager } from '../util/SelectionManager';
 import { PrefetchProxy } from '../../fields/Proxy';
 import { DragManager } from '../util/DragManager';
 import { discovery_v1, dialogflow_v2beta1 } from 'googleapis';
+import { undo } from 'prosemirror-history';
+import { undoBatch } from '../util/UndoManager';
 
 @observer
 export class MainView extends React.Component {
@@ -426,12 +428,18 @@ export class MainView extends React.Component {
     //sidebarScreenToLocal = () => new Transform(0, (RichTextMenu.Instance.Pinned ? -35 : 0) + (CollectionMenu.Instance.Pinned ? -35 : 0), 1);
     mainContainerXf = () => this.sidebarScreenToLocal().translate(0, -this._buttonBarHeight);
 
+    @computed get closePosition() { return 55 + this.flyoutWidth }
     @computed get flyout() {
         if (!(this.sidebarContent instanceof Doc)) {
             return (null);
         }
         return <div className="mainView-libraryFlyout">
             <div className="mainView-contentArea" style={{ position: "relative", height: `100%`, width: "100%", overflow: "visible" }}>
+                {this.flyoutWidth > 0 ? <div className="mainView-libraryFlyout-close"
+                    onPointerDown={this.closeFlyout}>
+                    <FontAwesomeIcon icon="times" color="black" size="sm" />
+                </div> : null}
+
                 <DocumentView
                     Document={this.sidebarContent}
                     DataDoc={undefined}
@@ -463,130 +471,129 @@ export class MainView extends React.Component {
             {this.docButtons}</div>;
     }
 
-    @computed get menuPanel() {
-
-        return <div className="mainView-menuPanel">
-            <DocumentView
-                Document={Doc.UserDoc().menuStack as Doc}
-                DataDoc={undefined}
-                LibraryPath={emptyPath}
-                addDocument={undefined}
-                addDocTab={this.addDocTabFunc}
-                pinToPres={emptyFunction}
-                NativeHeight={returnZero}
-                NativeWidth={returnZero}
-                rootSelected={returnTrue}
-                removeDocument={returnFalse}
-                onClick={undefined}
-                ScreenToLocalTransform={this.mainContainerXf}
-                ContentScaling={returnOne}
-                PanelWidth={() => 80}
-                PanelHeight={this.getContentsHeight}
-                renderDepth={0}
-                focus={emptyFunction}
-                backgroundColor={this.defaultBackgroundColors}
-                parentActive={returnTrue}
-                whenActiveChanged={emptyFunction}
-                bringToFront={emptyFunction}
-                docFilters={returnEmptyFilter}
-                ContainingCollectionView={undefined}
-                ContainingCollectionDoc={undefined}
-                relative={true}
-                scriptContext={this}
-            />
-        </div>;
-    }
-
     // @computed get menuPanel() {
+
     //     return <div className="mainView-menuPanel">
-    //         <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}>
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}
-    //                 onPointerDown={e => this.selectPanel("workspace")}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="desktop"
-    //                     color={this.panelContent === "workspace" ? "black" : "white"} size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"
-    //                     style={{ color: this.panelContent === "workspace" ? "black" : "white" }}> Workspace </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}>
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}
-    //                 onPointerDown={e => this.selectPanel("catalog")}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="file"
-    //                     color={this.panelContent === "catalog" ? "black" : "white"} size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"
-    //                     style={{ color: this.panelContent === "catalog" ? "black" : "white" }}> Catalog </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}>
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}
-    //                 onPointerDown={e => this.selectPanel("deleted")}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="archive"
-    //                     color={this.panelContent === "deleted" ? "black" : "white"} size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"
-    //                     style={{ color: this.panelContent === "deleted" ? "black" : "white" }}> Recently Used </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button">
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 onPointerDown={e => this.selectPanel("upload")}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="upload" color="white" size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"> Import </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button">
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 //onPointerDown={e => this.selectPanel("sharing")}
-    //                 onClick={() => GroupManager.Instance.open()}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="users" color="white" size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"> Sharing </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button" style={{ marginBottom: "110px", backgroundColor: this.panelContent === "tools" ? "lightgrey" : "", }}>
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 onPointerDown={e => this.selectPanel("tools")}
-    //                 style={{
-    //                     backgroundColor: this.panelContent === "tools" ? "lightgrey" : "",
-    //                 }}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="wrench"
-    //                     color={this.panelContent === "tools" ? "black" : "white"} size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"
-    //                     style={{ color: this.panelContent === "tools" ? "black" : "white" }}> Tools </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button">
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 // style={{backgroundColor: this.panelContent= "help" ? "lightgrey" : "black"}}
-    //                 onPointerDown={e => this.selectPanel("help")} >
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="question-circle" color="white" size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"> Help </div>
-    //             </div>
-    //         </div>
-
-    //         <div className="mainView-menuPanel-button">
-    //             <div className="mainView-menuPanel-button-wrap"
-    //                 // onPointerDown={e => this.selectPanel("settings")}
-    //                 onClick={() => SettingsManager.Instance.open()}>
-    //                 <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="cog" color="white" size="lg" />
-    //                 <div className="mainView-menuPanel-button-label"> Settings </div>
-    //             </div>
-    //         </div>
+    //         <DocumentView
+    //             Document={Doc.UserDoc().menuStack as Doc}
+    //             DataDoc={undefined}
+    //             LibraryPath={emptyPath}
+    //             addDocument={undefined}
+    //             addDocTab={this.addDocTabFunc}
+    //             pinToPres={emptyFunction}
+    //             NativeHeight={returnZero}
+    //             NativeWidth={returnZero}
+    //             rootSelected={returnTrue}
+    //             removeDocument={returnFalse}
+    //             onClick={undefined}
+    //             ScreenToLocalTransform={this.mainContainerXf}
+    //             ContentScaling={returnOne}
+    //             PanelWidth={() => 80}
+    //             PanelHeight={this.getContentsHeight}
+    //             renderDepth={0}
+    //             focus={emptyFunction}
+    //             backgroundColor={this.defaultBackgroundColors}
+    //             parentActive={returnTrue}
+    //             whenActiveChanged={emptyFunction}
+    //             bringToFront={emptyFunction}
+    //             docFilters={returnEmptyFilter}
+    //             ContainingCollectionView={undefined}
+    //             ContainingCollectionDoc={undefined}
+    //             relative={true}
+    //             scriptContext={this}
+    //         />
     //     </div>;
     // }
 
-    @action
+    @computed get menuPanel() {
+        return <div className="mainView-menuPanel">
+            <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}>
+                <div className="mainView-menuPanel-button-wrap"
+                    style={{ backgroundColor: this.panelContent === "workspace" ? "lightgrey" : "" }}
+                    onPointerDown={e => this.selectPanel("workspace")}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="desktop"
+                        color={this.panelContent === "workspace" ? "black" : "white"} size="lg" />
+                    <div className="mainView-menuPanel-button-label"
+                        style={{ color: this.panelContent === "workspace" ? "black" : "white" }}> Workspace </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}>
+                <div className="mainView-menuPanel-button-wrap"
+                    style={{ backgroundColor: this.panelContent === "catalog" ? "lightgrey" : "" }}
+                    onPointerDown={e => this.selectPanel("catalog")}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="file"
+                        color={this.panelContent === "catalog" ? "black" : "white"} size="lg" />
+                    <div className="mainView-menuPanel-button-label"
+                        style={{ color: this.panelContent === "catalog" ? "black" : "white" }}> Catalog </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button" style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}>
+                <div className="mainView-menuPanel-button-wrap"
+                    style={{ backgroundColor: this.panelContent === "deleted" ? "lightgrey" : "" }}
+                    onPointerDown={e => this.selectPanel("deleted")}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="archive"
+                        color={this.panelContent === "deleted" ? "black" : "white"} size="lg" />
+                    <div className="mainView-menuPanel-button-label"
+                        style={{ color: this.panelContent === "deleted" ? "black" : "white" }}> Recently Used </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button">
+                <div className="mainView-menuPanel-button-wrap"
+                    onPointerDown={e => this.selectPanel("upload")}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="upload" color="white" size="lg" />
+                    <div className="mainView-menuPanel-button-label"> Import </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button">
+                <div className="mainView-menuPanel-button-wrap"
+                    //onPointerDown={e => this.selectPanel("sharing")}
+                    onClick={() => GroupManager.Instance.open()}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="users" color="white" size="lg" />
+                    <div className="mainView-menuPanel-button-label"> Sharing </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button" style={{ marginBottom: "110px", backgroundColor: this.panelContent === "tools" ? "lightgrey" : "", }}>
+                <div className="mainView-menuPanel-button-wrap"
+                    onPointerDown={e => this.selectPanel("tools")}
+                    style={{
+                        backgroundColor: this.panelContent === "tools" ? "lightgrey" : "",
+                    }}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="wrench"
+                        color={this.panelContent === "tools" ? "black" : "white"} size="lg" />
+                    <div className="mainView-menuPanel-button-label"
+                        style={{ color: this.panelContent === "tools" ? "black" : "white" }}> Tools </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button">
+                <div className="mainView-menuPanel-button-wrap"
+                    // style={{backgroundColor: this.panelContent= "help" ? "lightgrey" : "black"}}
+                    onPointerDown={e => this.selectPanel("help")} >
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="question-circle" color="white" size="lg" />
+                    <div className="mainView-menuPanel-button-label"> Help </div>
+                </div>
+            </div>
+
+            <div className="mainView-menuPanel-button">
+                <div className="mainView-menuPanel-button-wrap"
+                    // onPointerDown={e => this.selectPanel("settings")}
+                    onClick={() => SettingsManager.Instance.open()}>
+                    <FontAwesomeIcon className="mainView-menuPanel-button-icon" icon="cog" color="white" size="lg" />
+                    <div className="mainView-menuPanel-button-label"> Settings </div>
+                </div>
+            </div>
+        </div>;
+    }
+
+    @action @undoBatch
     selectPanel = (str: string) => {
         if (this.panelContent === str && this.flyoutWidth !== 0) {
-            this.panelContent = "none";
-            this.flyoutWidth = 0;
+            this.closeFlyout();
         } else {
             this.panelContent = str;
             MainView.expandFlyout();
@@ -606,7 +613,13 @@ export class MainView extends React.Component {
         return true;
     }
 
-    @action
+    @action @undoBatch
+    closeFlyout = () => {
+        this.panelContent = "none";
+        this.flyoutWidth = 0;
+    }
+
+    @action @undoBatch
     selectMenu = (str: string) => {
         if (CurrentUserUtils.panelContent === str && this.flyoutWidth !== 0) {
             CurrentUserUtils.panelContent = "none";
@@ -630,7 +643,7 @@ export class MainView extends React.Component {
         return true;
     }
 
-    @action
+    @action @undoBatch
     onDown = (e: React.PointerEvent) => {
         setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => {
             this._propertiesWidth = this._panelWidth - Math.max(Transform.Identity().transformPoint(e.clientX, 0)[0], 0);
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 3113d8cb4..cc15a8195 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -6,7 +6,7 @@ import { observer } from "mobx-react";
 import { Doc, DocListCast } from "../../fields/Doc";
 import { RichTextField } from '../../fields/RichTextField';
 import { Cast, NumCast, BoolCast } from "../../fields/Types";
-import { emptyFunction, setupMoveUpEvents } from "../../Utils";
+import { emptyFunction, setupMoveUpEvents, Utils } from "../../Utils";
 import GoogleAuthenticationManager from '../apis/GoogleAuthenticationManager';
 import { Pulls, Pushes } from '../apis/google_docs/GoogleApiClientUtils';
 import { Docs, DocUtils } from '../documents/Documents';
@@ -27,6 +27,8 @@ import SharingManager from '../util/SharingManager';
 import { GooglePhotos } from '../apis/google_docs/GooglePhotosClientUtils';
 import { ImageField } from '../../fields/URLField';
 import { undoBatch, UndoManager } from '../util/UndoManager';
+import { DocumentType } from '../documents/DocumentTypes';
+import { CollectionFreeFormView } from './collections/collectionFreeForm/CollectionFreeFormView';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -471,6 +473,22 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         </Tooltip>;
     }
 
+    // @computed
+    // get importButton() {
+    //     const targetDoc = this.selectedDoc;
+    //     return !targetDoc ? (null) : <Tooltip
+    //         title={<><div className="dash-tooltip">{"Import a Document"}</div></>}>
+    //         <div className={"propertiesButtons-linkButton-empty"}
+    //             onPointerDown={() => {
+    //                 if (this.selectedDocumentView) {
+    //                     CollectionFreeFormView.importDocument(100, 100);
+    //                 }
+    //             }}>
+    //             {<FontAwesomeIcon className="documentdecorations-icon"
+    //                 icon="upload" size="sm" />}
+    //         </div>
+    //     </Tooltip>;
+    // }
 
     render() {
         if (!this.selectedDoc) return (null);
@@ -479,6 +497,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         const considerPull = isText && this.considerGoogleDocsPull;
         const considerPush = isText && this.considerGoogleDocsPush;
         const isImage = this.selectedDoc[Doc.LayoutFieldKey(this.selectedDoc)] instanceof ImageField;
+        const isCollection = this.selectedDoc.type === DocumentType.COL ? true : false;
+
         return <div><div className="propertiesButtons" style={{ paddingBottom: "5.5px" }}>
             <div className="propertiesButtons-button">
                 {this.templateButton}
@@ -518,6 +538,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 <div className="propertiesButtons-button" style={{ display: !isImage ? "none" : "" }}>
                     {this.googlePhotosButton}
                 </div>
+                {/* <div className="propertiesButtons-button" style={{ display: !isCollection ? "none" : "" }}>
+                    {this.importButton}
+                </div> */}
             </div>
         </div>;
     }
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 5553bbbb7..f67e049fd 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -253,7 +253,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             <div className="collectionSchema-headerMenu-group">
                 <div onClick={() => this.typesDropdownChange(!this._openTypes)}>
                     <label>Column type:</label>
-                    <FontAwesomeIcon icon={"caret-down"} size="sm" style={{ float: "right" }} />
+                    <FontAwesomeIcon icon={"caret-down"} size="lg" style={{ float: "right" }} />
                 </div>
                 {this._openTypes ? allColumnTypes : justColType}
             </div >
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index ae53f5ba0..5834e5542 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -308,7 +308,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
 
             const options = cm.findByDescription("Options...");
             const optionItems = options && "subitems" in options ? options.subitems : [];
-            optionItems.splice(0, 0, { description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" });
+            !Doc.UserDoc().noviceMode ? optionItems.splice(0, 0, { description: `${this.props.Document.forceActive ? "Select" : "Force"} Contents Active`, event: () => this.props.Document.forceActive = !this.props.Document.forceActive, icon: "project-diagram" }) : null;
             if (this.props.Document.childLayout instanceof Doc) {
                 optionItems.push({ description: "View Child Layout", event: () => this.props.addDocTab(this.props.Document.childLayout as Doc, "onRight"), icon: "project-diagram" });
             }
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index cde795098..75e693f96 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -208,7 +208,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 }}>
                 {col.heading}</div>;
 
-            const sortIcon = col.desc === undefined ? "circle" : col.desc === true ? "caret-down" : "caret-up";
+            const sortIcon = col.desc === undefined ? "caret-right" : col.desc === true ? "caret-down" : "caret-up";
 
             const header =
                 <div //className="collectionSchemaView-header"
@@ -224,12 +224,12 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                         {keysDropdown}
                     </div>
                     <div onClick={e => this.changeSorting(col)}
-                        style={{ paddingRight: "6px", display: "inline" }}>
+                        style={{ paddingRight: "6px", marginLeft: "4px", display: "inline" }}>
                         <FontAwesomeIcon icon={sortIcon} size="sm" />
                     </div>
                     <div onClick={e => this.props.openHeader(col, e.clientX, e.clientY)}
                         style={{ float: "right", paddingRight: "6px" }}>
-                        <FontAwesomeIcon icon={"compass"} size="sm" />
+                        <FontAwesomeIcon icon={"cog"} size="sm" />
                     </div>
                 </div>;
 
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 57336131a..e0981d797 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1239,13 +1239,15 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
         const appearanceItems = appearance && "subitems" in appearance ? appearance.subitems : [];
         appearanceItems.push({ description: "Reset View", event: () => { this.props.Document._panX = this.props.Document._panY = 0; this.props.Document[this.scaleFieldKey] = 1; }, icon: "compress-arrows-alt" });
         appearanceItems.push({ description: `${this.fitToContent ? "Make Zoomable" : "Scale to Window"}`, event: () => this.Document._fitToBox = !this.fitToContent, icon: !this.fitToContent ? "expand-arrows-alt" : "compress-arrows-alt" });
-        appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
+        !Doc.UserDoc().noviceMode ? appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" }) : null;
         !appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" });
 
         const viewctrls = ContextMenu.Instance.findByDescription("UI Controls...");
         const viewCtrlItems = viewctrls && "subitems" in viewctrls ? viewctrls.subitems : [];
-        viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" });
-        viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
+
+
+        !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" }) : null;
+        !Doc.UserDoc().noviceMode ? viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" }) : null;
         !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" });
 
         const options = ContextMenu.Instance.findByDescription("Options...");
diff --git a/src/client/views/linking/LinkMenuItem.tsx b/src/client/views/linking/LinkMenuItem.tsx
index 8084d96ae..0aabf5319 100644
--- a/src/client/views/linking/LinkMenuItem.tsx
+++ b/src/client/views/linking/LinkMenuItem.tsx
@@ -196,6 +196,7 @@ export class LinkMenuItem extends React.Component<LinkMenuItemProps> {
             case DocumentType.DOCHOLDER: destinationIcon = "expand"; break;
             case DocumentType.VID: destinationIcon = "video"; break;
             case DocumentType.INK: destinationIcon = "pen-nib"; break;
+            case DocumentType.PDF: destinationIcon = "file"; break;
             default: destinationIcon = "question"; break;
         }
 
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 856eb7246..f5ae9349a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -712,21 +712,21 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
         const options = cm.findByDescription("Options...");
         const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
-        optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
+        //optionItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
         !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
 
 
         const existingOnClick = cm.findByDescription("OnClick...");
         const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
         onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
-        onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "window-restore" });
+        onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "concierge-bell" });
         onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" });
-        onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "concierge-bell" });
-        !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("onRight", false, false), icon: "concierge-bell" });
-        onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "concierge-bell" });
-        onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "snowflake" });
-        onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" });
-        !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "hand-point-right" });
+        onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: () => this.toggleFollowLink("inPlace", true, false), icon: "link" });
+        !this.Document.isLinkButton && onClicks.push({ description: "Follow Link on Right", event: () => this.toggleFollowLink("onRight", false, false), icon: "link" });
+        onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: () => this.toggleFollowLink(undefined, false, false), icon: "link" });
+        onClicks.push({ description: (this.Document.isPushpin ? "Remove" : "Make") + " Pushpin", event: () => this.toggleFollowLink(undefined, false, true), icon: "map-pin" });
+        onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "terminal" });
+        !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "mouse-pointer" });
 
         const funcs: ContextMenuProps[] = [];
         if (this.layoutDoc.onDragStart) {
@@ -739,6 +739,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         const more = cm.findByDescription("More...");
         const moreItems = more && "subitems" in more ? more.subitems : [];
         moreItems.push({ description: "Share", event: () => SharingManager.Instance.open(this), icon: "users" });
+        moreItems.push({ description: this.Document.lockedPosition ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.Document.lockedPosition) ? "unlock" : "lock" });
         moreItems.push({ description: "Create an Alias", event: () => this.onCopy(), icon: "copy" });
         moreItems.push({ description: "Download document", icon: "download", event: async () => Doc.Zip(this.props.Document) });
         if (!Doc.UserDoc().noviceMode) {
-- 
cgit v1.2.3-70-g09d2


From a10db866ff80961e22bc794d51db95e8cb6d0f16 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Sun, 2 Aug 2020 14:50:10 -0400
Subject: keep filter view as a feature for expert users

---
 src/client/views/collections/CollectionMenu.tsx | 4 ++--
 src/client/views/collections/CollectionView.tsx | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

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

diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index fdd1b4e81..59e6ac7ff 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -332,11 +332,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
                         {this.props.type === CollectionViewType.Invalid ||
                             this.props.type === CollectionViewType.Docking || this.isText ? (null) : this.viewModes}
                         {this.props.type === CollectionViewType.Docking || this.isText ? (null) : this.templateChrome}
-                        {/* <div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: "grid" }}>
+                        {Doc.UserDoc().noviceMode ? (null) : <div className="collectionViewBaseChrome-viewSpecs" title="filter documents to show" style={{ display: "grid" }}>
                             <button className={"antimodeMenu-button"} onClick={this.toggleViewSpecs} >
                                 <FontAwesomeIcon icon="filter" size="lg" />
                             </button>
-                        </div> */}
+                        </div>}
 
                         {this.props.docView.props.ContainingCollectionDoc?._viewType !== CollectionViewType.Freeform ? (null) : <button className={"antimodeMenu-button"} key="float"
                             style={{ backgroundColor: !this.props.docView.layoutDoc.isAnnotating ? "121212" : undefined, borderRight: "1px solid gray" }}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 62e8dc26a..c2b55d38e 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -591,11 +591,11 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         Utils.CorsProxy(Cast(d.data, ImageField)!.url.href) : Cast(d.data, ImageField)!.url.href
                     :
                     ""))}
-            {/* {(!this.props.isSelected() && !this.props.Document.forceActive) || this.props.Document.hideFilterView ? (null) :
+            {(Doc.UserDoc()?.noviceMode || !this.props.isSelected() && !this.props.Document.forceActive) || this.props.Document.hideFilterView ? (null) :
                 <div className="collectionView-filterDragger" title="library View Dragger" onPointerDown={this.onPointerDown}
                     style={{ right: this.facetWidth() - 1, top: this.props.Document._viewType === CollectionViewType.Docking ? "25%" : "55%" }} />
             }
-            {this.facetWidth() < 10 ? (null) : this.filterView}  */}
+            {Doc.UserDoc()?.noviceMode || this.facetWidth() < 10 ? (null) : this.filterView}
         </div>);
     }
 }
-- 
cgit v1.2.3-70-g09d2


From ac177d7b9a01075fbf1ad1c327c7625d95569afb Mon Sep 17 00:00:00 2001
From: anika-ahluwalia <anika.ahluwalia@gmail.com>
Date: Sun, 2 Aug 2020 18:20:59 -0500
Subject: bug fixes found with sally

---
 src/client/views/PropertiesButtons.scss            | 13 +++++++--
 src/client/views/PropertiesButtons.tsx             | 29 +++++++++++++------
 src/client/views/collections/CollectionMenu.scss   | 19 ++++++++-----
 .../views/collections/CollectionTreeView.tsx       |  2 +-
 src/client/views/collections/CollectionView.tsx    |  2 +-
 .../collectionFreeForm/PropertiesView.scss         | 24 ++++++++++++++++
 .../collectionFreeForm/PropertiesView.tsx          | 33 ++++++++++------------
 src/client/views/nodes/DocumentView.tsx            |  8 +++---
 src/client/views/nodes/FontIconBox.scss            |  2 +-
 src/client/views/nodes/FontIconBox.tsx             | 23 ++++++++-------
 src/client/views/nodes/LabelBox.tsx                |  2 +-
 11 files changed, 103 insertions(+), 54 deletions(-)

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

diff --git a/src/client/views/PropertiesButtons.scss b/src/client/views/PropertiesButtons.scss
index e099122c4..b3a317a6b 100644
--- a/src/client/views/PropertiesButtons.scss
+++ b/src/client/views/PropertiesButtons.scss
@@ -77,10 +77,19 @@ $linkGap : 3px;
     text-align: center;
     border-radius: 5px;
     pointer-events: auto;
-    color: $dark-color;
-    border: $dark-color 1px solid;
+    // color: $dark-color;
+    // border: $dark-color 1px solid;
+    background-color: #252b33;
+    color: #fcfbf7;
     transition: 0.2s ease all;
     margin-right: 5px;
+    padding-top: 5px;
+
+    &:hover {
+        background: $main-accent;
+        transform: scale(1.05);
+        cursor: pointer;
+    }
 }
 
 .propertiesButtons-linker:hover {
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 59e7cc7c8..d3f056a34 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -208,7 +208,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         const isPinned = targetDoc && Doc.isDocPinned(targetDoc);
         return !targetDoc ? (null) : <Tooltip title={<><div className="dash-tooltip">{Doc.isDocPinned(targetDoc) ? "Unpin from presentation" : "Pin to presentation"}</div></>}>
             <div className="propertiesButtons-linker"
-                style={{ backgroundColor: isPinned ? "white" : "rgb(37, 43, 51)", color: isPinned ? "black" : "white" }}
+                style={{ backgroundColor: isPinned ? "white" : "", color: isPinned ? "black" : "white" }}
                 onClick={e => DockedFrameRenderer.PinDoc(targetDoc, isPinned)}>
                 <FontAwesomeIcon className="documentdecorations-icon" size="sm" icon="map-pin"
                 />
@@ -238,6 +238,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     onAliasButtonDown = (e: React.PointerEvent): void => {
         setupMoveUpEvents(this, e, this.onAliasButtonMoved, emptyFunction, emptyFunction);
     }
+    @undoBatch
     onAliasButtonMoved = () => {
         if (this._dragRef.current) {
             const dragDocView = this.selectedDocumentView!;
@@ -273,12 +274,17 @@ export class PropertiesButtons extends React.Component<{}, {}> {
                 </div></Tooltip>;
     }
 
+    @undoBatch
     onCopy = () => {
         if (this.selectedDoc && this.selectedDocumentView) {
-            const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true);
-            copy.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width);
-            copy.y = NumCast(this.selectedDoc.y) + 30;
-            this.selectedDocumentView.props.addDocument?.(copy);
+            // const copy = Doc.MakeCopy(this.selectedDocumentView.props.Document, true);
+            // copy.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width);
+            // copy.y = NumCast(this.selectedDoc.y) + 30;
+            // this.selectedDocumentView.props.addDocument?.(copy);
+            const alias = Doc.MakeAlias(this.selectedDoc);
+            alias.x = NumCast(this.selectedDoc.x) + NumCast(this.selectedDoc._width);
+            alias.y = NumCast(this.selectedDoc.y) + 30;
+            this.selectedDocumentView.props.addDocument?.(alias);
         }
     }
 
@@ -295,7 +301,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         </Tooltip>;
     }
 
-    @action
+    @action @undoBatch
     onLock = () => {
         this.selectedDocumentView?.toggleLockPosition();
     }
@@ -337,15 +343,19 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         return !targetDoc ? (null) : <Tooltip
             title={<><div className="dash-tooltip">{"Delete Document"}</div></>}>
             <div className={"propertiesButtons-linkButton-empty"}
-                onPointerDown={() => {
-                    this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document);
-                }}>
+                onPointerDown={this.deleteDocument}>
                 {<FontAwesomeIcon className="propertiesButtons-icon"
                     icon="trash-alt" size="sm" />}
             </div>
         </Tooltip>;
     }
 
+    @undoBatch
+    @action
+    deleteDocument = () => {
+        this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document);
+    }
+
     @computed
     get sharingButton() {
         const targetDoc = this.selectedDoc;
@@ -380,6 +390,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
         }
     }
 
+    @undoBatch
     @action
     handleOptionChange = (e: any) => {
         const value = e.target.value;
diff --git a/src/client/views/collections/CollectionMenu.scss b/src/client/views/collections/CollectionMenu.scss
index 9da204787..0a316317f 100644
--- a/src/client/views/collections/CollectionMenu.scss
+++ b/src/client/views/collections/CollectionMenu.scss
@@ -2,8 +2,8 @@
 
 
 .collectionMenu-cont {
-    position:relative;
-    display:inline-flex;
+    position: relative;
+    display: inline-flex;
     width: 100%;
     opacity: 0.9;
     z-index: 9001;
@@ -12,14 +12,15 @@
     color: white;
     transform-origin: top left;
     top: 0;
-    width:100%;
+    width: 100%;
 
     .antimodeMenu-button {
         padding: 0;
         width: 30px;
         display: flex;
+
         svg {
-            margin:auto;
+            margin: auto;
         }
     }
 
@@ -108,6 +109,7 @@
                 margin-top: auto;
                 margin-bottom: auto;
             }
+
             .collectionViewBaseChrome-viewSpecs {
                 margin-left: 5px;
                 display: grid;
@@ -318,12 +320,14 @@
         text-align: center;
         display: block;
     }
+
     .color-previewI {
         width: 80%;
         height: 20%;
         bottom: 0;
         position: absolute;
     }
+
     .color-previewII {
         width: 80%;
         height: 80%;
@@ -336,7 +340,7 @@
         margin: auto;
         /* Make the buttons appear below each other */
     }
-    
+
     .btn-draw {
         display: inline-flex;
         margin: auto;
@@ -374,6 +378,7 @@
             display: block;
             margin: auto;
         }
+
         border-right: solid gray 1px;
     }
 }
@@ -398,14 +403,14 @@
 
     .collectionSchemaViewChrome-toggler {
         width: 100px;
-        height: 41px;
+        height: 35px;
         background-color: black;
         position: relative;
     }
 
     .collectionSchemaViewChrome-togglerButton {
         width: 47px;
-        height: 35px;
+        height: 30px;
         background-color: $light-color-secondary;
         // position: absolute;
         transition: all 0.5s ease;
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 7787a8b38..3c7471d7c 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -785,7 +785,7 @@ export class CollectionTreeView extends CollectionSubView<Document, Partial<coll
         onClicks.push({
             description: "Edit onChecked Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.doc, undefined, "onCheckedClick"), "edit onCheckedClick"), icon: "edit"
         });
-        !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" });
+        !existingOnClick && ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "mouse-pointer" });
     }
     outerXf = () => Utils.GetScreenTransform(this._mainEle!);
     onTreeDrop = (e: React.DragEvent) => this.onExternalDrop(e, {});
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index c2b55d38e..89034a0c0 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -339,7 +339,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                     icon: "edit",
                     event: () => Doc.GetProto(this.props.Document)[StrCast(childClick.targetScriptKey)] = ObjectField.MakeCopy(ScriptCast(childClick.data)),
                 }));
-            !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" });
+            !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "mouse-pointer" });
 
             if (!Doc.UserDoc().noviceMode) {
                 const more = cm.findByDescription("More...");
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index a96716659..7df56115f 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -60,6 +60,10 @@
             padding-left: 8px;
             background-color: rgb(51, 51, 51);
 
+            &:hover {
+                cursor: pointer;
+            }
+
             .propertiesView-settings-title-icon {
                 float: right;
                 right: 0;
@@ -94,6 +98,10 @@
             padding-left: 8px;
             background-color: rgb(51, 51, 51);
 
+            &:hover {
+                cursor: pointer;
+            }
+
             .propertiesView-sharing-title-icon {
                 float: right;
                 right: 0;
@@ -127,6 +135,10 @@
             padding-left: 8px;
             background-color: rgb(51, 51, 51);
 
+            &:hover {
+                cursor: pointer;
+            }
+
             .propertiesView-appearance-title-icon {
                 float: right;
                 right: 0;
@@ -160,6 +172,10 @@
             padding-left: 8px;
             background-color: rgb(51, 51, 51);
 
+            &:hover {
+                cursor: pointer;
+            }
+
             .propertiesView-transform-title-icon {
                 float: right;
                 right: 0;
@@ -287,6 +303,10 @@
             padding-left: 8px;
             background-color: rgb(51, 51, 51);
 
+            &:hover {
+                cursor: pointer;
+            }
+
             .propertiesView-fields-title-name {
                 font-size: 12.5px;
                 font-weight: bold;
@@ -362,6 +382,10 @@
             padding-left: 8px;
             background-color: rgb(51, 51, 51);
 
+            &:hover {
+                cursor: pointer;
+            }
+
             .propertiesView-layout-title-icon {
                 float: right;
                 right: 0;
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 73f0f1bdd..0168c825f 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -205,7 +205,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         }
     }
 
-
+    @undoBatch
     setKeyValue = (value: string) => {
         if (this.selectedDoc && this.dataDoc) {
             const doc = this.layoutFields ? Doc.Layout(this.selectedDoc) : this.dataDoc;
@@ -266,9 +266,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         }
     }
 
+    @undoBatch
+    changePermissions = (e: any, user: string) => {
+        SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!);
+    }
+
     getPermissionsSelect(user: string) {
         return <select className="permissions-select"
-            onChange={e => SharingManager.Instance.shareFromPropertiesSidebar(user, e.currentTarget.value as SharingPermissions, this.selectedDoc!)}>
+            onChange={e => this.changePermissions(e, user)}>
             {Object.values(SharingPermissions).map(permission => {
                 return (
                     <option key={permission} value={permission} selected={this.selectedDoc![`ACL-${user.replace(".", "_")}`] === permission}>
@@ -344,6 +349,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         />;
     }
 
+    @undoBatch
     @action
     toggleCheckbox = () => {
         this.layoutFields = !this.layoutFields;
@@ -359,6 +365,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
             SetValue={this.setTitle} />;
     }
 
+    @undoBatch
     @action
     setTitle = (value: string) => {
         if (this.dataDoc) {
@@ -370,13 +377,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     }
 
 
-
-
-
-
-
-
-
     @undoBatch
     @action
     rotate = (angle: number) => {
@@ -739,9 +739,13 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
         if (!this.selectedDoc) {
             return <div className="propertiesView" style={{ width: this.props.width }}>
-                <div className="propertiesView-title" style={{ width: this.props.width, paddingLeft: 6 }}>
+                <div className="propertiesView-title" style={{ width: this.props.width }}>
                     No Document Selected
-            </div> </div>;
+                <div className="propertiesView-title-icon" onPointerDown={this.props.onDown}>
+                        <FontAwesomeIcon icon="times" color="black" size="xs" />
+                    </div>
+                </div>
+            </div>;
         }
 
         const novice = Doc.UserDoc().noviceMode;
@@ -783,9 +787,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 </div> : null}
             </div>
 
-
-
-
             {this.isInk ? <div className="propertiesView-appearance">
                 <div className="propertiesView-appearance-title"
                     onPointerDown={() => runInAction(() => { this.openAppearance = !this.openAppearance; })}
@@ -814,10 +815,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                 </div> : null}
             </div> : null}
 
-
-
-
-
             <div className="propertiesView-fields">
                 <div className="propertiesView-fields-title"
                     onPointerDown={() => runInAction(() => { this.openFields = !this.openFields; })}
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 30382a4ef..ec0a5f3ac 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -677,10 +677,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     @action
     onCopy = () => {
-        const copy = Doc.MakeCopy(this.props.Document, true);
-        copy.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width);
-        copy.y = NumCast(this.props.Document.y) + 30;
-        this.props.addDocument?.(copy);
+        const alias = Doc.MakeAlias(this.props.Document);
+        alias.x = NumCast(this.props.Document.x) + NumCast(this.props.Document._width);
+        alias.y = NumCast(this.props.Document.y) + 30;
+        this.props.addDocument?.(alias);
     }
 
     @action
diff --git a/src/client/views/nodes/FontIconBox.scss b/src/client/views/nodes/FontIconBox.scss
index 13af511a6..a142d873a 100644
--- a/src/client/views/nodes/FontIconBox.scss
+++ b/src/client/views/nodes/FontIconBox.scss
@@ -33,7 +33,7 @@
     padding-left: 5px;
     width: 100%;
     width: 60px;
-    height: 70px;
+    height: 60px;
     padding-top: 3px;
     padding-bottom: 3px;
 
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index 720d6a15d..7c538df92 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -66,18 +66,21 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
 
         if (this.layoutDoc.menuIcon) {
 
-            let backgroundColor = "black";
-            if (this.dataDoc.title === "Sharing" || this.dataDoc.title === "Help" || this.dataDoc.title === "Settings" || this.dataDoc.title === "Import") {
-                backgroundColor = "black";
-            } else {
-                backgroundColor = CurrentUserUtils.selectedPanel === this.dataDoc.title ? "lightgrey" : "black";
-            }
+            // let backgroundColor = "black";
+            // if (this.dataDoc.title === "Sharing" || this.dataDoc.title === "Help" || this.dataDoc.title === "Settings" || this.dataDoc.title === "Import") {
+            //     backgroundColor = "black";
+            // } else {
+            //     backgroundColor = CurrentUserUtils.selectedPanel === this.dataDoc.title ? "lightgrey" : "";
+            // }
 
-            const color = backgroundColor === "lightgrey" ? "black" : "white";
-            const menuBTN = <div className="menuButton" style={{ backgroundColor: backgroundColor }}>
+            const color = CurrentUserUtils.selectedPanel === this.dataDoc.title ? "black" : "white";
+            const menuBTN = <div className="menuButton"
+                style={{ backgroundColor: CurrentUserUtils.selectedPanel === this.dataDoc.title ? "lightgrey" : "" }}>
 
-                <div className="menuButton-wrap" style={{ backgroundColor: backgroundColor }}>
-                    <FontAwesomeIcon className="menuButton-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={color} size="lg" />
+                <div className="menuButton-wrap"
+                    style={{ backgroundColor: CurrentUserUtils.selectedPanel === this.dataDoc.title ? "lightgrey" : "" }}>
+                    <FontAwesomeIcon className="menuButton-icon"
+                        icon={StrCast(this.dataDoc.icon, "user") as any} color={color} size="lg" />
                     <div className="menuButton-label" style={{ color: color }}> {this.dataDoc.title} </div>
                 </div>
             </div>;
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 0dfbdc5cf..05ba6628c 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -41,7 +41,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps, LabelDocument
             }, icon: "trash"
         });
 
-        ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: funcs, icon: "asterisk" });
+        ContextMenu.Instance.addItem({ description: "OnClick...", noexpand: true, subitems: funcs, icon: "mouse-pointer" });
     }
 
     @undoBatch
-- 
cgit v1.2.3-70-g09d2

