From d252d6dba8b789215ed8da5b66889a26b06a2a18 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sat, 3 Apr 2021 20:13:58 -0400
Subject: dashboard sharing works, aliases to go

---
 src/client/util/SharingManager.tsx | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

(limited to 'src/client/util/SharingManager.tsx')

diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index ded56d1da..ca14154b2 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -5,7 +5,7 @@ import { observer } from "mobx-react";
 import * as React from "react";
 import Select from "react-select";
 import * as RequestPromise from "request-promise";
-import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
+import { AclAddonly, AclAdmin, AclEdit, AclPrivate, AclReadonly, AclSym, AclUnset, DataSym, Doc, DocListCast, DocListCastAsync, Opt } from "../../fields/Doc";
 import { List } from "../../fields/List";
 import { Cast, StrCast } from "../../fields/Types";
 import { distributeAcls, GetEffectiveAcl, normalizeEmail, SharingPermissions, TraceMobx } from "../../fields/util";
@@ -17,6 +17,7 @@ import { MainViewModal } from "../views/MainViewModal";
 import { DocumentView } from "../views/nodes/DocumentView";
 import { TaskCompletionBox } from "../views/nodes/TaskCompletedBox";
 import { SearchBox } from "../views/search/SearchBox";
+import { CurrentUserUtils } from "./CurrentUserUtils";
 import { DocumentManager } from "./DocumentManager";
 import { GroupManager, UserOptions } from "./GroupManager";
 import { GroupMemberView } from "./GroupMemberView";
@@ -170,6 +171,7 @@ export class SharingManager extends React.Component<{}> {
             doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc);
             distributeAcls(acl, permission as SharingPermissions, doc);
 
+            this.setDashboardBackground(doc, permission as SharingPermissions);
             if (permission !== SharingPermissions.None) return Doc.AddDocToList(sharingDoc, storage, doc);
             else return GetEffectiveAcl(doc, user.email) === AclPrivate && Doc.RemoveDocFromList(sharingDoc, storage, (doc.aliasOf as Doc || doc));
         }).some(success => !success);
