From 3bd97210a1112d9d0af802255677caf1de95616c Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Sat, 8 Aug 2020 21:24:47 -0400
Subject: tidying up assorted features, disabling editing doc keys in search,
 etc

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

(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 4d1cb670c..30747ff4f 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -46,6 +46,7 @@ import { CollectionTimeView } from './CollectionTimeView';
 import { CollectionTreeView } from "./CollectionTreeView";
 import './CollectionView.scss';
 import { ContextMenuProps } from '../ContextMenuItem';
+import { table } from 'console';
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -182,6 +183,8 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                     // targetDataDoc[this.props.fieldKey] = new List<Doc>([...docList, ...added]);
                     (targetDataDoc[this.props.fieldKey] as List<Doc>).push(...added);
                     targetDataDoc[this.props.fieldKey + "-lastModified"] = new DateField(new Date(Date.now()));
+                    const lastModified = "lastModified";
+                    targetDataDoc[lastModified] = new DateField(new Date(Date.now()));
                 }
             }
         }
-- 
cgit v1.2.3-70-g09d2


From f557c78db9a77812ab398aaff08d9511c1c65fc9 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 10 Aug 2020 18:07:51 +0530
Subject: prevented infinite loop in distributeAcls + allowed change of alias
 x, y, width, height in owned collection + changes to removeDocument calls in
 many places + comments etc

---
 src/client/util/KeyCodes.ts                               |  2 +-
 src/client/util/SharingManager.tsx                        |  4 +++-
 src/client/views/DocComponent.tsx                         |  6 +++++-
 src/client/views/DocumentDecorations.tsx                  | 10 +---------
 src/client/views/GlobalKeyHandler.ts                      |  9 +--------
 src/client/views/PropertiesButtons.tsx                    | 10 +---------
 src/client/views/collections/CollectionLinearView.tsx     |  2 +-
 src/client/views/collections/CollectionView.tsx           |  6 +++++-
 .../views/collections/collectionFreeForm/MarqueeView.tsx  |  9 +--------
 src/client/views/nodes/DocumentView.tsx                   | 15 ++++-----------
 src/fields/util.ts                                        | 10 +++++++---
 11 files changed, 30 insertions(+), 53 deletions(-)

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

diff --git a/src/client/util/KeyCodes.ts b/src/client/util/KeyCodes.ts
index cacb72a57..de2457a5a 100644
--- a/src/client/util/KeyCodes.ts
+++ b/src/client/util/KeyCodes.ts
@@ -131,6 +131,6 @@ export class KeyCodes {
     public static NUM_7: number = 55;
     public static NUM_8: number = 56;
     public static NUM_9: number = 57;
-    public static SUBSTRACT: number = 189;
+    public static SUBTRACT: number = 189;
     public static ADD: number = 187;
 }
\ No newline at end of file
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index d50a132f8..48a3c023f 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -179,6 +179,9 @@ export default class SharingManager extends React.Component<{}> {
         if (group.docsShared) DocListCast(group.docsShared).forEach(doc => Doc.IndexOf(doc, DocListCast(user.notificationDoc[storage])) === -1 && Doc.AddDocToList(user.notificationDoc, storage, doc));
     }
 
