From 5b4b916b2700da746c12754ba3238eb1f3bbf5f7 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 15 Aug 2020 01:42:57 +0530
Subject: many changes to acls, aliases, sharing sidebar etc

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

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 57e968aa7..b38eed495 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -403,7 +403,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         // })
 
         // shifts the current user and the owner to the top of the doc.
-        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : StrCast(this.selectedDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`])));
+        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!));
         if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
 
         return <div className="propertiesView-sharingTable">
-- 
cgit v1.2.3-70-g09d2


From 624de3234c8daccdeb0d759c407cbd72880d3b35 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 15 Aug 2020 16:51:30 +0530
Subject: mainly ui

---
 src/client/views/collections/collectionFreeForm/PropertiesView.scss | 1 -
 src/client/views/collections/collectionFreeForm/PropertiesView.tsx  | 5 +++--
 2 files changed, 3 insertions(+), 3 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index aee28366a..ddaca7d42 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -267,7 +267,6 @@
             padding: 3px;
             align-items: center;
             border-bottom: 0.5px solid grey;
-            cursor: pointer;
 
             &:hover .propertiesView-sharingTable-item-name {
                 overflow-x: unset;
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index b38eed495..5c1ec1280 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -389,7 +389,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         if (this.selectedDoc![AclSym]) {
             for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) {
                 const name = key.substring(4).replace("_", ".");
-                if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author/* && sidebarUsersDisplayed![name] !== false*/) {
+                if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) {
                     tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!));
                 }
             }
@@ -402,7 +402,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         //     }
         // })
 
-        // shifts the current user and the owner to the top of the doc.
+        // shifts the current user, owner, public to the top of the doc.
+        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, AclMap.get(this.selectedDoc![AclSym]["ACL-Public"])!))
         tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!));
         if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
 
-- 
cgit v1.2.3-70-g09d2


From e7fd28e27e7389c67c22410ed1a3ff313556a153 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 15 Aug 2020 19:20:52 +0530
Subject: more alias stuff

---
 src/client/util/SharingManager.tsx                                 | 4 ++--
 src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

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

diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 9d79188a3..30935c5dd 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -165,7 +165,7 @@ export default class SharingManager extends React.Component<{}> {
 
         users.forEach(({ user, notificationDoc }) => {
             if (permission !== SharingPermissions.None) Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target); // add the target to the notificationDoc if it hasn't already been added
-            else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target); // remove the target from the list if it already exists
+            else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf((target.aliasOf as Doc || target), DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, (target.aliasOf as Doc || target)); // remove the target from the list if it already exists
         });
     }
 
@@ -235,7 +235,7 @@ export default class SharingManager extends React.Component<{}> {
         GetEffectiveAcl(target) === AclAdmin && distributeAcls(ACL, permission as SharingPermissions, target);
 
         if (permission !== SharingPermissions.None) Doc.IndexOf(target, DocListCast(notificationDoc[storage])) === -1 && Doc.AddDocToList(notificationDoc, storage, target);
-        else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf(target, DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, target);
+        else GetEffectiveAcl(target, undefined, user.email) === AclPrivate && Doc.IndexOf((target.aliasOf as Doc || target), DocListCast(notificationDoc[storage])) !== -1 && Doc.RemoveDocFromList(notificationDoc, storage, (target.aliasOf as Doc || target));
 
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 5c1ec1280..5b58d0ef4 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -403,7 +403,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         // })
 
         // shifts the current user, owner, public to the top of the doc.
-        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, AclMap.get(this.selectedDoc![AclSym]["ACL-Public"])!))
+        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(this.selectedDoc![AclSym]?.["ACL-Public"]) || SharingPermissions.None)));
         tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!));
         if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
 
-- 
cgit v1.2.3-70-g09d2


From a248e49ddbabe1947a3883bba47e786e22e1158a Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:21:12 +0530
Subject: added layoutdoc toggles

---
 src/client/util/SharingManager.scss                | 21 +++++++++-
 src/client/util/SharingManager.tsx                 | 46 +++++++++++++---------
 .../collectionFreeForm/PropertiesView.scss         | 14 +++++++
 .../collectionFreeForm/PropertiesView.tsx          | 26 ++++++++----
 4 files changed, 79 insertions(+), 28 deletions(-)

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

diff --git a/src/client/util/SharingManager.scss b/src/client/util/SharingManager.scss
index 7912db74d..42c300712 100644
--- a/src/client/util/SharingManager.scss
+++ b/src/client/util/SharingManager.scss
@@ -62,6 +62,7 @@
 
                 input {
                     height: 10px;
+                    cursor: pointer;
                 }
 
                 label {
@@ -69,11 +70,29 @@
                     font-style: italic;
                 }
             }
+
+            .layoutDoc-acls {
+                display: flex;
+                flex-direction: column;
+                float: right;
+                margin-right: 12;
+                margin-top: -15;
+                align-items: center;
+
+                label {
+                    font-weight: normal;
+                    font-style: italic;
+                }
+
+                input {
+                    cursor: pointer;
+                }
+            }
         }
 
         .main-container {
             display: flex;
-            margin-top: -10px;
+            margin-top: -25px;
 
             .individual-container,
             .group-container {
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 30935c5dd..5a863c813 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -1,7 +1,7 @@
 import { observable, runInAction, action } from "mobx";
 import * as React from "react";
 import MainViewModal from "../views/MainViewModal";
-import { Doc, Opt, AclAdmin, AclPrivate, DocListCast } from "../../fields/Doc";
+import { Doc, Opt, AclAdmin, AclPrivate, DocListCast, DataSym } from "../../fields/Doc";
 import { DocServer } from "../DocServer";
 import { Cast, StrCast } from "../../fields/Types";
 import * as RequestPromise from "request-promise";
@@ -25,7 +25,6 @@ import { library } from "@fortawesome/fontawesome-svg-core";
 
 library.add(fa.faInfoCircle, fa.faCaretUp, fa.faCaretRight, fa.faCaretDown);
 
-
 export interface User {
     email: string;
     userDocumentId: string;
@@ -47,6 +46,8 @@ interface GroupedOptions {
 const indType = "!indType/";
 const groupType = "!groupType/";
 
+const storage = "data";
+
 /**
  * A user who also has a notificationDoc.
  */
@@ -55,7 +56,6 @@ interface ValidatedUser {
     notificationDoc: Doc;
 }
 
-const storage = "data";
 
 @observer
 export default class SharingManager extends React.Component<{}> {
@@ -75,7 +75,8 @@ export default class SharingManager extends React.Component<{}> {
     // if both showUserOptions and showGroupOptions are false then both are displayed
     @observable private showUserOptions: boolean = false; // whether to show individuals as options when sharing (in the react-select component)
     @observable private showGroupOptions: boolean = false; // // whether to show groups as options when sharing (in the react-select component)
-    private populating: boolean = false;
+    private populating: boolean = false; // whether the list of users is populating or not
+    @observable private layoutDocAcls: boolean = false; // whether the layout doc or data doc's acls are to be used
 
     // private get linkVisible() {
     //     return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
@@ -176,7 +177,6 @@ export default class SharingManager extends React.Component<{}> {
      */
     shareWithAddedMember = (group: Doc, emailId: string) => {
         const user: ValidatedUser = this.users.find(({ user: { email } }) => email === emailId)!;
-
         if (group.docsShared) DocListCast(group.docsShared).forEach(doc => Doc.IndexOf(doc, DocListCast(user.notificationDoc[storage])) === -1 && Doc.AddDocToList(user.notificationDoc, storage, doc));
     }
 
@@ -184,9 +184,12 @@ export default class SharingManager extends React.Component<{}> {
      * Called from the properties sidebar to change permissions of a user.
      */
     shareFromPropertiesSidebar = (shareWith: string, permission: SharingPermissions, target: Doc) => {
-        const user = this.users.find(({ user: { email } }) => email === (shareWith === "Me" ? Doc.CurrentUserEmail : shareWith));
-        if (user) this.setInternalSharing(user, permission, target);
-        else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, target);
+        if (shareWith !== "Public") {
+            const user = this.users.find(({ user: { email } }) => email === (shareWith === "Me" ? Doc.CurrentUserEmail : shareWith));
+            if (user) this.setInternalSharing(user, permission, target);
+            else this.setInternalGroupSharing(GroupManager.Instance.getGroup(shareWith)!, permission, target);
+        }
+        else if (GetEffectiveAcl(target) === AclAdmin) distributeAcls("ACL-Public", permission, target);
     }
 
     /**
@@ -370,8 +373,8 @@ export default class SharingManager extends React.Component<{}> {
      * @returns the main interface of the SharingManager.
      */
     private get sharingInterface() {
-        const groupList = GroupManager.Instance?.getAllGroups() || [];
 
+        const groupList = GroupManager.Instance?.getAllGroups() || [];
         const sortedUsers = this.users.slice().sort(this.sortUsers)
             .map(({ user: { email } }) => ({ label: email, value: indType + email }));
         const sortedGroups = groupList.slice().sort(this.sortGroups)
@@ -404,17 +407,19 @@ export default class SharingManager extends React.Component<{}> {
             }
         }
 
-        const users = this.individualSort === "ascending" ? this.users.sort(this.sortUsers) : this.individualSort === "descending" ? this.users.sort(this.sortUsers).reverse() : this.users;
-        const groups = this.groupSort === "ascending" ? groupList.sort(this.sortGroups) : this.groupSort === "descending" ? groupList.sort(this.sortGroups).reverse() : groupList;
+        const users = this.individualSort === "ascending" ? this.users.slice().sort(this.sortUsers) : this.individualSort === "descending" ? this.users.slice().sort(this.sortUsers).reverse() : this.users;
+        const groups = this.groupSort === "ascending" ? groupList.slice().sort(this.sortGroups) : this.groupSort === "descending" ? groupList.slice().sort(this.sortGroups).reverse() : groupList;
 
-        const effectiveAcl = this.targetDoc ? GetEffectiveAcl(this.targetDoc) : AclPrivate;
+        const targetDoc = this.layoutDocAcls ? this.targetDoc : this.targetDoc?.[DataSym];
+
+        const effectiveAcl = targetDoc ? GetEffectiveAcl(targetDoc) : AclPrivate;
 
         // the list of users shared with
         const userListContents: (JSX.Element | null)[] = users.map(({ user, notificationDoc }) => {
             const userKey = user.email.replace('.', '_');
-            const permissions = StrCast(this.targetDoc?.[`ACL-${userKey}`]);
+            const permissions = StrCast(targetDoc?.[`ACL-${userKey}`]);
 
-            return !permissions || user.email === this.targetDoc?.author ? null : (
+            return !permissions || user.email === targetDoc?.author ? (null) : (
                 <div
                     key={userKey}
                     className={"container"}
@@ -446,7 +451,7 @@ export default class SharingManager extends React.Component<{}> {
                     key={"owner"}
                     className={"container"}
                 >
-                    <span className={"padding"}>{this.targetDoc?.author === Doc.CurrentUserEmail ? "Me" : this.targetDoc?.author}</span>
+                    <span className={"padding"}>{targetDoc?.author === Doc.CurrentUserEmail ? "Me" : targetDoc?.author}</span>
                     <div className="edit-actions">
                         <div className={"permissions-dropdown"}>
                             Owner
@@ -454,7 +459,7 @@ export default class SharingManager extends React.Component<{}> {
                     </div>
                 </div>
             ),
-            this.targetDoc?.author !== Doc.CurrentUserEmail ?
+            targetDoc?.author !== Doc.CurrentUserEmail ?
                 (
                     <div
                         key={"me"}
@@ -463,7 +468,7 @@ export default class SharingManager extends React.Component<{}> {
                         <span className={"padding"}>Me</span>
                         <div className="edit-actions">
                             <div className={"permissions-dropdown"}>
-                                {this.targetDoc?.[`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`]}
+                                {targetDoc?.[`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`]}
                             </div>
                         </div>
                     </div>
@@ -472,7 +477,7 @@ export default class SharingManager extends React.Component<{}> {
 
         // the list of groups shared with
         const groupListContents = groups.map(group => {
-            const permissions = StrCast(this.targetDoc?.[`ACL-${StrCast(group.groupName)}`]);
+            const permissions = StrCast(targetDoc?.[`ACL-${StrCast(group.groupName)}`]);
 
             return !permissions ? null : (
                 <div
@@ -538,7 +543,7 @@ export default class SharingManager extends React.Component<{}> {
                 </div>
                 <div className={"hr-substitute"} /> */}
                 <div className="sharing-contents">
-                    <p className={"share-title"}><b>Share </b>{this.focusOn(StrCast(this.targetDoc?.title, "this document"))}</p>
+                    <p className={"share-title"}><b>Share </b>{this.focusOn(StrCast(targetDoc?.title, "this document"))}</p>
                     <div className={"close-button"} onClick={this.close}>
                         <FontAwesomeIcon icon={"times"} color={"black"} size={"lg"} />
                     </div>
@@ -569,6 +574,9 @@ export default class SharingManager extends React.Component<{}> {
                             <input type="checkbox" onChange={action(() => this.showUserOptions = !this.showUserOptions)} /> <label style={{ marginRight: 10 }}>Individuals</label>
                             <input type="checkbox" onChange={action(() => this.showGroupOptions = !this.showGroupOptions)} /> <label>Groups</label>
                         </div>
+                        <div className="layoutDoc-acls">
+                            <input type="checkbox" onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)} checked={this.layoutDocAcls} /> <label>Layout</label>
+                        </div>
                     </div>
                     }
                     <div className="main-container">
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.scss b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
index ddaca7d42..535581f2e 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.scss
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.scss
@@ -121,6 +121,19 @@
             padding: 10px;
             margin-left: 5px;
 
+            .propertiesView-acls-checkbox {
+                float: right;
+                height: 20px;
+                margin-top: -20px;
+                margin-right: -15;
+
+                .propertiesView-acls-checkbox-text {
+                    font-size: 7px;
+                    margin-top: -10px;
+                    margin-left: 6px;
+                }
+            }
+
             .change-buttons {
                 display: flex;
 
@@ -259,6 +272,7 @@
         background-color: #ececec;
         max-height: 130px;
         overflow-y: scroll;
+        width: 92%;
 
         .propertiesView-sharingTable-item {
 
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 5b58d0ef4..85a1d7137 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -2,7 +2,7 @@ import React = require("react");
 import { observer } from "mobx-react";
 import "./PropertiesView.scss";
 import { observable, action, computed, runInAction } from "mobx";
-import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync } from "../../../../fields/Doc";
+import { Doc, Field, WidthSym, HeightSym, AclSym, AclPrivate, AclReadonly, AclAddonly, AclEdit, AclAdmin, Opt, DocCastAsync, DataSym } from "../../../../fields/Doc";
 import { ComputedField } from "../../../../fields/ScriptField";
 import { EditableView } from "../../EditableView";
 import { KeyValueBox } from "../../nodes/KeyValueBox";
@@ -73,6 +73,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @observable openTransform: boolean = true;
     // @observable selectedUser: string = "";
     // @observable addButtonPressed: boolean = false;
+    @observable layoutDocAcls: boolean = false;
 
     //Pres Trails booleans:
     @observable openPresTransitions: boolean = false;
@@ -386,11 +387,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         const tableEntries = [];
 
         // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
-        if (this.selectedDoc![AclSym]) {
-            for (const [key, value] of Object.entries(this.selectedDoc![AclSym])) {
+        const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym];
+        if (target[AclSym]) {
+            for (const [key, value] of Object.entries(target[AclSym])) {
                 const name = key.substring(4).replace("_", ".");
-                if (name !== Doc.CurrentUserEmail && name !== this.selectedDoc!.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) {
-                    tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value)!));
+                if (name !== Doc.CurrentUserEmail && name !== target.author && name !== "Public"/* && sidebarUsersDisplayed![name] !== false*/) {
+                    tableEntries.push(this.sharingItem(name, effectiveAcl, AclMap.get(value as symbol)!));
                 }
             }
         }
@@ -403,9 +405,9 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         // })
 
         // shifts the current user, owner, public to the top of the doc.
-        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(this.selectedDoc![AclSym]?.["ACL-Public"]) || SharingPermissions.None)));
-        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === this.selectedDoc!.author ? "Owner" : AclMap.get(effectiveAcl)!));
-        if (Doc.CurrentUserEmail !== this.selectedDoc!.author) tableEntries.unshift(this.sharingItem(StrCast(this.selectedDoc!.author), effectiveAcl, "Owner"));
+        tableEntries.unshift(this.sharingItem("Public", effectiveAcl, (AclMap.get(target[AclSym]?.["ACL-Public"]) || SharingPermissions.None)));
+        tableEntries.unshift(this.sharingItem("Me", effectiveAcl, Doc.CurrentUserEmail === target.author ? "Owner" : AclMap.get(effectiveAcl)!));
+        if (Doc.CurrentUserEmail !== target.author) tableEntries.unshift(this.sharingItem(StrCast(target.author), effectiveAcl, "Owner"));
 
         return <div className="propertiesView-sharingTable">
             {tableEntries}
@@ -867,6 +869,14 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
                         </div>
                         {!this.openSharing ? (null) :
                             <div className="propertiesView-sharing-content">
+                                <div className="propertiesView-acls-checkbox">
+                                    <Checkbox
+                                        color="primary"
+                                        onChange={action(() => this.layoutDocAcls = !this.layoutDocAcls)}
+                                        checked={this.layoutDocAcls}
+                                    />;
+                                    <div className="propertiesView-acls-checkbox-text">Layout</div>
+                                </div>
                                 {this.sharingTable}
                                 {/* <div className="change-buttons">
                             <button
-- 
cgit v1.2.3-70-g09d2


From 8f180cd9ef75eb1aaa6fed9e6544b7b6256cda73 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 17 Aug 2020 23:28:55 +0530
Subject: properties panel acl issue fixed

---
 src/client/views/collections/collectionFreeForm/PropertiesView.tsx | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

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

diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 85a1d7137..ed451beab 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -383,11 +383,12 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
             [AclAdmin, SharingPermissions.Admin]
         ]);
 
-        const effectiveAcl = GetEffectiveAcl(this.selectedDoc!);
+        const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym];
+
+        const effectiveAcl = GetEffectiveAcl(target);
         const tableEntries = [];
 
         // DocCastAsync(Doc.UserDoc().sidebarUsersDisplayed).then(sidebarUsersDisplayed => {
-        const target = this.layoutDocAcls ? this.selectedDoc! : this.selectedDoc![DataSym];
         if (target[AclSym]) {
             for (const [key, value] of Object.entries(target[AclSym])) {
                 const name = key.substring(4).replace("_", ".");
-- 
cgit v1.2.3-70-g09d2


From a9f029cad5588ef127de753a4ee4ac0a8c739eb0 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Tue, 18 Aug 2020 23:08:13 -0400
Subject: added document selection for items in a SchemaView so that Properties
 and context menu can operate on them.

---
 src/client/util/SelectionManager.ts                | 17 ++++++++++++--
 src/client/util/SharingManager.tsx                 |  6 ++---
 .../views/collections/CollectionSchemaView.tsx     | 26 ++++++++++++++++++++--
 src/client/views/collections/SchemaTable.tsx       |  6 +++--
 .../collectionFreeForm/PropertiesView.tsx          | 10 +++++----
 src/client/views/nodes/DocumentView.tsx            |  4 ++--
 6 files changed, 54 insertions(+), 15 deletions(-)

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

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 113278593..14d06b9b6 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,10 +1,11 @@
 import { observable, action, runInAction, ObservableMap } from "mobx";
-import { Doc } from "../../fields/Doc";
+import { Doc, Opt } from "../../fields/Doc";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { computedFn } from "mobx-utils";
 import { List } from "../../fields/List";
 import { Scripting } from "./Scripting";
 import { DocumentManager } from "./DocumentManager";
+import { MobileDocumentUploadContent } from "../../server/Message";
 
 export namespace SelectionManager {
 
@@ -12,7 +13,12 @@ export namespace SelectionManager {
 
         @observable IsDragging: boolean = false;
         SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
+        @observable SelectedSchemaDocument: Doc | undefined;
 
+        @action
+        SelectSchemaDoc(doc: Opt<Doc>) {
+            manager.SelectedSchemaDocument = doc;
+        }
         @action
         SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
 
@@ -26,6 +32,7 @@ export namespace SelectionManager {
                 docView.props.whenActiveChanged(true);
             } else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) {
                 Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false));
+                manager.SelectedSchemaDocument = undefined;
                 manager.SelectedDocuments.clear();
                 manager.SelectedDocuments.set(docView, true);
             }
@@ -42,7 +49,7 @@ export namespace SelectionManager {
         }
         @action
         DeselectAll(): void {
-
+            manager.SelectedSchemaDocument = undefined;
             Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false));
             manager.SelectedDocuments.clear();
             Doc.UserDoc().activeSelection = new List<Doc>([]);
@@ -57,6 +64,9 @@ export namespace SelectionManager {
     export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
         manager.SelectDoc(docView, ctrlPressed);
     }
+    export function SelectSchemaDoc(document: Opt<Doc>): void {
+        manager.SelectSchemaDoc(document);
+    }
 
     // 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
@@ -84,4 +94,7 @@ export namespace SelectionManager {
     export function SelectedDocuments(): Array<DocumentView> {
         return Array.from(manager.SelectedDocuments.keys());
     }
+    export function SelectedSchemaDoc(): Doc | undefined {
+        return manager.SelectedSchemaDocument;
+    }
 }
\ No newline at end of file
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 5a863c813..b9918e900 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -82,15 +82,15 @@ export default class SharingManager extends React.Component<{}> {
     //     return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
     // }
 
-    public open = (target: DocumentView) => {
+    public open = (target?: DocumentView, target_doc?: Doc) => {
         runInAction(() => this.users = []);
         // SelectionManager.DeselectAll();
         this.populateUsers();
         runInAction(() => {
             this.targetDocView = target;
-            this.targetDoc = target.props.Document;
+            this.targetDoc = target_doc || target?.props.Document;
             DictationOverlay.Instance.hasActiveModal = true;
-            this.isOpen = true;
+            this.isOpen = this.targetDoc !== undefined;
             this.permissions = SharingPermissions.Edit;
         });
         this.targetDoc!.author === Doc.CurrentUserEmail && !this.targetDoc![`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`] && distributeAcls(`ACL-${Doc.CurrentUserEmail.replace(".", "_")}`, SharingPermissions.Admin, this.targetDoc!);
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index a72b349ec..f34ac7d03 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -7,7 +7,7 @@ import { observer } from "mobx-react";
 import Measure from "react-measure";
 import { Resize } from "react-table";
 import "react-table/react-table.css";
-import { Doc } from "../../../fields/Doc";
+import { Doc, Opt } from "../../../fields/Doc";
 import { List } from "../../../fields/List";
 import { listSpec } from "../../../fields/Schema";
 import { PastelSchemaPalette, SchemaHeaderField } from "../../../fields/SchemaHeaderField";
@@ -24,6 +24,9 @@ import { KeysDropdown } from "./CollectionSchemaHeaders";
 import "./CollectionSchemaView.scss";
 import { CollectionSubView } from "./CollectionSubView";
 import { SchemaTable } from "./SchemaTable";
+import { SelectionManager } from "../../util/SelectionManager";
+import { ContextMenu } from "../ContextMenu";
+import { ContextMenuProps } from "../ContextMenuItem";
 
 library.add(faCog, faPlus, faSortUp, faSortDown);
 library.add(faTable);
@@ -388,7 +391,10 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
 
     @action setFocused = (doc: Doc) => this._focusedTable = doc;
 
-    @action setPreviewDoc = (doc: Doc) => this.previewDoc = doc;
+    @action setPreviewDoc = (doc: Opt<Doc>) => {
+        SelectionManager.SelectSchemaDoc(doc);
+        this.previewDoc = doc;
+    }
 
     //toggles preview side-panel of schema
     @action
@@ -515,9 +521,24 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             </div>
         </div>;
     }
+    onSpecificMenu = (e: React.MouseEvent) => {
+        if ((e.target as any)?.className?.includes?.("collectionSchemaView-cell") || (e.target instanceof HTMLSpanElement)) {
+            const cm = ContextMenu.Instance;
+            const options = cm.findByDescription("Options...");
+            const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
+            optionItems.push({ description: "remove", event: () => this.previewDoc && this.props.removeDocument(this.previewDoc), icon: "trash" });
+            !options && cm.addItem({ description: "Options...", subitems: optionItems, icon: "compass" });
+            cm.displayMenu(e.clientX, e.clientY);
+            (e.nativeEvent as any).SchemaHandled = true; // not sure why this is needed, but if you right-click quickly on a cell, the Document/Collection contextMenu handlers still fire without this.
+            e.stopPropagation();
+        }
+    }
 
     @action
     onTablePointerDown = (e: React.PointerEvent): void => {
+        if (!(e.target as any)?.className?.includes?.("collectionSchemaView-cell") && !(e.target instanceof HTMLSpanElement)) {
+            this.setPreviewDoc(undefined);
+        }
         this.setFocused(this.props.Document);
         if (e.button === 0 && !e.altKey && !e.ctrlKey && !e.metaKey && this.props.isSelected(true)) {
             e.stopPropagation();
@@ -601,6 +622,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
             <div className="collectionSchemaView-tableContainer"
                 style={{ backgroundColor: "white", width: `calc(100% - ${this.previewWidth()}px)` }}
                 onKeyPress={this.onKeyPress}
+                onContextMenu={this.onSpecificMenu}
                 onPointerDown={this.onPointerDown}
                 onWheel={e => this.props.active(true) && e.stopPropagation()}
                 onDrop={e => this.onExternalDrop(e, {})}
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 5a86150fe..7913c92a4 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -70,7 +70,7 @@ export interface SchemaTableProps {
     isSelected: (outsideReaction?: boolean) => boolean;
     isFocused: (document: Doc, outsideReaction: boolean) => boolean;
     setFocused: (document: Doc) => void;
-    setPreviewDoc: (document: Doc) => void;
+    setPreviewDoc: (document: Opt<Doc>) => void;
     columns: SchemaHeaderField[];
     documentKeys: any[];
     headerIsEditing: boolean;
@@ -385,7 +385,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
 
             const pdoc = FieldValue(this.childDocs[this._focusedCell.row]);
             pdoc && this.props.setPreviewDoc(pdoc);
-        } else if ((this._cellIsEditing || this.props.headerIsEditing) && (e.keyCode === 37 || e.keyCode === 39)) {
+            e.stopPropagation();
+        } else if (e.keyCode === 27) {
+            this.props.setPreviewDoc(undefined);
             e.stopPropagation(); // stopPropagation for left/right arrows 
         }
     }
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index ed451beab..6fc03c3b5 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -49,8 +49,11 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
     @computed get MAX_EMBED_HEIGHT() { return 200; }
 
+    @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
     @computed get selectedDocumentView() {
-        if (SelectionManager.SelectedDocuments().length) {
+        if (SelectionManager.SelectedSchemaDoc())
+            return undefined;
+        else if (SelectionManager.SelectedDocuments().length) {
             return SelectionManager.SelectedDocuments()[0];
         } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) {
             return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
@@ -60,7 +63,6 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         if (this.selectedDoc?.type === DocumentType.PRES) return true;
         return false;
     }
-    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
     @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
 
     @observable layoutFields: boolean = false;
@@ -345,8 +347,8 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
     @computed get expansionIcon() {
         return <Tooltip title={<div className="dash-tooltip">{"Show more permissions"}</div>}>
             <div className="expansion-button" onPointerDown={() => {
-                if (this.selectedDocumentView) {
-                    SharingManager.Instance.open(this.selectedDocumentView);
+                if (this.selectedDocumentView || this.selectedDoc) {
+                    SharingManager.Instance.open(this.selectedDocumentView, this.selectedDoc);
                 }
             }}>
                 <FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" />
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 0939ccdf7..9ae113150 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -684,7 +684,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
     }
 
     @action
-    onContextMenu = async (e: React.MouseEvent | Touch): Promise<void> => {
+    onContextMenu = (e: React.MouseEvent | Touch) => {
         // the touch onContextMenu is button 0, the pointer onContextMenu is button 2
         if (!(e instanceof Touch)) {
             if (e.button === 0 && !e.ctrlKey) {
@@ -703,7 +703,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         }
 
         const cm = ContextMenu.Instance;
-        if (!cm) return;
+        if (!cm || ((e as any)?.nativeEvent as any)?.SchemaHandled) return;
 
         const customScripts = Cast(this.props.Document.contextMenuScripts, listSpec(ScriptField), []);
         Cast(this.props.Document.contextMenuLabels, listSpec("string"), []).forEach((label, i) =>
-- 
cgit v1.2.3-70-g09d2


From bf4baf81576cfd7363cccdd2526914f6afd59c98 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Wed, 19 Aug 2020 00:12:50 -0400
Subject: updated PropertiesButtons to work with selected documents in
 schemaViews

---
 src/client/util/SelectionManager.ts                | 17 +++++---
 src/client/views/PropertiesButtons.tsx             | 49 +++++++++++-----------
 .../views/collections/CollectionSchemaView.tsx     |  3 +-
 .../collectionFreeForm/PropertiesView.tsx          |  6 +--
 4 files changed, 39 insertions(+), 36 deletions(-)

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

diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 14d06b9b6..35b82cc30 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -3,9 +3,7 @@ import { Doc, Opt } from "../../fields/Doc";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { computedFn } from "mobx-utils";
 import { List } from "../../fields/List";
-import { Scripting } from "./Scripting";
-import { DocumentManager } from "./DocumentManager";
-import { MobileDocumentUploadContent } from "../../server/Message";
+import { CollectionSchemaView } from "../views/collections/CollectionSchemaView";
 
 export namespace SelectionManager {
 
@@ -14,10 +12,12 @@ export namespace SelectionManager {
         @observable IsDragging: boolean = false;
         SelectedDocuments: ObservableMap<DocumentView, boolean> = new ObservableMap();
         @observable SelectedSchemaDocument: Doc | undefined;
+        @observable SelectedSchemaCollection: CollectionSchemaView | undefined;
 
         @action
-        SelectSchemaDoc(doc: Opt<Doc>) {
+        SelectSchemaDoc(collectionView: Opt<CollectionSchemaView>, doc: Opt<Doc>) {
             manager.SelectedSchemaDocument = doc;
+            manager.SelectedSchemaCollection = collectionView;
         }
         @action
         SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
@@ -33,6 +33,7 @@ export namespace SelectionManager {
             } else if (!ctrlPressed && Array.from(manager.SelectedDocuments.entries()).length > 1) {
                 Array.from(manager.SelectedDocuments.keys()).map(dv => dv !== docView && dv.props.whenActiveChanged(false));
                 manager.SelectedSchemaDocument = undefined;
+                manager.SelectedSchemaCollection = undefined;
                 manager.SelectedDocuments.clear();
                 manager.SelectedDocuments.set(docView, true);
             }
@@ -49,6 +50,7 @@ export namespace SelectionManager {
         }
         @action
         DeselectAll(): void {
+            manager.SelectedSchemaCollection = undefined;
             manager.SelectedSchemaDocument = undefined;
             Array.from(manager.SelectedDocuments.keys()).map(dv => dv.props.whenActiveChanged(false));
             manager.SelectedDocuments.clear();
@@ -64,8 +66,8 @@ export namespace SelectionManager {
     export function SelectDoc(docView: DocumentView, ctrlPressed: boolean): void {
         manager.SelectDoc(docView, ctrlPressed);
     }
-    export function SelectSchemaDoc(document: Opt<Doc>): void {
-        manager.SelectSchemaDoc(document);
+    export function SelectSchemaDoc(colSchema: Opt<CollectionSchemaView>, document: Opt<Doc>): void {
+        manager.SelectSchemaDoc(colSchema, document);
     }
 
     // computed functions, such as used in IsSelected generate errors if they're called outside of a
@@ -97,4 +99,7 @@ export namespace SelectionManager {
     export function SelectedSchemaDoc(): Doc | undefined {
         return manager.SelectedSchemaDocument;
     }
+    export function SelectedSchemaCollection(): CollectionSchemaView | undefined {
+        return manager.SelectedSchemaCollection;
+    }
 }
\ No newline at end of file
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index dfedc9ccc..e220bd7fc 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -77,12 +77,12 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     public static hasPulledHack = false;
 
 
+    @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
     @computed get selectedDocumentView() {
         if (SelectionManager.SelectedDocuments().length) {
             return SelectionManager.SelectedDocuments()[0];
-        } else { return undefined; }
+        } else return undefined;
     }
-    @computed get selectedDoc() { return this.selectedDocumentView?.rootDoc; }
     @computed get dataDoc() { return this.selectedDocumentView?.dataDoc; }
 
     @computed get onClick() { return this.selectedDoc?.onClickBehavior ? this.selectedDoc?.onClickBehavior : "nothing"; }
@@ -297,9 +297,9 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     }
     @undoBatch
     onAliasButtonMoved = () => {
-        if (this._dragRef.current) {
+        if (this._dragRef.current && this.selectedDoc) {
             const dragDocView = this.selectedDocumentView!;
-            const dragData = new DragManager.DocumentDragData([dragDocView.props.Document]);
+            const dragData = new DragManager.DocumentDragData([this.selectedDoc]);
             const [left, top] = dragDocView.props.ScreenToLocalTransform().inverse().transformPoint(0, 0);
             dragData.dropAction = "alias";
             DragManager.StartDocumentDrag([dragDocView.ContentDiv!], dragData, left, top, {
@@ -314,7 +314,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
 
     @computed
     get templateButton() {
-        const docView = this.selectedDocumentView;
+        const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined;
         const templates: Map<Template, boolean> = new Map();
         const views = [this.selectedDocumentView];
         Array.from(Object.values(Templates.TemplateList)).map(template =>
@@ -366,7 +366,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
 
     @action @undoBatch
     onLock = () => {
-        this.selectedDocumentView?.toggleLockPosition();
+        const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined;
+        docView?.toggleLockPosition();
     }
 
     @computed
@@ -401,8 +402,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             <div>
                 <div className={"propertiesButtons-linkButton-empty"}
                     onPointerDown={async () => {
-                        if (this.selectedDocumentView?.props.Document) {
-                            Doc.Zip(this.selectedDocumentView?.props.Document);
+                        if (this.selectedDoc) {
+                            Doc.Zip(this.selectedDoc);
                         }
                     }}>
                     {<FontAwesomeIcon className="propertiesButtons-icon"
@@ -432,23 +433,22 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     @undoBatch
     @action
     deleteDocument = () => {
-        const selected = SelectionManager.SelectedDocuments().slice();
-        selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
-        this.selectedDoc && (this.selectedDoc.deleted = true);
-        this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document);
+        const removeDoc = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView?.props.removeDocument : SelectionManager.SelectedSchemaCollection()?.props.removeDocument;
+        this.selectedDoc && removeDoc?.(this.selectedDoc);
         SelectionManager.DeselectAll();
     }
 
     @computed
     get sharingButton() {
         const targetDoc = this.selectedDoc;
+        const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined;
         return !targetDoc ? (null) : <Tooltip
             title={<><div className="dash-tooltip">{"Share Document"}</div></>} placement="top">
             <div>
                 <div className={"propertiesButtons-linkButton-empty"}
                     onPointerDown={() => {
                         if (this.selectedDocumentView) {
-                            SharingManager.Instance.open(this.selectedDocumentView);
+                            SharingManager.Instance.open(docView, this.selectedDoc);
                         }
                     }}>
                     {<FontAwesomeIcon className="propertiesButtons-icon"
@@ -485,20 +485,21 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     handleOptionChange = (e: any) => {
         const value = e.target.value;
         this.selectedDoc && (this.selectedDoc.onClickBehavior = e.target.value);
+        const docView = this.selectedDocumentView?.props.Document === this.selectedDoc ? this.selectedDocumentView : undefined;
         if (value === "nothing") {
-            this.selectedDocumentView?.noOnClick();
+            docView?.noOnClick();
         } else if (value === "enterPortal") {
-            this.selectedDocumentView?.noOnClick();
-            this.selectedDocumentView?.makeIntoPortal();
+            docView?.noOnClick();
+            docView?.makeIntoPortal();
         } else if (value === "toggleDetail") {
-            this.selectedDocumentView?.noOnClick();
-            this.selectedDocumentView?.toggleDetail();
+            docView?.noOnClick();
+            docView?.toggleDetail();
         } else if (value === "linkInPlace") {
-            this.selectedDocumentView?.noOnClick();
-            this.selectedDocumentView?.toggleFollowLink("inPlace", true, false);
+            docView?.noOnClick();
+            docView?.toggleFollowLink("inPlace", true, false);
         } else if (value === "linkOnRight") {
-            this.selectedDocumentView?.noOnClick();
-            this.selectedDocumentView?.toggleFollowLink("onRight", false, false);
+            docView?.noOnClick();
+            docView?.toggleFollowLink("onRight", false, false);
         }
     }
 
@@ -565,8 +566,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             <div>
                 <div className={"propertiesButtons-linkButton-empty"}
                     onPointerDown={() => {
-                        if (this.selectedDocumentView) {
-                            GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDocumentView.Document }).then(console.log);
+                        if (this.selectedDoc) {
+                            GooglePhotos.Export.CollectionToAlbum({ collection: this.selectedDoc }).then(console.log);
                         }
                     }}>
                     {<FontAwesomeIcon className="documentdecorations-icon"
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index f34ac7d03..bc44ad8a5 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -20,7 +20,6 @@ import { undoBatch } from "../../util/UndoManager";
 import { COLLECTION_BORDER_WIDTH } from '../../views/globalCssVariables.scss';
 import '../DocumentDecorations.scss';
 import { ContentFittingDocumentView } from "../nodes/ContentFittingDocumentView";
-import { KeysDropdown } from "./CollectionSchemaHeaders";
 import "./CollectionSchemaView.scss";
 import { CollectionSubView } from "./CollectionSubView";
 import { SchemaTable } from "./SchemaTable";
@@ -392,7 +391,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
     @action setFocused = (doc: Doc) => this._focusedTable = doc;
 
     @action setPreviewDoc = (doc: Opt<Doc>) => {
-        SelectionManager.SelectSchemaDoc(doc);
+        SelectionManager.SelectSchemaDoc(this, doc);
         this.previewDoc = doc;
     }
 
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index 6fc03c3b5..fb138ecc0 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -51,9 +51,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
 
     @computed get selectedDoc() { return SelectionManager.SelectedSchemaDoc() || this.selectedDocumentView?.rootDoc; }
     @computed get selectedDocumentView() {
-        if (SelectionManager.SelectedSchemaDoc())
-            return undefined;
-        else if (SelectionManager.SelectedDocuments().length) {
+        if (SelectionManager.SelectedDocuments().length) {
             return SelectionManager.SelectedDocuments()[0];
         } else if (PresBox.Instance && PresBox.Instance._selectedArray.length) {
             return DocumentManager.Instance.getDocumentView(PresBox.Instance.rootDoc);
@@ -348,7 +346,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
         return <Tooltip title={<div className="dash-tooltip">{"Show more permissions"}</div>}>
             <div className="expansion-button" onPointerDown={() => {
                 if (this.selectedDocumentView || this.selectedDoc) {
-                    SharingManager.Instance.open(this.selectedDocumentView, this.selectedDoc);
+                    SharingManager.Instance.open(this.selectedDocumentView?.props.Document === this.selectedDocumentView ? this.selectedDocumentView : undefined, this.selectedDoc);
                 }
             }}>
                 <FontAwesomeIcon className="expansion-button-icon" icon="ellipsis-h" color="black" size="sm" />
-- 
cgit v1.2.3-70-g09d2