@@ -192,6 +194,7 @@ export class SharingManager extends React.Component<{}> {
         return !docs.map(doc => {
             doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc);
             distributeAcls(acl, permission as SharingPermissions, doc);
+            this.setDashboardBackground(doc, permission as SharingPermissions);
 
             if (group instanceof Doc) {
                 const members: string[] = JSON.parse(StrCast(group.members));
@@ -246,6 +249,25 @@ export class SharingManager extends React.Component<{}> {
         }
     }
 
+    /**
+     * Sets the background of the Dashboard if it has been shared as a visual indicator
+     */
+    setDashboardBackground = async (doc: Doc, permission: SharingPermissions) => {
+        if (Doc.IndexOf(doc, DocListCast(CurrentUserUtils.MyDashboards.data)) !== -1) {
+            if (permission !== SharingPermissions.None) {
+                doc.isShared = true;
+                doc.backgroundColor = "green";
+            }
+            else {
+                const acls = doc[DataSym][AclSym];
+                if (Object.keys(acls).every(key => key === `acl-${Doc.CurrentUserEmailNormalized}` ? true : [AclUnset, AclPrivate].includes(acls[key]))) {
+                    doc.isShared = undefined;
+                    doc.backgroundColor = undefined;
+                }
+            }
+        }
+    }
+
     /**
      * Removes the documents shared with a user through a group when the user is removed from the group.
      * @param group 
-- 
cgit v1.2.3-70-g09d2


From 2e76877dc1c9c5b1c226f5bd0394d17cabfec0b4 Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Mon, 17 May 2021 18:01:44 -0400
Subject: trying dynamic off screen docs

---
 src/client/documents/Documents.ts                  | 20 ++++++++--
 src/client/util/CurrentUserUtils.ts                | 33 ++++++++++++++---
 src/client/util/SharingManager.tsx                 | 40 ++++++++++++--------
 .../views/collections/CollectionDockingView.tsx    | 43 ++++++++++++++--------
 src/client/views/collections/TreeView.tsx          |  9 ++++-
 src/fields/util.ts                                 | 18 +++++----
 6 files changed, 115 insertions(+), 48 deletions(-)

(limited to 'src/client/util/SharingManager.tsx')

diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 1e2919bad..906603d78 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -648,8 +648,9 @@ export namespace Docs {
          * constructor just generates a new GUID. This is currently used
          * only when creating a DockDocument from the current user's already existing
          * main document.
+         * @param layoutData whether the fieldKey field on the layout doc should store the data or the data doc
          */
-        function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string) {
+        function InstanceFromProto(proto: Doc, data: Field | undefined, options: DocumentOptions, delegId?: string, fieldKey: string = "data", protoId?: string, layoutData?: boolean) {
             const viewKeys = ["x", "y", "system"]; // keys that should be addded to the view document even though they don't begin with an "_"
             const { omit: dataProps, extract: viewProps } = OmitKeys(options, viewKeys, "^_");
 
@@ -660,7 +661,17 @@ export namespace Docs {
             dataProps[`${fieldKey}-lastModified`] = new DateField;
             dataProps["acl-Override"] = "None";
             dataProps["acl-Public"] = Doc.UserDoc()?.defaultAclPrivate ? SharingPermissions.None : SharingPermissions.Add;
-            dataProps[fieldKey] = data;
+
+            if (layoutData) {
+                viewProps[fieldKey] = data;
+                const list = new List<Doc>();
+                console.log(DocListCast(data));
+                DocListCast(data).forEach(doc => {
+                    list.push(...DocListCast(doc.data));
+                });
+                dataProps[fieldKey + "-all"] = list;
+            }
+            else dataProps[fieldKey] = data;
             // so that the list of annotations is already initialised, prevents issues in addonly.
             // without this, if a doc has no annotations but the user has AddOnly privileges, they won't be able to add an annotation because they would have needed to create the field's list which they don't have permissions to do.
             dataProps[fieldKey + "-annotations"] = new List<Doc>();
@@ -891,7 +902,7 @@ export namespace Docs {
         export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
             const tabs = TreeDocument(documents, { title: "On-Screen Tabs", childDontRegisterViews: true, freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", _fitWidth: true, system: true });
             const all = TreeDocument([], { title: "Off-Screen Tabs", childDontRegisterViews: true, freezeChildren: "add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", system: true });
-            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
+            return InstanceFromProto(Prototypes.get(DocumentType.COL), new List([tabs, all]), { freezeChildren: "remove|add", treeViewExpandedViewLock: true, treeViewExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id, undefined, undefined, true);
         }
 
         export function DirectoryImportDocument(options: DocumentOptions = {}) {
@@ -1426,4 +1437,7 @@ Scripting.addGlobal(function generateLinkTitle(self: Doc) {
     const anchor2title = self.anchor2 && self.anchor2 !== self ? Cast(self.anchor2, Doc, null).title : "<?>";
     const relation = self.linkRelationship || "to";
     return `${anchor1title} (${relation}) ${anchor2title}`;
+});
+Scripting.addGlobal(function openTabAlias(tab: Doc) {
+    CollectionDockingView.AddSplit(Doc.MakeAlias(tab), "right");
 });
\ No newline at end of file
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 5dbded00e..6fdf649a4 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -750,7 +750,7 @@ export class CurrentUserUtils {
                 title: "My Dashboards", _height: 400, childHideLinkButton: true,
                 treeViewHideTitle: true, _xMargin: 5, _yMargin: 5, _gridGap: 5, _forceActive: true, childDropAction: "alias",
                 treeViewTruncateTitleWidth: 150, ignoreClick: true,
-                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", system: true
+                _lockedPosition: true, boxShadow: "0 0", childDontRegisterViews: true, targetDropAction: "same", treeViewType: "fileSystem", isFolder: true, system: true
             }));
             const newDashboard = ScriptField.MakeScript(`createNewDashboard(Doc.UserDoc())`);
             (doc.myDashboards as any as Doc).contextMenuScripts = new List<ScriptField>([newDashboard!]);
@@ -851,7 +851,6 @@ export class CurrentUserUtils {
         CurrentUserUtils.setupPresentations(doc);
         CurrentUserUtils.setupFilesystem(doc);
         CurrentUserUtils.setupRecentlyClosedDocs(doc);
-        // CurrentUserUtils.setupFilterDocs(doc);
         CurrentUserUtils.setupUserDoc(doc);
     }
 
@@ -1186,7 +1185,11 @@ export class CurrentUserUtils {
             title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`,
         };
         const freeformDoc = CurrentUserUtils.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
-        const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row");
+        const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, "row"); // add isFolder:true here?
+        freeformDoc.context = dashboardDoc;
+
+        DocListCast(dashboardDoc.data)[1].data = ComputedField.MakeFunction(`dynamicOffScreenDocs(dashboardDoc)`, { dashboardDoc: Doc.name }, { dashboardDoc }) as any;
+
         Doc.AddDocToList(myPresentations, "data", presentation);
         userDoc.activePresentation = presentation;
         const toggleTheme = ScriptField.MakeScript(`self.darkScheme = !self.darkScheme`);
@@ -1252,7 +1255,25 @@ Scripting.addGlobal(function shareDashboard(dashboard: Doc) {
     SharingManager.Instance.open(undefined, dashboard);
 },
     "opens sharing dialog for Dashboard");
-Scripting.addGlobal(function addToDashboards(dashboard: Doc) { Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboard); },
+Scripting.addGlobal(function addToDashboards(dashboard: Doc) {
+    const dashboardAlias = Doc.MakeAlias(dashboard);
+    dashboardAlias.data = new List<Doc>(DocListCast(dashboard.data).map(tabFolder => Doc.MakeAlias(tabFolder)));
+    // DocListCast(dashboardAlias.data).forEach(tabFolder => {
+    //     tabFolder.data = new List<Doc>(DocListCast(tabFolder.data).map(tab => Doc.MakeAlias(tab)));
+    // });
+    Doc.AddDocToList(CurrentUserUtils.MyDashboards, "data", dashboardAlias);
+    CurrentUserUtils.openDashboard(Doc.UserDoc(), dashboardAlias);
+},
     "adds Dashboard to set of Dashboards");
-Scripting.addGlobal(function toggleComicMode() { Doc.UserDoc().renderStyle = Doc.UserDoc().renderStyle === "comic" ? undefined : "comic"; },
-    "toggle between regular rendeing and an informal sketch/comic style");
+
+Scripting.addGlobal(function dynamicOffScreenDocs(dashboard: Doc) {
+    const allDocs = DocListCast(dashboard[DataSym]["data-all"]);
+    console.log(allDocs);
+    const onScreenTab = DocListCast(dashboard.data)[0];
+    const onScreenDocs = DocListCast(onScreenTab.data);
+    return allDocs.reduce((result: Doc[], doc) => {
+        !onScreenDocs.includes(doc) && (result.push(doc));
+        // console.log(doc);
+        return result;
+    }, []);
+});
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 2f8ecd4ee..18f254cd6 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -173,10 +173,14 @@ export class SharingManager extends React.Component<{}> {
         const target = targetDoc || this.targetDoc!;
         const acl = `acl-${normalizeEmail(user.email)}`;
         const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`;
+        console.log(DocListCast(CurrentUserUtils.MyDashboards.data));
+        console.log(target);
+        console.log(DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target));
+        const isDashboard = DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target) !== -1;
 
         const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document);
         return !docs.map(doc => {
-            doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc);
+            doc.author === Doc.CurrentUserEmail && !doc[myAcl] && distributeAcls(myAcl, SharingPermissions.Admin, doc, undefined, undefined, isDashboard);
 
             if (permission === SharingPermissions.None) {
                 if (doc[acl] && doc[acl] !== SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 1) - 1;
@@ -185,7 +189,7 @@ export class SharingManager extends React.Component<{}> {
                 if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numUsersShared = NumCast(doc.numUsersShared, 0) + 1;
             }
 
-            distributeAcls(acl, permission as SharingPermissions, doc);
+            distributeAcls(acl, permission as SharingPermissions, doc, undefined, undefined, isDashboard);
 
             this.setDashboardBackground(doc, permission as SharingPermissions);
             if (permission !== SharingPermissions.None) return Doc.AddDocToList(sharingDoc, storage, doc);
@@ -203,12 +207,13 @@ export class SharingManager extends React.Component<{}> {
         const target = targetDoc || this.targetDoc!;
         const key = normalizeEmail(StrCast(group.title));
         const acl = `acl-${key}`;
+        const isDashboard = DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target) !== -1;
 
         const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document);
 
         // ! ensures it returns true if document has been shared successfully, false otherwise
         return !docs.map(doc => {
-            doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc);
+            doc.author === Doc.CurrentUserEmail && !doc[`acl-${Doc.CurrentUserEmailNormalized}`] && distributeAcls(`acl-${Doc.CurrentUserEmailNormalized}`, SharingPermissions.Admin, doc, undefined, undefined, isDashboard);
 
             if (permission === SharingPermissions.None) {
                 if (doc[acl] && doc[acl] !== SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 1) - 1;
@@ -217,7 +222,7 @@ export class SharingManager extends React.Component<{}> {
                 if (!doc[acl] || doc[acl] === SharingPermissions.None) doc.numGroupsShared = NumCast(doc.numGroupsShared, 0) + 1;
             }
 
-            distributeAcls(acl, permission as SharingPermissions, doc);
+            distributeAcls(acl, permission as SharingPermissions, doc, undefined, undefined, isDashboard);
             this.setDashboardBackground(doc, permission as SharingPermissions);
 
             if (group instanceof Doc) {
@@ -267,8 +272,10 @@ export class SharingManager extends React.Component<{}> {
             });
         }
         else {
+            const dashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
             docs.forEach(doc => {
-                if (GetEffectiveAcl(doc) === AclAdmin) distributeAcls(`acl-${shareWith}`, permission, doc);
+                const isDashboard = dashboards.indexOf(doc) !== -1;
+                if (GetEffectiveAcl(doc) === AclAdmin) distributeAcls(`acl-${shareWith}`, permission, doc, undefined, undefined, isDashboard);
             });
         }
     }
@@ -316,10 +323,11 @@ export class SharingManager extends React.Component<{}> {
      */
     removeGroup = (group: Doc) => {
         if (group.docsShared) {
+            const dashboards = DocListCast(CurrentUserUtils.MyDashboards.data);
             DocListCast(group.docsShared).forEach(doc => {
                 const acl = `acl-${StrCast(group.title)}`;
-
-                distributeAcls(acl, SharingPermissions.None, doc);
+                const isDashboard = dashboards.indexOf(doc) !== -1;
+                distributeAcls(acl, SharingPermissions.None, doc, undefined, undefined, isDashboard);
 
                 const members: string[] = JSON.parse(StrCast(group.members));
                 const users: ValidatedUser[] = this.users.filter(({ user: { email } }) => members.includes(email));
@@ -445,16 +453,16 @@ export class SharingManager extends React.Component<{}> {
         }
     }
 
-    distributeOverCollection = (targetDoc?: Doc) => {
-        const target = targetDoc || this.targetDoc!;
+    // distributeOverCollection = (targetDoc?: Doc) => {
+    //     const target = targetDoc || this.targetDoc!;
 
-        const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document);
-        docs.forEach(doc => {
-            for (const [key, value] of Object.entries(doc[AclSym])) {
-                distributeAcls(key, this.AclMap.get(value)! as SharingPermissions, target);
-            }
-        });
-    }
+    //     const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document);
+    //     docs.forEach(doc => {
+    //         for (const [key, value] of Object.entries(doc[AclSym])) {
+    //             distributeAcls(key, this.AclMap.get(value)! as SharingPermissions, target);
+    //         }
+    //     });
+    // }
 
     /**
      * Sorting algorithm to sort users.
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 388f9a909..819667834 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -4,7 +4,7 @@ import { action, IReactionDisposer, observable, reaction, runInAction } from "mo
 import { observer } from "mobx-react";
 import * as ReactDOM from 'react-dom';
 import * as GoldenLayout from "../../../client/goldenLayout";
-import { Doc, DocListCast, Opt, DocListCastAsync } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, DocListCastAsync, DataSym } from "../../../fields/Doc";
 import { Id } from '../../../fields/FieldSymbols';
 import { InkTool } from '../../../fields/InkField';
 import { List } from '../../../fields/List';
@@ -24,6 +24,7 @@ import React = require("react");
 import { DocumentType } from '../../documents/DocumentTypes';
 import { listSpec } from '../../../fields/Schema';
 import { LightboxView } from '../LightboxView';
+import { inheritParentAcls } from '../../../fields/util';
 const _global = (window /* browser */ || global /* node */) as any;
 
 @observer
@@ -160,6 +161,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
         }
         const instance = CollectionDockingView.Instance;
         if (!instance) return false;
+        else Doc.AddDocToList(instance.props.Document[DataSym], "data-all", document);
         const docContentConfig = CollectionDockingView.makeDocumentConfig(document, panelName);
 
         if (!pullSide && stack) {
@@ -381,15 +383,22 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
         setTimeout(async () => {
             const sublists = await DocListCastAsync(this.props.Document[this.props.fieldKey]);
             const tabs = sublists && Cast(sublists[0], Doc, null);
-            const other = sublists && Cast(sublists[1], Doc, null);
+            // const other = sublists && Cast(sublists[1], Doc, null);
             const tabdocs = await DocListCastAsync(tabs?.data);
-            const otherdocs = await DocListCastAsync(other?.data);
-            tabs && (Doc.GetProto(tabs).data = new List<Doc>(docs));
-            const otherSet = new Set<Doc>();
-            otherdocs?.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
-            tabdocs?.filter(doc => !docs.includes(doc) && doc.type !== DocumentType.KVP).forEach(doc => otherSet.add(doc));
-            const vals = Array.from(otherSet.values()).filter(val => val instanceof Doc).map(d => d).filter(d => d.type !== DocumentType.KVP);
-            other && (Doc.GetProto(other).data = new List<Doc>(vals));
+            // const otherdocs = await DocListCastAsync(other?.data);
+            if (tabs) {
+                tabs.data = new List<Doc>(docs);
+                // DocListCast(tabs.aliases).forEach(tab => tab !== tabs && (tab.data = new List<Doc>(docs)));
+            }
+            // const otherSet = new Set<Doc>();
+            // otherdocs?.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
+            // tabdocs?.filter(doc => !docs.includes(doc) && doc.type !== DocumentType.KVP).forEach(doc => otherSet.add(doc));
+            // const vals = Array.from(otherSet.values()).filter(val => val instanceof Doc).map(d => d).filter(d => d.type !== DocumentType.KVP);
+            // this.props.Document[DataSym][this.props.fieldKey + "-all"] = new List<Doc>([...docs, ...vals]);
+            // if (other) {
+            //     other.data = new List<Doc>(vals);
+            //     // DocListCast(other.aliases).forEach(tab => tab !== other && (tab.data = new List<Doc>(vals)));
+            // }
         }, 0);
     }
 
@@ -399,7 +408,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
         tab.reactComponents?.forEach((ele: any) => ReactDOM.unmountComponentAtNode(ele));
     }
     tabCreated = (tab: any) => {
-        tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab);  // have to explicitly initialize tabs that reuse contents from previous abs (ie, when dragging a tab around a new tab is created for the old content)
+        tab.contentItem.element[0]?.firstChild?.firstChild?.InitTab?.(tab);  // have to explicitly initialize tabs that reuse contents from previous tabs (ie, when dragging a tab around a new tab is created for the old content)
     }
 
     stackCreated = (stack: any) => {
@@ -407,9 +416,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
             if (e.target === stack.header?.element[0] && e.button === 2) {
                 const emptyPane = CurrentUserUtils.EmptyPane;
                 emptyPane["dragFactory-count"] = NumCast(emptyPane["dragFactory-count"]) + 1;
-                CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([], {
-                    _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`
-                }), "", stack);
+                const docToAdd = Docs.Create.FreeformDocument([], {
+                    _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`,
+                });
+                this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd);
+                CollectionDockingView.AddSplit(docToAdd, "", stack);
             }
         });
 
@@ -430,9 +441,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
                 // stack.config.fixed = !stack.config.fixed;  // force the stack to have a fixed size
                 const emptyPane = CurrentUserUtils.EmptyPane;
                 emptyPane["dragFactory-count"] = NumCast(emptyPane["dragFactory-count"]) + 1;
-                CollectionDockingView.AddSplit(Docs.Create.FreeformDocument([], {
+                const docToAdd = Docs.Create.FreeformDocument([], {
                     _width: this.props.PanelWidth(), _height: this.props.PanelHeight(), _fitWidth: true, title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`
-                }), "", stack);
+                });
+                this.props.Document.isShared && inheritParentAcls(this.props.Document, docToAdd);
+                CollectionDockingView.AddSplit(docToAdd, "", stack);
             }));
     }
 
diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx
index 2e98fb508..ba4af2a6d 100644
--- a/src/client/views/collections/TreeView.tsx
+++ b/src/client/views/collections/TreeView.tsx
@@ -151,7 +151,10 @@ export class TreeView extends React.Component<TreeViewProps> {
             this.treeViewOpen = !this.treeViewOpen;
         } else {
             // choose an appropriate alias or make one. --- choose the first alias that (1) user owns,  (2) has no context field ... otherwise make a new alias
+            // this.props.addDocTab(CurrentUserUtils.ActiveDashboard.isShared ? Doc.MakeAlias(this.props.document) : this.props.document, "add:right");
+            // choose an appropriate alias or make one -- -- choose the first alias that (1) the user owns, (2) has no context field - if I own it and someone else does not have it open,, otherwise create an alias
             this.props.addDocTab(this.props.document, "add:right");
+
         }
     }
     constructor(props: any) {
@@ -507,7 +510,11 @@ export class TreeView extends React.Component<TreeViewProps> {
                     [{ script: ScriptField.MakeFunction(`DocFocusOrOpen(self)`)!, label: "Focus or Open" }];
     }
     onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.treeChildClick));
-    onChildDoubleClick = () => (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick);
+
+    onChildDoubleClick = () => {
+        console.log(this.props.document.onChildDoubleClick);
+        return (!this.props.treeView.outlineMode && this._openScript?.()) || ScriptCast(this.doc.treeChildDoubleClick)
+    };
 
     refocus = () => this.props.treeView.props.focus(this.props.treeView.props.Document);
     ignoreEvent = (e: any) => {
diff --git a/src/fields/util.ts b/src/fields/util.ts
index a4c99928a..882c7fee8 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -136,11 +136,9 @@ export function denormalizeEmail(email: string) {
  * Copies parent's acl fields to the child
  */
 export function inheritParentAcls(parent: Doc, child: Doc) {
-    if (parent.isShared) {
-        const dataDoc = parent[DataSym];
-        for (const key of Object.keys(dataDoc)) {
-            key.startsWith("acl") && distributeAcls(key, dataDoc[key], child);
-        }
+    const dataDoc = parent[DataSym];
+    for (const key of Object.keys(dataDoc)) {
+        key.startsWith("acl") && distributeAcls(key, dataDoc[key], child);
     }
 }
 
@@ -228,7 +226,7 @@ function getEffectiveAcl(target: any, user?: string): symbol {
  * @param inheritingFromCollection whether the target is being assigned rights after being dragged into a collection (and so is inheriting the acls from the collection)
  * inheritingFromCollection is not currently being used but could be used if acl assignment defaults change
  */
-export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[]) {
+export function distributeAcls(key: string, acl: SharingPermissions, target: Doc, inheritingFromCollection?: boolean, visited?: Doc[], isDashboard?: boolean) {
     if (!visited) visited = [] as Doc[];
     if (visited.includes(target)) return;
     visited.push(target);
@@ -249,6 +247,12 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
     if (GetEffectiveAcl(target) === AclAdmin && (!inheritingFromCollection || !target[key] || HierarchyMapping.get(StrCast(target[key]))! > HierarchyMapping.get(acl)!)) {
         target[key] = acl;
         layoutDocChanged = true;
+
+        if (isDashboard) {
+            DocListCast(target[Doc.LayoutFieldKey(target)]).forEach(d => {
+                distributeAcls(key, acl, d, inheritingFromCollection, visited);
+            });
+        }
     }
 
     if (dataDoc && (!inheritingFromCollection || !dataDoc[key] || HierarchyMapping.get(StrCast(dataDoc[key]))! > HierarchyMapping.get(acl)!)) {
@@ -263,7 +267,7 @@ export function distributeAcls(key: string, acl: SharingPermissions, target: Doc
         links.forEach(link => distributeAcls(key, acl, link, inheritingFromCollection, visited));
 
         // maps over the children of the document
-        DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc)]).map(d => {
+        DocListCast(dataDoc[Doc.LayoutFieldKey(dataDoc) + (isDashboard ? "-all" : "")]).map(d => { // this is now on the layoutdoc instead - figure out the "data-all" approach for the datadoc
             // if (GetEffectiveAcl(d) === AclAdmin && (!inheritingFromCollection || !d[key] || HierarchyMapping.get(StrCast(d[key]))! > HierarchyMapping.get(acl)!)) {
             distributeAcls(key, acl, d, inheritingFromCollection, visited);
             // }
-- 
cgit v1.2.3-70-g09d2


From 7a31b05aa21d5cf99fac1ad031ab745266ca3fda Mon Sep 17 00:00:00 2001
From: usodhi <61431818+usodhi@users.noreply.github.com>
Date: Sun, 30 May 2021 18:03:31 -0400
Subject: sharingmanagaer cleanup

---
 src/client/util/SharingManager.tsx | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

(limited to 'src/client/util/SharingManager.tsx')

diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index 18f254cd6..db23941c7 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -39,7 +39,7 @@ interface GroupedOptions {
 }
 
 // const SharingKey = "sharingPermissions";
-// const PublicKey = "publicLinkPermissions";
+// const PublicKey = "all";
 // const DefaultColor = "black";
 
 // used to differentiate between individuals and groups when sharing
@@ -91,7 +91,7 @@ export class SharingManager extends React.Component<{}> {
     ]);
 
     // private get linkVisible() {
-    //     return this.sharingDoc ? this.sharingDoc[PublicKey] !== SharingPermissions.None : false;
+    //     return this.targetDoc ? this.targetDoc["acl-" + PublicKey] !== SharingPermissions.None : false;
     // }
 
     public open = (target?: DocumentView, target_doc?: Doc) => {
@@ -173,9 +173,6 @@ export class SharingManager extends React.Component<{}> {
         const target = targetDoc || this.targetDoc!;
         const acl = `acl-${normalizeEmail(user.email)}`;
         const myAcl = `acl-${Doc.CurrentUserEmailNormalized}`;
-        console.log(DocListCast(CurrentUserUtils.MyDashboards.data));
-        console.log(target);
-        console.log(DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target));
         const isDashboard = DocListCast(CurrentUserUtils.MyDashboards.data).indexOf(target) !== -1;
 
         const docs = SelectionManager.Views().length < 2 ? [target] : SelectionManager.Views().map(docView => docView.props.Document);
@@ -340,11 +337,11 @@ export class SharingManager extends React.Component<{}> {
 
 
     // private setExternalSharing = (permission: string) => {
-    //     const sharingDoc = this.sharingDoc;
-    //     if (!sharingDoc) {
+    //     const targetDoc = this.targetDoc;
+    //     if (!targetDoc) {
     //         return;
     //     }
-    //     sharingDoc[PublicKey] = permission;
+    //     targetDoc["acl-" + PublicKey] = permission;
     // }
 
     // private get sharingUrl() {
@@ -595,7 +592,7 @@ export class SharingManager extends React.Component<{}> {
 
         // the list of groups shared with
         const groupListMap: (Doc | { title: string })[] = groups.filter(({ title }) => docs.length > 1 ? commonKeys.includes(`acl-${normalizeEmail(StrCast(title))}`) : true);
-        groupListMap.unshift({ title: "Public" });//, { title: "Override" });
+        groupListMap.unshift({ title: "Public" });//, { title: "ALL" });
         const groupListContents = groupListMap.map(group => {
             const groupKey = `acl-${StrCast(group.title)}`;
             const uniform = docs.every(doc => this.layoutDocAcls ? doc?.[AclSym]?.[groupKey] === docs[0]?.[AclSym]?.[groupKey] : doc?.[DataSym]?.[AclSym]?.[groupKey] === docs[0]?.[DataSym]?.[AclSym]?.[groupKey]);
@@ -644,6 +641,11 @@ export class SharingManager extends React.Component<{}> {
                     <div className={"close-button"} onClick={this.close}>
                         <FontAwesomeIcon icon={"times"} color={"black"} size={"lg"} />
                     </div>
+                    {/* {this.linkVisible ?
+                        <div>
+                            {this.sharingUrl}
+                        </div> :
+                        (null)} */}
                     {<div className="share-container">
                         <div className="share-setup">
                             <Select
-- 
cgit v1.2.3-70-g09d2