+    /**
+     * 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);
@@ -228,7 +231,6 @@ export default class SharingManager extends React.Component<{}> {
         const key = user.email.replace('.', '_');
         const ACL = `ACL-${key}`;
 
-
         target.author === Doc.CurrentUserEmail && distributeAcls(ACL, permission as SharingPermissions, target);
 
         if (permission !== SharingPermissions.None) {
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index eea133ed9..f453b02b8 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -129,7 +129,11 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
             const toRemove = value.filter(v => docs.includes(v));
             // can't assign new List<Doc>(result) to this because you can't assign new values in addonly
             if (toRemove.length !== 0) {
-                toRemove.forEach(doc => Doc.RemoveDocFromList(targetDataDoc, this.annotationKey, doc));
+                const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
+                toRemove.forEach(doc => {
+                    Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
+                    recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+                });
                 return true;
             }
 
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index f1169763e..804c60ec8 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -197,17 +197,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
     @action
     onCloseClick = async (e: React.MouseEvent | undefined) => {
         if (!e?.button) {
-            const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
             const selected = SelectionManager.SelectedDocuments().slice();
             SelectionManager.DeselectAll();
-
-            selected.map(dv => {
-                const effectiveAcl = GetEffectiveAcl(dv.props.Document);
-                if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
-                    recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
-                    dv.props.removeDocument?.(dv.props.Document);
-                }
-            });
+            selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
         }
     }
     @action
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 0ea02e3cb..2b31a8612 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -118,16 +118,9 @@ export default class KeyManager {
                     }
                 }
 
-                const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
                 const selected = SelectionManager.SelectedDocuments().slice();
                 UndoManager.RunInBatch(() => {
-                    selected.map(dv => {
-                        const effectiveAcl = GetEffectiveAcl(dv.props.Document);
-                        if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
-                            recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
-                            dv.props.removeDocument?.(dv.props.Document);
-                        }
-                    });
+                    selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
                 }, "delete");
                 SelectionManager.DeselectAll();
                 break;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 5e25ead87..0ca28df9c 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -432,16 +432,8 @@ export class PropertiesButtons extends React.Component<{}, {}> {
     @undoBatch
     @action
     deleteDocument = () => {
-        const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
         const selected = SelectionManager.SelectedDocuments().slice();
-
-        selected.map(dv => {
-            const effectiveAcl = GetEffectiveAcl(dv.props.Document);
-            if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
-                recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
-                dv.props.removeDocument?.(dv.props.Document);
-            }
-        });
+        selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
         this.selectedDoc && (this.selectedDoc.deleted = true);
         this.selectedDocumentView?.props.ContainingCollectionView?.removeDocument(this.selectedDocumentView?.props.Document);
         SelectionManager.DeselectAll();
diff --git a/src/client/views/collections/CollectionLinearView.tsx b/src/client/views/collections/CollectionLinearView.tsx
index 3cf46dbed..e1b07077e 100644
--- a/src/client/views/collections/CollectionLinearView.tsx
+++ b/src/client/views/collections/CollectionLinearView.tsx
@@ -119,7 +119,7 @@ export class CollectionLinearView extends CollectionSubView(LinearDocument) {
             // transform: this.props.Document.linearViewIsExpanded ? "" : "rotate(45deg)"
         }}
             onPointerDown={e => e.stopPropagation()} >
-            <p>+</p>
+            <p>{BoolCast(this.props.Document.linearViewIsExpanded) ? "–" : "+"}</p>
         </label>;
 
         return <div className="collectionLinearView-outer">
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 0feec3fbd..852826ebc 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -199,7 +199,11 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             const value = DocListCast(targetDataDoc[this.props.fieldKey]);
             const toRemove = value.filter(v => docs.includes(v));
             if (toRemove.length !== 0) {
-                toRemove.forEach(doc => Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc));
+                const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
+                toRemove.forEach(doc => {
+                    Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
+                    recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+                });
                 return true;
             }
         }
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 858f33291..a23f03e2a 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -345,14 +345,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
         const selected = this.marqueeSelect(false);
         SelectionManager.DeselectAll();
-
-        selected.map(doc => {
-            const effectiveAcl = GetEffectiveAcl(doc);
-            if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
-                recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
-                this.props.removeDocument(doc);
-            }
-        });
+        this.props.removeDocument(selected);
 
         this.cleanupInteractions(false);
         MarqueeOptionsMenu.Instance.fadeOut(true);
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 47e1b2715..52748ba0a 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -570,17 +570,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         if (Doc.UserDoc().activeWorkspace === this.props.Document) {
             alert("Can't delete the active workspace");
         } else {
-            const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
             const selected = SelectionManager.SelectedDocuments().slice();
             SelectionManager.DeselectAll();
-
-            selected.map(dv => {
-                const effectiveAcl = GetEffectiveAcl(dv.props.Document);
-                if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) { // deletes whatever you have the right to delete
-                    recent && Doc.AddDocToList(recent, "data", dv.props.Document, undefined, true, true);
-                    dv.props.removeDocument?.(dv.props.Document);
-                }
-            });
+            selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
 
             this.props.Document.deleted = true;
             this.props.removeDocument?.(this.props.Document);
@@ -776,8 +768,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()) && moreItems.push({ description: "Toggle Always Show Link End", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" });
         }
 
-        const effectiveAcl = GetEffectiveAcl(this.props.Document);
-        (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) && moreItems.push({ description: "Delete", event: this.deleteClicked, icon: "trash" });
+        // const effectiveAcl = GetEffectiveAcl(this.props.Document);
+        // (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) &&
+        moreItems.push({ description: "Close", event: this.deleteClicked, icon: "trash" });
 
         !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
         cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 4c71572db..7d3268b80 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -167,6 +167,9 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
         // if the ACL is being overriden or the property being modified is one of the playground fields (which can be freely modified)
         if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit;
 
+        // if it's your alias then you can manipulate the x, y, width, height
+        if ((target.aliasOf || target.__fields?.aliasOf) && Doc.CurrentUserEmail === (target.__fields?.author || target.author) && (in_prop && ["_width", "_height", "x", "y"].includes(in_prop.toString()))) return AclEdit;
+
         let effectiveAcl = AclPrivate;
         const HierarchyMapping = new Map<symbol, number>([
             [AclPrivate, 0],
@@ -218,9 +221,10 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
         changed = true;
 
         // maps over the aliases of the document
-        if (target.aliases) {
-            DocListCast(target.aliases).map(alias => {
-                distributeAcls(key, acl, alias, inheritingFromCollection);
+        const aliases = DocListCast(target.aliases);
+        if (aliases.length) {
+            aliases.map(alias => {
+                alias !== target && distributeAcls(key, acl, alias, inheritingFromCollection);
             });
         }
 
-- 
cgit v1.2.3-70-g09d2


From cf45a2398dce7af290bed364fa1bb8681134ce15 Mon Sep 17 00:00:00 2001
From: Andy Rickert <andrew_rickert@brown.edu>
Date: Mon, 10 Aug 2020 18:30:44 -0400
Subject: filter checkboxes

---
 src/client/views/MainView.tsx                      |   2 +-
 .../views/collections/CollectionSchemaCells.tsx    |  31 ++--
 .../views/collections/CollectionSchemaHeaders.tsx  | 200 ++++++++++++++++++++-
 .../views/collections/CollectionSchemaView.scss    |  41 +++++
 src/client/views/collections/CollectionView.tsx    | 111 ++++++------
 src/client/views/collections/SchemaTable.tsx       |  10 +-
 src/fields/Doc.ts                                  |   2 +
 src/server/ApiManagers/SearchManager.ts            |   2 +-
 src/server/websocket.ts                            |   3 +-
 9 files changed, 322 insertions(+), 80 deletions(-)

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

diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 744e5c68b..d7359d7e2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -195,7 +195,7 @@ export class MainView extends React.Component {
             let check = false;
             const icon = "icon";
             targets.forEach((thing) => {
-                if (thing.className.toString() === "collectionSchemaView-searchContainer" || (thing as any)?.dataset[icon] === "filter" || thing.className.toString() === "collectionSchema-header-menuOptions") {
+                if (thing.className.toString() === "collectionSchemaView-searchContainer" || (thing as any)?.dataset[icon] === "filter" || thing.className.toString() === "collectionSchema-header-menuOptions" || thing.className.toString() === "altcollectionTimeView-treeView") {
                     check = true;
                 }
             });
diff --git a/src/client/views/collections/CollectionSchemaCells.tsx b/src/client/views/collections/CollectionSchemaCells.tsx
index 64c925af2..2069255f7 100644
--- a/src/client/views/collections/CollectionSchemaCells.tsx
+++ b/src/client/views/collections/CollectionSchemaCells.tsx
@@ -34,6 +34,7 @@ import "react-datepicker/dist/react-datepicker.css";
 import { DateField } from "../../../fields/DateField";
 import { RichTextField } from "../../../fields/RichTextField";
 import { DocumentManager } from "../../util/DocumentManager";
+import { SearchUtil } from "../../util/SearchUtil";
 const path = require('path');
 
 library.add(faExpand);
@@ -218,19 +219,23 @@ export class CollectionSchemaCell extends React.Component<CellProps> {
         const fieldIsDoc = (type === "document" && typeof field === "object") || (typeof field === "object" && doc);
 
         const onItemDown = async (e: React.PointerEvent) => {
-            //DocumentManager.Instance.FollowLink(undefined, this.props.rowProps.original, doc => this.props.addDocTab(doc, "onRight"), false);
-            let doc = Doc.GetProto(this.props.rowProps.original);
-            const targetContext = doc.links;
-            //const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined;
-            console.log(targetContext);
-            DocumentManager.Instance.jumpToDocument(this.props.rowProps.original, false, undefined, undefined);
-
-            //target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "onRight"), finished), targetNavContext, linkDoc, undefined, doc, finished);
-            //fieldIsDoc &&     
-            // SetupDrag(this._focusRef,
-            //     () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
-            //     this._document[props.fieldKey] instanceof Doc ? (doc: Doc | Doc[], target: Doc | undefined, addDoc: (newDoc: Doc | Doc[]) => any) => addDoc(doc) : this.props.moveDocument,
-            //     this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
+            if (this.props.Document._searchDoc !== undefined) {
+                let doc = Doc.GetProto(this.props.rowProps.original);
+                const aliasdoc = await SearchUtil.GetAliasesOfDocument(doc);
+                let targetContext = undefined;
+                if (aliasdoc.length > 0) {
+                    targetContext = Cast(aliasdoc[0].context, Doc) as Doc;
+                }
+                console.log(targetContext);
+                DocumentManager.Instance.jumpToDocument(this.props.rowProps.original, false, undefined, targetContext);
+            }
+            else {
+                fieldIsDoc &&
+                    SetupDrag(this._focusRef,
+                        () => this._document[props.fieldKey] instanceof Doc ? this._document[props.fieldKey] : this._document,
+                        this._document[props.fieldKey] instanceof Doc ? (doc: Doc | Doc[], target: Doc | undefined, addDoc: (newDoc: Doc | Doc[]) => any) => addDoc(doc) : this.props.moveDocument,
+                        this._document[props.fieldKey] instanceof Doc ? "alias" : this.props.Document.schemaDoc ? "copy" : undefined)(e);
+            }
         };
         const onPointerEnter = (e: React.PointerEvent): void => {
             if (e.buttons === 1 && SnappingManager.GetIsDragging() && (type === "document" || type === undefined)) {
diff --git a/src/client/views/collections/CollectionSchemaHeaders.tsx b/src/client/views/collections/CollectionSchemaHeaders.tsx
index bde7d054e..e8dd74dab 100644
--- a/src/client/views/collections/CollectionSchemaHeaders.tsx
+++ b/src/client/views/collections/CollectionSchemaHeaders.tsx
@@ -1,5 +1,5 @@
 import React = require("react");
-import { action, observable } from "mobx";
+import { action, observable, computed } from "mobx";
 import { observer } from "mobx-react";
 import "./CollectionSchemaView.scss";
 import { faPlus, faFont, faHashtag, faAlignJustify, faCheckSquare, faToggleOn, faSortAmountDown, faSortAmountUp, faTimes, faImage, faListUl, faCalendar } from '@fortawesome/free-solid-svg-icons';
@@ -9,9 +9,21 @@ import { ColumnType } from "./CollectionSchemaView";
 import { faFile } from "@fortawesome/free-regular-svg-icons";
 import { SchemaHeaderField, PastelSchemaPalette } from "../../../fields/SchemaHeaderField";
 import { undoBatch } from "../../util/UndoManager";
-import { Doc } from "../../../fields/Doc";
-import { StrCast } from "../../../fields/Types";
+import { Transform } from '../../util/Transform';
+import { Doc, DocListCast, Field, Opt } from "../../../fields/Doc";
+import { StrCast, Cast } from "../../../fields/Types";
 import { optionFocusAriaMessage } from "react-select/src/accessibility";
+import { TraceMobx } from "../../../fields/util";
+import { CollectionTreeView } from "./CollectionTreeView";
+import { returnEmptyFilter, returnFalse, emptyPath, returnZero, emptyFunction, returnOne } from "../../../Utils";
+import { RichTextField } from "../../../fields/RichTextField";
+import { Docs } from "../../documents/Documents";
+import { List } from "../../../fields/List";
+import { listSpec } from "../../../fields/Schema";
+import { ScriptField, ComputedField } from "../../../fields/ScriptField";
+import { DocumentType } from "../../documents/DocumentTypes";
+import { CollectionView } from "./CollectionView";
+
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
@@ -287,7 +299,12 @@ export interface KeysDropdownProps {
     setIsEditing: (isEditing: boolean) => void;
     width?: string;
     docs?: Doc[];
-
+    Document?: Doc;
+    dataDoc?: Doc;
+    fieldKey?: string;
+    ContainingCollectionDoc?: Doc;
+    ContainingCollectionView?: CollectionView;
+    active?: (outsideReaction?: boolean) => boolean;
 }
 @observer
 export class KeysDropdown extends React.Component<KeysDropdownProps> {
@@ -426,7 +443,8 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         let keyOptions: string[] = [];
         const colpos = this._searchTerm.indexOf(":");
         const temp = this._searchTerm.slice(colpos + 1, this._searchTerm.length);
-        this.props.docs?.forEach((doc) => {
+        let docs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+        docs.forEach((doc) => {
             const key = StrCast(doc[this._key]);
             if (keyOptions.includes(key) === false && key.includes(temp)) {
                 keyOptions.push(key);
@@ -438,7 +456,11 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
             return <div key={key} className="key-option" style={{
                 border: "1px solid lightgray", width: this.props.width, maxWidth: this.props.width, overflowX: "hidden", background: "white", backgroundColor: "white",
             }}
-                onPointerDown={e => e.stopPropagation()} onClick={() => { this.onSelectValue(key); }}>{key}</div>;
+            >
+                <input type="checkbox" onChange={(e) => { e.target.checked === true ? Doc.setDocFilter(this.props.Document!, this._key, key, "check") : Doc.setDocFilter(this.props.Document!, this._key, key, undefined) }} ></input>
+                {key}
+
+            </div>;
         });
         if (options.length === 0) {
             this.defaultMenuHeight = 0;
@@ -457,8 +479,172 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
         return options;
     }
 
+
+    // @action
+    // renderFilterOptions = (): JSX.Element[] | JSX.Element => {
+    //     this.facetClick(this._key);
+    //     return <div>
+    //         {this.filterView}
+    //     </div>
+    // }
     @observable defaultMenuHeight = 0;
 
+
+    facetClick = (facetHeader: string) => {
+        facetHeader = this._key;
+        let newFacet: Opt<Doc>;
+        if (this.props.Document !== undefined) {
+            const facetCollection = this.props.Document;
+            // const found = DocListCast(facetCollection[this.props.fieldKey + "-filter"]).findIndex(doc => doc.title === facetHeader);
+            // if (found !== -1) {
+            //     console.log("found not n-1");
+            //     (facetCollection[this.props.fieldKey + "-filter"] as List<Doc>).splice(found, 1);
+            //     const docFilter = Cast(this.props.Document._docFilters, listSpec("string"));
+            //     if (docFilter) {
+            //         let index: number;
+            //         while ((index = docFilter.findIndex(item => item === facetHeader)) !== -1) {
+            //             docFilter.splice(index, 3);
+            //         }
+            //     }
+            //     const docRangeFilters = Cast(this.props.Document._docRangeFilters, listSpec("string"));
+            //     if (docRangeFilters) {
+            //         let index: number;
+            //         while ((index = docRangeFilters.findIndex(item => item === facetHeader)) !== -1) {
+            //             docRangeFilters.splice(index, 3);
+            //         }
+            //     }
+            // }
+
+
+
+            console.log("found is n-1");
+            const allCollectionDocs = DocListCast(this.props.dataDoc![this.props.fieldKey!]);
+            var rtfields = 0;
+            const facetValues = Array.from(allCollectionDocs.reduce((set, child) => {
+                const field = child[facetHeader] as Field;
+                const fieldStr = Field.toString(field);
+                if (field instanceof RichTextField || (typeof (field) === "string" && fieldStr.split(" ").length > 2)) rtfields++;
+                return set.add(fieldStr);
+            }, new Set<string>()));
+
+            let nonNumbers = 0;
+            let minVal = Number.MAX_VALUE, maxVal = -Number.MAX_VALUE;
+            facetValues.map(val => {
+                const num = Number(val);
+                if (Number.isNaN(num)) {
+                    nonNumbers++;
+                } else {
+                    minVal = Math.min(num, minVal);
+                    maxVal = Math.max(num, maxVal);
+                }
+            });
+            if (facetHeader === "text" || rtfields / allCollectionDocs.length > 0.1) {
+                console.log("Case1");
+                newFacet = Docs.Create.TextDocument("", { _width: 100, _height: 25, treeViewExpandedView: "layout", title: facetHeader, treeViewOpen: true, forceActive: true, ignoreClick: true });
+                Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
+                newFacet.target = this.props.Document;
+                newFacet._textBoxPadding = 4;
+                const scriptText = `setDocFilter(this.target, "${facetHeader}", text, "match")`;
+                newFacet.onTextChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, text: "string" });
+            } else if (nonNumbers / facetValues.length < .1) {
+                console.log("Case2");
+                newFacet = Docs.Create.SliderDocument({ title: facetHeader, treeViewExpandedView: "layout", treeViewOpen: true });
+                const newFacetField = Doc.LayoutFieldKey(newFacet);
+                const ranged = Doc.readDocRangeFilter(this.props.Document, facetHeader);
+                Doc.GetProto(newFacet).type = DocumentType.COL; // forces item to show an open/close button instead ofa checkbox
+                const extendedMinVal = minVal - Math.min(1, Math.abs(maxVal - minVal) * .05);
+                const extendedMaxVal = maxVal + Math.min(1, Math.abs(maxVal - minVal) * .05);
+                newFacet[newFacetField + "-min"] = ranged === undefined ? extendedMinVal : ranged[0];
+                newFacet[newFacetField + "-max"] = ranged === undefined ? extendedMaxVal : ranged[1];
+                Doc.GetProto(newFacet)[newFacetField + "-minThumb"] = extendedMinVal;
+                Doc.GetProto(newFacet)[newFacetField + "-maxThumb"] = extendedMaxVal;
+                newFacet.target = this.props.Document;
+                const scriptText = `setDocFilterRange(this.target, "${facetHeader}", range)`;
+                newFacet.onThumbChanged = ScriptField.MakeScript(scriptText, { this: Doc.name, range: "number" });
+                Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
+            } else {
+                console.log("Case3");
+                newFacet = new Doc();
+                newFacet.title = facetHeader;
+                newFacet.treeViewOpen = true;
+                newFacet.type = DocumentType.COL;
+                const capturedVariables = { layoutDoc: this.props.Document, dataDoc: this.props.dataDoc! };
+                this.props.Document.data = ComputedField.MakeFunction(`readFacetData(layoutDoc, dataDoc, "${this.props.fieldKey}", "${facetHeader}")`, {}, capturedVariables);
+                // this.props.Document.data
+            }
+            //newFacet && Doc.AddDocToList(facetCollection, this.props.fieldKey + "-filter", newFacet);
+        }
+    }
+
+
+    get ignoreFields() { return ["_docFilters", "_docRangeFilters"]; }
+
+    @computed get scriptField() {
+        console.log("we kinda made it");
+        const scriptText = "setDocFilter(containingTreeView, heading, this.title, checked)";
+        const script = ScriptField.MakeScript(scriptText, { this: Doc.name, heading: "string", checked: "string", containingTreeView: Doc.name });
+        return script ? () => script : undefined;
+    }
+    filterBackground = () => "rgba(105, 105, 105, 0.432)";
+
+
+    // @computed get filterView() {
+    //     TraceMobx();
+    //     if (this.props.Document !== undefined) {
+    //         //const facetCollection = this.props.Document;
+    //         // const flyout = (
+    //         //     <div className="collectionTimeView-flyout" style={{ width: `${this.facetWidth()}`, height: this.props.PanelHeight() - 30 }} onWheel={e => e.stopPropagation()}>
+    //         //         {this._allFacets.map(facet => <label className="collectionTimeView-flyout-item" key={`${facet}`} onClick={e => this.facetClick(facet)}>
+    //         //             <input type="checkbox" onChange={e => { }} checked={DocListCast(this.props.Document[this.props.fieldKey + "-filter"]).some(d => d.title === facet)} />
+    //         //             <span className="checkmark" />
+    //         //             {facet}
+    //         //         </label>)}
+    //         //     </div>
+    //         // );
+    //         return <div className="altcollectionTimeView-treeView">
+    //             <div className="altcollectionTimeView-tree" key="tree">
+    //                 <CollectionTreeView
+    //                     PanelPosition={""}
+    //                     Document={this.props.Document}
+    //                     DataDoc={this.props.Document}
+    //                     fieldKey={this.props.fieldKey!}
+    //                     CollectionView={undefined}
+    //                     docFilters={returnEmptyFilter}
+    //                     ContainingCollectionDoc={this.props.ContainingCollectionDoc!}
+    //                     ContainingCollectionView={this.props.ContainingCollectionView!}
+    //                     PanelWidth={() => 200}
+    //                     PanelHeight={() => 200}
+    //                     NativeHeight={returnZero}
+    //                     NativeWidth={returnZero}
+    //                     LibraryPath={emptyPath}
+    //                     rootSelected={returnFalse}
+    //                     renderDepth={1}
+    //                     dropAction={undefined}
+    //                     ScreenToLocalTransform={Transform.Identity}
+    //                     addDocTab={returnFalse}
+    //                     pinToPres={returnFalse}
+    //                     isSelected={returnFalse}
+    //                     select={returnFalse}
+    //                     bringToFront={emptyFunction}
+    //                     active={this.props.active!}
+    //                     whenActiveChanged={returnFalse}
+    //                     treeViewHideTitle={true}
+    //                     ContentScaling={returnOne}
+    //                     focus={returnFalse}
+    //                     treeViewHideHeaderFields={true}
+    //                     onCheckedClick={this.scriptField}
+    //                     ignoreFields={this.ignoreFields}
+    //                     annotationsKey={""}
+    //                     dontRegisterView={true}
+    //                     backgroundColor={this.filterBackground}
+    //                     moveDocument={returnFalse}
+    //                     removeDocument={returnFalse}
+    //                     addDocument={returnFalse} />
+    //             </div>
+    //         </div>;
+    //     }
+    // }
+
     render() {
         return (
             <div className="keys-dropdown" style={{ zIndex: 10, width: this.props.width, maxWidth: this.props.width }}>
@@ -470,7 +656,7 @@ export class KeysDropdown extends React.Component<KeysDropdownProps> {
                         e.stopPropagation();
                     }} onFocus={this.onFocus} onBlur={this.onBlur}></input>
                 <div className="keys-options-wrapper" style={{
-                    width: this.props.width, maxWidth: this.props.width, overflow: "scroll", height: this.defaultMenuHeight,
+                    width: this.props.width, maxWidth: this.props.width, overflow: "scroll", height: "auto",
                 }}
                     onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerOut}>
                     {this._searchTerm.includes(":") ?
diff --git a/src/client/views/collections/CollectionSchemaView.scss b/src/client/views/collections/CollectionSchemaView.scss
index 86bf9d0e0..ee643b86b 100644
--- a/src/client/views/collections/CollectionSchemaView.scss
+++ b/src/client/views/collections/CollectionSchemaView.scss
@@ -357,6 +357,47 @@ button.add-column {
     }
 }
 
+.altcollectionTimeView-treeView {
+    display: flex;
+    flex-direction: column;
+    width: 175px;
+    height: auto;
+    position: fixed;
+    border-left: solid 1px;
+    z-index: 1;
+
+    .collectionTimeView-addfacet {
+        display: inline-block;
+        width: 200px;
+        height: 30px;
+        background: darkGray;
+        text-align: left;
+
+        .collectionTimeView-button {
+            align-items: center;
+            display: flex;
+            width: 100%;
+            height: 100%;
+
+            .collectionTimeView-span {
+                margin: auto;
+            }
+        }
+
+        >div,
+        >div>div {
+            width: 100%;
+            height: 100%;
+        }
+    }
+
+    .altcollectionTimeView-tree {
+        display: inline-block;
+        width: 100%;
+        height: calc(100% - 30px);
+    }
+}
+
 .collectionSchema-row {
     height: 100%;
     background-color: white;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 30747ff4f..73a5566d6 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -513,56 +513,56 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 </label>)}
             </div>
         );
-        return !this._facetWidth || this.props.dontRegisterView ? (null) :
-            <div className="collectionTimeView-treeView" style={{ width: `${this.facetWidth()}px`, overflow: this.facetWidth() < 15 ? "hidden" : undefined }}>
-                <div className="collectionTimeView-addFacet" style={{ width: `${this.facetWidth()}px` }} onPointerDown={e => e.stopPropagation()}>
-                    <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout}>
-                        <div className="collectionTimeView-button">
-                            <FontAwesomeIcon icon={faEdit} size={"lg"} />
-                            <span className="collectionTimeView-span">Facet Filters</span>
-                        </div>
-                    </Flyout>
-                </div>
-                <div className="collectionTimeView-tree" key="tree">
-                    <CollectionTreeView
-                        PanelPosition={""}
-                        Document={facetCollection}
-                        DataDoc={facetCollection}
-                        fieldKey={`${this.props.fieldKey}-filter`}
-                        CollectionView={this}
-                        docFilters={returnEmptyFilter}
-                        ContainingCollectionDoc={this.props.ContainingCollectionDoc}
-                        ContainingCollectionView={this.props.ContainingCollectionView}
-                        PanelWidth={this.facetWidth}
-                        PanelHeight={this.props.PanelHeight}
-                        NativeHeight={returnZero}
-                        NativeWidth={returnZero}
-                        LibraryPath={emptyPath}
-                        rootSelected={this.props.rootSelected}
-                        renderDepth={1}
-                        dropAction={this.props.dropAction}
-                        ScreenToLocalTransform={this.props.ScreenToLocalTransform}
-                        addDocTab={returnFalse}
-                        pinToPres={returnFalse}
-                        isSelected={returnFalse}
-                        select={returnFalse}
-                        bringToFront={emptyFunction}
-                        active={this.props.active}
-                        whenActiveChanged={returnFalse}
-                        treeViewHideTitle={true}
-                        ContentScaling={returnOne}
-                        focus={returnFalse}
-                        treeViewHideHeaderFields={true}
-                        onCheckedClick={this.scriptField}
-                        ignoreFields={this.ignoreFields}
-                        annotationsKey={""}
-                        dontRegisterView={true}
-                        backgroundColor={this.filterBackground}
-                        moveDocument={returnFalse}
-                        removeDocument={returnFalse}
-                        addDocument={returnFalse} />
-                </div>
-            </div>;
+
+        return !this._facetWidth || this.props.dontRegisterView ? (null) : <div className="collectionTimeView-treeView" style={{ width: `${this.facetWidth()}px`, overflow: this.facetWidth() < 15 ? "hidden" : undefined }}>
+            <div className="collectionTimeView-addFacet" style={{ width: `${this.facetWidth()}px` }} onPointerDown={e => e.stopPropagation()}>
+                <Flyout anchorPoint={anchorPoints.LEFT_TOP} content={flyout}>
+                    <div className="collectionTimeView-button">
+                        <FontAwesomeIcon icon={faEdit} size={"lg"} />
+                        <span className="collectionTimeView-span">Facet Filters</span>
+                    </div>
+                </Flyout>
+            </div>
+            <div className="collectionTimeView-tree" key="tree">
+                <CollectionTreeView
+                    PanelPosition={""}
+                    Document={facetCollection}
+                    DataDoc={facetCollection}
+                    fieldKey={`${this.props.fieldKey}-filter`}
+                    CollectionView={this}
+                    docFilters={returnEmptyFilter}
+                    ContainingCollectionDoc={this.props.ContainingCollectionDoc}
+                    ContainingCollectionView={this.props.ContainingCollectionView}
+                    PanelWidth={this.facetWidth}
+                    PanelHeight={this.props.PanelHeight}
+                    NativeHeight={returnZero}
+                    NativeWidth={returnZero}
+                    LibraryPath={emptyPath}
+                    rootSelected={this.props.rootSelected}
+                    renderDepth={1}
+                    dropAction={this.props.dropAction}
+                    ScreenToLocalTransform={this.props.ScreenToLocalTransform}
+                    addDocTab={returnFalse}
+                    pinToPres={returnFalse}
+                    isSelected={returnFalse}
+                    select={returnFalse}
+                    bringToFront={emptyFunction}
+                    active={this.props.active}
+                    whenActiveChanged={returnFalse}
+                    treeViewHideTitle={true}
+                    ContentScaling={returnOne}
+                    focus={returnFalse}
+                    treeViewHideHeaderFields={true}
+                    onCheckedClick={this.scriptField}
+                    ignoreFields={this.ignoreFields}
+                    annotationsKey={""}
+                    dontRegisterView={true}
+                    backgroundColor={this.filterBackground}
+                    moveDocument={returnFalse}
+                    removeDocument={returnFalse}
+                    addDocument={returnFalse} />
+            </div>
+        </div>;
     }
 
     childLayoutTemplate = () => this.props.childLayoutTemplate?.() || Cast(this.props.Document.childLayoutTemplate, Doc, null);
@@ -595,11 +595,12 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                         Utils.CorsProxy(Cast(d.data, ImageField)!.url.href) : Cast(d.data, ImageField)!.url.href
                     :
                     ""))}
-            {(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%" }} />
-            }
-            {Doc.UserDoc()?.noviceMode || this.facetWidth() < 10 ? (null) : this.filterView}
+            {/* {(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%" }} />
+            {/* } */}
+            {/* {Doc.UserDoc()?.noviceMode || this.facetWidth() < 10 ? (null) : this.filterView} */}
+            {this.filterView};
         </div>);
     }
 }
diff --git a/src/client/views/collections/SchemaTable.tsx b/src/client/views/collections/SchemaTable.tsx
index 972f4c066..d8756aae3 100644
--- a/src/client/views/collections/SchemaTable.tsx
+++ b/src/client/views/collections/SchemaTable.tsx
@@ -177,9 +177,9 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 }
             );
         }
+        this.props.active
 
         const cols = this.props.columns.map(col => {
-
             const keysDropdown = <KeysDropdown
                 keyValue={col.heading}
                 possibleKeys={possibleKeys}
@@ -189,6 +189,14 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
                 onSelect={this.props.changeColumns}
                 setIsEditing={this.props.setHeaderIsEditing}
                 docs={this.props.childDocs}
+                Document={this.props.Document}
+                dataDoc={this.props.dataDoc}
+                fieldKey={this.props.fieldKey}
+                ContainingCollectionDoc={this.props.ContainingCollectionDoc}
+                ContainingCollectionView={this.props.ContainingCollectionView}
+                active={this.props.active}
+
+
                 // try commenting this out
                 width={"100%"}
             />;
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 6bfe91378..7769fd337 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1036,6 +1036,8 @@ export namespace Doc {
     // all documents with the specified value for the specified key are included/excluded 
     // based on the modifiers :"check", "x", undefined
     export function setDocFilter(container: Doc, key: string, value: any, modifiers?: "match" | "check" | "x" | undefined) {
+        console.log("WE REALLY MADE IT");
+        console.log(container, key, value, modifiers);
         const docFilters = Cast(container._docFilters, listSpec("string"), []);
         runInAction(() => {
             for (let i = 0; i < docFilters.length; i += 3) {
diff --git a/src/server/ApiManagers/SearchManager.ts b/src/server/ApiManagers/SearchManager.ts
index 7251e07a1..753c31fcf 100644
--- a/src/server/ApiManagers/SearchManager.ts
+++ b/src/server/ApiManagers/SearchManager.ts
@@ -176,7 +176,7 @@ export namespace SolrManager {
         "audio": ["_t", "url"],
         "web": ["_t", "url"],
         "date": ["_d", value => new Date(value.date).toISOString()],
-        // "proxy": ["_i", "fieldId"],
+        "proxy": ["_i", "fieldId"],
         "list": ["_l", list => {
             const results = [];
             for (const value of list.fields) {
diff --git a/src/server/websocket.ts b/src/server/websocket.ts
index 63cfa41f0..798c79164 100644
--- a/src/server/websocket.ts
+++ b/src/server/websocket.ts
@@ -230,8 +230,7 @@ export namespace WebSocket {
         "script": ["_t", value => value.script.originalScript],
         "RichTextField": ["_t", value => value.Text],
         "date": ["_d", value => new Date(value.date).toISOString()],
-        // "proxy": ["_i", "fieldId"],
-        // "proxy": ["", "fieldId"],
+        "proxy": ["_i", "fieldId"],
         "list": ["_l", list => {
             const results = [];
             for (const value of list.fields) {
-- 
cgit v1.2.3-70-g09d2


From 6cc1e1df5c4809ca0c31b40f11a6d02cf3b3dc04 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 12 Aug 2020 00:03:18 +0530
Subject: minor changes

---
 src/client/views/DocComponent.tsx               | 3 ++-
 src/client/views/collections/CollectionView.tsx | 1 +
 src/client/views/nodes/DocumentView.tsx         | 4 ----
 3 files changed, 3 insertions(+), 5 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index f453b02b8..a05bfc302 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -127,12 +127,13 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
             const targetDataDoc = this.dataDoc;
             const value = DocListCast(targetDataDoc[this.annotationKey]);
             const toRemove = value.filter(v => docs.includes(v));
-            // can't assign new List<Doc>(result) to this because you can't assign new values in addonly
+
             if (toRemove.length !== 0) {
                 const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
                 toRemove.forEach(doc => {
                     Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
                     recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+                    doc.deleted = true;
                 });
                 return true;
             }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 852826ebc..555db7e1a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -203,6 +203,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
                 toRemove.forEach(doc => {
                     Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
                     recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+                    doc.deleted = true;
                 });
                 return true;
             }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index af9967942..7d2c34b2b 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -573,8 +573,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             const selected = SelectionManager.SelectedDocuments().slice();
             SelectionManager.DeselectAll();
             selected.map(dv => dv.props.removeDocument?.(dv.props.Document));
-
-            this.props.Document.deleted = true;
             this.props.removeDocument?.(this.props.Document);
         }
     }
@@ -768,8 +766,6 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             Doc.AreProtosEqual(this.props.Document, Doc.UserDoc()) && moreItems.push({ description: "Toggle Always Show Link End", event: () => Doc.UserDoc()["documentLinksButton-hideEnd"] = !Doc.UserDoc()["documentLinksButton-hideEnd"], icon: "eye" });
         }
 
-        // const effectiveAcl = GetEffectiveAcl(this.props.Document);
-        // (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) &&
         moreItems.push({ description: "Close", event: this.deleteClicked, icon: "trash" });
 
         !more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
-- 
cgit v1.2.3-70-g09d2


From c01cb1dcda454a80555d2ae041800ef3bd261d81 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Wed, 12 Aug 2020 21:47:39 +0530
Subject: used datadoc for acl calculations in many places + some other changes

---
 src/client/views/DocComponent.tsx                  | 31 ++++++++++++----------
 src/client/views/DocumentDecorations.tsx           |  5 ++--
 src/client/views/GlobalKeyHandler.ts               |  3 +--
 src/client/views/PropertiesButtons.tsx             |  3 +--
 src/client/views/collections/CollectionView.tsx    |  8 +++---
 .../collections/collectionFreeForm/MarqueeView.tsx |  2 +-
 src/client/views/nodes/DocumentView.tsx            |  6 ++---
 src/client/views/nodes/WebBox.tsx                  |  4 +--
 src/client/views/pdf/PDFViewer.tsx                 |  4 +--
 src/fields/util.ts                                 |  6 +----
 10 files changed, 33 insertions(+), 39 deletions(-)

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

diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 4a92ed262..8c8bb6fde 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -122,20 +122,23 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
 
         @action.bound
         removeDocument(doc: Doc | Doc[]): boolean {
-            const docs = doc instanceof Doc ? [doc] : doc;
-            docs.map(doc => doc.isPushpin = doc.annotationOn = undefined);
-            const targetDataDoc = this.dataDoc;
-            const value = DocListCast(targetDataDoc[this.annotationKey]);
-            const toRemove = value.filter(v => docs.includes(v));
-
-            if (toRemove.length !== 0) {
-                const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
-                toRemove.forEach(doc => {
-                    Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey, doc);
-                    recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
-                    doc.deleted = true;
-                });
-                return true;
+            const effectiveAcl = GetEffectiveAcl(this.dataDoc);
+            if (effectiveAcl === AclAdmin || effectiveAcl === AclEdit) {
+                const docs = doc instanceof Doc ? [doc] : doc;
+                docs.map(doc => doc.isPushpin = doc.annotationOn = undefined);
+                const targetDataDoc = this.dataDoc;
+                const value = DocListCast(targetDataDoc[this.annotationKey]);
+                const toRemove = value.filter(v => docs.includes(v));
+
+                if (toRemove.length !== 0) {
+                    const recent = Cast(Doc.UserDoc().myRecentlyClosed, Doc) as Doc;
+                    toRemove.forEach(doc => {
+                        Doc.RemoveDocFromList(targetDataDoc, this.props.fieldKey + "-annotations", doc);
+                        recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
+                        doc.deleted = true;
+                    });
+                    return true;
+                }
             }
 
             return false;
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index cfe76f361..596c5931b 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -607,9 +607,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
             return (null);
         }
         const canDelete = SelectionManager.SelectedDocuments().some(docView => {
-            const docAcl = GetEffectiveAcl(docView.props.Document);
-            const collectionAcl = GetEffectiveAcl(docView.props.ContainingCollectionDoc);
-            return [docAcl, collectionAcl].some(acl => [AclAdmin, AclEdit].includes(acl));
+            const collectionAcl = GetEffectiveAcl(docView.props.ContainingCollectionDoc?.[DataSym]);
+            return collectionAcl === AclAdmin || collectionAcl === AclEdit;
         });
         const minimal = bounds.r - bounds.x < 100 ? true : false;
         const maximizeIcon = minimal ? (
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 1fc0ed034..be6aa6be2 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -1,6 +1,6 @@
 import { action } from "mobx";
 import { DateField } from "../../fields/DateField";
-import { Doc, DocListCast, AclEdit, AclAdmin } from "../../fields/Doc";
+import { Doc, DocListCast } from "../../fields/Doc";
 import { Id } from "../../fields/FieldSymbols";
 import { InkTool } from "../../fields/InkField";
 import { List } from "../../fields/List";
@@ -23,7 +23,6 @@ import PDFMenu from "./pdf/PDFMenu";
 import { ContextMenu } from "./ContextMenu";
 import GroupManager from "../util/GroupManager";
 import { CollectionFreeFormViewChrome } from "./collections/CollectionMenu";
-import { GetEffectiveAcl } from "../../fields/util";
 
 const modifiers = ["control", "meta", "shift", "alt"];
 type KeyHandler = (keycode: string, e: KeyboardEvent) => KeyControlInfo | Promise<KeyControlInfo>;
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 0ca28df9c..1ddae97ce 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -3,7 +3,7 @@ import { faArrowAltCircleDown, faArrowAltCircleRight, faArrowAltCircleUp, faChec
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { action, computed, observable, runInAction } from "mobx";
 import { observer } from "mobx-react";
-import { Doc, DocListCast, AclEdit, AclAdmin } from "../../fields/Doc";
+import { Doc } from "../../fields/Doc";
 import { RichTextField } from '../../fields/RichTextField';
 import { Cast, NumCast, BoolCast } from "../../fields/Types";
 import { emptyFunction, setupMoveUpEvents, Utils } from "../../Utils";
@@ -30,7 +30,6 @@ import { undoBatch, UndoManager } from '../util/UndoManager';
 import { DocumentType } from '../documents/DocumentTypes';
 import { InkField } from '../../fields/InkField';
 import { PresBox } from './nodes/PresBox';
-import { GetEffectiveAcl } from "../../fields/util";
 const higflyout = require("@hig/flyout");
 export const { anchorPoints } = higflyout;
 export const Flyout = higflyout.default;
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index a048d4ebd..7562d7e9c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -142,7 +142,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
         const targetDataDoc = this.props.Document[DataSym];
         const docList = DocListCast(targetDataDoc[this.props.fieldKey]);
         const added = docs.filter(d => !docList.includes(d));
-        const effectiveAcl = GetEffectiveAcl(this.props.Document);
+        const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
 
         if (added.length) {
             if (effectiveAcl === AclPrivate || effectiveAcl === AclReadonly) {
@@ -193,10 +193,8 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
 
     @action.bound
     removeDocument = (doc: any): boolean => {
-        const collectionEffectiveAcl = GetEffectiveAcl(this.props.Document);
-        const docEffectiveAcl = GetEffectiveAcl(doc);
-        // you can remove the document if you either have Admin/Edit access to the collection or to the specific document
-        if (collectionEffectiveAcl === AclEdit || collectionEffectiveAcl === AclAdmin || docEffectiveAcl === AclAdmin || docEffectiveAcl === AclEdit) {
+        const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
+        if (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) {
             const docs = doc instanceof Doc ? [doc] : doc as Doc[];
             const targetDataDoc = this.props.Document[DataSym];
             const value = DocListCast(targetDataDoc[this.props.fieldKey]);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index a396dc6c8..54b09ab72 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -278,7 +278,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
         } else {
             this._downX = x;
             this._downY = y;
-            const effectiveAcl = GetEffectiveAcl(this.props.Document);
+            const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
             if ([AclAdmin, AclEdit, AclAddonly].includes(effectiveAcl)) PreviewCursor.Show(x, y, this.onKeyPress, this.props.addLiveTextDocument, this.props.getTransform, this.props.addDocument, this.props.nudge);
             this.clearSelection();
         }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 58f8bdaac..a1c934e81 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -9,7 +9,7 @@ import { listSpec } from "../../../fields/Schema";
 import { SchemaHeaderField } from '../../../fields/SchemaHeaderField';
 import { ScriptField } from '../../../fields/ScriptField';
 import { BoolCast, Cast, NumCast, ScriptCast, StrCast } from "../../../fields/Types";
-import { GetEffectiveAcl, SharingPermissions, TraceMobx } from '../../../fields/util';
+import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
 import { MobileInterface } from '../../../mobile/MobileInterface';
 import { GestureUtils } from '../../../pen-gestures/GestureUtils';
 import { emptyFunction, emptyPath, OmitKeys, returnOne, returnTransparent, Utils } from "../../../Utils";
@@ -179,7 +179,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
         RadialMenu.Instance.openMenu(pt.pageX - 15, pt.pageY - 15);
 
         // RadialMenu.Instance.addItem({ description: "Open Fields", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "map-pin", selected: -1 });
-        const effectiveAcl = GetEffectiveAcl(this.props.Document);
+        const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
         (effectiveAcl === AclEdit || effectiveAcl === AclAdmin) && RadialMenu.Instance.addItem({ description: "Delete", event: () => { this.props.ContainingCollectionView?.removeDocument(this.props.Document), RadialMenu.Instance.closeMenu(); }, icon: "external-link-square-alt", selected: -1 });
         // RadialMenu.Instance.addItem({ description: "Open in a new tab", event: () => this.props.addDocTab(this.props.Document, "onRight"), icon: "trash", selected: -1 });
         RadialMenu.Instance.addItem({ description: "Pin", event: () => this.props.pinToPres(this.props.Document), icon: "map-pin", selected: -1 });
@@ -992,7 +992,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
 
     render() {
         if (!(this.props.Document instanceof Doc)) return (null);
-        if (GetEffectiveAcl(this.props.Document) === AclPrivate) return (null);
+        if (GetEffectiveAcl(this.props.Document[DataSym]) === AclPrivate) return (null);
         if (this.props.Document.hidden) return (null);
         const backgroundColor = Doc.UserDoc().renderStyle === "comic" ? undefined : this.props.forcedBackgroundColor?.(this.Document) || StrCast(this.layoutDoc._backgroundColor) || StrCast(this.layoutDoc.backgroundColor) || StrCast(this.Document.backgroundColor) || this.props.backgroundColor?.(this.Document, this.props.renderDepth);
         const opacity = Cast(this.layoutDoc._opacity, "number", Cast(this.layoutDoc.opacity, "number", Cast(this.Document.opacity, "number", null)));
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 3283f568a..f37909e6e 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -4,7 +4,7 @@ import { action, computed, IReactionDisposer, observable, reaction, runInAction
 import { observer } from "mobx-react";
 import { Dictionary } from "typescript-collections";
 import * as WebRequest from 'web-request';
-import { Doc, DocListCast, Opt, AclAddonly, AclEdit, AclAdmin } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, AclAddonly, AclEdit, AclAdmin, DataSym } from "../../../fields/Doc";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Id } from "../../../fields/FieldSymbols";
 import { HtmlField } from "../../../fields/HtmlField";
@@ -535,7 +535,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
     @action
     highlight = (color: string) => {
         // creates annotation documents for current highlights
-        const effectiveAcl = GetEffectiveAcl(this.props.Document);
+        const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
         const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) ? this.makeAnnotationDocument(color) : undefined;
         annotationDoc && this.addDocument?.(annotationDoc);
         return annotationDoc ?? undefined;
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 7c1b2f621..cca86adb5 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -4,7 +4,7 @@ const pdfjs = require('pdfjs-dist/es5/build/pdf.js');
 import * as Pdfjs from "pdfjs-dist";
 import "pdfjs-dist/web/pdf_viewer.css";
 import { Dictionary } from "typescript-collections";
-import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym, AclAddonly, AclEdit, AclAdmin } from "../../../fields/Doc";
+import { Doc, DocListCast, FieldResult, HeightSym, Opt, WidthSym, AclAddonly, AclEdit, AclAdmin, DataSym } from "../../../fields/Doc";
 import { documentSchema } from "../../../fields/documentSchemas";
 import { Id } from "../../../fields/FieldSymbols";
 import { InkTool } from "../../../fields/InkField";
@@ -573,7 +573,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
     @action
     highlight = (color: string) => {
         // creates annotation documents for current highlights
-        const effectiveAcl = GetEffectiveAcl(this.props.Document);
+        const effectiveAcl = GetEffectiveAcl(this.props.Document[DataSym]);
         const annotationDoc = [AclAddonly, AclEdit, AclAdmin].includes(effectiveAcl) && this.makeAnnotationDocument(color);
         annotationDoc && this.addDocument?.(annotationDoc);
         return annotationDoc as Doc ?? undefined;
diff --git a/src/fields/util.ts b/src/fields/util.ts
index 7d3268b80..3d832636f 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -161,15 +161,11 @@ export function GetEffectiveAcl(target: any, in_prop?: string | symbol | number)
     if (target[AclSym] && Object.keys(target[AclSym]).length) {
 
         // if the current user is the author of the document / the current user is a member of the admin group
-        // but not if the doc in question is an alias - the current user will be the author of their alias rather than the original author
-        if ((Doc.CurrentUserEmail === (target.__fields?.author || target.author) && !(target.aliasOf || target.__fields?.aliasOf)) || currentUserGroups.includes("admin")) return AclAdmin;
+        if (Doc.CurrentUserEmail === (target.__fields?.author || target.author) || currentUserGroups.includes("admin")) return AclAdmin;
 
         // if the ACL is being overriden or the property being modified is one of the playground fields (which can be freely modified)
         if (_overrideAcl || (in_prop && DocServer.PlaygroundFields?.includes(in_prop.toString()))) return AclEdit;
 
-        // if it's your alias then you can manipulate the x, y, width, height
-        if ((target.aliasOf || target.__fields?.aliasOf) && Doc.CurrentUserEmail === (target.__fields?.author || target.author) && (in_prop && ["_width", "_height", "x", "y"].includes(in_prop.toString()))) return AclEdit;
-
         let effectiveAcl = AclPrivate;
         const HierarchyMapping = new Map<symbol, number>([
             [AclPrivate, 0],
-- 
cgit v1.2.3-70-g09d2


From 8460f4e5c3a409a095e87a0b841b097d20a4e466 Mon Sep 17 00:00:00 2001
From: bobzel <zzzman@gmail.com>
Date: Thu, 13 Aug 2020 09:41:56 -0400
Subject: made stayInCollection a layout property

---
 src/client/documents/Documents.ts               | 2 +-
 src/client/util/CurrentUserUtils.ts             | 6 +++---
 src/client/views/InkingStroke.tsx               | 2 +-
 src/client/views/PropertiesButtons.tsx          | 2 +-
 src/client/views/collections/CollectionView.tsx | 2 +-
 src/fields/documentSchemas.ts                   | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

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

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index fe50ed0b3..42ba4d2c4 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -185,7 +185,7 @@ export interface DocumentOptions {
     targetContainer?: Doc; // document whose proto will be set to 'panel' as the result of a onClick click script
     searchFileTypes?: List<string>; // file types allowed in a search query
     strokeWidth?: number;
-    stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere
+    _stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere
     treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view
     treeViewHideTitle?: boolean; // whether to hide the title of a tree view
     treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items.
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index a73a13858..536baadd4 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -536,7 +536,7 @@ export class CurrentUserUtils {
                     iconShape: "square",
                     title,
                     _backgroundColor: "black",
-                    stayInCollection: true,
+                    _stayInCollection: true,
                     childDropAction: "same",
                     _width: 60,
                     _height: 60,
@@ -727,7 +727,7 @@ export class CurrentUserUtils {
         if (doc.myCatalog === undefined) {
             doc.myCatalog = new PrefetchProxy(Docs.Create.SchemaDocument([], [], {
                 title: "CATALOG", _height: 1000, _fitWidth: true, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false,
-                childDropAction: "alias", targetDropAction: "same", stayInCollection: true, treeViewOpen: true, system: true
+                childDropAction: "alias", targetDropAction: "same", _stayInCollection: true, treeViewOpen: true, system: true
             }));
         }
 
@@ -747,7 +747,7 @@ export class CurrentUserUtils {
         doc.myRecentlyClosed === undefined;
         if (doc.myRecentlyClosed === undefined) {
             doc.myRecentlyClosed = new PrefetchProxy(Docs.Create.TreeDocument([], {
-                title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, stayInCollection: true, system: true
+                title: "RECENTLY CLOSED", _height: 75, forceActive: true, boxShadow: "0 0", treeViewPreventOpen: false, treeViewOpen: true, _stayInCollection: true, system: true
             }));
         }
         // this is equivalent to using PrefetchProxies to make sure the recentlyClosed doc is ready
diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx
index e3390426b..41311ed86 100644
--- a/src/client/views/InkingStroke.tsx
+++ b/src/client/views/InkingStroke.tsx
@@ -43,7 +43,7 @@ export class InkingStroke extends ViewBoxBaseComponent<FieldViewProps, InkDocume
         this.props.Document._backgroundColor = "rgba(0,0,0,0.7)";
         this.props.Document.mixBlendMode = "hard-light";
         this.props.Document.color = "#9b9b9bff";
-        this.props.Document.stayInCollection = true;
+        this.props.Document._stayInCollection = true;
         this.props.Document.isInkMask = true;
     }
 
diff --git a/src/client/views/PropertiesButtons.tsx b/src/client/views/PropertiesButtons.tsx
index 2451ff55a..54effe559 100644
--- a/src/client/views/PropertiesButtons.tsx
+++ b/src/client/views/PropertiesButtons.tsx
@@ -639,7 +639,7 @@ export class PropertiesButtons extends React.Component<{}, {}> {
             this.selectedDoc._backgroundColor = "rgba(0,0,0,0.7)";
             this.selectedDoc.mixBlendMode = "hard-light";
             this.selectedDoc.color = "#9b9b9bff";
-            this.selectedDoc.stayInCollection = true;
+            this.selectedDoc._stayInCollection = true;
             this.selectedDoc.isInkMask = true;
         }
     }
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 7562d7e9c..6dd21ef7f 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -222,7 +222,7 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
             return true;
         }
         const first = doc instanceof Doc ? doc : doc[0];
-        if (!first?.stayInCollection && addDocument !== returnFalse) {
+        if (!first?._stayInCollection && addDocument !== returnFalse) {
             if (UndoManager.RunInTempBatch(() => this.removeDocument(doc))) {
                 const added = addDocument(doc);
                 if (!added) UndoManager.UndoTempBatch();
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index ada13226e..848a648e1 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -102,7 +102,7 @@ export const documentSchema = createSchema({
     _lockedTransform: "boolean",// whether a freeformview can pan/zoom
 
     // drag drop properties
-    stayInCollection: "boolean",// whether document can be dropped into a different collection
+    _stayInCollection: "boolean",// whether document can be dropped into a different collection
     dragFactory: Doc,           // the document that serves as the "template" for the onDragStart script.  ie, to drag out copies of the dragFactory document.
     dropAction: "string",       // override specifying what should happen when this document is dropped (can be "alias", "copy", "move")
     targetDropAction: "string", // allows the target of a drop event to specify the dropAction ("alias", "copy", "move") NOTE: if the document is dropped within the same collection, the dropAction is coerced to 'move'
-- 
cgit v1.2.3-70-g09d2

